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]
10:2'd31
*/
/* output logic CtrlRegDst,
Memtoreg: output logic[1:0] CtrlPC,
00: Alu output output logic CtrlMemRead,
01: Memory output output logic CtrlMemtoReg,
10: PC+4 output output logic[4:0] CtrlALUOp,
*/ output logic[4:0] Ctrlshamt,
output logic CtrlMemWrite,
output logic CtrlALUSrc,
output logic CtrlRegWrite
//Commented signals represents dont care(x) );
module mips_cpu_control{ /* logic[5:0] op;
input logic[5:0] Instr, logic[5:0] funct;
input logic[5:0] rt, logic[4:0] rt; */
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 /* assign op = Instr[31:26];
case(Instr) assign funct = Instr[5:0];
6'd0: begin assign rt = Instr[20:16]; */
Regdst=2'b01;
Branch=0; typedef enum logic[5:0]{
Memread=0; SPECIAL = 6'd0,
Memwrite=0; REGIMM = 6'd1,
Memtoreg=2'b00; J = 6'd2,
Alusrc=0; JAL = 6'd3,
Regwrite=1; BEQ = 6'd4,
Jump=0; BNE = 6'd5,
end BLEZ = 6'd6,
6'd1: begin BGTZ = 6'd7,
Regdst=2'b10; ADDI = 6'd8,
Branch=1; ADDIU = 6'd9,
Memread=0; SLTI = 6'd10,
Memwrite=0; SLTIU = 6'd11,
if(rt[5]==1)begin ANDI = 6'd12,
Memtoreg=2'b10; ORI = 6'd13,
Regwrite=1; XORI = 6'd14,
end LUI = 6'd15,
Alusrc=0; LB = 6'd32,
Jump=0; LH = 6'd33,
end LWL = 6'd34,
6'd2: begin LW = 6'd35,
//Regdst=2'b; LBU = 6'd36,
Branch=0; LHU = 6'd37,
Memread=0; LWR = 6'd38,
//Memtoreg=; SB = 6'd40,
Memwrite=0; SH = 6'd41,
//Alusrc=; SW = 6'd43
Regwrite=0; } op_enum;
Jump=1; op_enum op;
end assign op = Instr[31:26];
6'd3: begin
Regdst=2'b10; typedef enum logic[5:0]{
Branch=0; SLL = 6'd0,
Memread=0; SRL = 6'd2,
Memtoreg=2'b10; SRA = 6'd3,
Memwrite=0; SLLV = 6'd4,
//Alusrc=; SRLV = 6'd6,
Regwrite=1; SRAV = 6'd7,
Jump=1; JR = 6'd8,
end JALR = 6'd9,
6'd4: begin MTHI = 6'd17,
//Regdst=2'b; MTLO = 6'd19,
Branch=1; MULT = 6'd24,
Memread=0; MULTU = 6'd25,
//Memtoreg=; DIV = 6'd26,
Memwrite=0; DIVU = 6'd27,
Alusrc=0; ADDU = 6'd33,
Regwrite=0; SUBU = 6'd35,
Jump=0; AND = 6'd36,
end OR = 6'd37,
6'd5: begin XOR = 6'd38,
//Regdst=2'b; SLT = 6'd42,
Branch=1; SLTU = 6'd43
Memread=0; } funct_enum;
//Memtoreg=; funct_enum funct;
Memwrite=0; assign funct = Instr[5:0];
Alusrc=0;
Regwrite=0 typedef enum logic[4:0]{
Jump=0; BLTZ = 5'd0,
end BGEZ = 5'd1,
6'd6: begin BLTZAL = 5'd16,
//Regdst=2'b; BGEZAL = 5'd17
Branch=1; } rt_enum;
Memread=0; rt_enum rt;
//Memtoreg=; assign rt = Instr[20:16];
Memwrite=0;
Alusrc=0; always_comb begin
Regwrite=0;
Jump=0; //CtrlRegDst logic
end if(op == (ADDIU | ANDI | LB | LBU | LH | LHU | LUI | LW | LWL | LWR | ORI | SLTI | SLTIU | XORI))begin
6'd7: begin CtrlRegDst = 0; //Write address comes from rt
//Regdst=2'b; end else if (op == (SPECIAL & (funct == (ADDU | AND | JALR | OR | SLL | SLLV | SLT | SLTU | SRA | SRAV | SRL | SRLV | SUBU | XOR))))begin
Branch=1; CtrlRegDst = 1; //Write address comes from rd
Memread=0; end else begin CtrlRegDst = 1'bx; end//Not all instructions are encompassed so, added incase for debug purposes
//Memtoreg=;
Memwrite=0; //CtrlPC logic
Alusrc=0; if(op == (BEQ | BGTZ | BLEZ | BNE | (REGIMM & (rt == (BGEZ | BGEZAL | BLTZ | BLTZAL)))))begin
Regwrite=0; CtrlPC = 2'd1; // Branches - Jumps relative to PC
Jump=0; end else if(op == (J | JAL))begin
end CtrlPC = 2'd2; // Jumps within 256MB Region using 26-bit immediate in J type instruction
6'd9: begin end else if(op == (JR | JALR))begin
Regdst=2'b00; CtrlPC = 2'd3; // Jumps using Register.
Branch=0; end else begin CtrlPC = 2'd0;end // No jumps, just increment to next word
Memread=0;
Memtoreg=2'b00; //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.
Memwrite=0; if(op == (LB | LBU | LH | LHU | LW | LWL | LWR))begin
Alusrc=1; CtrlMemRead = 1;//Memory is read enabled
Regwrite=1; CtrlMemtoReg = 1;//write data port of memory is fed from data memory
Jump=0; 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
end CtrlMemRead = 0;//Memory is read disabled
6'd10: begin CtrlMemtoReg = 0;//write data port of memory if fed from ALURes
Regdst=2'b00; end else begin CtrlMemRead = 1'bx;end//Not all instructions are encompassed so, added incase for debug purposes
Branch=0;
Memread=0; //CtrlALUOp Logic
Memtoreg=2'b00; if(op == (ADDIU | (SPECIAL & (funct == ADDU))))begin
Memwrite=0; CtrlALUOp = 5'd0; //ADD from ALUOps
Alusrc=1; end else if (op == (ANDI | (SPECIAL & (funct == AND))))begin
Regwrite=1; CtrlALUOp = 5'd4;//AND from ALUOps
Jump=0; end else if (op == BEQ) begin
end CtrlALUOp = 5'd13;//EQ from ALUOps
6'd11: begin end else if (op == (REGIMM & (rt == (BGEZ | BGEZAL))))begin
Regdst=2'b00; CtrlALUOp = 5'd17;//GEQ from ALUOps
Branch=0; end else if (op == BGTZ)begin
Memread=0; CtrlALUOp = 5'd16;//GRT from ALUOps
Memtoreg=2'b00; end else if (op == BLEZ)begin
Memwrite=0; CtrlALUOp = 5'd15;//LEQ from ALUOps
Alusrc=1; end else if (op == (REGIMM & (rt == (BLTZ | BLTZAL))))begin
Regwrite=1; CtrlALUOp = 5'd14;//LES from ALUOps
Jump=0; end else if (OP == BNE)begin
end CtrlALUOp = 5'd18;//NEQ from ALUOps
6'd12: begin end else if (op == (SPECIAL & (funct == DIV)))begin
Regdst=2'b00; CtrlALUOp = 5'd3;//DIV from ALUOps
Branch=0; end else if (op == (SPECIAL & (funct == DIVU)))begin
Memread=0; CtrlALUOp = 5'd23;//DIVU from ALUOps
Memtoreg=2'b00; end else if (op == (LB | LBU | LH | LHU | LW | LWL | LWR | SB | SBH | SW))begin
Memwrite=0; CtrlALUOp = 5'd0;//ADD from ALUOps
Alusrc=1; end else if (op == LUI)begin
Regwrite=1; CtrlALUOp = 5'd7;//SLL from ALUOps
Jump=0; end else if (op == (SPECIAL & (funct == MTHI | MTLO)))begin
end CtrlALUOp = 5'd19;//PAS from ALUOps
6'd13: begin end else if (op == (SPECIAL & (funct == MULT)))begin
Regdst=2'b00; CtrlALUOp = 5'd2;//MUL from ALUOps
Branch=0; end else if (op == (SPECIAL & (funct == MULTU)))begin
Memread=0; CtrlALUOp = 5'd22;//MULU from ALUOps
Memtoreg=2'b00; end else if (op == (ORI | (SPECIAL & (funct == OR))))begin
Memwrite=0; CtrlALUOp = 5'd5;//OR from ALUOps
Alusrc=1; end else if (op == (SPECIAL & (funct == SLL)))begin
Regwrite=1; CtrlALUOp = 5'd7;//SLL from ALUOps
Jump=0; end else if (op == (SPECIAL & (funct == SLLV)))begin
end CtrlALUOp = 5'd8;//SLLV from ALUOps
6'd14: begin end else if (op == (SPECIAL & (funct == SRA)))begin
Regdst=2'b00; CtrlALUOp = 5'd11;//SRA from ALUOps
Branch=0; end else if (op == (SPECIAL & (funct == SRAV)))begin
Memread=0; CtrlALUOp = 5'd12;//SRAV from ALUOps
Memtoreg=2'b00; end else if (op == (SPECIAL & (funct == SRL)))begin
Memwrite=0; CtrlALUOp = 5'd9;//SRL from ALUOps
Alusrc=1; end else if (op == (SPECIAL & (funct == SRLV)))begin
Regwrite=1; CtrlALUOp = 5'd10;//SRLV from ALUOps
Jump=0; end else if (op == (SLTI | (SPECIAL & (funct == SLT))))begin
end CtrlALUOp = 5'd20;//SLT from ALUOps
6'd15: begin end else if (op == (SLTIU | (SPECIAL & (funct == SLTU))))begin
Regdst=2'b00; CtrlALUOp = 5'd21;//SLTU from ALUOps
Branch=0; end else if (op == (SPECIAL & (funct == SUBU)))begin
Memread=0; CtrlALUOp = 5'd1;//SUB from ALUOps
Memtoreg=2b'00; end else if (op == (XORI | (SPECIAL & (funct == XOR))))begin
Memwrite=0; CtrlALUOp = 5'd6;//XOR from ALUOps
Alusrc=1; end else begin
Regwrite=1; CtrlALUOp = 5'bxxxxx;
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