Merge branch 'main' of github.com:Thomas-J-Kidd/cvw
This commit is contained in:
Thomas Kidd 2024-01-25 17:25:06 -06:00
commit 9165541b97
23 changed files with 451 additions and 56 deletions

View File

@ -41,7 +41,7 @@ localparam COUNTERS = 12'd32;
localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 1;
localparam ZFA_SUPPORTED = 0;
localparam ZFA_SUPPORTED = 1;
localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 1;

View File

@ -111,7 +111,7 @@ localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($uns
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6)));
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ));
localparam CORRSHIFTSZ = NORMSHIFTSZ-2;
localparam CORRSHIFTSZ = (((DIVMINb+1+NF) > (3*NF+4) ? (DIVMINb+1+NF) : (3*NF+4))); // max(DIVMINb+NF+1, 3*NF+4)
// Disable spurious Verilator warnings

View File

@ -34,11 +34,24 @@ do GetLineNum.do
# DH 4/22/23: Exclude all LZAs
coverage exclude -srcfile lzc.sv
#################
# FPU Exclusions
#################
# DH 4/22/23: FDIVSQRT can't go directly from done to busy again
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
# DH 4/22/23: The busy->idle transition only occurs if a FlushE occurs while the divider is busy. The flush is caused by a trap or return,
# which won't happen while the divider is busy.
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state BUSY->IDLE
# All Memory-stage stalls have resolved by time fdivsqrt finishes regular operation in this configuration, so can't test StallM
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -linerange [GetLineNum ../src/fpu/fdivsqrt/fdivsqrtfsm.sv "exclusion-tag: fdivsqrtfsm stallm"] -item b 1
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -linerange [GetLineNum ../src/fpu/fdivsqrt/fdivsqrtfsm.sv "exclusion-tag: fdivsqrtfsm stallm"] -item s 1
# Division by zero never sets sticky/guard/overflow/round to cause inexact or underflow result, but check out of paranoia
coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineNum ../src/fpu/postproc/flags.sv "assign FpInexact"] -item e 1 -fecexprrow 15
coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineNum ../src/fpu/postproc/flags.sv "assign Underflow"] -item e 1 -fecexprrow 22
##################
# Cache Exclusions
##################
### Exclude D$ states and logic for the I$ instance
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
@ -79,6 +92,7 @@ for {set i 0} {$i < $numcacheways} {incr i} {
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SelectedWiteWordEn"] -item e 1 -fecexprrow 4 6
# below: flushD can't go high during an icache write b/c of pipeline stall
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache ClearValidEN"] -item e 1 -fecexprrow 4
}
## D$ Exclusions.
@ -94,6 +108,8 @@ for {set i 0} {$i < $numcacheways} {incr i} {
# FlushStage=1 will never happen when SetValidWay=1 since a pipeline stall is asserted by the cache in the fetch stage, which happens before
# going into the WRITE_LINE state (and asserting SetValidWay). No TrapM can fire and since StallW is high, a stallM caused by WFIStallM would not cause a flushW.
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache ClearValidEN"] -item e 1 -fecexprrow 4
# Not right; other ways can get flushed and dirtied simultaneously coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache UpdateDirty"] -item c 1 -fecexprrow 6
}
# D$ writeback, flush, write_line, or flush_writeback states can't be cancelled by a flush
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY
@ -224,6 +240,17 @@ coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item e
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item b 1
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item s 1
# IMMU never disables translations
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign Translate"] -item e 1 -fecexprrow 2
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign UpdateDA"] -item e 1 -fecexprrow 5
# never reaches this when ENVCFG_ADUE_1 because HPTW updates A bit first
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign PrePageFault"] -item e 1 -fecexprrow 18
# IMMU PMP does not support CBO instructions
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcbom"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboz"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboaccess"]
# No irom
set line [GetLineNum ../src/ifu/ifu.sv "~ITLBMissF & ~CacheableF & ~SelIROM"]
coverage exclude -scope /dut/core/ifu -linerange $line-$line -item c 1 -feccondrow 6
@ -258,5 +285,9 @@ coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0]
# EBU
####################
# Exclude EBU Beat Counter because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency
coverage exclude -scope /core/ebu/ebu/ebufsmarb/BeatCounter
# Exclude EBU Beat Counter flop because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb/BeatCounter/cntrflop

