From ac9a21873d0a1816047ed6d549bc980dfd78b47a Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 6 Apr 2024 10:34:21 -0700 Subject: [PATCH] Pass TEST to testbench with +TEST= rather than -G TEST= so that we don't have to recompile for every new test --- bin/wsim | 8 +- sim/questa/wally-batch.do | 99 ---------------------- sim/questa/wally.do | 158 ++++++++++++++++-------------------- testbench/common/loggers.sv | 53 ++++++++---- testbench/testbench.sv | 12 +-- 5 files changed, 121 insertions(+), 209 deletions(-) delete mode 100644 sim/questa/wally-batch.do diff --git a/bin/wsim b/bin/wsim index ffd2e7ca3..f03d152a8 100755 --- a/bin/wsim +++ b/bin/wsim @@ -40,10 +40,14 @@ if (args.coverage): # Launch selected simulator cd = "cd $WALLY/sim/" +args.sim if (args.sim == "questa"): - cmd = "do wally-batch.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.arg + cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.arg if (args.coverage): cmd += " -coverage" - os.system(cd + "; vsim -c -do \"" + cmd + "\"") + if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible + cmd = cd + "; vsim -do \"" + cmd + " +acc\"" + else: # launch Questa in batch mode + cmd = cd + "; vsim -c -do \"" + cmd + "\"" + os.system(cmd) elif (args.sim == "verilator"): print("Running Verilator on %s %s", args.config, args.testsuite) elif (args.sim == "vcs"): diff --git a/sim/questa/wally-batch.do b/sim/questa/wally-batch.do deleted file mode 100644 index 1c580919d..000000000 --- a/sim/questa/wally-batch.do +++ /dev/null @@ -1,99 +0,0 @@ -# wally-batch.do -# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -# -# Modification by Oklahoma State University & Harvey Mudd College -# 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 -# Example: do wally-batch.do rv64gc arch64i testbench - -# Use this wally-batch.do file to run this example. -# Either bring up ModelSim and type the following at the "ModelSim>" prompt: -# do wally-batch.do -# or, to run from a shell, type the following at the shell prompt: -# vsim -do wally-batch.do -c -# (omit the "-c" to see the GUI while running from the shell) - -onbreak {resume} - -set CFG ${1} -set TESTSUITE ${2} -set TESTBENCH ${3} -set WKDIR wkdir/${CFG}_${TESTSUITE} -set WALLY $::env(WALLY) -set CONFIG ${WALLY}/config -set SRC ${WALLY}/src -set TB ${WALLY}/testbench - -# create library -if [file exists ${WKDIR}] { - vdel -lib ${WKDIR} -all -} -vlib ${WKDIR} -# Create directory for coverage data -mkdir -p cov - -set coverage 0 -set CoverageVoptArg "" -set CoverageVsimArg "" - -# 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 -# variables and compacts into a single list for passing to vopt. -set configOptions "" -set from 4 -set step 1 -set lst {} -for {set i 0} true {incr i} { - set x [expr {$i*$step + $from}] - if {$x > $argc} break - set arg [expr "$$x"] - lappend lst $arg -} - -if {$argc >= 3} { - if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} { - set coverage 1 - set CoverageVoptArg "+cover=sbecf" - set CoverageVsimArg "-coverage" - } elseif {$3 eq "configOptions"} { - set configOptions $lst - puts $configOptions - } -} - -# compile source files -# suppress spurious warnngs about -# "Extra checking for conflicts with always_comb done at vopt time" -# because vsim will run vopt - -vlog -lint -work ${WKDIR} +incdir+${CONFIG}/$1 +incdir+${CONFIG}/deriv/$1 +incdir+${CONFIG}/shared ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -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 wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} -G TEST=$2 ${configOptions} -o testbenchopt ${CoverageVoptArg} -vsim -lib ${WKDIR} testbenchopt -fatal 7 -suppress 3829 ${CoverageVsimArg} - -# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -# power add generates the logging necessary for said generation. -# power add -r /dut/core/* -run -all -# power off -r /dut/core/* - - -if {$coverage} { - set UCDB cov/${CFG}_${TESTSUITE}.ucdb - echo "Saving coverage to ${UCDB}" - do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration - coverage save -instance /testbench/dut/core ${UCDB} -} - -# These aren't doing anything helpful -#profile report -calltree -file wally-calltree.rpt -cutoff 2 -#power report -all -bsaif power.saif -quit diff --git a/sim/questa/wally.do b/sim/questa/wally.do index 430146d39..b60360c1e 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -1,4 +1,4 @@ -# wally.do +# wally-batch.do # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 # # Modification by Oklahoma State University & Harvey Mudd College @@ -8,113 +8,93 @@ # # Takes 1:10 to run RV64IC tests using gui -# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m" +# Usage: do wally-batch.do [-coverage] [+acc] [any number of +value] [any number of -G VAR=VAL] +# Example: do wally-batch.do rv64gc arch64i testbench -# Use this wally-pipelined.do file to run this example. +# Use this wally-batch.do file to run this example. # Either bring up ModelSim and type the following at the "ModelSim>" prompt: -# do wally.do +# do wally-batch.do # or, to run from a shell, type the following at the shell prompt: -# vsim -do wally.do -c +# vsim -do wally-batch.do -c # (omit the "-c" to see the GUI while running from the shell) onbreak {resume} +set CFG ${1} +set TESTSUITE ${2} +set TESTBENCH ${3} +set WKDIR wkdir/${CFG}_${TESTSUITE} +set WALLY $::env(WALLY) +set CONFIG ${WALLY}/config +set SRC ${WALLY}/src +set TB ${WALLY}/testbench + # create library -if [file exists work] { - vdel -all +if [file exists ${WKDIR}] { + vdel -lib ${WKDIR} -all +} +vlib ${WKDIR} +# Create directory for coverage data +mkdir -p cov + +set coverage 0 +set CoverageVoptArg "" +set CoverageVsimArg "" + +# 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 +# variables and compacts into a single list for passing to vopt. +set configOptions "" +set from 4 +set step 1 +set lst {} +for {set i 0} true {incr i} { + set x [expr {$i*$step + $from}] + if {$x > $argc} break + set arg [expr "$$x"] + lappend lst $arg +} + +if {$argc >= 3} { + if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} { + set coverage 1 + set CoverageVoptArg "+cover=sbecf" + set CoverageVsimArg "-coverage" + } elseif {$3 eq "configOptions"} { + set configOptions $lst + puts $configOptions + } } -vlib work # compile source files # suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt +vlog -lint -work ${WKDIR} +incdir+${CONFIG}/$1 +incdir+${CONFIG}/deriv/$1 +incdir+${CONFIG}/shared ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -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 -if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { - vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 - # start and run simulation - vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt - vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 +#vopt wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} -G TEST=$2 ${configOptions} -o testbenchopt ${CoverageVoptArg} +vopt wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${configOptions} -o testbenchopt ${CoverageVoptArg} +vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} -fatal 7 -suppress 3829 ${CoverageVsimArg} - #-- Run the Simulation - #run -all - add log -recursive /* - do linux-wave.do - run -all +# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 +# power add generates the logging necessary for said generation. +# power add -r /dut/core/* +run -all +# power off -r /dut/core/* - exec ./slack-notifier/slack-notifier.py - -} elseif {$2 eq "buildroot-no-trace"} { - vlog -lint -work work_${1}_${2} +incdir+../config/deriv/$1 +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 - # start and run simulation - vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt - vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 - #-- Run the Simulation - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "Don't forget to change DEBUG_LEVEL = 0." - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - #run 100 ns - #force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa - #force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000 - run 14000 ms - #add log -recursive /* - #do linux-wave.do - #run -all - - exec ./slack-notifier/slack-notifier.py - -} elseif {$2 eq "fpga"} { - echo "hello" - vlog -work work +incdir+../config/fpga +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286 - vopt +acc work.testbench -G TEST=$2 -G DEBUG=0 -o workopt - vsim workopt +nowarn3829 -fatal 7 - - do fpga-wave.do - add log -r /* - run 20 ms - -} else { - vlog +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 - vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt - - vsim workopt +nowarn3829 -fatal 7 - - view wave - #-- display input and output signals as hexidecimal values - #do ./wave-dos/peripheral-waves.do - add log -recursive /* - do wave.do - #do wave-bus.do - - # power add generates the logging necessary for saif generation. - #power add -r /dut/core/* - #-- Run the Simulation - - run -all - #power off -r /dut/core/* - #power report -all -bsaif power.saif - noview ../testbench/testbench.sv - view wave +if {$coverage} { + set UCDB cov/${CFG}_${TESTSUITE}.ucdb + echo "Saving coverage to ${UCDB}" + do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration + coverage save -instance /testbench/dut/core ${UCDB} } - - -#elseif {$2 eq "buildroot-no-trace""} { -# vlog -lint -work work_${1}_${2} +incdir+../config/deriv/$1 +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 - # start and run simulation -# vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=470350800 -G INSTR_WAVEON=470350800 -G CHECKPOINT=470350800 -G DEBUG_TRACE=0 -o testbenchopt -# vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829 - - #-- Run the Simulation -# run 100 ns -# force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa -# force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000 -# add log -recursive /* -# do linux-wave.do -# run -all - -# exec ./slack-notifier/slack-notifier.py -#} +# These aren't doing anything helpful +#profile report -calltree -file wally-calltree.rpt -cutoff 2 +#power report -all -bsaif power.saif +quit diff --git a/testbench/common/loggers.sv b/testbench/common/loggers.sv index e4dd1e4fe..4104bd0ec 100644 --- a/testbench/common/loggers.sv +++ b/testbench/common/loggers.sv @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module loggers import cvw::*; #(parameter cvw_t P, - parameter string TEST, + parameter PrintHPMCounters, parameter I_CACHE_ADDR_LOGGER, parameter D_CACHE_ADDR_LOGGER, @@ -39,7 +39,8 @@ module loggers import cvw::*; #(parameter cvw_t P, // input logic BeginSample, // input logic StartSample, // input logic EndSample, - input string memfilename + input string memfilename, + input string TEST ); // performance counter logging @@ -79,40 +80,64 @@ module loggers import cvw::*; #(parameter cvw_t P, "Divide Cycles" }; + always_comb + if (TEST == "embench") begin + StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_trigger"; + EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_trigger"; + end else if (TEST == "coremark") begin + StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_time"; + EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_time"; + end else begin + StartSampleFirst = reset; + EndSample = DCacheFlushStart & ~DCacheFlushDone; + end + + /* if(TEST == "embench") begin // embench runs warmup then runs start_trigger // embench end with stop_trigger. - assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_trigger"; - flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); - assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + //assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_trigger"; + //flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + //assign StartSample = StartSampleFirst & ~ StartSampleDelayed; - assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_trigger"; + //assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_trigger"; flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); assign EndSample = EndSampleFirst & ~ EndSampleDelayed; end else if(TEST == "coremark") begin // embench runs warmup then runs start_trigger // embench end with stop_trigger. - assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_time"; - flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); - assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + //assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_time"; + //flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + //assign StartSample = StartSampleFirst & ~ StartSampleDelayed; - assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_time"; + //assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_time"; flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); assign EndSample = EndSampleFirst & ~ EndSampleDelayed; end else begin // default start condiction is reset // default end condiction is end of test (DCacheFlushDone) - assign StartSampleFirst = reset; - flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); - assign StartSample = StartSampleFirst & ~ StartSampleDelayed; - assign EndSample = DCacheFlushStart & ~DCacheFlushDone; + //assign StartSampleFirst = reset; + //flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + //assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + //assign EndSample = DCacheFlushStart & ~DCacheFlushDone; flop #(1) BeginReg(clk, StartSampleFirst, BeginDelayed); assign BeginSample = StartSampleFirst & ~BeginDelayed; end + + */ + + flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + assign StartSample = StartSampleFirst & ~StartSampleDelayed; + flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); + assign EndSample = EndSampleFirst & ~ EndSampleDelayed; + flop #(1) BeginReg(clk, StartSampleFirst, BeginDelayed); // ** is this redundant with StartSampleReg? + assign BeginSample = StartSampleFirst & ~BeginDelayed; + + always @(negedge clk) begin if(StartSample) begin for(HPMCindex = 0; HPMCindex < 32; HPMCindex += 1) begin diff --git a/testbench/testbench.sv b/testbench/testbench.sv index d126a9ef6..93d862587 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -39,7 +39,6 @@ module testbench; /* verilator lint_off WIDTHTRUNC */ /* verilator lint_off WIDTHEXPAND */ parameter DEBUG=0; - parameter string TEST="arch64m"; parameter PrintHPMCounters=0; parameter BPRED_LOGGER=0; parameter I_CACHE_ADDR_LOGGER=0; @@ -58,6 +57,7 @@ module testbench; logic clk; logic reset_ext, reset; logic ResetMem; + string TEST; // DUT signals logic [P.AHBW-1:0] HRDATAEXT; @@ -101,7 +101,9 @@ module testbench; // pick tests based on modes supported initial begin - $display("TEST is %s", TEST); + TEST = "none"; + if ($value$plusargs("TEST=%s", TEST)) + $display("TEST is %s", TEST); //tests = '{}; if (P.XLEN == 64) begin // RV64 case (TEST) @@ -309,7 +311,7 @@ module testbench; // Verify the test ran correctly by checking the memory against a known signature. //////////////////////////////////////////////////////////////////////////////// if(TestBenchReset) test = 1; - if (TEST == "coremark") + if (P.ZICSR_SUPPORTED & TEST == "coremark") if (dut.core.priv.priv.EcallFaultM) begin $display("Benchmark: coremark is done."); $stop; @@ -559,8 +561,8 @@ module testbench; ramxdetector #(P.XLEN, P.LLEN) ramxdetector(clk, dut.core.lsu.MemRWM[1], dut.core.lsu.LSULoadAccessFaultM, dut.core.lsu.ReadDataM, dut.core.ifu.PCM, InstrM, dut.core.lsu.IEUAdrM, InstrMName); riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration - loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) - loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename); + loggers #(P, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) + loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename, TEST); // track the current function or global label if (DEBUG == 1 | ((PrintHPMCounters | BPRED_LOGGER) & P.ZICNTR_SUPPORTED)) begin : FunctionName