ELEC50010-IAC-CW/rtl/mips_cpu_control.v

214 lines
10 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[2:0] CtrlMemtoReg,
2020-12-07 11:49:44 +00:00
output logic[4:0] CtrlALUOp,
output logic[4:0] Ctrlshamt,
output logic CtrlMemWrite,
2020-12-16 08:38:46 +00:00
output logic[1:0] CtrlALUSrc,
output logic CtrlRegWrite,
output logic CtrlSpcRegWriteEn
2020-12-07 11:49:44 +00:00
);
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;
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,
MFLO = 6'd18,
MFHI = 6'd16,
2020-12-07 11:49:44 +00:00
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;
2020-12-07 11:49:44 +00:00
typedef enum logic[4:0]{
BLTZ = 5'd0,
BGEZ = 5'd1,
BLTZAL = 5'd16,
BGEZAL = 5'd17
} rt_enum;
rt_enum rt;
always @(*) begin
assign op = Instr[31:26];
assign funct = Instr[5:0];
assign rt = Instr[20:16];
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==MFLO) || (funct==MFHI) || (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
2020-12-16 15:00:46 +00:00
end else if ((op == JAL) || ((op==REGIMM)&&((rt==BGEZAL) || (rt==BLTZAL))))begin
CtrlRegDst = 2'd2; //const reg 31, for writing to the link register
end else begin CtrlRegDst = 1'bx; end//Not all instructions are encompassed so, added incase for debug purposes
2020-12-07 11:49:44 +00:00
//CtrlPC logic
2020-12-09 12:24:21 +00:00
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
2020-12-09 12:24:21 +00:00
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
2020-12-16 08:38:46 +00:00
end else if((op==SPECIAL)&&((funct==JR) || (funct==JALR)))begin
2020-12-07 11:49:44 +00:00
CtrlPC = 2'd3; // Jumps using Register.
end else begin CtrlPC = 2'd0; end // No jumps or branches, just increment to next word
//CtrlMemRead and CtrlMemtoReg logic -- Interesting quirk that they have the same logic where both are concerned. Makes sense bc you'd only want to select the read data out when the memory itself is read enabled.
2020-12-09 12:24:21 +00:00
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 = 3'd1;//write data port of regfile is fed from data memory
2020-12-16 13:21:57 +00:00
end else if ((op==ADDIU) || (op==ANDI) || (op==ORI) || (op==LUI) || (op==SLTI) || (op==SLTIU) || (op==XORI) || ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (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
CtrlMemRead = 0;//Memory is read disabled
CtrlMemtoReg = 3'd0;//write data port of regfile is fed from ALURes
2020-12-16 15:00:46 +00:00
end else if ((op==JAL) || ((op==SPECIAL)&&(funct == JALR)) || ((op==REGIMM)&&((rt==BGEZAL) || (rt==BLTZAL))))begin
CtrlMemtoReg = 3'd2;//write data port of regfile is fed from PC + 8
2020-12-16 08:38:46 +00:00
end else if ((op==SPECIAL)&&(funct == MFHI))begin
CtrlMemtoReg = 3'd3;//write data port of regfile is fed from ALUHi
2020-12-16 08:38:46 +00:00
end else if ((op==SPECIAL)&&(funct == MFLO))begin
CtrlMemtoReg = 3'd4;//write data port of regfile is fed from ALULo
2020-12-17 17:02:58 +00:00
end else if (((op==SPECIAL)&&(funct == JR)) || (op == BEQ) || ((op==REGIMM)&&(rt==BGEZ)) || (op==BGTZ) || ((op==REGIMM)&&(rt==BLTZ)) || (op==BLEZ) || (op==BNE) || (op==J))begin
CtrlMemRead = 0;//Read disabled during jump
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
2020-12-07 11:49:44 +00:00
//CtrlALUOp Logic
2020-12-09 12:24:21 +00:00
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
2020-12-09 12:24:21 +00:00
end else if(op==BEQ) begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd13;//EQ from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==REGIMM)&&((rt==BGEZ) || (rt==BGEZAL)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd17;//GEQ from ALUOps
2020-12-09 12:24:21 +00:00
end else if(op==BGTZ)begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd16;//GRT from ALUOps
2020-12-09 12:24:21 +00:00
end else if(op==BLEZ)begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd15;//LEQ from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==REGIMM)&&((rt==BLTZ) || (rt==BLTZAL)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd14;//LES from ALUOps
2020-12-09 12:24:21 +00:00
end else if(op==BNE)begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd18;//NEQ from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==DIV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd3;//DIV from ALUOps
2020-12-09 12:24:21 +00:00
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
2020-12-09 12:24:21 +00:00
end else if(op==LUI)begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd7;//SLL from ALUOps
end else if((op==SPECIAL)&&((funct==MTHI)))begin
CtrlALUOp = 5'd24;//MTHI from ALUOps
end else if((op==SPECIAL)&&((funct==MTLO)))begin
CtrlALUOp = 5'd25;//MTLO from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==MULT))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd2;//MUL from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==MULTU))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd22;//MULU from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==ORI) || ((op==SPECIAL)&&(funct==OR)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd5;//OR from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SLL))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd7;//SLL from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SLLV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd8;//SLLV from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SRA))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd11;//SRA from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SRAV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd12;//SRAV from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SRL))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd9;//SRL from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SRLV))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd10;//SRLV from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SLTI) || ((op==SPECIAL)&&(funct==SLT)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd20;//SLT from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SLTIU) || ((op==SPECIAL)&&(funct==SLTU)))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd21;//SLTU from ALUOps
2020-12-09 12:24:21 +00:00
end else if((op==SPECIAL)&&(funct==SUBU))begin
2020-12-07 11:49:44 +00:00
CtrlALUOp = 5'd1;//SUB from ALUOps
2020-12-09 12:24:21 +00:00
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
2020-12-09 12:24:21 +00:00
if((op==SPECIAL)&&((funct==SRA) || (funct==SRL) || (funct==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
2020-12-09 12:24:21 +00:00
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.
//CtrlSpcRegWriteEn logic
2020-12-16 08:38:46 +00:00
if((op==SPECIAL)&&((funct==MTHI) || (funct==MTLO) || (funct==MULT) || (funct==MULTU) || (funct==DIV) || (funct==DIVU)))begin
CtrlSpcRegWriteEn = 1;//Special register Hi and Lo are write enabled
end else begin CtrlSpcRegWriteEn = 0;end//default is 0 to ensure no accidental overwriting.
2020-12-07 11:49:44 +00:00
//CtrlALUSrc logic
2020-12-16 08:38:46 +00:00
if((op==ADDIU) || (op==LUI) || (op==SLTI) || (op==SLTIU) || (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==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==DIV) || (funct==DIVU) || (funct==MULT) || (funct==MULTU) || (funct==OR) || (funct==SLL) || (funct==SLLV) || (funct==SLT) || (funct==SLTU) || (funct==SRA) || (funct==SRAV) || (funct==SRL) || (funct==SRLV) || (funct==SUBU) || (funct==XOR))) || ((op==REGIMM)&&((rt==BGEZ) || (rt==BGEZAL) || (rt==BLTZ) || (rt==BLTZAL))))begin
2020-12-07 11:49:44 +00:00
CtrlALUSrc = 0;///ALU Bus B is fed from rt.
2020-12-16 08:38:46 +00:00
end else if ((op==ORI) || (op==ANDI) || (op==XORI)) begin
CtrlALUSrc = 2;
2020-12-07 11:49:44 +00:00
end else begin CtrlALUSrc = 1'bx;end
2020-12-09 12:24:21 +00:00
2020-12-07 11:49:44 +00:00
//CtrlRegWrite logic
2020-12-16 15:00:46 +00:00
if((op==ADDIU) || (op==ANDI) || (op==LB) || (op==LBU) || (op==LH) || (op==LHU) || (op==LUI) || (op==LW) || (op==LWL) || (op==LWR) || (op==ORI) || (op==JAL) || (op==SLTI) || (op==XORI) || ((op==REGIMM)&&((rt==BGEZAL) || (rt==BLTZAL))) || ((op==SPECIAL)&&((funct==ADDU) || (funct==AND) || (funct==MFLO) || (funct==MFHI) || (funct==OR) || (funct==SLL) || (funct==SLLV) || (funct==SLT) || (funct==SLTU) || (funct==SRA) || (funct==SRAV) || (funct==SRL) || (funct==SRLV) || (funct==SUBU) || (funct==JALR) || (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
end
endmodule