View File

@ -11,6 +11,7 @@
--override cpu/mvendorid=0x602
--override cpu/marchid=0x24
--override refRoot/cpu/tvec_align=64
--override refRoot/cpu/envcfg_mask=1
# bit manipulation
--override cpu/add_Extensions=B
@ -21,6 +22,7 @@
--override cpu/Zcb=T
--override cpu/Zicond=T
--override cpu/Zfh=T
--override cpu/Zfa=T
# Cache block operations
--override cpu/Zicbom=T
@ -95,6 +97,7 @@
--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF
--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF
--callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF
#--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwxaA- 1248 " # UNCORE_RAM
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
# Enable the Imperas instruction coverage

View File

@ -105,7 +105,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
assign ClearDirtyWay = ClearDirty & SelData;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN
assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN
assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache ClearValidEN
// If writing the whole line set all write enables to 1, else only set the correct word.
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
@ -178,7 +178,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
if(CacheEn) begin
Dirty <= #1 DirtyBits[CacheSetTag];
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= #1 SetDirtyWay;
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= #1 SetDirtyWay; // exclusion-tag: cache UpdateDirty
end
end
end else assign Dirty = 1'b0;

View File

@ -67,12 +67,13 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
// LT/LE - signaling - sets invalid if NaN input
// EQ - quiet - sets invalid if signaling NaN input
always_comb begin
case (OpCtrl[2:0])
casez (OpCtrl[2:0])
3'b110: CmpNV = EitherSNaN; //min
3'b101: CmpNV = EitherSNaN; //max
3'b010: CmpNV = EitherSNaN; //equal
3'b001: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq / flt perform CompareQuietLess / CompareSignalingLess differing on when to set invalid
3'b011: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fleq / fle differ on when to set invalid
3'b0?1: if (P.ZFA_SUPPORTED)
CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq,fleq / flt,fle perform CompareQuietLess / CompareSignalingLess differing on when to set invalid
else CmpNV = EitherNaN; // flt, fle
default: CmpNV = 1'bx;
endcase
end

View File

@ -87,8 +87,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & P.D_SUPPORTED) |
(Fmt == 2'b10 & P.ZFH_SUPPORTED & {OpD[6:4], OpD[1:0]} != 5'b10011) | // fma not supported for Zfh
(Fmt == 2'b11 & P.Q_SUPPORTED));
(Fmt == 2'b10 & P.ZFH_SUPPORTED) | (Fmt == 2'b11 & P.Q_SUPPORTED));
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) |
(Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED));

View File

@ -70,8 +70,8 @@ module fdivsqrtfsm import cvw::*; #(parameter cvw_t P) (
end else if (state == BUSY) begin
if (step == 1 | WZeroE) state <= #1 DONE; // finished steps or terminate early on zero residual
step <= step - 1;
end else if (state == DONE) begin
if (StallM) state <= #1 DONE;
end else if (state == DONE) begin // Can't still be stalled in configs tested, but keep this check for paranoia
if (StallM) state <= #1 DONE; // exclusion-tag: fdivsqrtfsm stallm
else state <= #1 IDLE;
end
end

View File

