Simplified FWriteInt interfaces by merging into RegWrite

This commit is contained in:
David Harris 2021-12-18 05:36:32 -08:00
parent da1df17fbb
commit 1212e21eba
7 changed files with 91 additions and 107 deletions

View File

@ -36,7 +36,7 @@ module fpu (
input logic [4:0] RdM, RdW, // which FP register to write to (from IEU) input logic [4:0] RdM, RdW, // which FP register to write to (from IEU)
output logic FRegWriteM, // FP register write enable output logic FRegWriteM, // FP register write enable
output logic FStallD, // Stall the decode stage output logic FStallD, // Stall the decode stage
output logic FWriteIntE, FWriteIntM, FWriteIntW, // integer register write enable output logic FWriteIntE, // integer register write enables
output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory
output logic [`XLEN-1:0] FIntResM, // data to be written to integer register output logic [`XLEN-1:0] FIntResM, // data to be written to integer register
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
@ -260,9 +260,9 @@ module fpu (
flopenrc #(64) EMRegCmpRes (clk, reset, FlushM, ~StallM, FResE, FResM); flopenrc #(64) EMRegCmpRes (clk, reset, FlushM, ~StallM, FResE, FResM);
flopenrc #(5) EMRegCmpFlg (clk, reset, FlushM, ~StallM, FFlgE, FFlgM); flopenrc #(5) EMRegCmpFlg (clk, reset, FlushM, ~StallM, FFlgE, FFlgM);
flopenrc #(`XLEN) EMRegSgnRes (clk, reset, FlushM, ~StallM, FIntResE, FIntResM); flopenrc #(`XLEN) EMRegSgnRes (clk, reset, FlushM, ~StallM, FIntResE, FIntResM);
flopenrc #(8) EMCtrlReg (clk, reset, FlushM, ~StallM, flopenrc #(7) EMCtrlReg (clk, reset, FlushM, ~StallM,
{FRegWriteE, FResultSelE, FrmE, FmtE, FWriteIntE}, {FRegWriteE, FResultSelE, FrmE, FmtE},
{FRegWriteM, FResultSelM, FrmM, FmtM, FWriteIntM}); {FRegWriteM, FResultSelM, FrmM, FmtM});
// BEGIN MEMORY STAGE // BEGIN MEMORY STAGE
@ -273,9 +273,9 @@ module fpu (
flopenrc #(64) MWRegFma(clk, reset, FlushW, ~StallW, FMAResM, FMAResW); flopenrc #(64) MWRegFma(clk, reset, FlushW, ~StallW, FMAResM, FMAResW);
flopenrc #(64) MWRegDiv(clk, reset, FlushW, ~StallW, FDivResM, FDivResW); flopenrc #(64) MWRegDiv(clk, reset, FlushW, ~StallW, FDivResM, FDivResW);
flopenrc #(64) MWRegClass(clk, reset, FlushW, ~StallW, FResM, FResW); flopenrc #(64) MWRegClass(clk, reset, FlushW, ~StallW, FResM, FResW);
flopenrc #(5) MWCtrlReg(clk, reset, FlushW, ~StallW, flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW,
{FRegWriteM, FResultSelM, FmtM, FWriteIntM}, {FRegWriteM, FResultSelM, FmtM},
{FRegWriteW, FResultSelW, FmtW, FWriteIntW}); {FRegWriteW, FResultSelW, FmtW});
// BEGIN WRITEBACK STAGE // BEGIN WRITEBACK STAGE
@ -290,8 +290,6 @@ module fpu (
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
assign FStallD = 0; assign FStallD = 0;
assign FWriteIntE = 0; assign FWriteIntE = 0;
assign FWriteIntM = 0;
assign FWriteIntW = 0;
assign FWriteDataE = 0; assign FWriteDataE = 0;
assign FIntResM = 0; assign FIntResM = 0;
assign FDivBusyE = 0; assign FDivBusyE = 0;

View File

@ -37,6 +37,7 @@ module controller(
// Execute stage control signals // Execute stage control signals
input logic StallE, FlushE, input logic StallE, FlushE,
input logic [2:0] FlagsE, input logic [2:0] FlagsE,
input logic FWriteIntE,
output logic PCSrcE, // for datapath and Hazard Unit output logic PCSrcE, // for datapath and Hazard Unit
output logic [2:0] ALUControlE, output logic [2:0] ALUControlE,
output logic ALUSrcAE, ALUSrcBE, output logic ALUSrcAE, ALUSrcBE,
@ -56,6 +57,7 @@ module controller(
output logic RegWriteM, // for Hazard Unit output logic RegWriteM, // for Hazard Unit
output logic InvalidateICacheM, FlushDCacheM, output logic InvalidateICacheM, FlushDCacheM,
output logic InstrValidM, output logic InstrValidM,
output logic FWriteIntM,
// Writeback stage control signals // Writeback stage control signals
input logic StallW, FlushW, input logic StallW, FlushW,
output logic RegWriteW, // for datapath and Hazard Unit output logic RegWriteW, // for datapath and Hazard Unit
@ -98,6 +100,7 @@ module controller(
logic zeroE, ltE, ltuE; logic zeroE, ltE, ltuE;
logic unused; logic unused;
logic BranchFlagE; logic BranchFlagE;
logic IEURegWriteE;
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];
@ -167,25 +170,13 @@ module controller(
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD && InstrD[13]); // Don't write if setting or clearing zeros assign CSRWriteD = CSRReadD & !(CSRZeroSrcD && InstrD[13]); // Don't write if setting or clearing zeros
// ALU Decoding *** should move to ALU for better modularity // ALU Decoding
assign sltD = (Funct3D == 3'b010); assign sltD = (Funct3D == 3'b010);
assign sltuD = (Funct3D == 3'b011); assign sltuD = (Funct3D == 3'b011);
assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]);
assign sraD = (Funct3D == 3'b101 & Funct7D[5]); assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu
// assign SubArithD = aluc3D; // ***cleanup
// *** replace all of this
assign ALUControlD = {W64D, SubArithD, ALUOpD}; assign ALUControlD = {W64D, SubArithD, ALUOpD};
/* always_comb
case(ALUOpD)
2'b00: ALUControlD = 5'b00000; // addition
2'b01: ALUControlD = 5'b00000; // add for branch offset
// 2'b01: ALUControlD = 5'b01000; // subtraction
// 2'b11: ALUControlD = 5'b01110; // pass B through for lui ***no longer used
default: ALUControlD = {W64D, aluc3D, Funct3D}; // R-type instructions
endcase*/
// Fences // Fences
// Ordinary fence is presently a nop // Ordinary fence is presently a nop
@ -208,32 +199,24 @@ module controller(
// Execute stage pipeline control register and logic // Execute stage pipeline control register and logic
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE, flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD}, {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE}); {IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
// Branch Logic // Branch Logic
assign {zeroE, ltE, ltuE} = FlagsE; assign {zeroE, ltE, ltuE} = FlagsE;
mux4 #(1) branchflagmux(zeroE, 1'b0, ltE, ltuE, Funct3E[2:1], BranchFlagE); mux4 #(1) branchflagmux(zeroE, 1'b0, ltE, ltuE, Funct3E[2:1], BranchFlagE);
assign BranchTakenE = BranchFlagE ^ Funct3E[0]; assign BranchTakenE = BranchFlagE ^ Funct3E[0];
/* always_comb
case(Funct3E)
3'b000: BranchTakenE = zeroE; // beq
3'b001: BranchTakenE = ~zeroE; // bne
3'b100: BranchTakenE = ltE; // blt
3'b101: BranchTakenE = ~ltE; // bge
3'b110: BranchTakenE = ltuE; // bltu
3'b111: BranchTakenE = ~ltuE; // bgeu
default: BranchTakenE = 1'b0; // undefined mode
endcase*/
assign PCSrcE = JumpE | BranchE & BranchTakenE; assign PCSrcE = JumpE | BranchE & BranchTakenE;
assign MemReadE = MemRWE[1]; assign MemReadE = MemRWE[1];
assign SCE = (ResultSrcE == 3'b100); assign SCE = (ResultSrcE == 3'b100);
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
// Memory stage pipeline control register // Memory stage pipeline control register
flopenrc #(17) controlregM(clk, reset, FlushM, ~StallM, flopenrc #(18) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE}, {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, AtomicM, InvalidateICacheM, FlushDCacheM, InstrValidM}); {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, InstrValidM});
// Writeback stage pipeline control register // Writeback stage pipeline control register
flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW, flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW,

View File

@ -53,7 +53,6 @@ module datapath (
output logic [`XLEN-1:0] WriteDataM, output logic [`XLEN-1:0] WriteDataM,
// Writeback stage signals // Writeback stage signals
input logic StallW, FlushW, input logic StallW, FlushW,
input logic FWriteIntW,
input logic RegWriteW, input logic RegWriteW,
input logic SquashSCW, input logic SquashSCW,
input logic [2:0] ResultSrcW, input logic [2:0] ResultSrcW,
@ -92,8 +91,7 @@ module datapath (
assign Rs1D = InstrD[19:15]; assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20]; assign Rs2D = InstrD[24:20];
assign RdD = InstrD[11:7]; assign RdD = InstrD[11:7];
// *** can FWriteIntW be merged with RegWriteW regfile regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, WriteDataW, RD1D, RD2D);
regfile regf(clk, reset, {RegWriteW | FWriteIntW}, Rs1D, Rs2D, RdW, WriteDataW, RD1D, RD2D);
extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ExtImmD); extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ExtImmD);
// Execute stage pipeline register and logic // Execute stage pipeline register and logic
@ -106,7 +104,6 @@ module datapath (
mux3 #(`XLEN) faemux(RD1E, WriteDataW, ResultM, ForwardAE, ForwardedSrcAE); mux3 #(`XLEN) faemux(RD1E, WriteDataW, ResultM, ForwardAE, ForwardedSrcAE);
mux3 #(`XLEN) fbemux(RD2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE); mux3 #(`XLEN) fbemux(RD2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE);
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, FlagsE); comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE); mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE);
@ -119,12 +116,23 @@ module datapath (
flopenrc #(`XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); flopenrc #(`XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM);
flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM); flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM);
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM); flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, ResultM);
// Writeback stage pipeline register and logic // Writeback stage pipeline register and logic
flopenrc #(`XLEN) ResultWReg(clk, reset, FlushW, ~StallW, ResultM, ResultW); flopenrc #(`XLEN) ResultWReg(clk, reset, FlushW, ~StallW, ResultM, ResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW); flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
flopen #(`XLEN) ReadDataWReg(.clk, .en(~StallW), .d(ReadDataM), .q(ReadDataW)); flopen #(`XLEN) ReadDataWReg(.clk, .en(~StallW), .d(ReadDataM), .q(ReadDataW));
mux5 #(`XLEN) resultmuxW(ResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, WriteDataW);
// floating point interactions: fcvt, fp stores
generate
if (`F_SUPPORTED) begin:fpmux
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, ResultM);
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
end else begin
assign ResultM = IEUResultM;
assign WriteDataE = ForwardedSrcBE;
end
endgenerate
// handle Store Conditional result if atomic extension supported // handle Store Conditional result if atomic extension supported
generate generate
@ -133,6 +141,4 @@ module datapath (
else else
assign SCResultW = 0; assign SCResultW = 0;
endgenerate endgenerate
mux5 #(`XLEN) resultmuxW(ResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, WriteDataW);
endmodule endmodule

