module datapath(input clk, reset, | |
input [31:0] instr, | |
input [2:0] imm, | |
output [31:0] pc, | |
output [31:0] pcnext, | |
input pcsrc, pcadd, pcext, | |
input ISRsel, | |
input [31:0] ISR, | |
input unsign, | |
output gt, lt, eq, | |
input [3:0] alucontrol, | |
input alusrc, storepc, sltunsigned, | |
input [1:0] shtype, | |
input alu2src, | |
input memtoreg, regwrite, | |
output [31:0] aluout, writedata, | |
input [31:0] readdata, | |
input suspend); | |
wire [31:0] pcsum, pcimm_sum, pcjalr, pctoreg; | |
wire [31:0] signimm, signimm2; | |
wire [31:0] srca, srca2, srcb; | |
wire [31:0] result, result2; | |
wire [31:0] shoutput, aluout2; | |
wire [4:0] rs1; | |
wire compA,compB; | |
wire [31:0] pcISRin, pcext_imm; | |
wire [31:0] SEPC; | |
// SEPC | |
flopenr #(32) epc(.clk(clk), .reset(reset), .en(suspend), | |
.d(pc), .q(SEPC)); | |
// next PC logic | |
flopr #(32) pcreg(.clk(clk), .reset(reset), | |
.d(pcnext), .q(pc)); | |
// PC Next Adder PC+4 | |
adder pcadder(.a(pc), .b(32'b100), .y(pcsum)); | |
// need to read a zero on rs1 for lui to work. | |
// this is in the decoder, not in the bit-sliced datapath | |
mux2 #(5) rs1mux(.d0(instr[19:15]), .d1(5'b00000), | |
.s(imm[2]), .y(rs1)); | |
// register file logic | |
regfile rf (.clk(clk), .we3(regwrite), | |
.ra1(rs1), .ra2(instr[24:20]), | |
.wa3(instr[11:7]), .wd3(result), | |
.rd1(srca2), .rd2(writedata)); | |
// Sign Extension (Immediate) | |
signext se(.a(instr[31:0]), .sel(imm[1:0]), .y(signimm)); | |
// Sign Extension (lui) | |
mux2 #(32) semux(.d0(signimm), .d1({instr[31:12], 12'b0}), | |
.s(imm[2]), .y(signimm2)); | |
// Shifting immediate for PC | |
mux2 #(32) pcextmux(.d0(signimm2), .d1({signimm2[30:0],1'b0}), | |
.s(pcext), .y(pcext_imm)); | |
// Branch Mux | |
mux2 #(32) pcmux(.d0(pcsum), .d1(pcimm_sum), | |
.s(pcsrc), .y(pcISRin)); | |
mux2 #(32) pcmux2(.d0(pcimm_sum), .d1(pcsum), | |
.s(pcsrc), .y(pctoreg)); | |
// PC imm Adder PC + imm | |
adder pcimm(.a(pcjalr), .b(pcext_imm), .y(pcimm_sum)); | |
// ISR mux | |
mux2 #(32) ISRmux(.d0(pcISRin), .d1(ISR), | |
.s(ISRsel), .y(pcnext)); | |
// ALU PC/imm mux | |
mux2 #(32) pcsrcmux(.d0(srca2), .d1(pc), | |
.s(pcadd), .y(pcjalr)); | |
// ALU mem/imm mux | |
mux2 #(32) memsrcmux(.d0(writedata), .d1(pcext_imm), | |
.s(alusrc), .y(srcb)); | |
// Choose whether to invert the sign bit of the comparator | |
// or not for unsigned logic change these | |
// This can be 33rd bit logic | |
assign compA = srca2[31] ^ ~unsign; | |
assign compB = writedata[31] ^ ~unsign; | |
// Comparator (for beq, bge, blt, beq) | |
magcompare32 compare (.GT(gt), .LT(lt), .EQ(eq), | |
.A({compA, srca2[30:0]}), | |
.B({compB, writedata[30:0]})); | |
// ALU | |
alu alu (.a(srca2), .b(srcb), | |
.alucont(alucontrol), | |
.sltunsigned(sltunsigned), | |
.result(aluout2)); | |
// Shifter | |
shifter shift (.a(srca2), .shamt(srcb[4:0]), | |
.shtype(shtype), .y(shoutput)); | |
// Choose ALU or Shifter output | |
mux2 #(32) srccmux(.d0(aluout2), .d1(shoutput), | |
.s(alu2src), .y(aluout)); | |
// Memory Output | |
mux2 #(32) resmux(.d0(aluout), .d1(readdata), | |
.s(memtoreg), .y(result2)); | |
mux2 #(32) storepcmux(.d0(result2), .d1(pctoreg), | |
.s(storepc), .y(result)); | |
endmodule // datapath |