diff --git a/.gitignore b/.gitignore index ec5520c64..19dbba458 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,7 @@ sim/localhistory_m6k10_results_april24.txt sim/cfi/* sim/branch/* sim/covhtmlreport/ +sim/*/*Cache.log # Questa sim/questa/logs diff --git a/bin/CacheSim.py b/bin/CacheSim.py index f6b2cb7e1..d07ded9ea 100755 --- a/bin/CacheSim.py +++ b/bin/CacheSim.py @@ -41,7 +41,6 @@ # Add -d or --dist to report the distribution of loads, stores, and atomic ops. # These distributions may not add up to 100; this is because of flushes or invalidations. -import sys import math import argparse import os @@ -193,7 +192,7 @@ class Cache: return self.__str__() -if __name__ == "__main__": +def main(): parser = argparse.ArgumentParser(description="Simulates a L1 cache.") parser.add_argument('numlines', type=int, help="The number of lines per way (a power of 2)", metavar="L") parser.add_argument('numways', type=int, help="The number of ways (a power of 2)", metavar='W') @@ -207,7 +206,7 @@ if __name__ == "__main__": args = parser.parse_args() cache = Cache(args.numlines, args.numways, args.addrlen, args.taglen) extfile = os.path.expanduser(args.file) - nofails = True + mismatches = 0 if args.perf: hits = 0 @@ -269,7 +268,7 @@ if __name__ == "__main__": if not result == lninfo[2]: print("Result mismatch at address", lninfo[0]+ ". Wally:", lninfo[2]+", Sim:", result) - nofails = False + mismatches += 1 if args.dist: percent_loads = str(round(100*loads/totalops)) percent_stores = str(round(100*stores/totalops)) @@ -280,5 +279,9 @@ if __name__ == "__main__": ratio = round(hits/misses,3) print("There were", hits, "hits and", misses, "misses. The hit/miss ratio was", str(ratio)+".") - if nofails: - print("SUCCESS! There were no mismatches between Wally and the sim.") \ No newline at end of file + if mismatches == 0: + print("SUCCESS! There were no mismatches between Wally and the sim.") + return mismatches + +if __name__ == '__main__': + exit(main()) diff --git a/bin/wsim b/bin/wsim index 757fac9bf..3018c5caf 100755 --- a/bin/wsim +++ b/bin/wsim @@ -31,6 +31,7 @@ parser.add_argument("--fcov", "-f", help="Functional Coverage, implies lockstep" parser.add_argument("--fcov2", "-f2", help="Functional Coverage, implies lockstep", action="store_true") parser.add_argument("--fcovrvvi", "-fr", help="Functional Coverage RVVI", action="store_true") parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="") +parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", default="") parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true") parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") parser.add_argument("--locksteplog", "-b", help="Retired instruction number to be begin logging.", default=0) @@ -76,7 +77,10 @@ if (args.vcd): args.args += " -DMAKEVCD=1" if (args.rvvi): - args.args += " -GRVVI_SYNTH_SUPPORTED=1" + args.params += " RVVI_SYNTH_SUPPORTED=1 " + +if (args.tb == "testbench_fp"): + args.params += " TEST=\"" + args.testsuite + "\" " # if lockstep is enabled, then we need to pass the Imperas lockstep arguments if(int(args.locksteplog) >= 1): EnableLog = 1 @@ -91,10 +95,10 @@ if (args.lockstep): if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) else: ImperasPlusArgs = "" if(args.fcov): - CovEnableStr = "1" if int(args.covlog) > 0 else "0"; + CovEnableStr = "1" if int(args.covlog) > 0 else "0" if(args.covlog >= 1): EnableLog = 1 else: EnableLog = 0 - ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr suffix = "" if(args.fcov2): CovEnableStr = "1" if int(args.covlog) > 0 else "0"; @@ -108,7 +112,8 @@ if (args.lockstep): else: ImperasPlusArgs = "" suffix = "" -flags = suffix + " " + ImperasPlusArgs +flags = suffix +args.args += ImperasPlusArgs # other flags @@ -133,15 +138,18 @@ cd = "cd $WALLY/sim/" +args.sim # per-simulator launch if (args.sim == "questa"): + if (args.gui) and (args.tb == "testbench"): + args.params += "DEBUG=1" + if (ElfFile != ""): + args.args += " " + ElfFile + if (args.args != ""): + args.args = " --args \\\"" + args.args + "\\\"" + if (args.params != ""): + args.params = " --params \\\"" + args.params + "\\\"" # Questa cannot accept more than 9 arguments. fcov implies lockstep - if (args.tb == "testbench_fp"): - args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args - cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + flags + cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + args.params + " " + flags if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible - if(args.tb == "testbench"): - cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\"" - elif(args.tb == "testbench_fp"): - cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\"" + cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\"" else: # launch Questa in batch mode cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" print("Running Questa with command: " + cmd) @@ -149,17 +157,23 @@ if (args.sim == "questa"): elif (args.sim == "verilator"): # PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i print(f"Running Verilator on {args.config} {args.testsuite}") - os.system(f"/usr/bin/make -C {regressionDir}/verilator WALLYCONF={args.config} TEST={args.testsuite} TESTBENCH={args.tb} EXTRA_ARGS='{args.args}'") + os.system(f"/usr/bin/make -C {regressionDir}/verilator WALLYCONF={args.config} TEST={args.testsuite} TESTBENCH={args.tb} PLUS_ARGS=\"{args.args}\" PARAM_ARGS=\"{args.params}\"") elif (args.sim == "vcs"): + print("wsim params: " + args.params) print(f"Running VCS on " + args.config + " " + args.testsuite) - if (args.gui): - args.args += "gui" + # if (args.gui): + # flags += " --gui" if (args.args == ""): vcsargs = "" else: - vcsargs = " --args " + args.args + vcsargs = " --args \"" + args.args + "\" " + if (args.params == ""): + vcsparams = "" + else: + vcsparams = " --params \"" + args.params + "\" " + print("VCS params: " + vcsparams) if (ElfFile != ""): ElfFile = " --elffile " + ElfFile - cmd = cd + "; " + prefix + " ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags + cmd = cd + "; " + prefix + " ./run_vcs " + args.config + " " + args.testsuite + " " + " --tb " + args.tb + " " + vcsargs + vcsparams + ElfFile + " " + flags print(cmd) os.system(cmd) diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 1aa992a50..503fc710b 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -1,33 +1,46 @@ -# wally-batch.do +# wally.do # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 # # Modification by Oklahoma State University & Harvey Mudd College -# Use with Testbench +# Use with Testbench # James Stine, 2008; David Harris 2021 # Go Cowboys!!!!!! # # Takes 1:10 to run RV64IC tests using gui -# Usage: do wally-batch.do [--ccov] [--fcov] [+acc] [any number of +value] [any number of -G VAR=VAL] -# Example: do wally-batch.do rv64gc arch64i testbench +# Usage: do wally.do [--ccov] [--fcov] [+acc] [--args "any number of +value"] [--params "any number of VAR=VAL parameter overrides"] +# Example: do wally.do rv64gc arch64i testbench -# Use this wally-batch.do file to run this example. +# Use this wally.do file to run this example. # Either bring up ModelSim and type the following at the "ModelSim>" prompt: -# do wally-batch.do +# do wally.do # or, to run from a shell, type the following at the shell prompt: -# vsim -do wally-batch.do -c +# vsim -do wally.do -c # (omit the "-c" to see the GUI while running from the shell) -set DEBUG 1 +# lcheck - return 1 if value is in list and remove it from list +proc lcheck {listVariable value} { + upvar 1 $listVariable list + set index [lsearch -exact $list $value] + if {$index >= 0} { + set list [lreplace $list $index $index] + return 1 + } else { + return 0 + } +} +set DEBUG 1 onbreak {resume} onerror {quit -f} +# Initialize variables set CFG ${1} set TESTSUITE ${2} set TESTBENCH ${3} set WKDIR wkdir/${CFG}_${TESTSUITE} set WALLY $::env(WALLY) +set IMPERAS_HOME $::env(IMPERAS_HOME) set CONFIG ${WALLY}/config set SRC ${WALLY}/src set TB ${WALLY}/testbench @@ -38,10 +51,12 @@ if [file exists ${WKDIR}] { vdel -lib ${WKDIR} -all } vlib ${WKDIR} -# Create directory for coverage data -mkdir -p cov # Create directory for functional coverage data -mkdir -p ${WALLY}/addins/cvw-arch-verif/work +mkdir -p ${FCRVVI} + +set PlusArgs "" +set ParamArgs "" +set ExpandedParamArgs {} set ccov 0 set CoverageVoptArg "" @@ -51,47 +66,26 @@ set FuncCovRVVI 0 set FCdefineRVVI_COVERAGE "" set FunctCoverage 0 -set riscvISACOVsrc "" -set FCdefineINCLUDE_TRACE2COV "" -set FCdefineCOVER_BASE_RV64I "" -set FCdefineCOVER_LEVEL_DV_PR_EXT "" -set FCdefineCOVER_RV64I "" -set FCdefineCOVER_RV64M "" -set FCdefineCOVER_RV64A "" -set FCdefineCOVER_RV64F "" -set FCdefineCOVER_RV64D "" -set FCdefineCOVER_RV64ZICSR "" -set FCdefineCOVER_RV64C "" -set FCdefineIDV_INCLUDE_TRACE2COV "" -set FCTRACE2COV "" -set FCdefineIDV_TRACE2COV "" +set FCvlog "" +set FCvopt "" +set FCdefineCOVER_EXTS {} + set lockstep 0 -# ok this is annoying. vlog, vopt, and vsim are very picky about how arguments are passed. -# unforunately it won't allow these to be grouped as one argument per command so they are broken -# apart. -set lockstepvoptstring "" +set lockstepvlog "" set SVLib "" -set SVLibPath "" set OtherFlags "" -set ImperasPubInc "" -set ImperasPrivInc "" -set rvviFiles "" -set idvFiles "" set GUI 0 set accFlag "" # Need to be able to pass arguments to vopt. Unforunately argv does not work because # it takes on different values if vsim and the do file are called from the command line or -# if the do file isd called from questa sim directly. This chunk of code uses the $4 through $n +# if the do file is called from questa sim directly. This chunk of code uses the $4 through $n # variables and compacts into a single list for passing to vopt. -set tbArgs "" set from 4 set step 1 set lst {} -set PlusArgs {} -set ParamArgs {} for {set i 0} true {incr i} { set x [expr {$i*$step + $from}] if {$x > $argc} break @@ -103,106 +97,94 @@ echo "number of args = $argc" echo "lst = $lst" # if +acc found set flag and remove from list -set AccIndex [lsearch -exact $lst "+acc"] -if {$AccIndex >= 0} { +if {[lcheck lst "+acc"]} { set GUI 1 set accFlag "+acc" - set lst [lreplace $lst $AccIndex $AccIndex] } -# if +coverage found set flag and remove from list -set CoverageIndex [lsearch -exact $lst "--ccov"] -if {$CoverageIndex >= 0} { +# if --ccov found set flag and remove from list +if {[lcheck lst "--ccov"]} { set ccov 1 set CoverageVoptArg "+cover=sbecf" set CoverageVsimArg "-coverage" - set lst [lreplace $lst $CoverageIndex $CoverageIndex] } -set FCoverageIndexRVVI [lsearch -exact $lst "--fcovrvvi"] -if {$FCoverageIndexRVVI >= 0} { +# if --fcovrvvi found set flag and remove from list +if {[lcheck lst "--fcovrvvi"]} { set FuncCovRVVI 1 set FCdefineRVVI_COVERAGE "+define+RVVI_COVERAGE" - set lst [lreplace $lst $FCoverageIndexRVVI $FCoverageIndexRVVI] } -# if +coverage found set flag and remove from list -set FunctCoverageIndex [lsearch -exact $lst "--fcov"] -if {$FunctCoverageIndex >= 0} { +# if --fcov found set flag and remove from list +if {[lcheck lst "--fcov"]} { set FunctCoverage 1 - set riscvISACOVsrc +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source - - set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV" - set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I" - set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT" + set FCvlog "+define+INCLUDE_TRACE2COV \ + +define+IDV_INCLUDE_TRACE2COV \ + +define+COVER_BASE_RV64I \ + +define+COVER_LEVEL_DV_PR_EXT \ + +incdir+${IMPERAS_HOME}/ImpProprietary/source/host/riscvISACOV/source" + set FCvopt "+TRACE2COV_ENABLE=1 +IDV_TRACE2COV=1" # Uncomment various cover statements below to control which extensions get functional coverage - set FCdefineCOVER_RV64I "+define+COVER_RV64I" - #set FCdefineCOVER_RV64M "+define+COVER_RV64M" - #set FCdefineCOVER_RV64A "+define+COVER_RV64A" - #set FCdefineCOVER_RV64F "+define+COVER_RV64F" - #set FCdefineCOVER_RV64D "+define+COVER_RV64D" - #set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR" - #set FCdefineCOVER_RV64C "+define+COVER_RV64C" - set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV" - set FCTRACE2COV "+TRACE2COV_ENABLE=1" - set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1" - set lst [lreplace $lst $FunctCoverageIndex $FunctCoverageIndex] -}\ + lappend FCdefineCOVER_EXTS "+define+COVER_RV64I" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64M" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64A" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64F" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64D" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64ZICSR" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64C" -set FunctCoverageIndex2 [lsearch -exact $lst "--fcov2"] -if {$FunctCoverageIndex2 >= 0} { +} + +# if --fcov2 found set flag and remove from list +if {[lcheck lst "--fcov2"]} { set FunctCoverage 1 - set riscvISACOVsrc +incdir+$env(WALLY)/addins/riscvISACOV/source - - set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV" - set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV32I" - set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT" + set FCvlog "+define+INCLUDE_TRACE2COV \ + +define+IDV_INCLUDE_TRACE2COV \ + +define+COVER_BASE_RV32I \ + +define+COVER_LEVEL_DV_PR_EXT \ + +incdir+$env(WALLY)/addins/riscvISACOV/source" + set FCvopt "+TRACE2COV_ENABLE=1 +IDV_TRACE2COV=1" # Uncomment various cover statements below to control which extensions get functional coverage - set FCdefineCOVER_RV64I "+define+COVER_RV32I" - #set FCdefineCOVER_RV64M "+define+COVER_RV64M" - #set FCdefineCOVER_RV64A "+define+COVER_RV64A" - #set FCdefineCOVER_RV64F "+define+COVER_RV64F" - #set FCdefineCOVER_RV64D "+define+COVER_RV64D" - #set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR" - #set FCdefineCOVER_RV64C "+define+COVER_RV64C" - set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV" - set FCTRACE2COV "+TRACE2COV_ENABLE=1" - set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1" - set lst [lreplace $lst $FunctCoverageIndex2 $FunctCoverageIndex2] -}\ - -set LockStepIndex [lsearch -exact $lst "--lockstep"] -# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running -# functional coverage and imply it. -if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0 || $FunctCoverageIndex2 >= 0} { + lappend FCdefineCOVER_EXTS "+define+COVER_RV32I" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64M" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64A" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64F" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64D" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64ZICSR" + #lappend FCdefineCOVER_EXTS "+define+COVER_RV64C" +} + +# if --lockstep or --fcov found set flag and remove from list +if {[lcheck lst "--lockstep"] || $FunctCoverage == 1} { set lockstep 1 - - # ideally this would all be one or two variables, but questa is having a real hard time - # with this. For now they have to be separate. - set lockstepvoptstring "+define+USE_IMPERAS_DV" - set ImperasPubInc +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host - set ImperasPrivInc +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host - set rvviFiles $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/*.sv - set idvFiles $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/*.sv - set SVLib "-sv_lib" - set SVLibPath $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model + set lockstepvlog "+define+USE_IMPERAS_DV \ + +incdir+${IMPERAS_HOME}/ImpPublic/include/host \ + +incdir+${IMPERAS_HOME}/ImpProprietary/include/host \ + ${IMPERAS_HOME}/ImpPublic/source/host/rvvi/*.sv \ + ${IMPERAS_HOME}/ImpProprietary/source/host/idv/*.sv" + set SVLib "-sv_lib ${IMPERAS_HOME}/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model" #set OtherFlags $::env(OTHERFLAGS) # not working 7/15/24 dh; this should be the way to pass things like --verbose (Issue 871) - - if {$LockStepIndex >= 0} { - set lst [lreplace $lst $LockStepIndex $LockStepIndex] - } } - -# separate the +args from the -G parameters -foreach otherArg $lst { - if {[string index $otherArg 0] eq "+"} { - lappend PlusArgs $otherArg - } else { - lappend ParamArgs $otherArg - } +# Set PlusArgs passed using the --args flag +set PlusArgsIndex [lsearch -exact $lst "--args"] +if {$PlusArgsIndex >= 0} { + set PlusArgs [lindex $lst [expr {$PlusArgsIndex + 1}]] + set lst [lreplace $lst $PlusArgsIndex [expr {$PlusArgsIndex + 1}]] } +# Set ParamArgs passed using the --params flag and expand into a list of -G arguments +set ParamArgsIndex [lsearch -exact $lst "--params"] +if {$ParamArgsIndex >= 0} { + set ParamArgs [lindex $lst [expr {$ParamArgsIndex + 1}]] + set ParamArgs [regexp -all -inline {\S+} $ParamArgs] + foreach param $ParamArgs { + lappend ExpandedParamArgs -G$param + } + set lst [lreplace $lst $ParamArgsIndex [expr {$ParamArgsIndex + 1}]] +} + +# Debug print statements if {$DEBUG > 0} { echo "GUI = $GUI" echo "ccov = $ccov" @@ -211,41 +193,27 @@ if {$DEBUG > 0} { echo "FunctCoverage = $FunctCoverage" echo "remaining list = $lst" echo "Extra +args = $PlusArgs" - echo "Extra -args = $ParamArgs" + echo "Extra -args = $ExpandedParamArgs" } -foreach x $PlusArgs { - echo "Element is $x" -} - -# need a better solution this is really ugly -# Questa really don't like passing $PlusArgs on the command line to vsim. It treats the whole things -# as one string rather than mutliple separate +args. Is there an automated way to pass these? -set temp0 [lindex $PlusArgs 0] -set temp1 [lindex $PlusArgs 1] -set temp2 [lindex $PlusArgs 2] -set temp3 [lindex $PlusArgs 3] - -#quit - # compile source files -# suppress spurious warnngs about +# suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt - -vlog -lint +nowarnRDGN -suppress 2244 -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${FCdefineRVVI_COVERAGE} ${idvFiles} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv +incdir+${FCRVVI}/common +incdir+${FCRVVI} ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv -suppress 2244 -suppress 2282 -suppress 2583 -suppress 7063,2596,13286 +set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI}/common +incdir+${FCRVVI}" +set SOURCES "${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv" +vlog -lint +nowarnRDGN -work ${WKDIR} {*}${INC_DIRS} {*}${FCvlog} {*}${FCdefineCOVER_EXTS} {*}${lockstepvlog} ${FCdefineRVVI_COVERAGE} {*}${SOURCES} -suppress 2244 -suppress 2282 -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals -vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${ParamArgs} -o testbenchopt ${CoverageVoptArg} +vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} {*}${ExpandedParamArgs} -o testbenchopt ${CoverageVoptArg} -#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg} -#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} +IDV_TRACE2COV=1 +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg} -vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} $temp0 $temp1 $temp2 $temp3 -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} ${FCTRACE2COV} ${FCdefineIDV_TRACE2COV} -suppress 3829 ${CoverageVsimArg} +vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} {*}${PlusArgs} -fatal 7 {*}${SVLib} ${OtherFlags} {*}${FCvopt} -suppress 3829 ${CoverageVsimArg} -# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 # power add generates the logging necessary for saif generation. # power add -r /dut/core/* + +# add waveforms if GUI is enabled if { ${GUI} } { add log -recursive /* if { ${TESTBENCH} eq "testbench_fp" } { @@ -287,4 +255,3 @@ if {$ccov} { if { ${GUI} == 0} { quit } - diff --git a/sim/rv64gc_CacheSim.py b/sim/rv64gc_CacheSim.py index bc75fc13a..60dc092b5 100755 --- a/sim/rv64gc_CacheSim.py +++ b/sim/rv64gc_CacheSim.py @@ -6,8 +6,9 @@ ## Written: lserafini@hmc.edu ## Created: 11 April 2023 ## Modified: 12 April 2023 +## Modified: 10 August 2023, jcarlin@hmc.edu ## -## Purpose: Run the cache simulator on each rv64gc test suite in turn. +## Purpose: Run the cache simulator on each rv64gc test suite in turn. ## ## A component of the CORE-V-WALLY configurable RISC-V project. ## https://github.com/openhwgroup/cvw @@ -16,24 +17,24 @@ ## ## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 ## -## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You ## may obtain a copy of the License at ## ## https:##solderpad.org/licenses/SHL-2.1/ ## -## Unless required by applicable law or agreed to in writing, any work distributed under the -## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -## either express or implied. See the License for the specific language governing permissions +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions ## and limitations under the License. ################################################################################################ -import sys import os import argparse +import subprocess # NOTE: make sure testbench.sv has the ICache and DCache loggers enabled! # This does not check the test output for correctness, run regression for that. -# Add -p or --perf to report the hit/miss ratio. +# Add -p or --perf to report the hit/miss ratio. # Add -d or --dist to report the distribution of loads, stores, and atomic ops. # These distributions may not add up to 100; this is because of flushes or invalidations. @@ -48,36 +49,46 @@ class bcolors: BOLD = '\033[1m' UNDERLINE = '\033[4m' -# tests64gc = ["coverage64gc", "arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", -tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", - "arch64zi", "wally64a", "wally64periph", "wally64priv", - "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", - "imperas64f", "imperas64d", "imperas64c", "imperas64i"] +tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zcb", + "arch64zifencei", "arch64zicond", "arch64a_amo", "wally64a_lrsc", "wally64periph", "wally64priv", + "arch64zbkb", "arch64zbkc", "arch64zbkx", "arch64zknd", "arch64zkne", "arch64zknh", + "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # arch64i is the most interesting case. Uncomment line below to run just that case -tests64gc = ["arch64i"] +# tests64gc = ["arch64i"] cachetypes = ["ICache", "DCache"] -simdir = os.path.expanduser("~/cvw/sim") +simdir = os.path.expandvars("$WALLY/sim") -if __name__ == '__main__': +def main(): parser = argparse.ArgumentParser(description="Runs the cache simulator on all rv64gc test suites") parser.add_argument('-p', "--perf", action='store_true', help="Report hit/miss ratio") parser.add_argument('-d', "--dist", action='store_true', help="Report distribution of operations") - + parser.add_argument('-s', "--sim", help="Simulator", choices=["questa", "verilator", "vcs"], default="verilator") args = parser.parse_args() - - testcmd = "vsim -do \"do wally-batch.do rv64gc {}\" -c > /dev/null" + simargs = "I_CACHE_ADDR_LOGGER=1\\\'b1 D_CACHE_ADDR_LOGGER=1\\\'b1" + testcmd = "wsim --sim " + args.sim + " rv64gc {} --params \"" + simargs + "\" > /dev/null" cachecmd = "CacheSim.py 64 4 56 44 -f {}" - + mismatches = 0 + if args.perf: cachecmd += " -p" if args.dist: cachecmd += " -d" - + for test in tests64gc: print(f"{bcolors.HEADER}Commencing test", test+f":{bcolors.ENDC}") + # remove wkdir to force recompile with logging enabled + os.system("rm -rf " + simdir + "/" + args.sim + "/wkdir/rv64gc_" + test) + os.system("rm -rf " + simdir + "/" + args.sim + "/*Cache.log") + print(testcmd.format(test)) os.system(testcmd.format(test)) for cache in cachetypes: print(f"{bcolors.OKCYAN}Running the", cache, f"simulator.{bcolors.ENDC}") - os.system(cachecmd.format(cache+".log")) + result = subprocess.run(cachecmd.format(args.sim+"/"+cache+".log"), shell=True) + mismatches += result.returncode print() + return mismatches + +if __name__ == '__main__': + exit(main()) + diff --git a/sim/vcs/run_vcs b/sim/vcs/run_vcs index 00bfea9c7..02eccc59b 100755 --- a/sim/vcs/run_vcs +++ b/sim/vcs/run_vcs @@ -23,10 +23,12 @@ def runfindcmd(cmd): parser = argparse.ArgumentParser() parser.add_argument("config", help="Configuration file") parser.add_argument("testsuite", help="Test suite (or none, when running a single ELF file) ") +parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench") parser.add_argument("--elffile", "-e", help="ELF file name", default="") parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true") parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true") parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="") +parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", default="") parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") # GUI not yet implemented #parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") @@ -49,7 +51,8 @@ rtlsrc_cmd = "find " + srcdir + ' -name "*.sv" ! -path "' + srcdir + '/generic/m rtlsrc_files = runfindcmd(rtlsrc_cmd) tbcommon_cmd = 'find ' + tbdir+'/common -name "*.sv" ! -path "' + tbdir+'/common/wallyTracer.sv"' tbcommon_files = runfindcmd(tbcommon_cmd) -RTL_FILES = tbdir+'/testbench.sv ' + str(rtlsrc_files) + ' ' + str(tbcommon_files) +tb_file = tbdir + "/" + args.tb + ".sv" +RTL_FILES = tb_file + ' ' + str(rtlsrc_files) + ' ' + str(tbcommon_files) # Include directories INCLUDE_PATH="+incdir+" + cfgdir + "/" + args.config + " +incdir+" + cfgdir + "/deriv/" + args.config + " +incdir+" + cfgdir + "/shared +incdir+$WALLY/tests +incdir+" + tbdir + " +incdir+" + srcdir @@ -68,10 +71,23 @@ if (args.coverage): else: COV_OPTIONS = "" +# Write parameter overrides to a file +f = open(os.path.expandvars(wkdir) + "/param_overrides.txt", "w") +for param in args.params.split(): + [param, value] = param.split("=") + if "\\'" in value: # for bit values + value = value.replace("\\'", "'") + else: # for strings + value = "\"" + value + "\"" + # print("param=" + param + " value=" + value) + f.write("assign " + value + " " + args.tb + "/" + param + "\n") +f.close() +PARAM_OVERRIDES=" -parameters " + wkdir + "/param_overrides.txt " + # Simulation commands OUTPUT="sim_out" -VCS_CMD="vcs +lint=all,noGCWM,noUI,noSVA-UA,noIDTS,noNS,noULCO,noCAWM-L,noWMIA-L,noSV-PIU,noSTASKW_CO,noSTASKW_CO1,noSTASKW_RMCOF -suppress +warn -sverilog +vc -Mupdate -line -full64 -lca -ntb_opts sensitive_dyn " + INCLUDE_PATH # Disabled Debug flags; add them back for a GUI mode -debug_access+all+reverse -kdb +vcs+vcdpluson -VCS = VCS_CMD + " -Mdir=" + wkdir + " " + srcdir + "/cvw.sv " + LOCKSTEP_OPTIONS + " " + COV_OPTIONS + " " + RTL_FILES + " -o " + wkdir + "/" + OUTPUT + " -work " + wkdir + " -Mlib " + wkdir + " -l " + logdir + "/" + args.config + "_" + args.testsuite + ".log" +VCS_CMD="vcs +lint=all,noGCWM,noUI,noSVA-UA,noIDTS,noNS,noULCO,noCAWM-L,noWMIA-L,noSV-PIU,noSTASKW_CO,noSTASKW_CO1,noSTASKW_RMCOF -suppress +warn -sverilog +vc -Mupdate -line -full64 -lca -ntb_opts sensitive_dyn " + "-top " + args.tb + PARAM_OVERRIDES + INCLUDE_PATH # Disabled Debug flags; add them back for a GUI mode -debug_access+all+reverse -kdb +vcs+vcdpluson +VCS = VCS_CMD + " -Mdir=" + wkdir + " " + srcdir + "/cvw.sv " + LOCKSTEP_OPTIONS + " " + COV_OPTIONS + " " + RTL_FILES + " -o " + wkdir + "/" + OUTPUT + " -work " + wkdir + " -Mlib=" + wkdir + " -l " + logdir + "/" + args.config + "_" + args.testsuite + ".log" SIMV_CMD= wkdir + "/" + OUTPUT + " +TEST=" + args.testsuite + " " + args.elffile + " " + args.args + " -no_save " + LOCKSTEP_SIMV # Run simulation @@ -81,4 +97,3 @@ subprocess.run(SIMV_CMD, shell=True) if (args.coverage): COV_RUN = "urg -dir " + wkdir + "/coverage.vdb -format text -report IndividualCovReport/" + args.config + "_" + args.testsuite subprocess.run(COV_RUN, shell=True) - diff --git a/sim/verilator/Makefile b/sim/verilator/Makefile index a7a57244e..326c397de 100644 --- a/sim/verilator/Makefile +++ b/sim/verilator/Makefile @@ -7,12 +7,13 @@ SHELL := /bin/bash # verilator configurations OPT= -PARAMS?=-DVERILATOR=1 --no-trace-top +PARAMS?=--no-trace-top NONPROF?=--stats VERILATOR_DIR=${WALLY}/sim/verilator SOURCE=${WALLY}/config/shared/*.vh ${WALLY}/config/${WALLYCONF} ${WALLY}/config/deriv/${WALLYCONF} ${WALLY}/src/cvw.sv ${WALLY}/testbench/*.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv -EXTRA_ARGS= - +PLUS_ARGS= +PARAM_ARGS= +EXPANDED_PARAM_ARGS:=$(patsubst %,-G%,$(PARAM_ARGS)) WALLYCONF?=rv64gc TEST?=arch64i @@ -32,11 +33,9 @@ DEPENDENCIES=${WALLY}/config/shared/*.vh $(SOURCES) # regular testbench requires a wrapper defining getenvval ifeq ($(TESTBENCH), testbench) WRAPPER=${WALLY}/sim/verilator/wrapper.c - GTEST= ARGTEST=+TEST=$(TEST) else WRAPPER= - GTEST=-GTEST="\"${TEST}\"" ARGTEST= endif @@ -44,7 +43,7 @@ default: run run: wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} mkdir -p $(VERILATOR_DIR)/logs - wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} ${ARGTEST} $(EXTRA_ARGS) + wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} ${ARGTEST} $(PLUS_ARGS) profile: obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) $(VERILATOR_DIR)/obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) ${ARGTEST} @@ -64,7 +63,7 @@ wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH}: $(DEPENDENCIES) --top-module ${TESTBENCH} --relative-includes \ $(INCLUDE_PATH) \ ${WRAPPER} \ - ${GTEST} \ + ${EXPANDED_PARAM_ARGS} \ $(SOURCES) obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES) @@ -76,7 +75,7 @@ obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES) --top-module ${TESTBENCH} --relative-includes \ $(INCLUDE_PATH) \ ${WRAPPER} \ - ${GTEST} \ + ${EXPANDED_PARAM_ARGS} \ $(SOURCES) clean: diff --git a/testbench/testbench_fp.sv b/testbench/testbench_fp.sv index 61fa12fcc..58d37ba29 100644 --- a/testbench/testbench_fp.sv +++ b/testbench/testbench_fp.sv @@ -637,7 +637,11 @@ module testbench_fp; // check if nothing is being tested if (Tests.size() == 0) begin $display("TEST %s not supported in this configuration", TEST); - $stop; +`ifdef QUESTA + $stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug +`else + $finish; +`endif end end @@ -987,7 +991,11 @@ module testbench_fp; X[P.FLEN-1:0], Y[P.FLEN-1:0], Z[P.FLEN-1:0], SrcA, Res[P.FLEN-1:0], ResFlg, Ans[P.FLEN-1:0], AnsFlg); //$display(" fma.Xs %h Xe %h Xm %h Ys %h Ye %h Ym %h Ss %h Se %h Sm %h", fma.Xs, fma.Xe, fma.Xm, fma.Ys, fma.Ye, fma.Ym, fma.Ss, fma.Se, fma.Sm); //$display(" readvectors.unpack.X %h Xs %h Xe %h Xm %h", readvectors.unpack.X, readvectors.unpack.Xs, readvectors.unpack.Xe, readvectors.unpack.Xm); - $stop; +`ifdef QUESTA + $stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug +`else + $finish; +`endif end if (TestVectors[VectorNum] == '1 & Tests[TestNum] !== "") begin // if reached the eof @@ -1013,7 +1021,11 @@ module testbench_fp; // if no more Tests - finish if (Tests[TestNum] === "") begin $display("\nAll Tests completed with %d errors\n", errors); - $stop; +`ifdef QUESTA + $stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug +`else + $finish; +`endif end $display("Running %s vectors", Tests[TestNum]); end