diff --git a/bin/nightly_build.py b/bin/nightly_build.py index d82877a7a..08052ffe1 100755 --- a/bin/nightly_build.py +++ b/bin/nightly_build.py @@ -692,7 +692,7 @@ def main(): # Define tests that we can run if (args.tests == "nightly"): - test_list = [["python", "regression-wally", "--nightly"]] + test_list = [["python", "regression-wally", "--nightly --buildroot"]] elif (args.tests == "test"): test_list = [["python", "regression-wally", ""]] elif (args.tests == "test_lint"): diff --git a/bin/regression-wally b/bin/regression-wally index ed725b51a..4842a15d5 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -170,7 +170,7 @@ derivconfigtests = [ ["fh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64zfh", "arch64zfh_divsqrt", "arch64zfaf"]], ["fdh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt", "arch64zfaf", "arch64zfad"]], ["fdq_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64i", "arch64zfaf", "arch64zfad"]], - ["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt", "arch64i", "wally64q", "arch64zfaf", "arch64zfad"]], + ["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt", "arch64i", "arch64zfaf", "arch64zfad"]], # "wally64q" when Q is supported again in riscof config file ] bpredtests = [ @@ -312,7 +312,6 @@ regressionDir = WALLY + '/sim' os.chdir(regressionDir) coveragesim = "questa" # Questa is required for code/functional coverage -#defaultsim = "vcs" # Default simulator for all other tests; change to Verilator when flow is ready #defaultsim = "questa" # Default simulator for all other tests; change to Verilator when flow is ready defaultsim = "verilator" # Default simulator for all other tests @@ -320,6 +319,7 @@ coverage = '--coverage' in sys.argv fp = '--fp' in sys.argv nightly = '--nightly' in sys.argv testfloat = '--testfloat' in sys.argv +buildroot = '--buildroot' in sys.argv if (nightly): nightMode = "--nightly"; @@ -345,22 +345,27 @@ configs = [ grepfile = WALLY + "/sim/verilator/logs/all_lints.log") ] +# run full buildroot boot simulation (slow) if buildroot flag is set. Start it early to overlap with other tests +if (buildroot): + addTests(tests_buildrootboot, defaultsim) + if (coverage): # only run RV64GC tests on Questa in coverage mode addTests(tests64gc_nofp, "questa") if (fp): addTests(tests64gc_fp, "questa") else: for sim in sims: - addTests(tests_buildrootshort, sim) + if (not (buildroot and sim == defaultsim)): # skip shot buildroot sim if running long one + addTests(tests_buildrootshort, sim) addTests(tests, sim) addTests(tests64gc_nofp, sim) addTests(tests64gc_fp, sim) - # run derivative configurations in nightly regression +# run derivative configurations in nightly regression if (nightly): -# addTests(tests_buildrootboot, defaultsim) addTests(derivconfigtests, defaultsim) + # testfloat tests if (testfloat): # for testfloat alone, just run testfloat tests configs = [] diff --git a/bin/wsim b/bin/wsim index 35b48dbb1..945ffa8ad 100755 --- a/bin/wsim +++ b/bin/wsim @@ -41,7 +41,13 @@ def LaunchSim(ElfFile, flags): print(f"Running VCS on " + args.config + " " + args.testsuite) if (args.gui): args.args += "gui" - cmd = cd + "; ./run_vcs " + args.config + " " + args.testsuite + " " + args.args + " " + flags + if (args.args == ""): + vcsargs = "" + else: + vcsargs = " --args " + args.args + if (ElfFile != ""): + ElfFile = " --elffile " + ElfFile + cmd = cd + "; ./run_vcs.py " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags print(cmd) os.system(cmd) diff --git a/sim/vcs/run_vcs.py b/sim/vcs/run_vcs.py new file mode 100755 index 000000000..a9e9c2fca --- /dev/null +++ b/sim/vcs/run_vcs.py @@ -0,0 +1,84 @@ +#!/usr/bin/python3 + +# run_vcs +# David_Harris@hmc.edu 2 July 2024 +# Run VCS on a given file, passing appropriate flags +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + +import argparse +import os +import subprocess + +# run a Linux command and return the result as a string in a form that VCS can use +def runfindcmd(cmd): +# print("Executing: " + str(cmd) ) + res = subprocess.check_output(cmd, shell=True) + res = str(res) + res = res.replace("\\n", " ") # replace newline with space + res = res.replace("\'", "") # strip off quotation marks + res = res[1:] # strip off leading b from byte string + return res + +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("--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("--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") +args = parser.parse_args() +print("run_vcs Config=" + args.config + " tests=" + args.testsuite + " elffile=" + args.elffile + " lockstep=" + str(args.lockstep) + " args='" + args.args + "'") + +cfgdir = "$WALLY/config" +srcdir = "$WALLY/src" +tbdir = "$WALLY/testbench" +wkdir = "$WALLY/sim/vcs/wkdir/" + args.config + "_" + args.testsuite +covdir = "$WALLY/sim/vcs/cov/" + args.config + "_" + args.testsuite +logdir = "$WALLY/sim/vcs/logs" + +os.system("mkdir -p " + wkdir) +os.system("mkdir -p " + covdir) +os.system("mkdir -p " + logdir) + +# Find RTL source files +rtlsrc_cmd = "find " + srcdir + ' -name "*.sv" ! -path "' + srcdir + '/generic/mem/rom1p1r_128x64.sv" ! -path "' + srcdir + '/generic/mem/ram2p1r1wbe_128x64.sv" ! -path "' + srcdir + '/generic/mem/rom1p1r_128x32.sv" ! -path "' + srcdir + '/generic/mem/ram2p1r1wbe_2048x64.sv"' +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) + +# Include directories +INCLUDE_PATH="+incdir+" + cfgdir + "/" + args.config + " +incdir+" + cfgdir + "/deriv/" + args.config + " +incdir+" + cfgdir + "/shared +incdir+$WALLY/tests +incdir+" + tbdir + " +incdir+" + srcdir + +# lockstep mode +if (args.lockstep): + LOCKSTEP_OPTIONS = " +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 " + tbdir + "/common/wallyTracer.sv" + LOCKSTEP_SIMV = "-sv_lib $IMPERAS_HOME/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model" +else: + LOCKSTEP_OPTIONS = "" + LOCKSTEP_SIMV = "" + +# coverage mode +if (args.coverage): + COV_OPTIONS = "-cm line+cond+branch+fsm+tgl -cm_log " + wkdir + "/coverage.log -cm_dir " + wkdir + "/coverage" +else: + COV_OPTIONS = "" + +# 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" +SIMV_CMD= wkdir + "/" + OUTPUT + " +TEST=" + args.testsuite + " " + args.elffile + " " + args.args + " -no_save " + LOCKSTEP_SIMV + +# Run simulation +print("Executing: " + str(VCS) ) +subprocess.run(VCS, shell=True) +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/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index de4692a36..8c72a6816 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -56,8 +56,8 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi); logic [`NUM_REGS-1:0] frf_wb; logic [4:0] frf_a4; logic frf_we4; - logic [P.XLEN-1:0] CSRArray [logic[11:0]]; - logic [P.XLEN-1:0] CSRArrayOld [logic[11:0]]; + logic [P.XLEN-1:0] CSRArray [4095:0]; + logic [P.XLEN-1:0] CSRArrayOld [4095:0]; logic [`NUM_CSRS-1:0] CSR_W; logic CSRWriteM, CSRWriteW; logic [11:0] CSRAdrM, CSRAdrW; diff --git a/testbench/common/watchdog.sv b/testbench/common/watchdog.sv index 296900b20..69b185c40 100644 --- a/testbench/common/watchdog.sv +++ b/testbench/common/watchdog.sv @@ -26,7 +26,8 @@ module watchdog #(parameter XLEN, WatchDogTimerThreshold) (input clk, - input reset + input reset, + string TEST ); // check for hang up. @@ -46,9 +47,14 @@ module watchdog #(parameter XLEN, WatchDogTimerThreshold) always_comb begin WatchDogTimeOut = WatchDogTimerCount >= WatchDogTimerThreshold; if(WatchDogTimeOut) begin - $display("FAILURE: Watch Dog Time Out triggered. PCW stuck at %x for more than %d cycles", PCW, WatchDogTimerCount); - $stop; - end + if (TEST == "buildroot") $display("Watch Dog Time Out triggered. This is a normal termination for a full buildroot boot. Check sim//logs/buildroot_uart.log to check if the boot printed the login prompt."); + else $display("FAILURE: Watch Dog Time Out triggered. PCW stuck at %x for more than %d cycles", PCW, WatchDogTimerCount); + `ifdef QUESTA + $stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug + `else + $finish; + `endif + end end endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index be0422550..f6087da1b 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -118,10 +118,9 @@ module testbench; TEST = "none"; if (!$value$plusargs("ElfFile=%s", ElfFile)) ElfFile = "none"; - else begin - end if (!$value$plusargs("INSTR_LIMIT=%d", INSTR_LIMIT)) INSTR_LIMIT = 0; + //$display("TEST = %s ElfFile = %s", TEST, ElfFile); // pick tests based on modes supported //tests = '{}; @@ -613,7 +612,7 @@ module testbench; InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); // watch for problems such as lockup, reading unitialized memory, bad configs - watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck + watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset, .TEST); // check if PCW is stuck 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