Updated ALU and Control

This commit is contained in:
jc4419 2020-12-07 15:49:44 +04:00
parent a2bcf3ed1b
commit 9198c4f51b
2 changed files with 250 additions and 349 deletions

View file

@ -1,6 +1,6 @@
module mips_cpu_alu( module mips_cpu_alu(
input signed logic[31:0] A, //Bus A - Input from the Readdata1 output from the reg file which corresponds to rs. input logic[31:0] A, //Bus A - Input from the Readdata1 output from the reg file which corresponds to rs.
input signed logic[31:0] B, //Bus B - Input from the Readdata2 output from the reg file which corresponds to rt. input logic[31:0] B, //Bus B - Input from the Readdata2 output from the reg file which corresponds to rt. Or from the 16-bit immediate sign extended to 32-bit value taken from Instr[15-0].
input logic [4:0] ALUOp, // 5-bit output from Control that tells the alu what operation to do from a list of 20 distinct alu operations(see below). input logic [4:0] ALUOp, // 5-bit output from Control that tells the alu what operation to do from a list of 20 distinct alu operations(see below).
input logic [4:0] shamt, //5-bit input used to specify shift amount for shift operations. Taken directly from the R-type instruction (Non-Variable) or from input logic [4:0] shamt, //5-bit input used to specify shift amount for shift operations. Taken directly from the R-type instruction (Non-Variable) or from
@ -11,9 +11,9 @@ module mips_cpu_alu(
/* /*
Alu Operations: Alu Operations:
-Manipulation Operations: The perform an operation on a value(s). -Manipulation Operations: They perform an operation on a value(s) and have an output to ALURes.
- Addition - Addition (unsigned)
- Subtraction - Subtraction (unsigned)
- Multiplication - Multiplication
- Division - Division
- Bitwise AND - Bitwise AND
@ -25,14 +25,18 @@ Alu Operations:
- Shift Right Logical Variable - Shift Right Logical Variable
- Shift Right Arithmetic - Shift Right Arithmetic
- Shift Right Arithmetic Variable - Shift Right Arithmetic Variable
-Condtional Check Operations: They check conditions. - Set On Less Than (signed)
- Equality (=) - Set On Less Than Unsigned
- Less Than (<) - Multiplication (unsigned)
- Less Than or Equal To (<=) - Division (unsigned)
- Greater Than (>) -Condtional Check Operations: They check conditions and have an output to ALUCond
- Greater Than or Equal to (>=) - Equality (=) (signed)
- Negative Equality(=/=) - Less Than (<) (signed)
-Implementation Operation: - Less Than or Equal To (<=) (signed)
- Greater Than (>) (signed)
- Greater Than or Equal to (>=) (signed)
- Negative Equality(=/=) (signed)
-Implementation Operation: A design choice used for implmentation.
- Pass-through (Used to implement MTHI and MTLO, as these instructions do not need the ALU but the alu is in the pathway to the regfile, so the register value simply passes through.) - Pass-through (Used to implement MTHI and MTLO, as these instructions do not need the ALU but the alu is in the pathway to the regfile, so the register value simply passes through.)
*/ */
@ -41,8 +45,8 @@ Alu Operations:
ADD = 5'd0, ADD = 5'd0,
SUB = 5'd1, SUB = 5'd1,
MUL = 5'd2, MUL = 5'd2,//signed multiply
DIV = 5'd3, DIV = 5'd3,//signed divide
AND = 5'd4, AND = 5'd4,
OR = 5'd5, OR = 5'd5,
XOR = 5'd6, XOR = 5'd6,
@ -58,11 +62,16 @@ Alu Operations:
GRT = 5'd16, GRT = 5'd16,
GEQ = 5'd17, GEQ = 5'd17,
NEQ = 5'd18, NEQ = 5'd18,
PAS = 5'd19 PAS = 5'd19,
SLT = 5'd20,//signed compare
SLTU = 5'd21,//unsigned compare
MULU = 5'd22,//unsigned divide
DIVU = 5'd23//unsigned multiply
} Ops; } Ops;
Ops ALUOps; //Note confusing naming to avoid potential duplicate variable naming errors, as a result of enum implemetnation quirks. Ops ALUOps; //Note confusing naming to avoid potential duplicate variable naming errors, as a result of enum implemetnation.
assign ALUOps = ALUOp assign ALUOps = ALUOp
@ -72,19 +81,19 @@ assign ALUOps = ALUOp
case(ALUOps) case(ALUOps)
ADD: begin ADD: begin
ALURes = A + B; ALURes = $signed(A) + $signed(B);
end end
SUB: begin SUB: begin
ALURes = A - B; ALURes = $signed(A) - $signed(B) ;
end end
MUL: begin MUL: begin
ALURes = A * B; ALURes = $signed(A) * $signed(B);
end end
DIV: begin DIV: begin
ALURes = A / B; ALURes = $signed(A) / $signed(B);
end end
AND: begin AND: begin
@ -124,7 +133,7 @@ assign ALUOps = ALUOp
end end
EQ: begin EQ: begin
if A == B begin if ($signed(A) == $signed(B)) begin
ALUCond = 1; ALUCond = 1;
end end
else begin else begin
@ -134,7 +143,7 @@ assign ALUOps = ALUOp
end end
LES: begin LES: begin
if A < B begin if ($signed(A) < $signed(B)) begin
ALUCond = 1; ALUCond = 1;
end end
else begin else begin
@ -144,17 +153,7 @@ assign ALUOps = ALUOp
end end
LEQ: begin LEQ: begin
if A <= B begin if ($signed(A) <= $signed(B)) begin
ALUCond = 1;
end
else begin
ALUCond = 0;
end
end
LEQ: begin
if A <= B begin
ALUCond = 1; ALUCond = 1;
end end
else begin else begin
@ -164,7 +163,7 @@ assign ALUOps = ALUOp
end end
GRT: begin GRT: begin
if A > B begin if ($signed(A) > $signed(B)) begin
ALUCond = 1; ALUCond = 1;
end end
else begin else begin
@ -174,7 +173,7 @@ assign ALUOps = ALUOp
end end
GEQ: begin GEQ: begin
if A >= B begin if ($signed(A) >= $signed(B)) begin
ALUCond = 1; ALUCond = 1;
end end
else begin else begin
@ -184,7 +183,7 @@ assign ALUOps = ALUOp
end end
NEQ: begin NEQ: begin
if A != B begin if ($signed(A) != $signed(B)) begin
ALUCond = 1; ALUCond = 1;
end end
else begin else begin
@ -197,6 +196,26 @@ assign ALUOps = ALUOp
ALURes = A; ALURes = A;
end end
SLT: begin
if ($signed(A) < $signed(B)) begin
ALURes = 1;
end
end
SLTU: begin
if (A < B) begin
ALURes = 1;
end
end
MULU: begin
ALURes = A * B;
end
DIVU: begin
ALURes = A / B;
end
endcase endcase
end end
endmodule endmodule

View file

@ -1,319 +1,201 @@
/* module mips_cpu_control(
Instr
*0: XOR SUBU SRLV SRL SRAV SRA SLTU SLT SLLV
SLL OR MULTU MULT MTLO MTHI JR JALR DIVU
DIV AND ADDU
1: BLTZAL BLTZ BGEZAL BGEZ
2: J
3: JAL
4: BEQ
5: BNE
6: BLEZ
7: BGTZ
*9: ADDIU
10: SLTI
11: SLTIU
12: ANDI
13: ORI
14: XORI
15: LUI
32: LB
33: LH
34: LWL
*35: LW
36: LBU
37: LHU
38: LWR
40: SB
41: SH
*43: SW
*/
/* input logic[31:0] Instr,
Regdst: input logic ALUCond,
00:Instr[20-16]
01:Instr[15-11] output logic CtrlRegDst,
10:2'd31 output logic[1:0] CtrlPC,
*/ output logic CtrlMemRead,
output logic CtrlMemtoReg,
output logic[4:0] CtrlALUOp,
output logic[4:0] Ctrlshamt,
output logic CtrlMemWrite,
output logic CtrlALUSrc,
output logic CtrlRegWrite
/* );
Memtoreg:
00: Alu output
01: Memory output
10: PC+4 output
*/
//Commented signals represents dont care(x) /* logic[5:0] op;
logic[5:0] funct;
logic[4:0] rt; */
module mips_cpu_control{ /* assign op = Instr[31:26];
input logic[5:0] Instr, assign funct = Instr[5:0];
input logic[5:0] rt, assign rt = Instr[20:16]; */
output logic[1:0] Regdst,
output logic Branch,
output logic Memread,
output logic[1:0] Memtoreg,
output logic Memwrite,
output logic Alusrc,
output logic Regwrite,
output logic Jump,
);
always_comb begin typedef enum logic[5:0]{
case(Instr) SPECIAL = 6'd0,
6'd0: begin REGIMM = 6'd1,
Regdst=2'b01; J = 6'd2,
Branch=0; JAL = 6'd3,
Memread=0; BEQ = 6'd4,
Memwrite=0; BNE = 6'd5,
Memtoreg=2'b00; BLEZ = 6'd6,
Alusrc=0; BGTZ = 6'd7,
Regwrite=1; ADDI = 6'd8,
Jump=0; ADDIU = 6'd9,
end SLTI = 6'd10,
6'd1: begin SLTIU = 6'd11,
Regdst=2'b10; ANDI = 6'd12,
Branch=1; ORI = 6'd13,
Memread=0; XORI = 6'd14,
Memwrite=0; LUI = 6'd15,
if(rt[5]==1)begin LB = 6'd32,
Memtoreg=2'b10; LH = 6'd33,
Regwrite=1; LWL = 6'd34,
end LW = 6'd35,
Alusrc=0; LBU = 6'd36,
Jump=0; LHU = 6'd37,
end LWR = 6'd38,
6'd2: begin SB = 6'd40,
//Regdst=2'b; SH = 6'd41,
Branch=0; SW = 6'd43
Memread=0; } op_enum;
//Memtoreg=; op_enum op;
Memwrite=0; assign op = Instr[31:26];
//Alusrc=;
Regwrite=0; typedef enum logic[5:0]{
Jump=1; SLL = 6'd0,
end SRL = 6'd2,
6'd3: begin SRA = 6'd3,
Regdst=2'b10; SLLV = 6'd4,
Branch=0; SRLV = 6'd6,
Memread=0; SRAV = 6'd7,
Memtoreg=2'b10; JR = 6'd8,
Memwrite=0; JALR = 6'd9,
//Alusrc=; MTHI = 6'd17,
Regwrite=1; MTLO = 6'd19,
Jump=1; MULT = 6'd24,
end MULTU = 6'd25,
6'd4: begin DIV = 6'd26,
//Regdst=2'b; DIVU = 6'd27,
Branch=1; ADDU = 6'd33,
Memread=0; SUBU = 6'd35,
//Memtoreg=; AND = 6'd36,
Memwrite=0; OR = 6'd37,
Alusrc=0; XOR = 6'd38,
Regwrite=0; SLT = 6'd42,
Jump=0; SLTU = 6'd43
end } funct_enum;
6'd5: begin funct_enum funct;
//Regdst=2'b; assign funct = Instr[5:0];
Branch=1;
Memread=0; typedef enum logic[4:0]{
//Memtoreg=; BLTZ = 5'd0,
Memwrite=0; BGEZ = 5'd1,
Alusrc=0; BLTZAL = 5'd16,
Regwrite=0 BGEZAL = 5'd17
Jump=0; } rt_enum;
end rt_enum rt;
6'd6: begin assign rt = Instr[20:16];
//Regdst=2'b;
Branch=1; always_comb begin
Memread=0;
//Memtoreg=; //CtrlRegDst logic
Memwrite=0; if(op == (ADDIU | ANDI | LB | LBU | LH | LHU | LUI | LW | LWL | LWR | ORI | SLTI | SLTIU | XORI))begin
Alusrc=0; CtrlRegDst = 0; //Write address comes from rt
Regwrite=0; end else if (op == (SPECIAL & (funct == (ADDU | AND | JALR | OR | SLL | SLLV | SLT | SLTU | SRA | SRAV | SRL | SRLV | SUBU | XOR))))begin
Jump=0; CtrlRegDst = 1; //Write address comes from rd
end end else begin CtrlRegDst = 1'bx; end//Not all instructions are encompassed so, added incase for debug purposes
6'd7: begin
//Regdst=2'b; //CtrlPC logic
Branch=1; if(op == (BEQ | BGTZ | BLEZ | BNE | (REGIMM & (rt == (BGEZ | BGEZAL | BLTZ | BLTZAL)))))begin
Memread=0; CtrlPC = 2'd1; // Branches - Jumps relative to PC
//Memtoreg=; end else if(op == (J | JAL))begin
Memwrite=0; CtrlPC = 2'd2; // Jumps within 256MB Region using 26-bit immediate in J type instruction
Alusrc=0; end else if(op == (JR | JALR))begin
Regwrite=0; CtrlPC = 2'd3; // Jumps using Register.
Jump=0; end else begin CtrlPC = 2'd0;end // No jumps, just increment to next word
end
6'd9: begin //CtrlMemRead and CtrlMemtoReg logic -- Interesting quirk that they have the same logic. Makes sense bc you'd only want to select the read data out when the memory itself is read enabled.
Regdst=2'b00; if(op == (LB | LBU | LH | LHU | LW | LWL | LWR))begin
Branch=0; CtrlMemRead = 1;//Memory is read enabled
Memread=0; CtrlMemtoReg = 1;//write data port of memory is fed from data memory
Memtoreg=2'b00; end else if (op == (ADDIU | ANDI | ORI | SLTI | SLTIU | XORI | (SPECIAL & (funct == (ADDU | AND | DIV | DIVU | MTHI | MTLO | MULT | MULTU | OR | SLL | SLLV | SLT | SLTU | SRA | SRAV | SRL | SRLV | SUBU | XOR)))))begin
Memwrite=0; CtrlMemRead = 0;//Memory is read disabled
Alusrc=1; CtrlMemtoReg = 0;//write data port of memory if fed from ALURes
Regwrite=1; end else begin CtrlMemRead = 1'bx;end//Not all instructions are encompassed so, added incase for debug purposes
Jump=0;
end //CtrlALUOp Logic
6'd10: begin if(op == (ADDIU | (SPECIAL & (funct == ADDU))))begin
Regdst=2'b00; CtrlALUOp = 5'd0; //ADD from ALUOps
Branch=0; end else if (op == (ANDI | (SPECIAL & (funct == AND))))begin
Memread=0; CtrlALUOp = 5'd4;//AND from ALUOps
Memtoreg=2'b00; end else if (op == BEQ) begin
Memwrite=0; CtrlALUOp = 5'd13;//EQ from ALUOps
Alusrc=1; end else if (op == (REGIMM & (rt == (BGEZ | BGEZAL))))begin
Regwrite=1; CtrlALUOp = 5'd17;//GEQ from ALUOps
Jump=0; end else if (op == BGTZ)begin
end CtrlALUOp = 5'd16;//GRT from ALUOps
6'd11: begin end else if (op == BLEZ)begin
Regdst=2'b00; CtrlALUOp = 5'd15;//LEQ from ALUOps
Branch=0; end else if (op == (REGIMM & (rt == (BLTZ | BLTZAL))))begin
Memread=0; CtrlALUOp = 5'd14;//LES from ALUOps
Memtoreg=2'b00; end else if (OP == BNE)begin
Memwrite=0; CtrlALUOp = 5'd18;//NEQ from ALUOps
Alusrc=1; end else if (op == (SPECIAL & (funct == DIV)))begin
Regwrite=1; CtrlALUOp = 5'd3;//DIV from ALUOps
Jump=0; end else if (op == (SPECIAL & (funct == DIVU)))begin
end CtrlALUOp = 5'd23;//DIVU from ALUOps
6'd12: begin end else if (op == (LB | LBU | LH | LHU | LW | LWL | LWR | SB | SBH | SW))begin
Regdst=2'b00; CtrlALUOp = 5'd0;//ADD from ALUOps
Branch=0; end else if (op == LUI)begin
Memread=0; CtrlALUOp = 5'd7;//SLL from ALUOps
Memtoreg=2'b00; end else if (op == (SPECIAL & (funct == MTHI | MTLO)))begin
Memwrite=0; CtrlALUOp = 5'd19;//PAS from ALUOps
Alusrc=1; end else if (op == (SPECIAL & (funct == MULT)))begin
Regwrite=1; CtrlALUOp = 5'd2;//MUL from ALUOps
Jump=0; end else if (op == (SPECIAL & (funct == MULTU)))begin
end CtrlALUOp = 5'd22;//MULU from ALUOps
6'd13: begin end else if (op == (ORI | (SPECIAL & (funct == OR))))begin
Regdst=2'b00; CtrlALUOp = 5'd5;//OR from ALUOps
Branch=0; end else if (op == (SPECIAL & (funct == SLL)))begin
Memread=0; CtrlALUOp = 5'd7;//SLL from ALUOps
Memtoreg=2'b00; end else if (op == (SPECIAL & (funct == SLLV)))begin
Memwrite=0; CtrlALUOp = 5'd8;//SLLV from ALUOps
Alusrc=1; end else if (op == (SPECIAL & (funct == SRA)))begin
Regwrite=1; CtrlALUOp = 5'd11;//SRA from ALUOps
Jump=0; end else if (op == (SPECIAL & (funct == SRAV)))begin
end CtrlALUOp = 5'd12;//SRAV from ALUOps
6'd14: begin end else if (op == (SPECIAL & (funct == SRL)))begin
Regdst=2'b00; CtrlALUOp = 5'd9;//SRL from ALUOps
Branch=0; end else if (op == (SPECIAL & (funct == SRLV)))begin
Memread=0; CtrlALUOp = 5'd10;//SRLV from ALUOps
Memtoreg=2'b00; end else if (op == (SLTI | (SPECIAL & (funct == SLT))))begin
Memwrite=0; CtrlALUOp = 5'd20;//SLT from ALUOps
Alusrc=1; end else if (op == (SLTIU | (SPECIAL & (funct == SLTU))))begin
Regwrite=1; CtrlALUOp = 5'd21;//SLTU from ALUOps
Jump=0; end else if (op == (SPECIAL & (funct == SUBU)))begin
end CtrlALUOp = 5'd1;//SUB from ALUOps
6'd15: begin end else if (op == (XORI | (SPECIAL & (funct == XOR))))begin
Regdst=2'b00; CtrlALUOp = 5'd6;//XOR from ALUOps
Branch=0; end else begin
Memread=0; CtrlALUOp = 5'bxxxxx;
Memtoreg=2b'00;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd32: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd33: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd34: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd35: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd36: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd37: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd38: begin
Regdst=2'b00;
Branch=0;
Memread=1;
Memtoreg=2'b01;
Memwrite=0;
Alusrc=1;
Regwrite=1;
Jump=0;
end
6'd40: begin
//Regdst=2'b;
Branch=0;
Memread=0;
//Memtoreg=;
Memwrite=1;
Alusrc=1;
Regwrite=0;
Jump=0;
end
6'd41: begin
//Regdst=2'b;
Branch=0;
Memread=0;
//Memtoreg=;
Memwrite=1;
Alusrc=1;
Regwrite=0;
Jump=0;
end
6'd43: begin
//Regdst=2'b;
Branch=0;
Memread=0;
//Memtoreg=;
Memwrite=1;
Alusrc=1;
Regwrite=0;
Jump=0;
end
endcase
end end
//Ctrlshamt logic
if(op == (SPECIAL & (funct == (SRA | SRL | SLL))))begin
Ctrlshamt = Instr[10:6];// Shift amount piped in from the instruction
end else if(op == LUI)begin
Ctrlshamt = 5'd16;//Used specifically to implement LUI as the instruction itslef does not include shamt
end else begin Ctrlshamt = 5'bxxxxx;end
//CtrlMemWrite logic
if(op == (SB | SH | SW)begin
CtrlMemWrite = 1;//Memory is write enabled
end else begin CtrlMemWrite = 0;end//default is 0 to ensure no accidental overwriting.
//CtrlALUSrc logic
if(op == (ADDIU | ANDI | LUI | ORI | SLTI | SLTIU | XORI | LB | LBU | LH | LHU | LW | LWL | LWR | SB | SH | SW)begin
CtrlALUSrc = 1;//ALU Bus B is fed from the 16-bit immediate sign extended to 32-bit value taken from Instr[15-0]
end else if (op == (BEQ | BGTZ | BLEZ | BNE | (REGIMM & (rt == (BGEZ | BGEZAL | BLTZ | BLTZAL)) (SPECIAL & (funct == (ADDU | AND | DIV | DIVU | MULT | MULTU | OR | SLLV | SLT | SLTU | SRAV | SRLV | SUBU | XOR)))))begin
CtrlALUSrc = 0;///ALU Bus B is fed from rt.
end else begin CtrlALUSrc = 1'bx;end
//CtrlRegWrite logic
if(op == (ADDIU | ANDI | LB | LBU | LH | LHU | LUI | LW | LWL | LWR | ORI | SLTI | SLTIU | XORI | (SPECIAL & (funct == (ADDU | AND | DIV | DIVU | MULT | MULTU | JALR | OR | SLL | SLLV | SLT | SLTU | SRA | SRAV | SRL | SRLV | SUBU | XOR)))))begin
CtrlRegWrite = 1;//The Registers are Write Enabled
end else begin CtrlRegWrite = 0;end // The Registers are Write Disabled
end
endmodule endmodule