From 5d8d82414b3a1091d3a0294d33e788a9fe073133 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Feb 2024 11:40:38 -0800 Subject: [PATCH] Coverage improvements --- sim/coverage-exclusions-rv64gc.do | 36 ++++++++++++++++++++++++++++++- sim/regression-wally | 4 ++-- src/cache/cachefsm.sv | 5 ++--- src/ebu/buscachefsm.sv | 14 ++++++------ src/fpu/unpackinput.sv | 2 +- tests/coverage/fpu.S | 8 +++++++ tests/coverage/tlbmisc.S | 8 +++++-- 7 files changed, 61 insertions(+), 16 deletions(-) diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index 907573de4..6fe7716dc 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -63,6 +63,7 @@ coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrSta coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache state-case"] -item b 1 # exclude branch/condition coverage: LineDirty if statement coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FETCHStatement"] -item bc 1 +coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FLUSHStatement"] -item bs 1 # exclude the unreachable logic set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"] set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"] @@ -81,6 +82,7 @@ set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache flushdir coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"] coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10 +coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrTag"] -item e 1 -fecexprrow 8 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12 # cache.sv AdrSelMuxData and AdrSelMuxTag and CacheBusAdrMux, excluding unhit Flush branch coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxData -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 @@ -100,6 +102,27 @@ for {set i 0} {$i < $numcacheways} {incr i} { # No dirty ways in read-only I$ coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache DirtyWay"] -item e 1 } +# I$ buscachefsm does not perform atomics or write/writeback; HREADY is always 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicReadData"] +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm Atomic"] +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicPhase"] +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"] -item b 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item b 2 +#coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWait"] -item b 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback"] +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback2"] -item b 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY1"] -item b 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"] -item b 1 +#coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY5"] -item b 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"] -item b 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY1"] -item c 1 -feccondrow 1,2,4 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADYread"] -item c 1 -feccondrow 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item c 1 -feccondrow 1,2,3,4,6 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"] -item c 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"] -item c 1 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign BeatCntEn"] -item e 1 -fecexprrow 4 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheAccess"] -item e 1 -fecexprrow 4 +coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign BusStall"] -item e 1 -fecexprrow 10,12,18 ## D$ Exclusions. # InvalidateCache is I$ only: @@ -117,7 +140,7 @@ for {set i 0} {$i < $numcacheways} {incr i} { # 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 +# 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 -feccondrow 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 @@ -228,6 +251,10 @@ set line [GetLineNum ../src/mmu/mmu.sv "ExecuteAccessF \\| ReadAccessM"] coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,3,4 set line [GetLineNum ../src/mmu/mmu.sv "ReadAccessM & ~WriteAccessM"] coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 2-4 +set line [GetLineNum ../src/mmu/mmu.sv "assign AmoAccessM"] +coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 +set line [GetLineNum ../src/mmu/mmu.sv "assign AmoMisalignedCausesAccessFaultM"] +coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 set line [GetLineNum ../src/mmu/mmu.sv "DataMisalignedM & WriteAccessM"] coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,2,4 set line [GetLineNum ../src/mmu/mmu.sv "TLBPageFault & ExecuteAccessF"] @@ -370,6 +397,13 @@ coverage exclude -srcfile priorityonehot.sv coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1 +#################### +# Privileged +#################### + +# Instruction Misaligned never asserted because compresssed instructions are accepted +coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ../src/privileged/trap.sv "assign ExceptionM"] -item e 1 -fecexprrow 2 + #################### # EBU #################### diff --git a/sim/regression-wally b/sim/regression-wally index 5f4e68bf1..a219304d1 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -124,7 +124,7 @@ for test in tests32e: grepstr="All tests ran without failures") configs.append(tc) -tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfaf", "arch64zfad", +tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfaf", "arch64zfad", "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"] # add arch64zfh_fma when available; arch64zicobz, arch64zcb when working #tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", # "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"] @@ -132,7 +132,7 @@ if (coverage): # delete all but 64gc tests when running coverage configs = [] tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zifencei", "arch64zicond", "arch64a", "wally64a", "wally64periph", "wally64priv", - "arch64zba", "arch64zbb", "arch64zbs"] # add when working: "arch64zcb", "arch64zicboz" + "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zcb", "arch64zicboz" if (fp): tests64gc.append("arch64f") tests64gc.append("arch64d") diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 0d3b2c0e0..2e22a2f10 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -117,12 +117,11 @@ module cachefsm import cvw::*; #(parameter cvw_t P, NextState = STATE_READY; case (CurrState) // exclusion-tag: icache state-case STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck - else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; + else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; // exclusion-tag: icache FLUSHStatement else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement else NextState = STATE_READY; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; - else if(CacheBusAck) NextState = STATE_READY; else NextState = STATE_FETCH; STATE_WRITE_LINE: NextState = STATE_READ_HOLD; STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; @@ -204,7 +203,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, (CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITE_LINE) | resetDelay; - assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed + assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed (CurrState == STATE_FETCH) | (CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITE_LINE) | diff --git a/src/ebu/buscachefsm.sv b/src/ebu/buscachefsm.sv index 4f2965474..117b03991 100644 --- a/src/ebu/buscachefsm.sv +++ b/src/ebu/buscachefsm.sv @@ -87,17 +87,17 @@ module buscachefsm #( always_comb begin case(CurrState) - ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; // exclusion-tag: buscachefsm HREADY0 - else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm HREADY1 - else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; + ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; // exclusion-tag: buscachefsm HREADY0 + else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm HREADY1 + else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADYread else NextState = ADR_PHASE; DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm HREADY2 else if(HREADY & ~BusAtomic) NextState = MEM3; // exclusion-tag: buscachefsm HREADY3 else NextState = DATA_PHASE; - ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; + ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicReadData else NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm Atomic - ATOMIC_PHASE: if(HREADY) NextState = MEM3; - else NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicWait + ATOMIC_PHASE: if(HREADY) NextState = MEM3; // exclusion-tag: buscachefsm AtomicPhase + else NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicWait MEM3: if(Stall) NextState = MEM3; else NextState = ADR_PHASE; CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm FetchWriteback @@ -108,7 +108,7 @@ module buscachefsm #( else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADY4 else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; // exclusion-tag: buscachefsm HREADY5 else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; // exclusion-tag: buscachefsm HREADY6 - else NextState = CACHE_WRITEBACK; + else NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback2 default: NextState = ADR_PHASE; endcase end diff --git a/src/fpu/unpackinput.sv b/src/fpu/unpackinput.sv index 1cdf5a089..e5c5f3deb 100644 --- a/src/fpu/unpackinput.sv +++ b/src/fpu/unpackinput.sv @@ -142,7 +142,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) ( always_comb if (BadNaNBox & Fmt == P.FMT1) PostBox = {{(P.FLEN-P.LEN1){1'b1}}, 1'b1, {(P.NE1+1){1'b1}}, {(P.LEN1-P.NE1-2){1'b0}}}; - else if (BadNaNBox & Fmt == P.FMT2) + else if (BadNaNBox) // Fmt == P.FMT2 PostBox = {{(P.FLEN-P.LEN2){1'b1}}, 1'b1, {(P.NE2+1){1'b1}}, {(P.LEN2-P.NE2-2){1'b0}}}; else PostBox = In; diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index ca68e7275..337647426 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -109,6 +109,12 @@ main: # fcvt.w.q a0, ft0 # fcvt.q.d ft3, ft0 + # half-precision NaN boxing + la t0, TestData3 + fld ft2, 0(t0) // bad NaN-boxed number + fmadd.h ft1, ft2, ft2, ft2 // Test NaN boxing + fmadd.s ft1, ft2, ft2, ft2 // Test NaN boxing + // fdivsqrt: test busy->idle transition caused by a FlushE while divider is busy (when interrupt arrives) // This code doesn't actually trigger a busy->idle transition because the pending timer interrupt doesn't occur until the division finishes. li t0, 0x3F812345 # random value slightly bigger than 1 @@ -206,4 +212,6 @@ TestData2: .int 0xbf800000 #FP -1.0 .int 0x7fa00000 #SNaN .int 0x3fffffff #OverFlow Test +TestData3: +.dword 0xABCD543212345678 # NaN box test DivTestData: diff --git a/tests/coverage/tlbmisc.S b/tests/coverage/tlbmisc.S index 216b3c837..f64645689 100644 --- a/tests/coverage/tlbmisc.S +++ b/tests/coverage/tlbmisc.S @@ -206,6 +206,10 @@ ConcurrentICacheMissDTLBMiss: # change back to default trap handler after checking everything that might cause an instruction page fault jal changetodefaulthandler + # uncachable AMO access + li t0, 0x80401000 # PBMT sets as uncachable + amoadd.w t0, t0, 0(t0) + # exercise CBOM instructions with various permissions li t0, 0x80800000 cbo.zero (t0) @@ -457,8 +461,8 @@ SpecialPage: # Leaf page table at 0x80014000 with PBMT pages .align 12 #80400000 - .8byte 0x60000000200020CF # reserved entry - .8byte 0x40000000201000CF # non-cache non-idempotent + .8byte 0x60000000200020CF # reserved entry VA 80400000 + .8byte 0x40000000201000CF # non-cache non-idempotent VA 80401000 # Leaf page table at 0x80015000 with various permissions for testing CBOM and CBOZ .align 12