mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 10:15:19 +00:00
Merge pull request #219 from davidharrishmc/dev
Spill logic coverage and fdivsqrt cleanup
This commit is contained in:
commit
cfab7c8b45
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -43,4 +43,7 @@ main:
|
||||
|
||||
//.hword 0x9C01 //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else
|
||||
|
||||
|
||||
|
||||
|
||||
j done
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
173
tests/coverage/vm64check.S
Normal file
173
tests/coverage/vm64check.S
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user