diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv index bdbfbde00..2c1aa7ed3 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv @@ -52,7 +52,8 @@ module fdivsqrt( output logic FDivBusyE, IFDivStartE, FDivDoneE, // output logic DivDone, output logic [`NE+1:0] QeM, - output logic [`DIVb:0] QmM + output logic [`DIVb:0] QmM, + output logic [`XLEN-1:0] FPIntDivResultM // output logic [`XLEN-1:0] RemM, ); @@ -88,5 +89,5 @@ module fdivsqrt( .WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAE, .n, .ALTBM, .m, .BZero, .As, - .QmM, .WZero, .DivSM); + .QmM, .WZero, .DivSM, .FPIntDivResultM); endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv index 7ac8229b9..925c12892 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv @@ -43,7 +43,8 @@ module fdivsqrtpostproc( input logic [`DIVBLEN:0] n, m, output logic [`DIVb:0] QmM, output logic WZero, - output logic DivSM + output logic DivSM, + output logic [`XLEN-1:0] FPIntDivResultM ); logic [`DIVb+3:0] W, Sum, RemDM; @@ -53,7 +54,7 @@ module fdivsqrtpostproc( logic [`DIVBLEN:0] NormShiftM; logic [`DIVb:0] IntQuotM, NormQuotM; logic [`DIVb+3:0] IntRemM, NormRemM; - logic [`DIVb+3:0] PreResultM, ResultM; + logic [`DIVb+3:0] PreResultM, PreFPIntDivResultM; // check for early termination on an exact result. If the result is not exact, the sticky should be set aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0); @@ -136,8 +137,9 @@ module fdivsqrtpostproc( // division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted - assign ResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)}; - + assign PreFPIntDivResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)}; + assign FPIntDivResultM = PreFPIntDivResultM[`XLEN-1:0]; + assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit assign QmM = SqrtM ? (PreQmM << 1) : PreQmM; endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index bd4053dcb..10fa4d70e 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -55,7 +55,8 @@ module fpu ( output logic FCvtIntW, // select FCvtIntRes (to IEU) output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU) output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction (to privileged unit) - output logic [4:0] SetFflagsM // FPU flags (to privileged unit) + output logic [4:0] SetFflagsM, // FPU flags (to privileged unit) + output logic [`XLEN-1:0] FPIntDivResultW ); // FPU specifics: @@ -152,6 +153,7 @@ module fpu ( logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed logic [`FLEN-1:0] BoxedOneE; // Zero value for Z for multiplication, with NaN boxing if needed logic StallUnpackedM; + logic [`XLEN-1:0] FPIntDivResultM; // DECODE STAGE @@ -267,7 +269,7 @@ module fpu ( .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E, .StallE, .StallM, .TrapM, .DivSM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM, - .QmM /*, .DivDone(DivDoneM) */); + .QmM, .FPIntDivResultM /*, .DivDone(DivDoneM) */); // // compare @@ -387,7 +389,8 @@ module fpu ( // M/W pipe registers flopenrc #(`FLEN) MWRegFp(clk, reset, FlushW, ~StallW, FpResM, FpResW); - flopenrc #(`XLEN) MWRegInt(clk, reset, FlushW, ~StallW, FCvtIntResM, FCvtIntResW); + flopenrc #(`XLEN) MWRegIntCvtRes(clk, reset, FlushW, ~StallW, FCvtIntResM, FCvtIntResW); + flopenrc #(`XLEN) MWRegIntDivRes(clk, reset, FlushW, ~StallW, FPIntDivResultM, FPIntDivResultW); // BEGIN WRITEBACK STAGE diff --git a/pipelined/src/ieu/controller.sv b/pipelined/src/ieu/controller.sv index ab623b0e5..bf9482c80 100644 --- a/pipelined/src/ieu/controller.sv +++ b/pipelined/src/ieu/controller.sv @@ -65,7 +65,7 @@ module controller( output logic FWriteIntM, // Writeback stage control signals input logic StallW, FlushW, - output logic RegWriteW, // for datapath and Hazard Unit + output logic RegWriteW, DivW, // for datapath and Hazard Unit output logic [2:0] ResultSrcW, // Stall during CSRs output logic CSRWriteFencePendingDEM, @@ -109,6 +109,7 @@ module controller( logic IllegalERegAdrD; logic [1:0] AtomicE; logic FencePendingD, FencePendingE, FencePendingM; + logic DivE, DivM; // Extract fields @@ -222,16 +223,17 @@ module controller( assign MemReadE = MemRWE[1]; assign SCE = (ResultSrcE == 3'b100); assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers + assign DivE = MDUE & Funct3E[2]; // Division operation // Memory stage pipeline control register - flopenrc #(19) controlregM(clk, reset, FlushM, ~StallM, - {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE}, - {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FencePendingM, InstrValidM}); + flopenrc #(20) controlregM(clk, reset, FlushM, ~StallM, + {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE, DivE}, + {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FencePendingM, InstrValidM, DivM}); // Writeback stage pipeline control register - flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW, - {RegWriteM, ResultSrcM}, - {RegWriteW, ResultSrcW}); + flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW, + {RegWriteM, ResultSrcM, DivM}, + {RegWriteW, ResultSrcW, DivW}); // Stall pipeline at Fetch if a CSR Write or Fence is pending in the subsequent stages assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FencePendingD | FencePendingE | FencePendingM; diff --git a/pipelined/src/ieu/datapath.sv b/pipelined/src/ieu/datapath.sv index 89ebd9b5d..abc232651 100644 --- a/pipelined/src/ieu/datapath.sv +++ b/pipelined/src/ieu/datapath.sv @@ -57,14 +57,15 @@ module datapath ( output logic [`XLEN-1:0] WriteDataM, // Writeback stage signals input logic StallW, FlushW, -(* mark_debug = "true" *) input logic RegWriteW, +(* mark_debug = "true" *) input logic RegWriteW, DivW, input logic SquashSCW, input logic [2:0] ResultSrcW, input logic [`XLEN-1:0] FCvtIntResW, input logic [`XLEN-1:0] ReadDataW, // input logic [`XLEN-1:0] PCLinkW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW, - // Hazard Unit signals + input logic [`XLEN-1:0] FPIntDivResultW, + // Hazard Unit signals output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, output logic [4:0] RdE, RdM, RdW ); @@ -85,7 +86,7 @@ module datapath ( // Writeback stage signals logic [`XLEN-1:0] SCResultW; logic [`XLEN-1:0] ResultW; - logic [`XLEN-1:0] IFResultW, IFCvtResultW; + logic [`XLEN-1:0] IFResultW, IFCvtResultW, MulDivResultW; // Decode stage assign Rs1D = InstrD[19:15]; @@ -125,10 +126,12 @@ module datapath ( if (`F_SUPPORTED) begin:fpmux mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM); mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW); + mux2 #(`XLEN) divresultmuxW(MDUResultW, FPIntDivResultW, DivW, MulDivResultW); end else begin:fpmux assign IFResultM = IEUResultM; assign IFCvtResultW = IFResultW; + assign MulDivResultW = MDUResultW; end - mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW); + mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW); // handle Store Conditional result if atomic extension supported if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW}; diff --git a/pipelined/src/ieu/ieu.sv b/pipelined/src/ieu/ieu.sv index 014d24f67..40d91a409 100644 --- a/pipelined/src/ieu/ieu.sv +++ b/pipelined/src/ieu/ieu.sv @@ -58,6 +58,7 @@ module ieu ( output logic InvalidateICacheM, FlushDCacheM, // Writeback stage + input logic [`XLEN-1:0] FPIntDivResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW, input logic [`XLEN-1:0] FCvtIntResW, output logic [4:0] RdW, @@ -83,6 +84,7 @@ module ieu ( logic SCE; logic [4:0] RdE; logic FWriteIntM; + logic DivW; // forwarding signals logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; @@ -99,15 +101,15 @@ module ieu ( .Funct3E, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM, - .StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWriteFencePendingDEM, .StoreStallD); + .StallW, .FlushW, .RegWriteW, .DivW, .ResultSrcW, .CSRWriteFencePendingDEM, .StoreStallD); datapath dp( .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, - .StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, - .CSRReadValW, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); + .StallW, .FlushW, .RegWriteW, .DivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, + .CSRReadValW, .MDUResultW, .FPIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); forward fw( .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW, diff --git a/pipelined/src/muldiv/muldiv.sv b/pipelined/src/muldiv/muldiv.sv index 5fa717e5f..c41ec4592 100644 --- a/pipelined/src/muldiv/muldiv.sv +++ b/pipelined/src/muldiv/muldiv.sv @@ -59,10 +59,17 @@ module muldiv ( // Divide // Start a divide when a new division instruction is received and the divider isn't already busy or finishing - assign DivE = MDUE & Funct3E[2]; - assign DivSignedE = ~Funct3E[0]; - intdivrestoring div(.clk, .reset, .StallM, .TrapM, .DivSignedE, .W64E, .DivE, - .ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM); + // When F extensions are supported, use the FPU divider instead + if (`F_SUPPORTED) begin + assign QuotM = 0; + assign RemM = 0; + assign DivBusyE = 0; + end else begin + assign DivE = MDUE & Funct3E[2]; + assign DivSignedE = ~Funct3E[0]; + intdivrestoring div(.clk, .reset, .StallM, .TrapM, .DivSignedE, .W64E, .DivE, + .ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM); + end // Result multiplexer always_comb diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index 076088857..a34a088e6 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -99,6 +99,7 @@ module wallypipelinedcore ( logic FpLoadStoreM; logic [1:0] FResSelW; logic [4:0] SetFflagsM; + logic [`XLEN-1:0] FPIntDivResultW; // memory management unit signals logic ITLBWriteF; @@ -228,7 +229,7 @@ module wallypipelinedcore ( .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM, // Writeback stage - .CSRReadValW, .MDUResultW, + .CSRReadValW, .MDUResultW, .FPIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]), .InstrValidM, .FCvtIntResW, @@ -405,7 +406,8 @@ module wallypipelinedcore ( .FCvtIntW, // fpu result selection .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) .IllegalFPUInstrM, // Is the instruction an illegal fpu instruction - .SetFflagsM // FPU flags (to privileged unit) + .SetFflagsM, // FPU flags (to privileged unit) + .FPIntDivResultW ); // floating point unit end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low assign FStallD = 0; diff --git a/tests/riscof/Makefile b/tests/riscof/Makefile index aba3983c3..8292b9888 100644 --- a/tests/riscof/Makefile +++ b/tests/riscof/Makefile @@ -8,8 +8,7 @@ wally_workdir = $(work)/wally-riscv-arch-test current_dir = $(shell pwd) #XLEN ?= 64 -all: root fsd_fld_tempfix arch32 wally32 wally32e arch64 wally64 -#all: root fsd_fld_tempfix wally32 +all: root arch32 wally32 wally32e arch64 wally64 root: mkdir -p $(work_dir) @@ -20,14 +19,8 @@ root: sed 's,{0},$(current_dir),g;s,{1},64gc,g' config.ini > config64.ini sed 's,{0},$(current_dir),g;s,{1},32e,g' config.ini > config32e.ini -fsd_fld_tempfix: - # this is a temporary fix, there's a typo on the rv64i_m/D/src/d_fsd-align-01.S and rv64i_m/D/src/d_fld-align-01.S tests - # https://github.com/riscv-non-isa/riscv-arch-test/issues/266 - find ../../addins/riscv-arch-test/riscv-test-suite -type f -name "*d_fld-align*.S" | xargs -I{} sed -i 's,regex(\.\*32\.\*),regex(\.\*64\.\*),g' {} - find ../../addins/riscv-arch-test/riscv-test-suite -type f -name "*d_fsd-align*.S" | xargs -I{} sed -i 's,regex(\.\*32\.\*),regex(\.\*64\.\*),g' {} - arch32: - riscof --verbose debug run --work-dir=$(work_dir) --config=config32.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env --no-browser + riscof run --work-dir=$(work_dir) --config=config32.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env --no-browser rsync -a $(work_dir)/rv32i_m/ $(arch_workdir)/rv32i_m/ || echo "error suppressed" arch64: