From ab82bb397c51b67bd768105a1b6e0efccc2697d7 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 08:32:02 -0700 Subject: [PATCH 01/13] Privilege test improvements --- tests/coverage/priv.S | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 3aa3aea5c..008d06be6 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -36,4 +36,30 @@ main: addi t0, zero, 0 csrr t0, stimecmp + # CSR coverage + csrw scause, zero + csrw stval, zero + csrw scounteren, zero + csrw satp, zero + + # satp write with mstatus.TVM = 1 + bseti t0, zero, 20 + csrs mstatus, t0 + csrw satp, zero + + # STIMECMP from S mode + li t0, 1 + ecall # enter S-mode + csrw stimecmp, zero + li t0, 3 + ecall # return to M-mode + csrsi mcounteren, 2 # mcounteren_tm = 1 + li t0, 1 + ecall # supervisor mode again + csrw stimecmp, zero + li t0, 3 + ecall # machine mode again + + + j done From fd0c9e973d98b05176a81c6f275838344713afba Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 08:33:46 -0700 Subject: [PATCH 02/13] Coverage improvements in ieu, hazard units --- sim/coverage-exclusions-rv64gc.do | 6 +++++- src/hazard/hazard.sv | 2 ++ src/ieu/bmu/bmuctrl.sv | 6 ++++-- src/ieu/controller.sv | 2 ++ src/lsu/lsu.sv | 2 +- src/privileged/csr.sv | 2 +- 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index 9905c897b..d58e4c514 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -24,8 +24,12 @@ #// and limitations under the License. #//////////////////////////////////////////////////////////////////////////////////////////////// +# This file should be a last resort. It's preferable to put +# // coverage off +# statements inline with the code whenever possible. + # LZA (i<64) statement confuses coverage tool -# This is ugly to exlcude the whole file - is there a better option +# This is ugly to exlcude the whole file - is there a better option? // coverage off isn't working coverage exclude -srcfile lzc.sv diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index cf3a22c1f..bc9f7baa0 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -88,7 +88,9 @@ module hazard ( assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled + // coverage off: StallFCause is always 0 assign #1 StallF = StallFCause | StallD; + // coverage on assign #1 StallD = StallDCause | StallE; assign #1 StallE = StallECause | StallM; assign #1 StallM = StallMCause | StallW; diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 90d031a14..0bfbfeb49 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -101,8 +101,10 @@ module bmuctrl( BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // sign extend instruction else if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction - 17'b0110011_0000100_100: if (`XLEN == 32) - BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) +// // coverage off: This case can't occur in RV64 +// 17'b0110011_0000100_100: if (`XLEN == 32) +// BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) +// // coverage on 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 5d0b78457..2174b96c3 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -264,7 +264,9 @@ module controller( end else assign sltD = (Funct3D == 3'b010); // Combine base and bit manipulation signals + // coverage off: IllegalERegAdr can't occur in rv64gc; only applicable to E mode assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; + // coverage on assign RegWriteD = BaseRegWriteD | BRegWriteD; assign W64D = BaseW64D | BW64D; assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD; diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 0b0bc81e3..f2e147f00 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -149,7 +149,7 @@ module lsu ( // MMU include PMP and is needed if any privileged supported ///////////////////////////////////////////////////////////////////////////////////////////// - if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED + if(`VIRTMEM_SUPPORTED) begin : hptw hptw hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF, .DTLBMissM, .DTLBWriteM, .InstrUpdateDAF, .DataUpdateDAM, .FlushW, .DCacheStallM, .SATP_REGW, .PCSpillF, diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 688218b7b..db142de5f 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -202,7 +202,7 @@ module csr #(parameter assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; assign UngatedCSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE); assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM; - assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; + assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; assign CSRUWriteM = CSRWriteM & InstrValidNotFlushedM; assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; From fa17487d6774b75016c9b85688a5584cca190625 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 08:37:16 -0700 Subject: [PATCH 03/13] Merged privileged test --- tests/coverage/priv.S | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 0d59a2555..008d06be6 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -36,7 +36,6 @@ main: addi t0, zero, 0 csrr t0, stimecmp -<<<<<<< HEAD # CSR coverage csrw scause, zero csrw stval, zero @@ -63,13 +62,4 @@ main: -======= - # Test write to STVAL, SCAUSE, SEPC, and STIMECMP CSRs - li t0, 0 - csrw stval, t0 - csrw scause, t0 - csrw sepc, t0 - csrw stimecmp, t0 - ->>>>>>> 37d289cf44530c3e3a6f53e54b06e6eda7f0c3c1 j done From 69805b4a60d731665644315f5411a983e7e6522c Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 09:15:15 -0700 Subject: [PATCH 04/13] Regression update --- sim/regression-wally | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sim/regression-wally b/sim/regression-wally index 7a509c890..045d7b947 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -49,6 +49,7 @@ configs = [ ] def getBuildrootTC(boot): INSTR_LIMIT = 4000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM +# INSTR_LIMIT = 8000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM MAX_EXPECTED = 246000000 # *** TODO: replace this with a search for the login prompt. if boot: name="buildrootboot" @@ -56,7 +57,12 @@ def getBuildrootTC(boot): BRgrepstr="WallyHostname login:" else: name="buildroot" - BRcmd="vsim > {} -c < {} -c < {} -c < Date: Fri, 31 Mar 2023 09:59:38 -0700 Subject: [PATCH 05/13] regression cleanup; unable to run buildroot coverage because of different config file --- sim/Makefile | 3 ++- sim/imperas.ic | 4 ++-- sim/regression-wally | 17 +++++------------ sim/wally-batch.do | 13 ++++++++++--- tests/coverage/ieu.S | 6 ++++++ 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/sim/Makefile b/sim/Makefile index 540c9418f..9cf3f0034 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -18,7 +18,8 @@ all: riscoftests memfiles coveragetests coverage: #make -C ../tests/coverage --jobs #iter-elf.bash --cover --search ../tests/coverage - vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb riscv.ucdb -logfile cov/log + vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb cov/buildroot_buildroot.ucdb riscv.ucdb -logfile cov/log +# vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb riscv.ucdb /home/rthompson/buildroot_buildroot-no-trace.ucdb -logfile cov/log vcover report -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt vcover report cov/cov.ucdb -details -instance=/core/ebu. > cov/rv64gc_coverage_ebu.rpt vcover report cov/cov.ucdb -details -instance=/core/priv. > cov/rv64gc_coverage_priv.rpt diff --git a/sim/imperas.ic b/sim/imperas.ic index 167c0cc44..fe8220399 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -6,7 +6,7 @@ # Core settings --override cpu/unaligned=F --override cpu/ignore_non_leaf_DAU=1 ---override cpu/wfi_is_nop=T +#--override cpu/wfi_is_nop=T --override cpu/mimpid=0x100 --override cpu/misa_Extensions_mask=0x0 @@ -49,7 +49,7 @@ # Add Imperas simulator application instruction tracing --override cpu/show_c_prefix=T ---trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 10500000 +--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 800000 # Exceptions and pagetables debug --override cpu/debugflags=6 diff --git a/sim/regression-wally b/sim/regression-wally index 045d7b947..c70177206 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -49,7 +49,6 @@ configs = [ ] def getBuildrootTC(boot): INSTR_LIMIT = 4000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM -# INSTR_LIMIT = 8000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM MAX_EXPECTED = 246000000 # *** TODO: replace this with a search for the login prompt. if boot: name="buildrootboot" @@ -182,8 +181,6 @@ def main(): try: os.chdir(regressionDir) os.mkdir("logs") - #print(os.getcwd()) - #print(regressionDir) except: pass try: @@ -204,9 +201,11 @@ def main(): TIMEOUT_DUR = 30*7200 # seconds configs=[getBuildrootTC(boot=True)] elif '-coverage' in sys.argv: - TIMEOUT_DUR = 20*60 # seconds - configs.append(getBuildrootTC(boot=False)) - os.system('rm cov/*.ucdb') + TIMEOUT_DUR = 20*60 # seconds + # Presently don't run buildroot because it has a different config and can't be merged with the rv64gc coverage. + # Also it is slow to run. + # configs.append(getBuildrootTC(boot=False)) + os.system('rm -f cov/*.ucdb') else: TIMEOUT_DUR = 10*60 # seconds configs.append(getBuildrootTC(boot=False)) @@ -228,12 +227,6 @@ def main(): # Coverage report if coverage: os.system('make coverage') - #print('Generating coverage report') - #os.system('vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log') - #os.system('vcover report -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt') - #os.system('vcover report -below 100 cov/cov.ucdb > cov/rv64gc_coverage.rpt') - #os.system('vcover report -recursive cov/cov.ucdb > cov/rv64gc_recursive.rpt') - #os.system('vcover report -details -threshH 100 -html cov/cov.ucdb') # Count the number of failures if num_fail: print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 7815e94fc..df49518c1 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -46,7 +46,7 @@ mkdir -p cov # Check if measuring coverage set coverage 0 if {$argc >= 3} { - if {$3 eq "-coverage"} { + if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} { set coverage 1 } } @@ -61,8 +61,14 @@ if {$argc >= 3} { if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 # start and run simulation - vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt - vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 + if { $coverage } { + echo "wally-batch buildroot coverage" + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt +cover=sbecf + vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 -cover + } else { + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt + vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 + } run -all run -all @@ -139,6 +145,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } if {$coverage} { + echo "Saving coverage to ${1}_${2}.ucdb" do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration coverage save -instance /testbench/dut/core cov/${1}_${2}.ucdb } diff --git a/tests/coverage/ieu.S b/tests/coverage/ieu.S index e1b239371..3fd56686f 100644 --- a/tests/coverage/ieu.S +++ b/tests/coverage/ieu.S @@ -28,6 +28,11 @@ main: + # Division test (having trouble with buildroot) + li x11, 0x384000 + li x12, 0x1c2000 + divuw x9, x11, x12 + # Test clz with all bits being 0 li t0, 0 clz t1, t0 @@ -61,5 +66,6 @@ main: .word 0x6080101B // Illegal BMU similar to count word .word 0x6030101B // Illegal BMU similar to count word + j done From c1ec1cb09c9638f4317ad46f5cbfd65ad67b953a Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 10:54:03 -0700 Subject: [PATCH 06/13] Added SSTC support to imperas.ic and wallyTracer. Fixes many of the privileged tests --- sim/imperas.ic | 10 +++++++++- testbench/common/wallyTracer.sv | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index fe8220399..beadba6fa 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -10,10 +10,15 @@ --override cpu/mimpid=0x100 --override cpu/misa_Extensions_mask=0x0 -# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=16 --override cpu/PMP_undefined=T +# Wally-specific non-default configuraiton +--override refRoot/cpu/Sstc=T +# Zba doesn't seem to exist - Lee is finding the name +#--override refRoot/cpu/Zba=T + + # Illegal instruction should not contain the bit pattern # illegal pmp read contained this # --override cpu/tval_ii_code=F @@ -47,8 +52,11 @@ #-override refRoot/cpu/cv/cover=basic #-override refRoot/cpu/cv/extensions=RV32I + + # Add Imperas simulator application instruction tracing --override cpu/show_c_prefix=T + --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 800000 # Exceptions and pagetables debug diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index 4df1956ad..221c8d7f8 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -162,6 +162,7 @@ module wallyTracer(rvviTrace rvvi); CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; + CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // user CSRs CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW; @@ -211,6 +212,7 @@ module wallyTracer(rvviTrace rvvi); CSRArray[12'h143] = CSRArrayOld[12'h143]; CSRArray[12'h142] = CSRArrayOld[12'h142]; CSRArray[12'h144] = CSRArrayOld[12'h144]; + CSRArray[12'h14D] = CSRArrayOld[12'h14D]; // user CSRs CSRArray[12'h001] = CSRArrayOld[12'h001]; CSRArray[12'h002] = CSRArrayOld[12'h002]; @@ -329,6 +331,7 @@ module wallyTracer(rvviTrace rvvi); CSRArrayOld[12'h143] = CSRArray[12'h143]; CSRArrayOld[12'h142] = CSRArray[12'h142]; CSRArrayOld[12'h144] = CSRArray[12'h144]; + CSRArrayOld[12'h14D] = CSRArray[12'h14D]; // user CSRs CSRArrayOld[12'h001] = CSRArray[12'h001]; CSRArrayOld[12'h002] = CSRArray[12'h002]; @@ -376,6 +379,7 @@ module wallyTracer(rvviTrace rvvi); assign #2 CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0; assign #2 CSR_W[12'h142] = (CSRArrayOld[12'h142] != CSRArray[12'h142]) ? 1 : 0; assign #2 CSR_W[12'h144] = (CSRArrayOld[12'h144] != CSRArray[12'h144]) ? 1 : 0; + assign #2 CSR_W[12'h14D] = (CSRArrayOld[12'h14D] != CSRArray[12'h14D]) ? 1 : 0; assign #2 CSR_W[12'h001] = (CSRArrayOld[12'h001] != CSRArray[12'h001]) ? 1 : 0; assign #2 CSR_W[12'h002] = (CSRArrayOld[12'h002] != CSRArray[12'h002]) ? 1 : 0; assign #2 CSR_W[12'h003] = (CSRArrayOld[12'h003] != CSRArray[12'h003]) ? 1 : 0; @@ -412,6 +416,7 @@ module wallyTracer(rvviTrace rvvi); assign rvvi.csr_wb[0][0][12'h143] = CSR_W[12'h143]; assign rvvi.csr_wb[0][0][12'h142] = CSR_W[12'h142]; assign rvvi.csr_wb[0][0][12'h144] = CSR_W[12'h144]; + assign rvvi.csr_wb[0][0][12'h14D] = CSR_W[12'h14D]; assign rvvi.csr_wb[0][0][12'h001] = CSR_W[12'h001]; assign rvvi.csr_wb[0][0][12'h002] = CSR_W[12'h002]; assign rvvi.csr_wb[0][0][12'h003] = CSR_W[12'h003]; @@ -448,6 +453,7 @@ module wallyTracer(rvviTrace rvvi); assign rvvi.csr[0][0][12'h143] = CSRArray[12'h143]; assign rvvi.csr[0][0][12'h142] = CSRArray[12'h142]; assign rvvi.csr[0][0][12'h144] = CSRArray[12'h144]; + assign rvvi.csr[0][0][12'h14D] = CSRArray[12'h14D]; assign rvvi.csr[0][0][12'h001] = CSRArray[12'h001]; assign rvvi.csr[0][0][12'h002] = CSRArray[12'h002]; assign rvvi.csr[0][0][12'h003] = CSRArray[12'h003]; From 59596cd7ccfd8a15d8b857a076accee1d9c70612 Mon Sep 17 00:00:00 2001 From: Alexa Wright Date: Sat, 1 Apr 2023 16:02:23 -0700 Subject: [PATCH 07/13] Added tests for writing and reading to HPMCOUNTERM csrs --- tests/coverage/priv.S | 46 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 8cd18925b..7382d331c 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -42,5 +42,49 @@ main: csrw scause, t0 csrw sepc, t0 csrw stimecmp, t0 - + + # Switch to machine mode + li a0, 3 + ecall + # Testing the HPMCOUNTERM performance counter: writing + # Base address is 2816 (MHPMCOUNTERBASE) + # There are 32 HPMCOUNTER registers + csrw 2816, t0 + csrw 2817, t0 + csrw 2818, t0 + csrw 2819, t0 + csrw 2820, t0 + csrw 2821, t0 + csrw 2822, t0 + csrw 2823, t0 + csrw 2824, t0 + csrw 2825, t0 + csrw 2826, t0 + csrw 2827, t0 + csrw 2828, t0 + csrw 2829, t0 + csrw 2830, t0 + csrw 2831, t0 + csrw 2832, t0 + csrw 2833, t0 + csrw 2834, t0 + csrw 2835, t0 + csrw 2836, t0 + csrw 2837, t0 + csrw 2838, t0 + csrw 2839, t0 + csrw 2840, t0 + csrw 2841, t0 + csrw 2842, t0 + csrw 2843, t0 + csrw 2844, t0 + csrw 2845, t0 + csrw 2846, t0 + csrw 2847, t0 + + # Testing the HPMCOUNTERM performance counter: reading + csrr t0, 2817 j done + + + From 55655157ae58d06fea365c5bd54443e726e9a744 Mon Sep 17 00:00:00 2001 From: Sydney Riley Date: Sun, 2 Apr 2023 23:51:34 -0700 Subject: [PATCH 08/13] expanded ifu coverage including 4 added directed tests and 1 exclusion, expanded fpu coverage including 6 directed tests and 2 multiline exclusions. --- src/fpu/fctrl.sv | 9 ++++++++- src/ifu/decompress.sv | 6 ++++++ tests/coverage/fpu.S | 18 +++++++++++++++++- tests/coverage/ifu.S | 19 ++++++++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index ad9007014..23279bd17 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -146,10 +146,13 @@ module fctrl ( ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + // coverage off + // We are turning off coverage because rv64gc configuration doesn't support quad or half 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) + // coverage on 7'b1101000: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s @@ -174,6 +177,9 @@ module fctrl ( 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase + //coverage off + // turning coverage off here because rv64gc configuration does not support floating point halfs and quads + // verified that these branches will not ever be taken in rv64gc configuration. 7'b1101010: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h @@ -197,7 +203,8 @@ module fctrl ( 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase + endcase + // coverage on endcase endcase /* verilator lint_off CASEINCOMPLETE */ diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 0ab0e706a..b28a9e7be 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -135,10 +135,16 @@ module decompress ( IllegalCompInstrD = 1; InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap end + // coverage off + // are excluding this branch from coverage because in rv64gc XLEN is always 64 and thus greater than 32 bits + // This branch will only be taken if instr16[12:10] == 3'b111 and 'XLEN !> 32, because all other + // possible values for instr16[12:10] are covered by branches above. XLEN !> 32 + // will never occur in rv64gc so this branch can not be covered else begin // illegal instruction IllegalCompInstrD = 1; InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap end + // coverage on 5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j 5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz 5'b01111: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 1a2d5ce7b..527547bb3 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -55,7 +55,23 @@ main: fcvt.l.q a0, ft3 fcvt.lu.q a0, ft3 - + + // Tests verfying that half and quad floating point convertion instructions are not supported by rv64gc + # fcvt.h.d ft3, ft0 // Somehow this instruction is taking the route on line 124 + // idea: enable the Q extension for this to work properly? A: Q and halfs not supported in rv64gc + # fcvt.h.w ft3, a0 + # fcvt.w.h a0, ft0 + # fcvt.q.w ft3, a0 + # fcvt.w.q a0, ft0 + # fcvt.q.d ft3, ft0 + + .word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011 + .word 0x40000053 // Line 145 All False Test case - illegal instruction? + .word 0xd0400053 // Line 156 All False Test case - illegal instruction? + .word 0xc0400053 // Line 162 All False Test case - illegal instruction? + .word 0xd2400053 // Line 168 All False Test case - illegal instruction? + .word 0xc2400053 // Line 174 All False Test case - illegal instruction? + # Test illegal instructions are detected .word 0x00000007 // illegal floating-point load (bad Funct3) .word 0x00000027 // illegal floating-point store (bad Funct3) diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index 3ceeeac12..68db3d087 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -32,9 +32,26 @@ main: csrs mstatus, t0 # calling compressed floating point load double instruction - //.halfword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op + //.hword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op // binary version 0000 0000 0000 0000 0010 0000 0000 0000 mv s0, sp c.fld fs0, 0(s0) + c.fsd fs0, 0(s0) + + // c.fldsp fs0, 0 + .hword 0x2002 + + // c.fsdsp fs0, 0 + .hword 0xA002 + + # set XLEN to 64 + li t0, 0x200000000 + csrs mstatus, t0 + + //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else + //.hword 0x9C01 + + # Illegal compressed instruction + .hword 0x9C41 j done From 981e5bd5f6ee7ebcfc82e555153976d5b576e2bb Mon Sep 17 00:00:00 2001 From: Sydeny Date: Mon, 3 Apr 2023 01:55:23 -0700 Subject: [PATCH 09/13] Manual merge for fctrl.sv, fpu.S, and ifu.S files --- src/fpu/fctrl.sv | 204 ++++++++++++++++++++++--------------------- tests/coverage/fpu.S | 3 - tests/coverage/ifu.S | 7 +- 3 files changed, 107 insertions(+), 107 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 0c345a495..b34001077 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -100,105 +100,111 @@ module fctrl ( ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // default: non-implemented instruction /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed case(OpD) - 7'b0000111: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw - 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld - 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq - 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh - endcase - 7'b0100111: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw - 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd - 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq - 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh - endcase - 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd - 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub - 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub - 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd - 7'b1010011: casez(Funct7D) - 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd - 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub - 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul - 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv - 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt - 7'b00100??: case(Funct3D) - 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj - 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn - 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx - endcase - 7'b00101??: case(Funct3D) - 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin - 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax - endcase - 7'b10100??: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq - 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt - 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle - endcase - 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass - else if (Funct3D == 3'b000 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register - 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg - 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) - ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) - 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) - ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) - 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) - ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) - 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) - ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) - 7'b1101000: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s - endcase - 7'b1100000: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu - endcase - 7'b1101001: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d - endcase - 7'b1100001: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu - endcase - 7'b1101010: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h - endcase - 7'b1100010: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu - endcase - 7'b1101011: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q - endcase - 7'b1100011: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase - endcase + 7'b0000111: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw + 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld + 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq + 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh + endcase + 7'b0100111: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw + 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd + 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq + 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh + endcase + 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd + 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub + 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub + 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd + 7'b1010011: casez(Funct7D) + 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd + 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub + 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul + 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv + 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt + 7'b00100??: case(Funct3D) + 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj + 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn + 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx + endcase + 7'b00101??: case(Funct3D) + 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin + 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax + endcase + 7'b10100??: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq + 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt + 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle + endcase + 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass + else if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register + 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg + 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) + ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) + 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) + ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + // coverage off + // Not covered in testing because rv64gc does not support half or quad precision + 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) + ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) + 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) + ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) + // coverage on + 7'b1101000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s + endcase + 7'b1100000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu + endcase + 7'b1101001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d + endcase + 7'b1100001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu + endcase + // coverage off + // Not covered in testing because rv64gc does not support half or quad precision + 7'b1101010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h + endcase + 7'b1100010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu + endcase + 7'b1101011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q + endcase + 7'b1100011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu + endcase + // coverage on + endcase endcase end /* verilator lint_on CASEINCOMPLETE */ diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 17fed79b3..a349ac606 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -57,7 +57,6 @@ main: fcvt.l.q a0, ft3 fcvt.lu.q a0, ft3 -<<<<<<< HEAD // Tests verfying that half and quad floating point convertion instructions are not supported by rv64gc # fcvt.h.d ft3, ft0 // Somehow this instruction is taking the route on line 124 @@ -75,8 +74,6 @@ main: .word 0xd2400053 // Line 168 All False Test case - illegal instruction? .word 0xc2400053 // Line 174 All False Test case - illegal instruction? -======= ->>>>>>> d4b7da34dee55ec8394ab391ecd6514c887a9790 # Test illegal instructions are detected .word 0x00000007 // illegal floating-point load (bad Funct3) .word 0x00000027 // illegal floating-point store (bad Funct3) diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index 68db3d087..9cde14ce2 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -36,6 +36,7 @@ main: // binary version 0000 0000 0000 0000 0010 0000 0000 0000 mv s0, sp c.fld fs0, 0(s0) + c.fsd fs0, 0(s0) // c.fldsp fs0, 0 @@ -44,14 +45,10 @@ main: // c.fsdsp fs0, 0 .hword 0xA002 - # set XLEN to 64 - li t0, 0x200000000 - csrs mstatus, t0 - //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else //.hword 0x9C01 - # Illegal compressed instruction + # Line Illegal compressed instruction .hword 0x9C41 j done From a6117e9befca7ee2452fbac1f803073c2fea8ea6 Mon Sep 17 00:00:00 2001 From: David Harris Date: Mon, 3 Apr 2023 17:55:30 -0700 Subject: [PATCH 10/13] Updated imperas.ic to enable B extension --- sim/imperas.ic | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index beadba6fa..2295c9d45 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -15,9 +15,8 @@ # Wally-specific non-default configuraiton --override refRoot/cpu/Sstc=T -# Zba doesn't seem to exist - Lee is finding the name -#--override refRoot/cpu/Zba=T - +--override cpu/add_implicit_Extensions=B +--override cpu/bitmanip_version=1.0.0 # Illegal instruction should not contain the bit pattern # illegal pmp read contained this From acebdeeb819c758f477c42a660a92b3a2e3260fe Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Mon, 3 Apr 2023 22:53:46 -0700 Subject: [PATCH 11/13] reduced mux3 to mux2 for input signal to clmul --- src/ieu/bmu/zbc.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ieu/bmu/zbc.sv b/src/ieu/bmu/zbc.sv index 1fb41193f..b173a5f63 100644 --- a/src/ieu/bmu/zbc.sv +++ b/src/ieu/bmu/zbc.sv @@ -41,7 +41,7 @@ module zbc #(parameter WIDTH=32) ( bitreverse #(WIDTH) brB(B, RevB); mux3 #(WIDTH) xmux({RevA[WIDTH-2:0], {1'b0}}, RevA, A, ~Funct3[1:0], X); - mux3 #(WIDTH) ymux({{1'b0}, RevB[WIDTH-2:0]}, RevB, B, ~Funct3[1:0], Y); + mux2 #(WIDTH) ymux(RevB, B, ~Funct3[1], Y); clmul #(WIDTH) clm(.X, .Y, .ClmulResult); From adafc8037db0070b114edfd9a85e86bf6f26d440 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Tue, 4 Apr 2023 17:20:00 +0100 Subject: [PATCH 12/13] add support for Sstc --- sim/imperas.ic | 48 +++++++++++++++------------- testbench/testbench-linux-imperas.sv | 9 +++--- testbench/testbench_imperas.sv | 10 +++--- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index 2295c9d45..4c221f2af 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -4,24 +4,36 @@ --showcommands # Core settings +--override cpu/priv_version=1.12 +--override cpu/user_version=20191213 +# arch +--override cpu/mimpid=0x100 +--override refRoot/cpu/tvec_align=64 + +# clarify +#--override refRoot/cpu/mtvec_sext=F + +--override cpu/tval_ii_code=T + +#--override cpu/time_undefined=T +#--override cpu/cycle_undefined=T +#--override cpu/instret_undefined=T +#--override cpu/hpmcounter_undefined=T + +--override cpu/reset_address=0x80000000 + --override cpu/unaligned=F --override cpu/ignore_non_leaf_DAU=1 -#--override cpu/wfi_is_nop=T ---override cpu/mimpid=0x100 +--override cpu/wfi_is_nop=T --override cpu/misa_Extensions_mask=0x0 +#--override cpu/updatePTEA=T +#--override cpu/updatePTED=T +--override cpu/Sstc=T +# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=16 --override cpu/PMP_undefined=T -# Wally-specific non-default configuraiton ---override refRoot/cpu/Sstc=T ---override cpu/add_implicit_Extensions=B ---override cpu/bitmanip_version=1.0.0 - -# Illegal instruction should not contain the bit pattern -# illegal pmp read contained this -# --override cpu/tval_ii_code=F - # PMA Settings # 'r': read access allowed # 'w': write access allowed @@ -51,19 +63,11 @@ #-override refRoot/cpu/cv/cover=basic #-override refRoot/cpu/cv/extensions=RV32I - - # Add Imperas simulator application instruction tracing ---override cpu/show_c_prefix=T - ---trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 800000 - -# Exceptions and pagetables debug ---override cpu/debugflags=6 - -# Turn on verbose output for Imperas simulator and Model --verbose ---override cpu/verbose=1 +--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 0 +--override cpu/debugflags=6 --override cpu/verbose=1 +--override cpu/show_c_prefix=T # Store simulator output to logfile --output imperas.log diff --git a/testbench/testbench-linux-imperas.sv b/testbench/testbench-linux-imperas.sv index 00167e5fd..d3d71626f 100644 --- a/testbench/testbench-linux-imperas.sv +++ b/testbench/testbench-linux-imperas.sv @@ -413,10 +413,11 @@ module testbench; end end - always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); - always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); - always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); - always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); + always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); + always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); + always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); final begin void'(rvviRefShutdown()); diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index f63c640d7..56ca763af 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -198,10 +198,12 @@ module testbench; end - always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); - always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); - always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); - always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); + always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); + always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); + always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); + final begin void'(rvviRefShutdown()); From 4552f9cf8c0eea745fccb060afb43afac6684d47 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 4 Apr 2023 09:32:26 -0700 Subject: [PATCH 13/13] Fixed WFI to commit when an interrupt occurs --- src/hazard/hazard.sv | 10 ++++++++-- src/privileged/privileged.sv | 6 ++---- src/privileged/trap.sv | 2 -- src/wally/wallypipelinedcore.sv | 12 +++++++----- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index bc9f7baa0..11efacffa 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -36,7 +36,7 @@ module hazard ( input logic FCvtIntStallD, FPUStallD, input logic DivBusyE, FDivBusyE, input logic EcallFaultM, BreakpointFaultM, - input logic WFIStallM, + input logic wfiM, IntPendingM, // Stall & flush outputs output logic StallF, StallD, StallE, StallM, StallW, output logic FlushD, FlushE, FlushM, FlushW @@ -45,6 +45,12 @@ module hazard ( logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic LatestUnstalledD, LatestUnstalledE, LatestUnstalledM, LatestUnstalledW; logic FlushDCause, FlushECause, FlushMCause, FlushWCause; + + logic WFIStallM, WFIInterruptedM; + + // WFI logic + assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout + assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -68,7 +74,7 @@ module hazard ( assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; - assign FlushWCause = TrapM; + assign FlushWCause = TrapM & ~WFIInterruptedM; // Stall causes // Most data depenency stalls are identified in the decode stage diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 6fa8dcf98..ca3d35717 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -93,7 +93,7 @@ module privileged ( output logic BigEndianM, // Use big endian in current privilege mode // Fault outputs output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire - output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout + output logic wfiM, IntPendingM // Stall in Memory stage for WFI until interrupt pending or timeout ); logic [3:0] CauseM; // trap cause @@ -110,8 +110,6 @@ module privileged ( logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return logic DelegateM; // trap should be delegated - logic wfiM; // wait for interrupt instruction - logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi logic InterruptM; // interrupt occuring logic ExceptionM; // Memory stage instruction caused a fault @@ -156,7 +154,7 @@ module privileged ( .mretM, .sretM, .PrivilegeModeW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .InstrValidM, .CommittedM, .CommittedF, - .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .WFIStallM, .CauseM); + .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); endmodule diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index ace63b48b..b6e99f2e0 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -48,7 +48,6 @@ module trap ( output logic ExceptionM, // exception is occurring output logic IntPendingM, // Interrupt is pending, might occur if enabled output logic DelegateM, // Delegate trap to supervisor handler - output logic WFIStallM, // Stall due to WFI instruction output logic [3:0] CauseM // trap cause ); @@ -74,7 +73,6 @@ module trap ( assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE); - assign WFIStallM = wfiM & ~IntPendingM; /////////////////////////////////////////// // Trigger Traps and RET diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 343cf1fdb..81f1997af 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -106,7 +106,7 @@ module wallypipelinedcore ( logic [1:0] PrivilegeModeW; logic [`XLEN-1:0] PTE; logic [1:0] PageType; - logic sfencevmaM, WFIStallM; + logic sfencevmaM; logic SelHPTW; // PMA checker signals @@ -162,7 +162,8 @@ module wallypipelinedcore ( logic CommittedF; logic BranchD, BranchE, JumpD, JumpE; logic DCacheStallM, ICacheStallF; - + logic wfiM, IntPendingM; + // instruction fetch unit: PC, branch prediction, instruction cache ifu ifu(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, @@ -265,7 +266,7 @@ module wallypipelinedcore ( .FCvtIntStallD, .FPUStallD, .DivBusyE, .FDivBusyE, .EcallFaultM, .BreakpointFaultM, - .WFIStallM, + .wfiM, .IntPendingM, // Stall & flush outputs .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW); @@ -292,13 +293,14 @@ module wallypipelinedcore ( .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, - .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM); + .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); end else begin assign CSRReadValW = 0; assign UnalignedPCNextF = PC2NextF; assign RetM = 0; assign TrapM = 0; - assign WFIStallM = 0; + assign wfiM = 0; + assign IntPendingM = 0; assign sfencevmaM = 0; assign BigEndianM = 0; end