diff --git a/src/fpu/fdivsqrt/fdivsqrtpreproc.sv b/src/fpu/fdivsqrt/fdivsqrtpreproc.sv index 9a69085fd..a00d82663 100644 --- a/src/fpu/fdivsqrt/fdivsqrtpreproc.sv +++ b/src/fpu/fdivsqrt/fdivsqrtpreproc.sv @@ -54,47 +54,67 @@ module fdivsqrtpreproc ( logic [`DIVb:0] PreSqrtX; logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed logic [`NE+1:0] QeE; // Quotient Exponent (FP only) - logic [`DIVb-1:0] IFNormLenX, IFNormLenD; // Correctly-sized inputs for iterator + logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs logic NumerZeroE; // Numerator is zero (X or A) logic AZeroE, BZeroE; // A or B is Zero for integer division + logic signedDiv; // signed division + logic NegQuotE; // Integer quotient is negative + logic AsE, BsE; // Signs of integer inputs + logic [`XLEN-1:0] AE; // input A after W64 adjustment if (`IDIV_ON_FPU) begin:intpreproc // Int Supported - logic signedDiv, NegQuotE; - logic AsBit, BsBit, AsE, BsE, ALTBE; - logic [`XLEN-1:0] AE, BE, PosA, PosB; - logic [`DIVBLEN:0] ZeroDiff, p; + logic [`XLEN-1:0] BE, PosA, PosB; // Extract inputs, signs, zero, depending on W64 mode if applicable assign signedDiv = ~Funct3E[0]; - assign NegQuotE = AsE ^ BsE; // Quotient is negative - + // Source handling if (`XLEN==64) begin // 64-bit, supports W64 - mux2 #(1) azeromux(~(|ForwardedSrcAE), ~(|ForwardedSrcAE[31:0]), W64E, AZeroE); - mux2 #(1) bzeromux(~(|ForwardedSrcBE), ~(|ForwardedSrcBE[31:0]), W64E, BZeroE); - mux2 #(1) abitmux(ForwardedSrcAE[63], ForwardedSrcAE[31], W64E, AsBit); - mux2 #(1) bbitmux(ForwardedSrcBE[63], ForwardedSrcBE[31], W64E, BsBit); - mux2 #(64) amux(ForwardedSrcAE, {{(`XLEN-32){AsE}}, ForwardedSrcAE[31:0]}, W64E, AE); - mux2 #(64) bmux(ForwardedSrcBE, {{(`XLEN-32){BsE}}, ForwardedSrcBE[31:0]}, W64E, BE); - assign AsE = signedDiv & AsBit; - assign BsE = signedDiv & BsBit; + mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & signedDiv}}, ForwardedSrcAE[31:0]}, W64E, AE); + mux2 #(64) bmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31] & signedDiv}}, ForwardedSrcBE[31:0]}, W64E, BE); end else begin // 32 bits only - assign AsE = signedDiv & ForwardedSrcAE[31]; - assign BsE = signedDiv & ForwardedSrcBE[31]; assign AE = ForwardedSrcAE; assign BE = ForwardedSrcBE; - assign AZeroE = ~(|ForwardedSrcAE); - assign BZeroE = ~(|ForwardedSrcBE); - end + end + assign AZeroE = ~(|AE); + assign BZeroE = ~(|BE); + assign AsE = AE[`XLEN-1] & signedDiv; + assign BsE = BE[`XLEN-1] & signedDiv; + assign NegQuotE = AsE ^ BsE; // Integer Quotient is negative // Force integer inputs to be postiive mux2 #(`XLEN) posamux(AE, -AE, AsE, PosA); mux2 #(`XLEN) posbmux(BE, -BE, BsE, PosB); // Select integer or floating point inputs - mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenX); - mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenD); + mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFX); + mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFD); + + + end else begin // Int not supported + assign IFX = {Xm, {(`DIVb-`NF-1){1'b0}}}; + assign IFD = {Ym, {(`DIVb-`NF-1){1'b0}}}; + end + + // count leading zeros for Subnorm FP and to normalize integer inputs + lzc #(`DIVb) lzcX (IFX, ell); + lzc #(`DIVb) lzcY (IFD, mE); + + // Normalization shift + assign XPreproc = IFX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1 + assign DPreproc = IFD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); + + // append leading 1 (for normal inputs) + // shift square root to be in range [1/4, 1) + // Normalized numbers are shifted right by 1 if the exponent is odd + // Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd. + mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX); + assign DivX = {3'b000, ~NumerZeroE, XPreproc}; + + if (`IDIV_ON_FPU) begin:intrightshift // Int Supported + logic [`DIVBLEN:0] ZeroDiff, p; + logic ALTBE; // calculate number of fractional bits p assign ZeroDiff = mE - ell; // Difference in number of leading zeros @@ -133,34 +153,16 @@ module fdivsqrtpreproc ( flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM); flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM); flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM); - flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM); + flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM); flopen #(`DIVBLEN+1) mreg(clk, IFDivStartE, mE, mM); flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM); if (`XLEN==64) flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M); - - end else begin // Int not supported - assign IFNormLenX = {Xm, {(`DIVb-`NF-1){1'b0}}}; - assign IFNormLenD = {Ym, {(`DIVb-`NF-1){1'b0}}}; + end else begin assign NumerZeroE = XZeroE; assign X = PreShiftX; end - // count leading zeros for Subnorm FP and to normalize integer inputs - lzc #(`DIVb) lzcX (IFNormLenX, ell); - lzc #(`DIVb) lzcY (IFNormLenD, mE); - - // Normalization shift - assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1 - assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); - - // append leading 1 (for normal inputs) - // shift square root to be in range [1/4, 1) - // Normalized numbers are shifted right by 1 if the exponent is odd - // Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd. - mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX); - assign DivX = {3'b000, ~NumerZeroE, XPreproc}; - // Sqrt is initialized on step one as R(X-1), so depends on Radix if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX}; else assign SqrtX = {2'b11, PreSqrtX, 1'b0}; diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 11efacffa..224ff8b37 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -71,6 +71,7 @@ module hazard ( // Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents // Branch misprediction is found in the Execute stage and must flush the next two instructions. // However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete + // When a WFI is interrupted and causes a trap, it flushes the rest of the pipeline but not the W stage, because the WFI needs to commit assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index c1556daeb..75b2bc9e8 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -130,7 +130,7 @@ module ifu ( logic CacheableF; // PMA indicates instruction address is cacheable logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF logic BusStall; // Bus interface busy with multicycle operation - logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation + logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation logic GatedStallD; // StallD gated by selected next spill // branch predictor signal logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF @@ -147,7 +147,7 @@ module ifu ( if(`C_SUPPORTED) begin : Spill spill #(`ICACHE_SUPPORTED) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, - .InstrUpdateDAF, .IFUCacheBusStallD, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); + .InstrUpdateDAF, .IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); end else begin : NoSpill assign PCSpillNextF = PCNextF; assign PCSpillF = PCF; @@ -288,8 +288,8 @@ module ifu ( assign InstrRawF = IROMInstrF; end - assign IFUCacheBusStallD = ICacheStallF | BusStall; - assign IFUStallF = IFUCacheBusStallD | SelSpillNextF; + assign IFUCacheBusStallF = ICacheStallF | BusStall; + assign IFUStallF = IFUCacheBusStallF | SelSpillNextF; assign GatedStallD = StallD & ~SelSpillNextF; flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD); diff --git a/src/ifu/spill.sv b/src/ifu/spill.sv index db68fb9b4..54c0f2261 100644 --- a/src/ifu/spill.sv +++ b/src/ifu/spill.sv @@ -40,7 +40,7 @@ module spill #( input logic [`XLEN-1:2] PCPlus4F, // PCF + 4 input logic [`XLEN-1:0] PCNextF, // The next PCF input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed - input logic IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched + input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched input logic ITLBMissF, // ITLB miss, ignore memory request input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active) output logic [`XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill @@ -78,7 +78,7 @@ module spill #( //////////////////////////////////////////////////////////////////////////////////////////////////// assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; - assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF)); + assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF)); always_ff @(posedge clk) if (reset | FlushD) CurrState <= #1 STATE_READY; @@ -88,14 +88,14 @@ module spill #( case (CurrState) STATE_READY: if (TakeSpillF) NextState = STATE_SPILL; else NextState = STATE_READY; - STATE_SPILL: if(IFUCacheBusStallD | StallD) NextState = STATE_SPILL; + STATE_SPILL: if(StallD) NextState = STATE_SPILL; else NextState = STATE_READY; default: NextState = STATE_READY; endcase end assign SelSpillF = (CurrState == STATE_SPILL); - assign SelSpillNextF = (CurrState == STATE_READY & TakeSpillF) | (CurrState == STATE_SPILL & IFUCacheBusStallD); + assign SelSpillNextF = (CurrState == STATE_READY & TakeSpillF) | (CurrState == STATE_SPILL & IFUCacheBusStallF); assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF & ~FlushD; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index be63adb43..ee78e6ccb 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -33,7 +33,9 @@ `include "wally-config.vh" module csrc #(parameter MHPMCOUNTERBASE = 12'hB00, + MTIME = 12'hB01, // this is a memory-mapped register; no such CSR exists, and access should fault MHPMCOUNTERHBASE = 12'hB80, + MTIMEH = 12'hB81, // this is a memory-mapped register; no such CSR exists, and access should fault MHPMEVENTBASE = 12'h320, HPMCOUNTERBASE = 12'hC00, HPMCOUNTERHBASE = 12'hC80, @@ -152,8 +154,10 @@ module csrc #(parameter /* verilator lint_off WIDTH */ if (CSRAdrM == TIME) CSRCReadValM = MTIME_CLINT; // TIME register is a shadow of the memory-mapped MTIME from the CLINT /* verilator lint_on WIDTH */ - else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; - else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; + else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS & CSRAdrM != MTIME) + CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; + else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+`COUNTERS) + CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; else begin CSRCReadValM = 0; IllegalCSRCAccessM = 1; // requested CSR doesn't exist @@ -164,10 +168,14 @@ module csrc #(parameter if (CSRAdrM == TIME) CSRCReadValM = MTIME_CLINT[31:0];// TIME register is a shadow of the memory-mapped MTIME from the CLINT else if (CSRAdrM == TIMEH) CSRCReadValM = MTIME_CLINT[63:32]; /* verilator lint_on WIDTH */ - else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; - else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; - else if (CSRAdrM >= MHPMCOUNTERHBASE & CSRAdrM < MHPMCOUNTERHBASE+`COUNTERS) CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; - else if (CSRAdrM >= HPMCOUNTERHBASE & CSRAdrM < HPMCOUNTERHBASE+`COUNTERS) CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; + else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+`COUNTERS & CSRAdrM != MTIME) + CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; + else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+`COUNTERS) + CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; + else if (CSRAdrM >= MHPMCOUNTERHBASE & CSRAdrM < MHPMCOUNTERHBASE+`COUNTERS & CSRAdrM != MTIMEH) + CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; + else if (CSRAdrM >= HPMCOUNTERHBASE & CSRAdrM < HPMCOUNTERHBASE+`COUNTERS) + CSRCReadValM = HPMCOUNTERH_REGW[CounterNumM]; else begin CSRCReadValM = 0; IllegalCSRCAccessM = 1; // requested CSR doesn't exist diff --git a/testbench/tests.vh b/testbench/tests.vh index 7f5ad4d0d..ca35ddd3b 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -49,7 +49,9 @@ string tvpaths[] = '{ "csrwrites", "priv", "ifu", - "fpu" + "fpu", + "lsu", + "vm64check" }; string coremark[] = '{ @@ -1052,6 +1054,28 @@ string imperas32f[] = '{ string arch64f[] = '{ `RISCVARCHTEST, + "rv64i_m/F/src/fdiv_b1-01.S", + "rv64i_m/F/src/fdiv_b20-01.S", + "rv64i_m/F/src/fdiv_b2-01.S", + "rv64i_m/F/src/fdiv_b21-01.S", + "rv64i_m/F/src/fdiv_b3-01.S", + "rv64i_m/F/src/fdiv_b4-01.S", + "rv64i_m/F/src/fdiv_b5-01.S", + "rv64i_m/F/src/fdiv_b6-01.S", + "rv64i_m/F/src/fdiv_b7-01.S", + "rv64i_m/F/src/fdiv_b8-01.S", + "rv64i_m/F/src/fdiv_b9-01.S", + "rv64i_m/F/src/fsqrt_b1-01.S", + "rv64i_m/F/src/fsqrt_b20-01.S", + "rv64i_m/F/src/fsqrt_b2-01.S", + "rv64i_m/F/src/fsqrt_b3-01.S", + "rv64i_m/F/src/fsqrt_b4-01.S", + "rv64i_m/F/src/fsqrt_b5-01.S", + "rv64i_m/F/src/fsqrt_b7-01.S", + "rv64i_m/F/src/fsqrt_b8-01.S", + "rv64i_m/F/src/fsqrt_b9-01.S", + + "rv64i_m/F/src/fadd_b10-01.S", "rv64i_m/F/src/fadd_b1-01.S", "rv64i_m/F/src/fadd_b11-01.S", @@ -1203,6 +1227,28 @@ string imperas32f[] = '{ string arch64d[] = '{ `RISCVARCHTEST, + // for speed + "rv64i_m/D/src/fdiv.d_b1-01.S", + "rv64i_m/D/src/fdiv.d_b20-01.S", + "rv64i_m/D/src/fdiv.d_b2-01.S", + "rv64i_m/D/src/fdiv.d_b21-01.S", + "rv64i_m/D/src/fdiv.d_b3-01.S", + "rv64i_m/D/src/fdiv.d_b4-01.S", + "rv64i_m/D/src/fdiv.d_b5-01.S", + "rv64i_m/D/src/fdiv.d_b6-01.S", + "rv64i_m/D/src/fdiv.d_b7-01.S", + "rv64i_m/D/src/fdiv.d_b8-01.S", + "rv64i_m/D/src/fdiv.d_b9-01.S", + "rv64i_m/D/src/fsqrt.d_b1-01.S", + "rv64i_m/D/src/fsqrt.d_b20-01.S", + "rv64i_m/D/src/fsqrt.d_b2-01.S", + "rv64i_m/D/src/fsqrt.d_b3-01.S", + "rv64i_m/D/src/fsqrt.d_b4-01.S", + "rv64i_m/D/src/fsqrt.d_b5-01.S", + "rv64i_m/D/src/fsqrt.d_b7-01.S", + "rv64i_m/D/src/fsqrt.d_b8-01.S", + "rv64i_m/D/src/fsqrt.d_b9-01.S", + "rv64i_m/D/src/fadd.d_b10-01.S", "rv64i_m/D/src/fadd.d_b1-01.S", "rv64i_m/D/src/fadd.d_b11-01.S", diff --git a/tests/coverage/WALLY-init-lib.h b/tests/coverage/WALLY-init-lib.h index f95ef285c..1dd43accf 100644 --- a/tests/coverage/WALLY-init-lib.h +++ b/tests/coverage/WALLY-init-lib.h @@ -36,6 +36,7 @@ rvtest_entry_point: csrw mtvec, t0 # Initialize MTVEC to trap_handler csrw mideleg, zero # Don't delegate interrupts csrw medeleg, zero # Don't delegate exceptions + li t0, 0x80 csrw mie, t0 # Enable machine timer interrupt la t0, topoftrapstack csrw mscratch, t0 # MSCRATCH holds trap stack pointer @@ -65,9 +66,8 @@ interrupt: # must be a timer interrupt j trap_return # clean up and return exception: - csrr t1, mepc # add 4 to MEPC to determine return Address - addi t1, t1, 4 - csrw mepc, t1 + li t0, 2 + csrr t1, mcause li t1, 8 # is it an ecall trap? andi t0, t0, 0xFC # if CAUSE = 8, 9, or 11 bne t0, t1, trap_return # ignore other exceptions @@ -86,6 +86,20 @@ changeprivilege: csrs mstatus, a0 # set mstatus.MPP with desired privilege trap_return: # return from trap handler + csrr t0, mepc # get address of instruction that caused exception + lh t0, 0(t0) # get instruction that caused exception + li t1, 3 + and t0, t0, t1 # mask off upper bits + beq t0, t1, instr32 # if lower 2 bits are 11, instruction is uncompresssed + li t0, 2 # increment PC by 2 for compressed instruction + j updateepc +instr32: + li t0, 4 +updateepc: + csrr t1, mepc # add 2 or 4 (from t0) to MEPC to determine return Address + add t1, t1, t0 + csrw mepc, t1 + ld t1, -8(tp) # restore t1 and t0 ld t0, 0(tp) csrrw tp, mscratch, tp # restore tp diff --git a/tests/coverage/csrwrites.S b/tests/coverage/csrwrites.S index 76e310e5f..41d211467 100644 --- a/tests/coverage/csrwrites.S +++ b/tests/coverage/csrwrites.S @@ -27,9 +27,11 @@ #include "WALLY-init-lib.h" main: + li t0, -5 + csrw stimecmp, t0 # initialize so ImperasDV agrees csrrw t0, stimecmp, t0 - csrrw t0, satp, t0 - csrrw t0, stvec, t0 - csrrw t0, sscratch, t0 + csrrw t0, satp, zero + csrrw t0, stvec, zero + csrrw t0, sscratch, zero j done diff --git a/tests/coverage/ieu.S b/tests/coverage/ieu.S index 3fd56686f..cb0dae877 100644 --- a/tests/coverage/ieu.S +++ b/tests/coverage/ieu.S @@ -42,6 +42,7 @@ main: clz t1, t0 # Test forwarding from store conditional + mv a0, sp lr.w t0, 0(a0) sc.w t0, a1, 0(a0) addi t0, t0, 1 diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index 662629916..ef863c617 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -43,4 +43,7 @@ main: //.hword 0x9C01 //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else + + + j done diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index c4e9e302d..e9a04a68f 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -33,7 +33,8 @@ main: ecall # Test read to stimecmp fails when MCOUNTEREN_TM is not set - addi t0, zero, 0 + li t1, -3 + csrw stimecmp, t1 csrr t0, stimecmp diff --git a/tests/coverage/vm64check.S b/tests/coverage/vm64check.S new file mode 100644 index 000000000..55c4db959 --- /dev/null +++ b/tests/coverage/vm64check.S @@ -0,0 +1,173 @@ +/////////////////////////////////////////// +// vm64check.S +// +// Written: David_Harris@hmc.edu 7 April 2023 +// +// Purpose: vm64check coverage +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// Cover IMMU vm64check block by jumping to illegal virtual addresses +// Need a nonstandard trap handler to deal with returns from theses jumps +// assign eq_46_38 = &(VAdr[46:38]) | ~|(VAdr[46:38]); + // assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]); + // assign UpperBitsUnequal = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47; + +.section .text.init +.global rvtest_entry_point + +rvtest_entry_point: + la sp, topofstack # Initialize stack pointer (not used) + + # Set up interrupts + la t0, trap_handler + csrw mtvec, t0 # Initialize MTVEC to trap_handler + # set up PMP so user and supervisor mode can access full address space + csrw pmpcfg0, 0xF # configure PMP0 to TOR RWX + li t0, 0xFFFFFFFF + csrw pmpaddr0, t0 # configure PMP0 top of range to 0xFFFFFFFF to allow all 32-bit addresses + + # SATP in non-39 mode + csrw satp, zero + + // vm64check coverage +check1: + // check virtual addresses with bits 63:47 and/or 46:38 being equal or unequal + li t0, 0x00000001800F0000 # unimplemented memory with upper and lower all zero + la ra, check2 + jalr t0 + +check2: + li t0, 0xFFFFFFF1800F0000 # unimplemented memory with upper and lower all one + la ra, check3 + jalr t0 + +check3: + li t0, 0xFFF81001800F0000 # unimplemented memory with upper all one, lower mixed + la ra, check4 + jalr t0 + +check4: + li t0, 0x03001001800F0000 # unimplemented memory with upper mixed, lower mixed + la ra, check5 + jalr t0 + +check5: + li t0, 0x00001001800F0000 # unimplemented memory with upper all zero, lower mixed + la ra, check11 + jalr t0 + +check11: + # SATP in SV39 mode + li t0, 0x8000000000000000 + csrw satp, t0 + + // check virtual addresses with bits 63:47 and/or 46:38 being equal or unequal + li t0, 0x00000001800F0000 # unimplemented memory with upper and lower all zero + la ra, check12 + jalr t0 + +check12: + li t0, 0xFFFFFFF1800F0000 # unimplemented memory with upper and lower all one + la ra, check13 + jalr t0 + +check13: + li t0, 0xFFF81001800F0000 # unimplemented memory with upper all one, lower mixed + la ra, check14 + jalr t0 + +check14: + li t0, 0x03001001800F0000 # unimplemented memory with upper mixed, lower mixed + la ra, check15 + jalr t0 + +check15: + li t0, 0x00001001800F0000 # unimplemented memory with upper all zero, lower mixed + la ra, check16 + jalr t0 + +check16: + +write_tohost: + la t1, tohost + li t0, 1 # 1 for success, 3 for failure + sd t0, 0(t1) # send success code + +self_loop: + j self_loop # wait + +.align 4 # trap handlers must be aligned to multiple of 4 +trap_handler: + csrw mepc, ra # return to address in ra + mret + +.section .tohost +tohost: # write to HTIF + .dword 0 +fromhost: + .dword 0 + + +# Initialize stack with room for 512 bytes +.bss + .space 512 +topofstack: + + + + + + j done + + lw t1, 0(t0) + li t0, 0xFFFFFFFF80000000 + lw t1, 0(t0) + li t1, 0xFFF8000080000000 + lw t1, 0(t0) + li t1, 0x1000000080000000 + lw t1, 0(t0) + li t1, 0x0000010080000000 + lw t1, 0(t0) + li t0, 0x8000000000000000 + csrw satp, t0 # SV39 mode + li t0, 0x0000000080000000 + lw t1, 0(t0) + li t0, 0xFFFFFFFF80000000 + lw t1, 0(t0) + li t1, 0xFFF8000080000000 + lw t1, 0(t0) + li t1, 0x1000000080000000 + lw t1, 0(t0) + li t1, 0x0000010080000000 + lw t1, 0(t0) + li t0, 0x9000000000000000 + csrw satp, t0 # SV48 mode + li t0, 0x0000000080000000 + lw t1, 0(t0) + li t0, 0xFFFFFFFF80000000 + lw t1, 0(t0) + li t1, 0xFFF8000080000000 + lw t1, 0(t0) + li t1, 0x1000000080000000 + lw t1, 0(t0) + li t1, 0x0000010080000000 + lw t1, 0(t0) + li t0, 0x0000000000000000 + csrw satp, t0 # disable virtual memory \ No newline at end of file