@ -98,6 +98,6 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// determine if the result underflows ??? -> fp
// - if the first 1 is shifted out of the result then the result underflows
// - can't underflow an integer to fp conversions
assign CvtResUf = ($signed(CvtCe) < $signed({{P.NE-$clog2(P.NF){1'b1}}, ResNegNF}))&~XZero&~IntToFp;
assign CvtResUf = ($signed(CvtCe) < $signed({{P.NE-$clog2(P.NF){1'b1}}, ResNegNF}))&~XZero; // dh &~IntToFp not necessary because integer to float conversion never underflows
endmodule

View File

@ -148,7 +148,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
// Set Inexact flag if the result is diffrent from what would be outputed given infinite precision
// - Don't set the underflow flag if an underflowed res isn't outputed
assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid);
//assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid|XZero);
// if the res is too small to be represented and not 0
// | and if the res is not invalid (outside the integer bounds)

View File

@ -101,9 +101,9 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF2-2+P.BIAS-P.BIAS2)) | ~|PreNormSumExp;
always_comb begin
case (Fmt)
P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
P.FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
P.FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL; // & ~FmaSZero; // checking sum is not zero is harmless but turns out to be unnecessary
P.FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL; // & ~FmaSZero;
P.FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL; // & ~FmaSZero;
default: FmaPreResultSubnorm = 1'bx;
endcase
end

View File

@ -68,6 +68,7 @@ module round import cvw::*; #(parameter cvw_t P) (
logic CalcPlus1; // calculated plus1
logic FpPlus1; // do you add one to the fp result
logic [P.FLEN:0] RoundAdd; // how much to add to the result
logic CvtToInt; // Convert to integer operation
// what position is XLEN in?
// options:
@ -111,6 +112,7 @@ module round import cvw::*; #(parameter cvw_t P) (
// determine what format the final result is in: int or fp
assign IntRes = ToInt;
assign FpRes = ~IntRes;
assign CvtToInt = ToInt; // under current encodings, CvtOp always is 1 when ToInt is selected, so leave it out
// sticky bit calculation
if (P.FPSIZES == 1) begin
@ -244,9 +246,9 @@ module round import cvw::*; #(parameter cvw_t P) (
endcase
end
assign Guard = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard;
assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
assign Guard = CvtToInt ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard;
assign LsbRes = CvtToInt ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
assign Round = CvtToInt ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
always_comb begin
// Determine if you add 1
@ -272,7 +274,7 @@ module round import cvw::*; #(parameter cvw_t P) (
// If an answer is exact don't round
assign Plus1 = CalcPlus1 & (Sticky|Round|Guard);
assign FpPlus1 = Plus1&~(ToInt&CvtOp);
assign FpPlus1 = Plus1&~(CvtToInt);
assign UfPlus1 = UfCalcPlus1 & (Sticky|Round);
// place Plus1 into the proper position for the format

View File

@ -44,7 +44,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
output logic [P.NE+1:0] Ue // corrected exponent for divider
);
logic [P.CORRSHIFTSZ-1:0] CorrSumShifted; // the shifted sum after LZA correction
logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
logic ResSubnorm; // is the result Subnormal
@ -68,7 +68,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
always_comb
if(FmaOp) Mf = {CorrSumShifted};
if(FmaOp) Mf = {CorrSumShifted, {P.CORRSHIFTSZ-(3*P.NF+4){1'b0}}};
else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];

View File

@ -342,7 +342,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
else OfIntRes2 = OfIntRes;
if (Zfa) Int64Res = {{(P.XLEN-32){CvtNegRes[P.XLEN-1]}}, CvtNegRes[31:0]};
else Int64Res = CvtNegRes[P.XLEN-1:0];
if (Zfa) SelCvtOfRes = InfIn | NaNIn; // fcvtmod.w.d only overflows to 0 on NaN or Infinity
if (Zfa) SelCvtOfRes = InfIn | NaNIn | (CvtCe > 32 + 52); // fcvtmod.w.d only overflows to 0 on NaN or Infinity, or if the shift is so large that only zeros are left
else SelCvtOfRes = IntInvalid; // regular fcvt gives an overflow if out of range
end
else

View File

@ -70,13 +70,13 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
priorityonehot #(P.PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
// Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | (|(L & FirstMatch)); // *** switch to this logic when PMP is initialized for non-machine mode
assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | (|(L & FirstMatch));
assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~|((R|W) & FirstMatch) ;
assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~|(W & FirstMatch) ;
assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault;
assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~|((R|W) & FirstMatch) ; // exclusion-tag: immu-pmpcbom
assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~|(W & FirstMatch) ; // exclusion-tag: immu-pmpcboz
assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault; // exclusion-tag: immu-pmpcboaccess
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
assign PMPStoreAmoAccessFaultM = (EnforcePMP & WriteAccessM & ~|(W & FirstMatch)) | PMPCMOAccessFault;
assign PMPStoreAmoAccessFaultM = (EnforcePMP & WriteAccessM & ~|(W & FirstMatch)) | PMPCMOAccessFault; // exclusion-tag: immu-pmpstoreamoaccessfault
assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ;
endmodule

View File

@ -67,6 +67,7 @@ string tvpaths[] = '{
"pmpcfg1",
"pmpcfg2",
"pmppriority",
"pmpcbo",
"pmpadrdecs"
};

View File

@ -17,7 +17,7 @@ all: $(OBJECTS)
# Change many things if bit width isn't 64
%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \
-nostartfiles -T../../examples/link/link.ld $<
riscv64-unknown-elf-objdump -S $@ > $@.objdump
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile

View File

@ -24,6 +24,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////
// load code to initalize stack, handle interrupts, terminate
// The PMP tests are sensitive to the exact addresses in this code, so unfortunately
// modifying anything breaks those tests.
.section .text.init
.global rvtest_entry_point
@ -36,7 +38,11 @@ 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, -1 # set mtimecmp to biggest number so it doesnt interrupt again
# li t1, 0x02004000 # MTIMECMP in CLINT
# sd t0, 0(t1)
li t0, 0x80
# li t0, 0x00
csrw mie, t0 # Enable machine timer interrupt
la t0, topoftrapstack
csrw mscratch, t0 # MSCRATCH holds trap stack pointer

View File

@ -1,7 +1,7 @@
///////////////////////////////////////////
// ebu.S
//
// Written: David_Harris@hmc.edu 23 March 2023
// Written: David_Harris@hmc.edu 21 January 2024
//
// Purpose: Test coverage for EBU
//
@ -24,22 +24,289 @@
////////////////////////////////////////////////////////////////////////////////////////////////
// load code to initalize stack, handle interrupts, terminate
#include "WALLY-init-lib.h"
# run-elf.bash find this in project description
main:
li t5, 0x1
slli t5, t5, 62
ori t5, t5, 0xF0
csrs menvcfg, t5 # menvcfg.PBMTE = 1, CBZE, CBCFE, CBIE all 1
# Test clz with all bits being 0
li t0, 0
clz t1, t0
li t0, -1
clz t1, t0
li t0, 1
clz t1, t0
# Page table root address at 0x80010000; SV48
li t5, 0x9000000000080010
csrw satp, t5
# Test forwarding from store conditional
lr.w t0, 0(a0)
sc.w t0, a1, 0(a0)
addi t0, t0, 1
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
#
# Tricky case to cover. I$ miss concurrent with DTLB miss. HPTW has to hit the first
# access in the cache and miss a later one. Trigger this by doing a load that touches
# a page not in the DTLB but where the top-level PTE is already there. Has to happen
# near the end of the 16-instruction I$ line.
#
# Condition Coverage for instance /core/ebu/ebu/ebufsmarb --
#
# File ../src/ebu/ebufsmarb.sv
#----------------Focused Condition View-------------------
#Line 72 Item 1 ((HREADY & FinalBeatD) & (LSUReq ~& IFUReq))
#Condition totals: 2 of 4 input terms covered = 50.00%
#
# Input Term Covered Reason for no coverage Hint
# ----------- -------- ----------------------- --------------
# HREADY Y
# FinalBeatD Y
# LSUReq N '_1' not hit Hit '_1'
# IFUReq N No hits Hit '_0' and '_1'
#
# Rows: Hits FEC Target Non-masking condition(s)
# --------- --------- -------------------- -------------------------
# Row 1: 2 HREADY_0 ((LSUReq ~& IFUReq) && FinalBeatD)
# Row 2: 14 HREADY_1 ((LSUReq ~& IFUReq) && FinalBeatD)
# Row 3: 1 FinalBeatD_0 ((LSUReq ~& IFUReq) && HREADY)
# Row 4: 14 FinalBeatD_1 ((LSUReq ~& IFUReq) && HREADY)
# Row 5: 14 LSUReq_0 ((HREADY & FinalBeatD) && IFUReq)
# Row 6: ***0*** LSUReq_1 ((HREADY & FinalBeatD) && IFUReq)
# Row 7: ***0*** IFUReq_0 ((HREADY & FinalBeatD) && LSUReq)
# Row 8: ***0*** IFUReq_1 ((HREADY & FinalBeatD) && LSUReq)
li a0, 0x80000000
li a1, 0x80A00000
j label1
.align 6 # start on multiple of 64 bytes / 16 instruction cache line
label1:
addi t2, t3, 0x100 # occupy part of cache line
sfence.vma # flush tlb
lw t0, 0x234(a0) # load to get an entry in the DTLB accessing top-level PTE
addi t2, t3, 0x103 # occupy part of cache line
addi t2, t3, 0x104 # occupy part of cache line
addi t2, t3, 0x105 # occupy part of cache line
addi t2, t3, 0x106 # occupy part of cache line
addi t2, t3, 0x107 # occupy part of cache line
addi t2, t3, 0x108 # occupy part of cache line
addi t2, t3, 0x109 # occupy part of cache line
addi t2, t3, 0x10A # occupy part of cache line
lw t0, 0x234(a1) # trigger DTLB miss
addi t2, t3, 0x10C # occupy part of cache line
addi t2, t3, 0x10D # occupy part of cache line
addi t2, t3, 0x10E # occupy part of cache line
addi t2, t3, 0x10F # occupy part of cache line
# next multiple of 16
addi t2, t3, 0x100 # occupy part of cache line
sfence.vma # flush tlb
lw t0, 0x334(a0) # load to get an entry in the DTLB accessing top-level PTE
addi t2, t3, 0x103 # occupy part of cache line
addi t2, t3, 0x104 # occupy part of cache line
addi t2, t3, 0x105 # occupy part of cache line
addi t2, t3, 0x106 # occupy part of cache line
addi t2, t3, 0x107 # occupy part of cache line
addi t2, t3, 0x108 # occupy part of cache line
addi t2, t3, 0x109 # occupy part of cache line
addi t2, t3, 0x10A # occupy part of cache line
addi t2, t3, 0x10B # occupy part of cache line
lw t0, 0x334(a1) # trigger DTLB miss
addi t2, t3, 0x10D # occupy part of cache line
addi t2, t3, 0x10E # occupy part of cache line
addi t2, t3, 0x10F # occupy part of cache line
# next multiple of 16
addi t2, t3, 0x100 # occupy part of cache line
sfence.vma # flush tlb
lw t0, 0x434(a0) # load to get an entry in the DTLB accessing top-level PTE
addi t2, t3, 0x103 # occupy part of cache line
addi t2, t3, 0x104 # occupy part of cache line
addi t2, t3, 0x105 # occupy part of cache line
addi t2, t3, 0x106 # occupy part of cache line
addi t2, t3, 0x107 # occupy part of cache line
addi t2, t3, 0x108 # occupy part of cache line
addi t2, t3, 0x109 # occupy part of cache line
addi t2, t3, 0x10A # occupy part of cache line
addi t2, t3, 0x10B # occupy part of cache line
addi t2, t3, 0x10C # occupy part of cache line
lw t0, 0x434(a1) # trigger DTLB miss
addi t2, t3, 0x10E # occupy part of cache line
addi t2, t3, 0x10F # occupy part of cache line
# next multiple of 16
addi t2, t3, 0x100 # occupy part of cache line
sfence.vma # flush tlb
lw t0, 0x534(a0) # load to get an entry in the DTLB accessing top-level PTE
addi t2, t3, 0x103 # occupy part of cache line
addi t2, t3, 0x104 # occupy part of cache line
addi t2, t3, 0x105 # occupy part of cache line
addi t2, t3, 0x106 # occupy part of cache line
addi t2, t3, 0x107 # occupy part of cache line
addi t2, t3, 0x108 # occupy part of cache line
addi t2, t3, 0x109 # occupy part of cache line
addi t2, t3, 0x10A # occupy part of cache line
addi t2, t3, 0x10B # occupy part of cache line
addi t2, t3, 0x10C # occupy part of cache line
addi t2, t3, 0x10D # occupy part of cache line
lw t0, 0x534(a1) # trigger DTLB miss
addi t2, t3, 0x10F # occupy part of cache line
# wrap up
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
ecall
j done
.data
.align 16
# root Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 # 0x00000000-0x80_00000000: PTE at 0x80011000 C1 dirty, accessed, valid
.8byte 0x00000000000010CF # misaligned terapage at 0x80_00000000
# next page table at 0x80011000
.align 12
.8byte 0x00000000000010CF # misaligned gigapage at 0x00000000
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000
.8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
# Next page table at 0x80012000 for gigapage at 0x80000000
.align 12
.8byte 0x0000000020004CC1 # for VA starting at 80000000 (pointer to NAPOT 64 KiB pages)
.8byte 0x0000000020014CCF # for VA starting at 80200000 (misaligned megapage)
.8byte 0x00000000200050C1 # for VA starting at 80400000 (bad PBMT pages)
.8byte 0x4000000020004CC1 # for VA starting at 80600000 (bad entry: nonleaf PTE can't have PBMT != 0)
.8byte 0x00000000200054C1 # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz)
.8byte 0x00000000200058C1 # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000)
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
# Leaf page table at 0x80013000 with NAPOT pages
.align 12
#80000000
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
# Leaf page table at 0x80014000 with PBMT pages
.align 12
#80400000
.8byte 0x60000000200020CF # reserved entry
# Leaf page table at 0x80015000 with various permissions for testing CBOM and CBOZ
.align 12
#80800000
.8byte 0x00000000200000CF # valid rwx for VA 80800000
.8byte 0x00000000200000CB # valid r x for VA 80801000
.8byte 0x00000000200000C3 # valid r for VA 80802000
.8byte 0x00000000200000C9 # valid x for VA 80803000
.8byte 0x00000000200000CD # valid wx for VA 80804000 (illegal combination, but used to test tlbcontrol)
.8byte 0x000000002000000F # valid rwx for VA 80805000 for covering ITLB translate and UpdateDA
.8byte 0x20000000200000CF # PBMT=1 for VA 80806000 for covering ITLB BadPBMT
# Leaf page table at 0x80016000 with NAPOT pages
.align 12
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF

View File

@ -139,7 +139,7 @@ main:
.word 0xc5000007 // Attempting to toggle (Op7 != 7) to 0 on line 97 in fctrl, not sure what instruction this works out to
.word 0xe0101053 // toggling (Rs2D == 0) to 0 on line 139 in fctrl. Illegal Intsr (like fclass but incorrect rs2)
.word 0xe0100053 // toggling (Rs2D == 0) to 0 on line 141 in fctrl. Illegal Intsr (like fmv but incorrect rs2)
.word 0x40500053 // toggling (Rs2D[4:2] == 0) to 0 on line 145 in fctrl.
.word 0x40D00053 // toggling (Rs2D[4:2] == 0) to 0 on line 145 in fctrl.
.word 0x40300053 // toggling SupportFmt2 to 0 on line 145 in fctrl.
.word 0x42100053 // toggling (Rs2D[1:0] != 1) to 0 on line 147 in fctrl. Illegal Instr
.word 0xf0100053 // toggling (Rs2D == 0) to 0 on line 143 in fctrl. Illegal Instr
@ -155,6 +155,39 @@ main:
.word 0xF0007053 // illegal fmv (bad Funct3)
.word 0x43007053 // illegal fcvt.d.* (bad Rs2D)
.word 0x42207053 // illegal fcvt.d.* (bad Rs2D[1])
.word 0xD5F00053 // illegal fcvt.h.* (bad Rs2D)
.word 0xC5F00053 // illegal fcvt.*.h (bad Rs2D)
.word 0x04000043 // illegal fmadd.h (h not supported)
// Test divide by zero with rounding mode toward zero
li t0, 1
csrw frm, t0 // set rounding mode = 1
li t0, 0x3f800000
fcvt.s.w ft1, t0
fcvt.s.w ft2, zero
fdiv.s ft3, ft1, ft2
/* These didn't make a difference
// Test subtraction of identical denormalized numbers with to exercise FmaPreResultSubnorm logic with FmaSZero
li t0, 0xFFFFFFFF00000001
fmv.w.x ft1, t0 // smallest denorm
fsub.s ft1, ft1, ft1 // difference = 0
li t0, 0x0000000000000001
fmv.d.x ft1, t0 // smallest denorm
fsub.d ft1, ft1, ft1 // difference = 0
// Test subtraction of identical denormalized numbers with to exercise FmaPreResultSubnorm logic with FmaSZero
li t0, 0xFFFFFFFF00100001
fmv.w.x ft1, t0 // almost largest denorm
fsub.s ft1, ft1, ft1 // difference = 0
li t0, 0x0001000000000001
fmv.d.x ft1, t0 // smallest denorm
fsub.d ft1, ft1, ft1 // difference = 0
*/
# Test floating point convert to integer and using result
fcvt.w.s t0, f0

View File

@ -30,4 +30,7 @@ main:
sfence.vma x0, x0 // sfence.vma to assert TLBFlush
li a0, 0x80000001 # misaligned address
amoadd.w t0, a0, (a0) # amo access to misaligned address
j done

31
tests/coverage/pmpcbo.S Normal file
View File

@ -0,0 +1,31 @@
// pmpcbo.S
// David_Harris@hmc.edu 1/21/24
// Cover PMP checks of cache management instructions
#include "WALLY-init-lib.h"
main:
# set up PMP so user and supervisor mode can access partial address space
li t0, 0x080F;
# li t0, 0x0808;
csrw pmpcfg0, t0 # configure PMP0 to TOR RWX and PMP1 to TOR no access
li t0, 0x2003FFFF
li t1, 0xFFFFFFFF
csrw pmpaddr0, t0 # configure PMP0 top of range to 0x800FFFFF to allow all 32-bit addresses
csrw pmpaddr1, t1 # configure PMP1 top of range to 0xFFFFFFFF to prohibit accesses above
# enable cbo instructions
li t0, 0xF0
csrw menvcfg, t0
csrw senvcfg, t0
# switch to supervisor mode
li a0, 1
ecall
# cbo instructions to PMP-forbidded address
li a0, 0x81000000 # forbidden address
cbo.zero (a0)
cbo.inval (a0)
j done

View File

@ -62,13 +62,30 @@ main:
jalr ra, t0 # jump to misaligned gigapage
li t0, 0x80200000
jalr ra, t0 # jump to misaligned megapage
li t0, 0x7FFFFFFF80000000
# exercise ebufsmarb (not yet providing coverage 1/1/24 DH & RT)
li t0, 0x80000000
lw t1, 0(t0) # fetch from an address to warm up tlb entries
li t0, 0x80A00000
lw t1, 0(t0) # trigger TLB miss on a non-first entry
jal backandforth
jalr ra, t0 # jump to page with UpperBitsUnequal
li t0, 0x0000000080C00000
jalr ra, t0 # jump to page with bad reserved bits 60:54 in PTE
# test with ENVCFG_ADUE = 1: switch to machine mode, set ADUE, access page with A=0, clear ADUE,
li a0, 3
ecall # switch to machine mode
li t0, 1
slli t0, t0, 61
csrs menvcfg, t0 # set menvcfg.ADUE
li a0, 1
ecall # switch back to supervisor mode
li t0, 0x0000000080E00000
jalr ra, t0 # jump to page without accessed bit yet set
li a0, 3
ecall # switch to machine mode
li t0, 1
slli t0, t0, 61
csrc menvcfg, t0 # clear menvcfg.ADUE
li a0, 1
ecall # switch back to supervisor mode
# exercise malformed PBMT pages
@ -97,7 +114,7 @@ main:
li t0, 1
ecall # switch back to supervisor mode
li t0, 0x80806000
jalr ra, t0 # jump to page to exercise ITLB with PBMT !=0 when ENVCFG_BPMTE=0
jalr ra, t0 # jump to page to exercise ITLB with PBMT !=0 when ENVCFG_PMTE=0
# change back to default trap handler after checking everything that might cause an instruction page fault
jal changetodefaulthandler
@ -154,6 +171,8 @@ main:
li a0, 1
ecall
# wrap up
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
ecall
@ -229,8 +248,8 @@ pagetable:
.8byte 0x4000000020004CC1 # for VA starting at 80600000 (bad entry: nonleaf PTE can't have PBMT != 0)
.8byte 0x00000000200054C1 # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz)
.8byte 0x0000000020004CC1 # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000)
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0F00000020004CCF # for VA starting at 80C00000 (bad reserved field in bits 60:54)
.8byte 0x000000002000000F # for VA starting at 80E00000 (not dirty or accessed)
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1