ELEC50010-IAC-CW/rtl/mips_cpu_control.v

200 lines
8.9 KiB
Coq
Raw Normal View History

2020-12-07 11:49:44 +00:00
module mips_cpu_control(
input logic[31:0] Instr,
input logic ALUCond,
output logic[1:0] CtrlRegDst,
2020-12-07 11:49:44 +00:00
output logic[1:0] CtrlPC,
output logic CtrlMemRead,
output logic[1:0] CtrlMemtoReg,
2020-12-07 11:49:44 +00:00
output logic[4:0] CtrlALUOp,
output logic[4:0] Ctrlshamt,
output logic CtrlMemWrite,
output logic CtrlALUSrc,
output logic CtrlRegWrite
);
2020-12-01 07:30:57 +00:00
2020-12-07 11:49:44 +00:00
typedef enum logic[5:0]{
SPECIAL = 6'd0,
REGIMM = 6'd1,
J = 6'd2,
JAL = 6'd3,
BEQ = 6'd4,
BNE = 6'd5,
BLEZ = 6'd6,
BGTZ = 6'd7,
ADDI = 6'd8,
ADDIU = 6'd9,
SLTI = 6'd10,
SLTIU = 6'd11,
ANDI = 6'd12,
ORI = 6'd13,
XORI = 6'd14,
LUI = 6'd15,
LB = 6'd32,
LH = 6'd33,
LWL = 6'd34,
LW = 6'd35,
LBU = 6'd36,
LHU = 6'd37,
LWR = 6'd38,
SB = 6'd40,
SH = 6'd41,
SW = 6'd43
} op_enum;
op_enum op;
assign op = Instr[31:26];
2020-12-07 11:49:44 +00:00
typedef enum logic[5:0]{
SLL = 6'd0,
SRL = 6'd2,
SRA = 6'd3,
SLLV = 6'd4,
SRLV = 6'd6,
SRAV = 6'd7,
JR = 6'd8,
JALR = 6'd9,
MTHI = 6'd17,
MTLO = 6'd19,
MULT = 6'd24,
MULTU = 6'd25,
DIV = 6'd26,
DIVU = 6'd27,
ADDU = 6'd33,
SUBU = 6'd35,
AND = 6'd36,
OR = 6'd37,
XOR = 6'd38,
SLT = 6'd42,
SLTU = 6'd43
} funct_enum;
funct_enum funct;
assign funct = Instr[5:0];
typedef enum logic[4:0]{
BLTZ = 5'd0,
BGEZ = 5'd1,
BLTZAL = 5'd16,
BGEZAL = 5'd17
} rt_enum;
rt_enum rt;
assign rt = Instr[20:16];
2020-12-07 11:49:44 +00:00
always @(*) begin
2020-12-07 11:49:44 +00:00
//CtrlRegDst logic
if((op == ADDIU | op == ANDI | op == LB | op == LBU | op == LH | op == LHU | op == LUI | op == LW | op == LWL | op == LWR | op == ORI | op == SLTI | op == SLTIU | op == XORI))begin
CtrlRegDst = 2'd0; //Write address comes from rt
end else if ((op == SPECIAL) & ((funct == ADDU | funct == AND | funct == JALR | funct == OR | funct == SLL | funct == SLLV | funct == SLT | funct == SLTU | funct == SRA | funct == SRAV | funct == SRL | funct == SRLV | funct == SUBU | funct == XOR)))begin
CtrlRegDst = 2'd1; //Write address comes from rd
end else if (op == JAL)begin
CtrlRegDst = 2'd2; //const reg 31, for writing to the link register
2020-12-07 11:49:44 +00:00
end else begin CtrlRegDst = 1'bx; end//Not all instructions are encompassed so, added incase for debug purposes
//CtrlPC logic
if(ALUCond & ( (op == BEQ | op == BGTZ | op ==BLEZ | op ==BNE | (op == REGIMM & ((rt == BGEZ | rt == BGEZAL | rt == BLTZ | rt == BLTZAL))))))begin
2020-12-07 11:49:44 +00:00
CtrlPC = 2'd1; // Branches - Jumps relative to PC
$display("Ctrl PC Branch");
end else if( (op == J | op == JAL))begin
2020-12-07 11:49:44 +00:00
CtrlPC = 2'd2; // Jumps within 256MB Region using 26-bit immediate in J type instruction
$display("Ctrl PC Jump Immediate");
end else if((funct == JR | funct == JALR))begin
2020-12-07 11:49:44 +00:00
CtrlPC = 2'd3; // Jumps using Register.
$display("Ctrl PC Jump Register");
end else begin CtrlPC = 2'd0; $display("Ctrl PC No Jump/Branch");end // No jumps or branches, just increment to next word
2020-12-07 11:49:44 +00:00
//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.
if((op == LB | op == LBU | op == LH | op == LHU | op == LW | op == LWL | op == LWR))begin
2020-12-07 11:49:44 +00:00
CtrlMemRead = 1;//Memory is read enabled
CtrlMemtoReg = 2'd1;//write data port of memory is fed from data memory
end else if ((op == ADDIU | op == ANDI | op == ORI | op == SLTI | op == SLTIU | op == XORI | (op == SPECIAL & (funct == (ADDU | AND | DIV | DIVU | MTHI | MTLO | MULT | MULTU | OR | SLL | SLLV | SLT | SLTU | SRA | SRAV | SRL | SRLV | SUBU | XOR)))))begin
2020-12-07 11:49:44 +00:00
CtrlMemRead = 0;//Memory is read disabled
CtrlMemtoReg = 2'd0;//write data port of memory is fed from ALURes
end else if ((op == JAL) | ((op == SPECIAL) & (funct == JALR)))begin
CtrlMemtoReg = 2'd2;//write data port of memory is fed from PC + 8
2020-12-07 11:49:44 +00:00
end else begin CtrlMemRead = 1'bx;end//Not all instructions are encompassed so, added incase for debug purposes
//CtrlALUOp Logic
if((op == ADDIU | (op == SPECIAL & (funct == ADDU))))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd0; //ADD from ALUOps
end else if ((op == ANDI | (op == SPECIAL & (funct == AND))))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd4;//AND from ALUOps
end else if (op == BEQ) begin
CtrlALUOp = 5'd13;//EQ from ALUOps
end else if ((op == REGIMM & ((rt == BGEZ | rt == BGEZAL))))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd17;//GEQ from ALUOps
end else if (op == BGTZ)begin
CtrlALUOp = 5'd16;//GRT from ALUOps
end else if (op == BLEZ)begin
CtrlALUOp = 5'd15;//LEQ from ALUOps
end else if ((op == REGIMM & ((rt == BLTZ | rt == BLTZAL))))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd14;//LES from ALUOps
end else if (op == BNE)begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd18;//NEQ from ALUOps
end else if ((op == SPECIAL & (funct == DIV)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd3;//DIV from ALUOps
end else if ((op == SPECIAL & (funct == DIVU)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd23;//DIVU from ALUOps
end else if ((op == LB | op == LBU | op == LH | op == LHU | op == LW | op == LWL | op == LWR | op == SB | op == SH | op == SW))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd0;//ADD from ALUOps
end else if (op == LUI)begin
CtrlALUOp = 5'd7;//SLL from ALUOps
end else if ((op == SPECIAL & (funct == MTHI | MTLO)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd19;//PAS from ALUOps
end else if ((op == SPECIAL & (funct == MULT)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd2;//MUL from ALUOps
end else if ((op == SPECIAL & (funct == MULTU)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd22;//MULU from ALUOps
end else if ((op == ORI | (op == SPECIAL & (funct == OR))))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd5;//OR from ALUOps
end else if (op == SPECIAL & (funct == SLL))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd7;//SLL from ALUOps
end else if (op == SPECIAL & (funct == SLLV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd8;//SLLV from ALUOps
end else if (op == SPECIAL & (funct == SRA))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd11;//SRA from ALUOps
end else if (op == SPECIAL & (funct == SRAV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd12;//SRAV from ALUOps
end else if (op == SPECIAL & (funct == SRL))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd9;//SRL from ALUOps
end else if (op == SPECIAL & (funct == SRLV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd10;//SRLV from ALUOps
end else if (op == SLTI | (op == SPECIAL & (funct == SLT)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd20;//SLT from ALUOps
end else if (op == SLTIU | (op == SPECIAL & (funct == SLTU)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd21;//SLTU from ALUOps
end else if (op == SPECIAL & (funct == SUBU))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd1;//SUB from ALUOps
end else if (op == XORI | (op == SPECIAL & (funct == XOR)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd6;//XOR from ALUOps
end else begin
CtrlALUOp = 5'bxxxxx;
2020-12-01 07:30:57 +00:00
end
2020-12-07 11:49:44 +00:00
//Ctrlshamt logic
if(op == SPECIAL & (funct == (SRA | SRL | SLL)))begin
2020-12-07 11:49:44 +00:00
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 | op == SH | op == SW)begin
2020-12-07 11:49:44 +00:00
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 | op == ANDI | op == LUI | op == ORI | op == SLTI | op == SLTIU | op == XORI | op == LB | op == LBU | op == LH | op == LHU | op == LW | op == LWL | op == LWR | op == SB | op == SH | op == SW))begin
2020-12-07 11:49:44 +00:00
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 | op == BGTZ | op == BLEZ | op == BNE | (op == REGIMM & ((rt == BGEZ | rt == BGEZAL | rt == BLTZ | rt == BLTZAL))) | (op == SPECIAL & ((funct == ADDU | funct == AND | funct == DIV | funct == DIVU | funct == MULT | funct == MULTU | funct == OR | funct == SLLV | funct == SLT | funct == SLTU | funct == SRAV | funct == SRLV | funct == SUBU | funct == XOR)))))begin
2020-12-07 11:49:44 +00:00
CtrlALUSrc = 0;///ALU Bus B is fed from rt.
end else begin CtrlALUSrc = 1'bx;end
//CtrlRegWrite logic
if((op == ADDIU | op == ANDI | op == LB | op == LBU | op == LH | op == LHU | op == LUI | op == LW | op == LWL | op == LWR | op == ORI | op == SLTI | op == SLTIU | op == XORI | (op == SPECIAL & ((funct == ADDU | funct == AND | funct == DIV | funct == DIVU | funct == MULT | funct == MULTU | funct == JALR | funct == OR | funct == SLL | funct == SLLV | funct == SLT | funct == SLTU | funct == SRA | funct == SRAV | funct == SRL | funct == SRLV | funct == SUBU | funct == XOR)))))begin
2020-12-07 11:49:44 +00:00
CtrlRegWrite = 1;//The Registers are Write Enabled
end else begin CtrlRegWrite = 0; end // The Registers are Write Disabled
2020-12-07 11:49:44 +00:00
end
2020-12-01 07:30:57 +00:00
endmodule