View File

@ -30,7 +30,7 @@ module forward(
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
input logic MemReadE, MulDivE, CSRReadE, input logic MemReadE, MulDivE, CSRReadE,
input logic RegWriteM, RegWriteW, input logic RegWriteM, RegWriteW,
input logic FWriteIntE, FWriteIntM, FWriteIntW, input logic FWriteIntE,
input logic SCE, input logic SCE,
// Forwarding controls // Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, output logic [1:0] ForwardAE, ForwardBE,
@ -41,12 +41,12 @@ module forward(
ForwardAE = 2'b00; ForwardAE = 2'b00;
ForwardBE = 2'b00; ForwardBE = 2'b00;
if (Rs1E != 5'b0) if (Rs1E != 5'b0)
if ((Rs1E == RdM) & (RegWriteM|FWriteIntM)) ForwardAE = 2'b10; if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
else if ((Rs1E == RdW) & (RegWriteW|FWriteIntW)) ForwardAE = 2'b01; else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
if (Rs2E != 5'b0) if (Rs2E != 5'b0)
if ((Rs2E == RdM) & (RegWriteM|FWriteIntM)) ForwardBE = 2'b10; if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & (RegWriteW|FWriteIntW)) ForwardBE = 2'b01; else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time // Stall on dependent operations that finish in Mem Stage and can't bypass in time

View File

@ -40,9 +40,7 @@ module ieu (
output logic [`XLEN-1:0] IEUAdrE, output logic [`XLEN-1:0] IEUAdrE,
output logic MulDivE, W64E, output logic MulDivE, W64E,
output logic [2:0] Funct3E, output logic [2:0] Funct3E,
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B
// output logic [`XLEN-1:0] SrcAE, SrcBE,
input logic FWriteIntM,
// Memory stage interface // Memory stage interface
input logic SquashSCW, // from LSU input logic SquashSCW, // from LSU
@ -59,7 +57,6 @@ module ieu (
// Writeback stage // Writeback stage
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MulDivResultW, input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MulDivResultW,
input logic FWriteIntW,
output logic [4:0] RdW, output logic [4:0] RdW,
output logic [`XLEN-1:0] ReadDataW, output logic [`XLEN-1:0] ReadDataW,
// input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
@ -82,6 +79,7 @@ module ieu (
logic ALUResultSrcE; logic ALUResultSrcE;
logic SCE; logic SCE;
logic [4:0] RdE; logic [4:0] RdE;
logic FWriteIntM;
// forwarding signals // forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E;
@ -96,7 +94,7 @@ module ieu (
.StallD, .FlushD, .InstrD, .ImmSrcD, .StallD, .FlushD, .InstrD, .ImmSrcD,
.IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD,
// Execute stage control signals // Execute stage control signals
.StallE, .FlushE, .FlagsE, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, // for datapath and Hazard Unit .PCSrcE, // for datapath and Hazard Unit
.ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUControlE, .ALUSrcAE, .ALUSrcBE,
.ALUResultSrcE, .ALUResultSrcE,
@ -109,6 +107,7 @@ module ieu (
.SCE, .AtomicE, .AtomicM, .Funct3M, .SCE, .AtomicE, .AtomicM, .Funct3M,
.RegWriteM, // for Hazard Unit .RegWriteM, // for Hazard Unit
.InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM,
.FWriteIntM,
// Writeback stage control signals // Writeback stage control signals
.StallW, .FlushW, .StallW, .FlushW,
.RegWriteW, // for datapath and Hazard Unit .RegWriteW, // for datapath and Hazard Unit
@ -133,7 +132,7 @@ module ieu (
.StallM, .FlushM, .FWriteIntM, .FIntResM, .StallM, .FlushM, .FWriteIntM, .FIntResM,
.SrcAM, .WriteDataM, .SrcAM, .WriteDataM,
// Writeback stage signals // Writeback stage signals
.StallW, .FlushW, .FWriteIntW, .RegWriteW, .StallW, .FlushW, .RegWriteW,
.SquashSCW, .ResultSrcW, .ReadDataW, .SquashSCW, .ResultSrcW, .ReadDataW,
// input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
.CSRReadValW, .ReadDataM, .MulDivResultW, .CSRReadValW, .ReadDataM, .MulDivResultW,
@ -146,7 +145,7 @@ module ieu (
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
.MemReadE, .MulDivE, .CSRReadE, .MemReadE, .MulDivE, .CSRReadE,
.RegWriteM, .RegWriteW, .RegWriteM, .RegWriteW,
.FWriteIntE, .FWriteIntM, .FWriteIntW, .FWriteIntE,
.SCE, .SCE,
// Forwarding controls // Forwarding controls
.ForwardAE, .ForwardBE, .ForwardAE, .ForwardBE,

View File

@ -42,82 +42,82 @@ module subwordread (
logic [`XLEN-1:0] offset4, offset5, offset6, offset7; logic [`XLEN-1:0] offset4, offset5, offset6, offset7;
always_comb always_comb
case(Funct3M[1:0]) case(Funct3M[1:0])
3: offset0 = ReadDataWordMuxM; //ld 3: offset0 = ReadDataWordMuxM; //ld
2: offset0 = Funct3M[2] ? {{32'b0}, ReadDataWordMuxM[31:0]} : {{32{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:0]}; //lw(u) 2: offset0 = Funct3M[2] ? {{32'b0}, ReadDataWordMuxM[31:0]} : {{32{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:0]}; //lw(u)
1: offset0 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[15:0]} : {{48{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:0]}; //lh(u) 1: offset0 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[15:0]} : {{48{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:0]}; //lh(u)
0: offset0 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[7:0]} : {{56{ReadDataWordMuxM[7]}}, ReadDataWordMuxM[7:0]}; //lb(u) 0: offset0 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[7:0]} : {{56{ReadDataWordMuxM[7]}}, ReadDataWordMuxM[7:0]}; //lb(u)
endcase endcase
assign offset1 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[15:8]} : {{56{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:8]}; //lb(u) assign offset1 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[15:8]} : {{56{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:8]}; //lb(u)
always_comb always_comb
case(Funct3M[0]) case(Funct3M[0])
1: offset2 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[31:16]} : {{48{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:16]};//lh(u) 1: offset2 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[31:16]} : {{48{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:16]};//lh(u)
0: offset2 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[23:16]} : {{56{ReadDataWordMuxM[23]}}, ReadDataWordMuxM[23:16]};//lb(u) 0: offset2 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[23:16]} : {{56{ReadDataWordMuxM[23]}}, ReadDataWordMuxM[23:16]};//lb(u)
endcase endcase
assign offset3 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[31:24]} : {{56{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:24]};//lb(u) assign offset3 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[31:24]} : {{56{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:24]};//lb(u)
always_comb always_comb
case(Funct3M[1:0]) case(Funct3M[1:0])
3: offset4 = Funct3M[2] ? {{32'b0}, ReadDataWordMuxM[63:32]} : {{32{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:32]};//ld(u) // unaligned will cause fault. 3: offset4 = Funct3M[2] ? {{32'b0}, ReadDataWordMuxM[63:32]} : {{32{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:32]};//ld(u) // unaligned will cause fault.
2: offset4 = Funct3M[2] ? {{32'b0}, ReadDataWordMuxM[63:32]} : {{32{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:32]};//lw(u) 2: offset4 = Funct3M[2] ? {{32'b0}, ReadDataWordMuxM[63:32]} : {{32{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:32]};//lw(u)
1: offset4 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[47:32]} : {{48{ReadDataWordMuxM[47]}}, ReadDataWordMuxM[47:32]};//lh(u) 1: offset4 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[47:32]} : {{48{ReadDataWordMuxM[47]}}, ReadDataWordMuxM[47:32]};//lh(u)
0: offset4 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[39:32]} : {{56{ReadDataWordMuxM[39]}}, ReadDataWordMuxM[39:32]};//lb(u) 0: offset4 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[39:32]} : {{56{ReadDataWordMuxM[39]}}, ReadDataWordMuxM[39:32]};//lb(u)
endcase endcase
assign offset5 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[47:40]} : {{56{ReadDataWordMuxM[47]}}, ReadDataWordMuxM[47:40]};//lb(u) assign offset5 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[47:40]} : {{56{ReadDataWordMuxM[47]}}, ReadDataWordMuxM[47:40]};//lb(u)
always_comb always_comb
case(Funct3M[0]) case(Funct3M[0])
1: offset6 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[63:48]} : {{48{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:48]};//lh(u) 1: offset6 = Funct3M[2] ? {{48'b0}, ReadDataWordMuxM[63:48]} : {{48{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:48]};//lh(u)
0: offset6 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[55:48]} : {{56{ReadDataWordMuxM[55]}}, ReadDataWordMuxM[55:48]};//lb(u) 0: offset6 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[55:48]} : {{56{ReadDataWordMuxM[55]}}, ReadDataWordMuxM[55:48]};//lb(u)
endcase endcase
assign offset7 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[63:56]} : {{56{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:56]};//lb(u) assign offset7 = Funct3M[2] ? {{56'b0}, ReadDataWordMuxM[63:56]} : {{56{ReadDataWordMuxM[63]}}, ReadDataWordMuxM[63:56]};//lb(u)
// address mux // address mux
always_comb always_comb
case(MemPAdrM[2:0]) case(MemPAdrM[2:0])
0: ReadDataM = offset0; 0: ReadDataM = offset0;
1: ReadDataM = offset1; 1: ReadDataM = offset1;
2: ReadDataM = offset2; 2: ReadDataM = offset2;
3: ReadDataM = offset3; 3: ReadDataM = offset3;
4: ReadDataM = offset4; 4: ReadDataM = offset4;
5: ReadDataM = offset5; 5: ReadDataM = offset5;
6: ReadDataM = offset6; 6: ReadDataM = offset6;
7: ReadDataM = offset7; 7: ReadDataM = offset7;
endcase endcase
end else begin // 32-bit end else begin // 32-bit
// byte mux // byte mux
always_comb always_comb
case(Funct3M[1:0]) case(Funct3M[1:0])
3: offset0 = ReadDataWordMuxM; //ld illegal 3: offset0 = ReadDataWordMuxM; //ld illegal
2: offset0 = ReadDataWordMuxM[31:0]; //lw 2: offset0 = ReadDataWordMuxM[31:0]; //lw
1: offset0 = Funct3M[2] ? {{16'b0}, ReadDataWordMuxM[15:0]} : {{16{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:0]}; //lh(u) 1: offset0 = Funct3M[2] ? {{16'b0}, ReadDataWordMuxM[15:0]} : {{16{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:0]}; //lh(u)
0: offset0 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[7:0]} : {{24{ReadDataWordMuxM[7]}}, ReadDataWordMuxM[7:0]}; //lb(u) 0: offset0 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[7:0]} : {{24{ReadDataWordMuxM[7]}}, ReadDataWordMuxM[7:0]}; //lb(u)
endcase endcase
assign offset1 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[15:8]} : {{24{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:8]}; //lb(u) assign offset1 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[15:8]} : {{24{ReadDataWordMuxM[15]}}, ReadDataWordMuxM[15:8]}; //lb(u)
always_comb always_comb
case(Funct3M[0]) case(Funct3M[0])
1: offset2 = Funct3M[2] ? {{16'b0}, ReadDataWordMuxM[31:16]} : {{16{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:16]};//lh(u) 1: offset2 = Funct3M[2] ? {{16'b0}, ReadDataWordMuxM[31:16]} : {{16{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:16]};//lh(u)
0: offset2 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[23:16]} : {{24{ReadDataWordMuxM[23]}}, ReadDataWordMuxM[23:16]};//lb(u) 0: offset2 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[23:16]} : {{24{ReadDataWordMuxM[23]}}, ReadDataWordMuxM[23:16]};//lb(u)
endcase endcase
assign offset3 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[31:24]} : {{24{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:24]};//lb(u) assign offset3 = Funct3M[2] ? {{24'b0}, ReadDataWordMuxM[31:24]} : {{24{ReadDataWordMuxM[31]}}, ReadDataWordMuxM[31:24]};//lb(u)
// address mux // address mux
always_comb always_comb
case(MemPAdrM[1:0]) case(MemPAdrM[1:0])
0: ReadDataM = offset0; 0: ReadDataM = offset0;
1: ReadDataM = offset1; 1: ReadDataM = offset1;
2: ReadDataM = offset2; 2: ReadDataM = offset2;
3: ReadDataM = offset3; 3: ReadDataM = offset3;
endcase endcase
end end
endgenerate endgenerate
endmodule endmodule

View File

@ -89,7 +89,7 @@ module wallypipelinedhart (
logic [2:0] FRM_REGW; logic [2:0] FRM_REGW;
logic [4:0] RdM, RdW; logic [4:0] RdM, RdW;
logic FStallD; logic FStallD;
logic FWriteIntE, FWriteIntM, FWriteIntW; logic FWriteIntE;
logic [`XLEN-1:0] FWriteDataE; logic [`XLEN-1:0] FWriteDataE;
logic [`XLEN-1:0] FIntResM; logic [`XLEN-1:0] FIntResM;
logic FDivBusyE; logic FDivBusyE;
@ -210,8 +210,6 @@ module wallypipelinedhart (
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE, .PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
.FWriteDataE, .IEUAdrE, .MulDivE, .W64E, .FWriteDataE, .IEUAdrE, .MulDivE, .W64E,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
//.SrcAE, .SrcBE,
.FWriteIntM,
// Memory stage interface // Memory stage interface
.SquashSCW, // from LSU .SquashSCW, // from LSU
@ -225,7 +223,7 @@ module wallypipelinedhart (
// Writeback stage // Writeback stage
.CSRReadValW, .ReadDataM, .MulDivResultW, .CSRReadValW, .ReadDataM, .MulDivResultW,
.FWriteIntW, .RdW, .ReadDataW, .RdW, .ReadDataW,
.InstrValidM, .InstrValidM,
// hazards // hazards
@ -370,7 +368,7 @@ module wallypipelinedhart (
.RdM, .RdW, // which FP register to write to (from IEU) .RdM, .RdW, // which FP register to write to (from IEU)
.FRegWriteM, // FP register write enable .FRegWriteM, // FP register write enable
.FStallD, // Stall the decode stage .FStallD, // Stall the decode stage
.FWriteIntE, .FWriteIntM, .FWriteIntW, // integer register write enable .FWriteIntE, // integer register write enable
.FWriteDataE, // Data to be written to memory .FWriteDataE, // Data to be written to memory
.FIntResM, // data to be written to integer register .FIntResM, // data to be written to integer register
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)