diff --git a/wally-pipelined/regression/wally-pipelined.do b/wally-pipelined/regression/wally-pipelined.do index b8e72968..c9051274 100644 --- a/wally-pipelined/regression/wally-pipelined.do +++ b/wally-pipelined/regression/wally-pipelined.do @@ -72,7 +72,7 @@ add wave /testbench/InstrEName add wave -hex /testbench/dut/hart/ieu/dp/SrcAE add wave -hex /testbench/dut/hart/ieu/dp/SrcBE add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE -add wave /testbench/dut/hart/ieu/dp/PCSrcE +#add wave /testbench/dut/hart/ieu/dp/PCSrcE add wave -divider add wave -hex /testbench/dut/hart/ifu/PCM add wave -hex /testbench/dut/hart/ifu/InstrM diff --git a/wally-pipelined/src/hazard/hazard.sv b/wally-pipelined/src/hazard/hazard.sv index 2321c652..43fc1ad9 100644 --- a/wally-pipelined/src/hazard/hazard.sv +++ b/wally-pipelined/src/hazard/hazard.sv @@ -28,7 +28,7 @@ module hazard( // Detect hazards input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM, - input logic LoadStallD, MulDivStallD, + input logic LoadStallD, MulDivStallD, CSRRdStallD, input logic InstrStall, DataStall, // Stall & flush outputs output logic StallF, StallD, StallE, StallM, StallW, @@ -54,7 +54,8 @@ module hazard( assign BranchFlushDE = PCSrcE | RetM | TrapM; assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE); - assign StallDCause = LoadStallD | MulDivStallD; // stall in decode if instruction is a load/mul dependent on previous + assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous +// assign StallDCause = LoadStallD | MulDivStallD | CSRRdStallD; // stall in decode if instruction is a load/mul/csr dependent on previous assign StallECause = 0; assign StallMCause = 0; assign StallWCause = DataStall | InstrStall; diff --git a/wally-pipelined/src/ieu/controller.sv b/wally-pipelined/src/ieu/controller.sv index a369785a..a917bbb6 100644 --- a/wally-pipelined/src/ieu/controller.sv +++ b/wally-pipelined/src/ieu/controller.sv @@ -29,9 +29,7 @@ module controller( input logic clk, reset, // Decode stage control signals - input logic [6:0] OpD, - input logic [2:0] Funct3D, - input logic [6:0] Funct7D, + input logic [31:0] InstrD, output logic [2:0] ImmSrcD, input logic IllegalIEUInstrFaultD, output logic IllegalBaseInstrFaultD, @@ -42,13 +40,13 @@ module controller( output logic [4:0] ALUControlE, output logic ALUSrcAE, ALUSrcBE, output logic TargetSrcE, - output logic MemReadE, // for Hazard Unit + output logic MemReadE, CSRReadE, // for Hazard Unit output logic [2:0] Funct3E, output logic MulDivE, W64E, // Memory stage control signals input logic StallM, FlushM, output logic [1:0] MemRWM, - output logic CSRWriteM, PrivilegedM, + output logic CSRReadM, CSRWriteM, PrivilegedM, output logic [2:0] Funct3M, output logic RegWriteM, // for Hazard Unit // Writeback stage control signals @@ -60,6 +58,11 @@ module controller( output logic CSRWritePendingDEM ); + logic [6:0] OpD; + logic [2:0] Funct3D; + logic [6:0] Funct7D; + logic [4:0] Rs1D; + // pipelined control signals logic RegWriteD, RegWriteE; logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; @@ -70,6 +73,8 @@ module controller( logic [4:0] ALUControlD; logic ALUSrcAD, ALUSrcBD; logic TargetSrcD, W64D, MulDivD; + logic CSRZeroSrcD; + logic CSRReadD; logic CSRWriteD, CSRWriteE; logic InstrValidE, InstrValidM; logic PrivilegedD, PrivilegedE; @@ -80,14 +85,19 @@ module controller( logic zeroE, ltE, ltuE; logic unused; + // Extract fields + assign OpD = InstrD[6:0]; + assign Funct3D = InstrD[14:12]; + assign Funct7D = InstrD[31:25]; + assign Rs1D = InstrD[19:15]; // Main Instruction Decoder - // *** decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so + // *** perhaps decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so // they don't get generated if that mode is disabled generate always_comb case(OpD) - // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRWrite_Privileged_MulDiv_Illegal + // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_MulDiv_Illegal 7'b0000011: ControlsD = 21'b1_000_01_10_001_0_00_0_0_0_0_0_0_0; // lw 7'b0100011: ControlsD = 21'b0_001_01_01_000_0_00_0_0_0_0_0_0_0; // sw 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) @@ -126,10 +136,13 @@ module controller( // squash control signals if coming from an illegal compressed instruction assign IllegalBaseInstrFaultD = ControlsD[0]; assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD, - ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD, + ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRReadD, PrivilegedD, MulDivD, unused} = ControlsD & ~IllegalIEUInstrFaultD; // *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions + 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 + // ALU Decoding *** should move to ALU for better modularity assign sltD = (Funct3D == 3'b010); assign sltuD = (Funct3D == 3'b011); @@ -147,9 +160,9 @@ module controller( endcase // Execute stage pipeline control register and logic - flopenrc #(24) controlregE(clk, reset, FlushE, ~StallE, - {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, 1'b1}, - {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, InstrValidE}); + flopenrc #(25) controlregE(clk, reset, FlushE, ~StallE, + {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, 1'b1}, + {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, InstrValidE}); // Branch Logic assign {zeroE, ltE, ltuE} = FlagsE; @@ -170,15 +183,14 @@ module controller( assign MemReadE = MemRWE[1]; // Memory stage pipeline control register - flopenrc #(12) controlregM(clk, reset, FlushM, ~StallM, - {RegWriteE, ResultSrcE, MemRWE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE}, - {RegWriteM, ResultSrcM, MemRWM, CSRWriteM, PrivilegedM, Funct3M, InstrValidM}); + flopenrc #(13) controlregM(clk, reset, FlushM, ~StallM, + {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE}, + {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, InstrValidM}); // Writeback stage pipeline control register flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW, {RegWriteM, ResultSrcM, InstrValidM}, {RegWriteW, ResultSrcW, InstrValidW}); - // *** improve this so CSR reads don't trigger this signal and cause pipeline flushes assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM; endmodule diff --git a/wally-pipelined/src/ieu/forward.sv b/wally-pipelined/src/ieu/forward.sv index fd367ae7..3f38004e 100644 --- a/wally-pipelined/src/ieu/forward.sv +++ b/wally-pipelined/src/ieu/forward.sv @@ -28,11 +28,11 @@ module forward( // Detect hazards input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, - input logic MemReadE, MulDivE, + input logic MemReadE, MulDivE, CSRReadE, input logic RegWriteM, RegWriteW, // Forwarding controls output logic [1:0] ForwardAE, ForwardBE, - output logic LoadStallD, MulDivStallD + output logic LoadStallD, MulDivStallD, CSRRdStallD ); always_comb begin @@ -47,7 +47,9 @@ module forward( else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01; end + // Stall on dependent operations that finish in Mem Stage and can't bypass in time assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE)); - assign MulDivStallD = MulDivE & & ((Rs1D == RdE) | (Rs2D == RdE)); // *** extend with stalls for divide + assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE)); // *** extend with stalls for divide + assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE)); endmodule diff --git a/wally-pipelined/src/ieu/ieu.sv b/wally-pipelined/src/ieu/ieu.sv index d0588c73..29ffb497 100644 --- a/wally-pipelined/src/ieu/ieu.sv +++ b/wally-pipelined/src/ieu/ieu.sv @@ -51,10 +51,10 @@ module ieu ( // hazards input logic StallE, StallM, StallW, input logic FlushE, FlushM, FlushW, - output logic LoadStallD, MulDivStallD, + output logic LoadStallD, MulDivStallD, CSRRdStallD, output logic PCSrcE, - output logic CSRWriteM, PrivilegedM, + output logic CSRReadM, CSRWriteM, PrivilegedM, output logic CSRWritePendingDEM ); @@ -69,9 +69,9 @@ module ieu ( logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW; logic [1:0] ForwardAE, ForwardBE; logic RegWriteM, RegWriteW; - logic MemReadE; + logic MemReadE, CSRReadE; - controller c(.OpD(InstrD[6:0]), .Funct3D(InstrD[14:12]), .Funct7D(InstrD[31:25]), .*); + controller c(.*); datapath dp(.*); forward fw(.*); endmodule diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index bee0ba86..f1f16ac9 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -31,7 +31,7 @@ module csr ( input logic FlushW, StallW, input logic [31:0] InstrM, input logic [`XLEN-1:0] PCM, SrcAM, - input logic CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM, + input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM, input logic TimerIntM, ExtIntM, SwIntM, input logic InstrValidW, FloatRegWriteW, LoadStallD, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, @@ -111,7 +111,7 @@ module csr ( (CSRAdrM[9:8] == 2'b01 && PrivilegeModeW == `U_MODE); assign IllegalCSRAccessM = (IllegalCSRCAccessM && IllegalCSRMAccessM && IllegalCSRSAccessM && IllegalCSRUAccessM && IllegalCSRNAccessM || - InsufficientCSRPrivilegeM) && CSRWriteM; + InsufficientCSRPrivilegeM) && CSRReadM; end else begin // CSRs not implemented assign STATUS_MPP = 2'b11; assign STATUS_SPP = 2'b0; @@ -132,7 +132,7 @@ module csr ( assign STATUS_SIE = 0; assign FRM_REGW = 0; assign CSRReadValM = 0; - assign IllegalCSRAccessM = CSRWriteM; + assign IllegalCSRAccessM = CSRReadM; end endgenerate endmodule diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 6b124972..71b90586 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -29,7 +29,7 @@ module privileged ( input logic clk, reset, input logic FlushW, - input logic CSRWriteM, + input logic CSRReadM, CSRWriteM, input logic [`XLEN-1:0] SrcAM, input logic [31:0] InstrM, input logic [`XLEN-1:0] PCM, diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index 6ea1a4aa..793eafb2 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -60,7 +60,7 @@ module wallypipelinedhart ( // new signals that must connect through DP logic MulDivE, W64E; - logic CSRWriteM, PrivilegedM; + logic CSRReadM, CSRWriteM, PrivilegedM; logic [`XLEN-1:0] SrcAE, SrcBE; logic [`XLEN-1:0] SrcAM; logic [2:0] Funct3E; @@ -81,7 +81,7 @@ module wallypipelinedhart ( logic PCSrcE; logic CSRWritePendingDEM; - logic LoadStallD, MulDivStallD; + logic LoadStallD, MulDivStallD, CSRRdStallD; logic [4:0] SetFflagsM; logic [2:0] FRM_REGW; logic FloatRegWriteW; diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 7ec8fa59..e121c460 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -90,6 +90,7 @@ string tests64iNOc[] = { "rv64i/I-MISALIGN_JMP-01","2000" }; string tests64i[] = '{ + "rv64i/I-MISALIGN_LDST-01", "2010", "rv64i/I-ADD-01", "3000", "rv64i/I-ADDI-01", "3000", "rv64i/I-ADDIW-01", "3000", @@ -322,7 +323,7 @@ string tests32i[] = { tests = {tests64i}; if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic}; else tests = {tests, tests64iNOc}; - if (`M_SUPPORTED % 2 == 1) tests = {tests64m, tests}; + if (`M_SUPPORTED % 2 == 1) tests = {tests, tests64m}; end else begin // RV32 tests = {tests32i}; if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};