From 0b9fd8a4b310554b4744a2178e2eafe4dd4c572d Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 21 Feb 2023 09:32:17 -0800 Subject: [PATCH 1/3] Fixed Issue #106: fld rasies load access fault instead of illegal instruction. The IEU controller had considered all fp loads and stores to be legal regardless of whether the FPU is enabled or the type is supported. Merged illegal instruction detection from both units into the Decode stage, saving two bits of pipeline register as well. --- src/fpu/fctrl.sv | 15 +++++++-------- src/fpu/fpu.sv | 4 ++-- src/ieu/controller.sv | 12 ++++++------ src/ieu/ieu.sv | 6 +++--- src/ifu/ifu.sv | 11 +++++++---- src/privileged/privdec.sv | 7 +++---- src/privileged/privileged.sv | 10 +++++----- src/privileged/privpiperegs.sv | 14 +++++++------- src/wally/wallypipelinedcore.sv | 15 +++++++-------- 9 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 56320613..e787d10b 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -60,14 +60,13 @@ module fctrl ( output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input // other control signals - output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction + output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction output logic FDivStartE, IDivStartE // Start division or squareroot ); `define FCTRLW 12 logic [`FCTRLW-1:0] ControlsD; // control signals - logic IllegalFPUInstrD, IllegalFPUInstrE; // is the intruction an illegal fpu instruction logic FRegWriteD; // FP register write enable logic FDivStartD; // start division/sqrt logic FWriteIntD; // integer register write enable @@ -280,9 +279,9 @@ module fctrl ( assign Adr3D = InstrD[31:27]; // D/E pipleine register - flopenrc #(14+`FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE, - {FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, IllegalFPUInstrD, FCvtIntD}, - {FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE, FCvtIntE}); + flopenrc #(13+`FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE, + {FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD}, + {FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE}); flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E}); flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE); flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE}); @@ -292,9 +291,9 @@ module fctrl ( else assign IDivStartE = 0; // E/M pipleine register - flopenrc #(14+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM, - {FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE, FCvtIntE}, - {FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, IllegalFPUInstrM, FCvtIntM}); + flopenrc #(13+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM, + {FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE}, + {FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM}); // renameing for readability assign FpLoadStoreM = FResSelM[1]; diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index 73bf1971..eabc57b3 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -55,7 +55,7 @@ module fpu ( output logic FpLoadStoreM, // Fp load instruction? (to LSU) output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU) output logic [`XLEN-1:0] FIntResM, // data to be written to integer register (to IEU) - output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction (to privileged unit) + output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU) output logic [4:0] SetFflagsM, // FPU flags (to privileged unit) // Writeback stage input logic [4:0] RdW, // which FP register to write to (from IEU) @@ -171,7 +171,7 @@ module fpu ( .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE, .reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .FpLoadStoreM, - .IllegalFPUInstrM, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE, + .IllegalFPUInstrD, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE, .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .FCvtIntW, .Adr1D, .Adr2D, .Adr3D, .Adr1E, .Adr2E, .Adr3E); diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index d6642534..0b1852cb 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -36,8 +36,8 @@ module controller( input logic StallD, FlushD, // Stall, flush Decode stage input logic [31:0] InstrD, // Instruction in Decode stage output logic [2:0] ImmSrcD, // Type of immediate extension - input logic IllegalIEUInstrFaultD, // Illegal IEU instruction - output logic IllegalBaseInstrFaultD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers + input logic IllegalIEUFPUInstrD, // Illegal IEU and FPU instruction + output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers // Execute stage control signals input logic StallE, FlushE, // Stall, flush Execute stage input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) @@ -126,7 +126,7 @@ module controller( // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Illegal instruction 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw - 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // flw - only legal if FP supported + 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported 7'b0001111: if (`ZIFENCEI_SUPPORTED) ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence else @@ -138,7 +138,7 @@ module controller( else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction 7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // sw - 7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // fsw - only legal if FP supported + 7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_1; // fsw - only legal if FP supported 7'b0101111: if (`A_SUPPORTED) begin if (InstrD[31:27] == 5'b00010) ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0; // lr @@ -178,10 +178,10 @@ module controller( // Squash control signals if coming from an illegal compressed instruction // On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them. assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11]; - assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD; + assign IllegalBaseInstrD = ControlsD[0] | IllegalERegAdrD; assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD, ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD, - PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD; + PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD; assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index 9d3a833e..346594eb 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -32,8 +32,8 @@ module ieu ( input logic clk, reset, // Decode stage signals input logic [31:0] InstrD, // Instruction - input logic IllegalIEUInstrFaultD, // Illegal instruction - output logic IllegalBaseInstrFaultD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers + input logic IllegalIEUFPUInstrD, // Illegal instruction + output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers // Execute stage signals input logic [`XLEN-1:0] PCE, // PC input logic [`XLEN-1:0] PCLinkE, // PC + 4 @@ -94,7 +94,7 @@ module ieu ( controller c( .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, - .IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE, + .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE, .Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 51317e0b..1a63bfca 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -70,9 +70,10 @@ module ifu ( output logic RASPredPCWrongM, // RAS prediction is wrong output logic PredictionInstrClassWrongM, // Class prediction is wrong // Faults - input logic IllegalBaseInstrFaultD, // Illegal non-compressed instruction + input logic IllegalBaseInstrD, // Illegal non-compressed instruction + input logic IllegalFPUInstrD, // Illegal FP instruction output logic InstrPageFaultF, // Instruction page fault - output logic IllegalIEUInstrFaultD, // Illegal instruction including compressed + output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) // mmu management input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage @@ -116,6 +117,7 @@ module ifu ( logic CompressedE; // The execution instruction is compressed logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage + logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good logic [1:0] IFURWF; // IFU alreays read IFURWF = 10 logic [31:0] InstrE; // Instruction in the Execution stage @@ -349,11 +351,12 @@ module ifu ( if (`C_SUPPORTED) begin logic IllegalCompInstrD; decompress decomp(.InstrRawD, .InstrD, .IllegalCompInstrD); - assign IllegalIEUInstrFaultD = IllegalBaseInstrFaultD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr + assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr end else begin assign InstrD = InstrRawD; - assign IllegalIEUInstrFaultD = IllegalBaseInstrFaultD; + assign IllegalIEUInstrD = IllegalBaseInstrD; end + assign IllegalIEUFPUInstrD = IllegalIEUInstrD & IllegalFPUInstrD; // Misaligned PC logic // Instruction address misalignement only from br/jal(r) instructions. diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index fe73ebbf..21239dc9 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -34,8 +34,7 @@ module privdec ( input logic StallM, input logic [31:20] InstrM, // privileged instruction function field input logic PrivilegedM, // is this a privileged instruction (from IEU controller) - input logic IllegalIEUInstrFaultM, // Not a legal IEU instruction - input logic IllegalFPUInstrM, // Not a legal FPU instruction + input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction input logic IllegalCSRAccessM, // Not a legal CSR access input logic [1:0] PrivilegeModeW, // current privilege level input logic STATUS_TSR, STATUS_TVM, STATUS_TW, // status bits @@ -85,6 +84,6 @@ module privdec ( /////////////////////////////////////////// assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM); - assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM | - WFITimeoutM; + assign IllegalInstrFaultM = IllegalIEUFPUInstrM | IllegalPrivilegedInstrM | IllegalCSRAccessM | + WFITimeoutM; endmodule diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 29d65f13..300da8a6 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -65,7 +65,7 @@ module privileged ( input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults input logic InstrMisalignedFaultM, // misaligned instruction fault input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault - input logic IllegalIEUInstrFaultD, IllegalFPUInstrM, // illegal instruction faults + input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources input logic [63:0] MTIME_CLINT, // timer value from CLINT input logic [4:0] SetFflagsM, // set FCSR flags from FPU @@ -95,7 +95,7 @@ module privileged ( logic [11:0] MIDELEG_REGW; // interrupt delegation CSR logic sretM, mretM; // supervisor / machine return instruction logic IllegalCSRAccessM; // Illegal access to CSR - logic IllegalIEUInstrFaultM; // Illegal IEU instruction, delayed to Mem stage + logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages logic IllegalInstrFaultM; // Illegal instruction fault @@ -115,7 +115,7 @@ module privileged ( // decode privileged instructions privdec pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]), - .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, + .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM); @@ -137,8 +137,8 @@ module privileged ( // pipeline early-arriving trap sources privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, - .InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUInstrFaultD, - .InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUInstrFaultM); + .InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUFPUInstrD, + .InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUFPUInstrM); // trap logic trap trap(.reset, diff --git a/src/privileged/privpiperegs.sv b/src/privileged/privpiperegs.sv index 03e1d621..c3d308c1 100644 --- a/src/privileged/privpiperegs.sv +++ b/src/privileged/privpiperegs.sv @@ -33,24 +33,24 @@ module privpiperegs ( input logic StallD, StallE, StallM, input logic FlushD, FlushE, FlushM, input logic InstrPageFaultF, InstrAccessFaultF, // instruction faults - input logic IllegalIEUInstrFaultD, // illegal IEU instruction decoded + input logic IllegalIEUFPUInstrD, // illegal IEU instruction decoded output logic InstrPageFaultM, InstrAccessFaultM, // delayed instruction faults - output logic IllegalIEUInstrFaultM // delayed illegal IEU instruction + output logic IllegalIEUFPUInstrM // delayed illegal IEU instruction ); // Delayed fault signals logic InstrPageFaultD, InstrAccessFaultD; logic InstrPageFaultE, InstrAccessFaultE; - logic IllegalIEUInstrFaultE; + logic IllegalIEUFPUInstrE; // pipeline fault signals flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD, {InstrPageFaultF, InstrAccessFaultF}, {InstrPageFaultD, InstrAccessFaultD}); flopenrc #(3) faultregE(clk, reset, FlushE, ~StallE, - {IllegalIEUInstrFaultD, InstrPageFaultD, InstrAccessFaultD}, - {IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE}); + {IllegalIEUFPUInstrD, InstrPageFaultD, InstrAccessFaultD}, + {IllegalIEUFPUInstrE, InstrPageFaultE, InstrAccessFaultE}); flopenrc #(3) faultregM(clk, reset, FlushM, ~StallM, - {IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE}, - {IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM}); + {IllegalIEUFPUInstrE, InstrPageFaultE, InstrAccessFaultE}, + {IllegalIEUFPUInstrM, InstrPageFaultM, InstrAccessFaultM}); endmodule \ No newline at end of file diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index a03caea1..7ac53117 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -70,7 +70,7 @@ module wallypipelinedcore ( logic [1:0] MemRWM; logic InstrValidD, InstrValidE, InstrValidM; logic InstrMisalignedFaultM; - logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD; + logic IllegalBaseInstrD, IllegalFPUInstrD, IllegalIEUFPUInstrD; logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM; logic LoadMisalignedFaultM, LoadAccessFaultM; logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM; @@ -91,7 +91,6 @@ module wallypipelinedcore ( logic [`XLEN-1:0] FCvtIntResW; logic FCvtIntW; logic FDivBusyE; - logic IllegalFPUInstrM; logic FRegWriteM; logic FCvtIntStallD; logic FpLoadStoreM; @@ -180,7 +179,7 @@ module wallypipelinedcore ( .InstrD, .InstrM, .PCM, .InstrClassM, .DirPredictionWrongM, .JumpOrTakenBranchM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, // Faults out - .IllegalBaseInstrFaultD, .InstrPageFaultF, .IllegalIEUInstrFaultD, .InstrMisalignedFaultM, + .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, // mmu management .PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ITLBWriteF, .sfencevmaM, .ITLBMissF, @@ -190,7 +189,7 @@ module wallypipelinedcore ( // integer execution unit: integer register file, datapath and controller ieu ieu(.clk, .reset, // Decode Stage interface - .InstrD, .IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, + .InstrD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, // Execute Stage interface .PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E, .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, @@ -294,12 +293,12 @@ module wallypipelinedcore ( .RASPredPCWrongM, .PredictionInstrClassWrongM, .InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, - .InstrMisalignedFaultM, .IllegalIEUInstrFaultD, + .InstrMisalignedFaultM, .IllegalIEUFPUInstrD, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .IEUAdrM, .SetFflagsM, .InstrAccessFaultF, .HPTWInstrAccessFaultM, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW, - .IllegalFPUInstrM, .PrivilegeModeW, .SATP_REGW, + .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM); @@ -347,7 +346,7 @@ module wallypipelinedcore ( .FCvtIntResW, // fp -> int conversion result to be stored in int register .FCvtIntW, // fpu result selection .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) - .IllegalFPUInstrM, // Is the instruction an illegal fpu instruction + .IllegalFPUInstrD, // Is the instruction an illegal fpu instruction .SetFflagsM, // FPU flags (to privileged unit) .FIntDivResultW); end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low @@ -357,7 +356,7 @@ module wallypipelinedcore ( assign FIntResM = 0; assign FCvtIntW = 0; assign FDivBusyE = 0; - assign IllegalFPUInstrM = 1; + assign IllegalFPUInstrD = 1; assign SetFflagsM = 0; assign FpLoadStoreM = 0; end From 5ce476241bf0be4aafc8edb56594ab06e717bc55 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 21 Feb 2023 09:33:36 -0800 Subject: [PATCH 2/3] Debug test case updates --- tests/custom/debug/Makefile | 1 + tests/custom/debug/debug.S | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/custom/debug/Makefile b/tests/custom/debug/Makefile index ddabe4e3..7f3fd926 100644 --- a/tests/custom/debug/Makefile +++ b/tests/custom/debug/Makefile @@ -4,6 +4,7 @@ TARGET = debug $(TARGET).signature.output: $(TARGET).elf.memfile $(TARGET).elf spike --isa=rv64gc +signature=$(TARGET).signature.output +signature-granularity=4 $(TARGET).elf + riscv_sim_RV64 debug.elf -T debug.sig # diff --ignore-case $(TARGET).signature.output $(TARGET).reference_output || exit # echo "Signature matches! Success!" mkdir -p ../work diff --git a/tests/custom/debug/debug.S b/tests/custom/debug/debug.S index e6e00e86..d91229da 100644 --- a/tests/custom/debug/debug.S +++ b/tests/custom/debug/debug.S @@ -18,24 +18,29 @@ rvtest_entry_point: fsd f12, 0(a6) # openhwgroup/cvw Issue #56 - fld f4, 16(a7) + fld f4, 16(a7) # cfa695b1047553b1 fld f14, 24(a7) fsgnjx.s f10,f4,f14 # expected f 0xffffffff7fc00000, hdl has been giving 0xcfa695b1047553b1 - fsd f19, 8(a6) + fsd f19, 16(a6) # openhwgroup/cvw Issue #57 fld f0, 32(a7) fld f15, 40(a7) fsgnjx.s f30,f0,f15 # expected f 0xfffffffffb3754ef, hdl has been giving 0xffffffff7b3754ef - fsd f30, 16(a6) + fsd f30, 24(a6) # openhwgroup/cvw Issue #58 fld f14, 48(a7) fclass.s x2, f14 # expected 0x0000000000000200, hdl had been giving 0x0000000000000220 - sd x2, 24(a6) + sd x2, 32(a6) # fsgnjx.s, fclass.s, fsgnjn.s, fsgnj.s, fneg.s, fabs.s, fmv.s all treat inputs as dp rather than sp + #openhwgroup/cvw Issue #65 #expected 0xffffffffffffffff, hdl had been giving 0x00000000ffffffff + fld f17, 56(a7) + fmv.x.s x30, f17 + sd x30, 40(a6) + ######################### # HTIF and signature @@ -66,6 +71,7 @@ rvtest_data: .dword 0xffffffff7fc00000 .dword 0xfffffffffb3754ef .dword 0x7fefffffffffffff +.dword 0x00000000ffffffff .EQU XLEN,64 begin_signature: From 8df7768d3250c7712614d98bf9614fbd94b2a8b5 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 21 Feb 2023 09:57:57 -0800 Subject: [PATCH 3/3] Fixed Issue #65 fmv sign selection. Sign needs to come from most significant bit of raw X source without doing NaN Box fixes first. --- src/fpu/fpu.sv | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index eabc57b3..8ff36fbf 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -160,6 +160,7 @@ module fpu ( logic [`FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt logic [`FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer + logic mvsgn; // sign bit for extending move ////////////////////////////////////////////////////////////////////////////////////////// // Decode Stage: fctrl decoder, read register file @@ -278,21 +279,25 @@ module fpu ( mux3 #(`FLEN) FResMux(SgnResE, AlignedSrcAE, CmpFpResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE); assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE); - // select the result that may be written to the integer register - to IEU - if(`FPSIZES == 1) + // select the result that may be written to the integer register with fmv - to IEU + if(`FPSIZES == 1) begin + assign mvsgn = XE[`FLEN-1]; assign SgnExtXE = XE; - else if(`FPSIZES == 2) - mux2 #(`FLEN) sgnextmux ({{`FLEN-`LEN1{XsE}}, XE[`LEN1-1:0]}, XE, FmtE, SgnExtXE); - else if(`FPSIZES == 3 | `FPSIZES == 4) - mux4 #(`FLEN) fmulzeromux ({{`FLEN-`H_LEN{XsE}}, XE[`H_LEN-1:0]}, - {{`FLEN-`S_LEN{XsE}}, XE[`S_LEN-1:0]}, - {{`FLEN-`D_LEN{XsE}}, XE[`D_LEN-1:0]}, + end else if(`FPSIZES == 2) begin + mux2 #(1) sgnmux (XE[`LEN1-1], XE[`FLEN-1],FmtE, mvsgn); + mux2 #(`FLEN) sgnextmux ({{`FLEN-`LEN1{mvsgn}}, XE[`LEN1-1:0]}, XE, FmtE, SgnExtXE); + end else if(`FPSIZES == 3 | `FPSIZES == 4) begin + mux4 #(1) sgnmux (XE[`H_LEN-1], XE[`S_LEN-1], XE[`D_LEN-1], XE[`LLEN-1], FmtE, mvsgn); + mux4 #(`FLEN) fmulzeromux ({{`FLEN-`H_LEN{mvsgn}}, XE[`H_LEN-1:0]}, + {{`FLEN-`S_LEN{mvsgn}}, XE[`S_LEN-1:0]}, + {{`FLEN-`D_LEN{mvsgn}}, XE[`D_LEN-1:0]}, XE, FmtE, SgnExtXE); + end if (`FLEN>`XLEN) assign IntSrcXE = SgnExtXE[`XLEN-1:0]; else - assign IntSrcXE = {{`XLEN-`FLEN{XsE}}, SgnExtXE}; + assign IntSrcXE = {{`XLEN-`FLEN{mvsgn}}, SgnExtXE}; mux3 #(`XLEN) IntResMux (ClassResE, IntSrcXE, CmpIntResE, {~FResSelE[1], FResSelE[0]}, FIntResE); // E/M pipe registers