diff --git a/.gitignore b/.gitignore index 9a5f1668c..3eba7966b 100644 --- a/.gitignore +++ b/.gitignore @@ -93,7 +93,7 @@ synthDC/wallyplots/ synthDC/runArchive synthDC/hdl sim/power.saif -tests/fp/vectors/*.tv +tests/fp/vectors synthDC/Summary.csv tests/custom/work tests/custom/*/*/*.list @@ -237,3 +237,4 @@ tests/functcov tests/functcov/* tests/functcov/*/* sim/vcs/simprofile* +sim/verilator/verilator.log diff --git a/bin/derivgen.pl b/bin/derivgen.pl index 656612956..58991faae 100755 --- a/bin/derivgen.pl +++ b/bin/derivgen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/env perl -w +#!/usr/bin/env -S perl -w ########################################### ## derivgen.pl diff --git a/bin/iterelf b/bin/iterelf new file mode 100755 index 000000000..af284a858 --- /dev/null +++ b/bin/iterelf @@ -0,0 +1,103 @@ +#!/usr/bin/python3 + +# iterelf +# David_Harris@hmc.edu and Rose Thompson 7/3/2024 +# Run wsim on all the ELF files in a directory in parallel in lockstep + + +import argparse +import os +import multiprocessing +from multiprocessing import Pool, TimeoutError +TIMEOUT_DUR = 60 # 1` minute + +class bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKCYAN = '\033[96m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + +def search_log_for_mismatches(logfile): + """Search through the given log file for text, returning True if it is found or False if it is not""" + grepwarn = "grep -H Warning: " + logfile + os.system(grepwarn) + greperr = "grep -H Error: " + logfile + os.system(greperr) + grepcmd = "grep -a -e 'Mismatches : 0' '%s' > /dev/null" % logfile +# print(" search_log_for_text invoking %s" % grepcmd) + return os.system(grepcmd) == 0 + +def run_test_case(elf): + """Run the given test case, and return 0 if the test suceeds and 1 if it fails""" + WALLY = os.environ.get('WALLY') + fields = elf.rsplit('/', 3) + if (fields[2] == "ref"): + shortelf = fields[1] + "_" + fields[3] + else: + shortelf = fields[2] + "_" + fields[3] +# shortelf = fields[1] + "_" + fields[2] + logfile = WALLY + "/sim/" + args.sim + "/logs/" + shortelf + ".log" + cmd = "wsim " + args.config + " " + shortelf + " --elf " + elf + " --sim " + args.sim + " --lockstep > " + logfile # add coveerage flags if necessary +# print("cmd = " + cmd) + os.system(cmd) + if search_log_for_mismatches(logfile): + print(f"{bcolors.OKGREEN}%s: Success{bcolors.ENDC}" % (cmd)) + return 0 + else: + print(f"{bcolors.FAIL}%s: Failures detected in output{bcolors.ENDC}" % (cmd)) + print(" Check %s" % logfile) + return 1 + +################################## +# Main body +################################## + +# Parse arguments +parser = argparse.ArgumentParser() +parser.add_argument("dir", help="Configuration file") +parser.add_argument("--config", help="Configuration", default="rv64gc") +parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "vcs"], default="questa") +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("--exclude", help="Exclude files with this sufix", default="my.elf") +args = parser.parse_args() + +# find all ELF files in directory + +ElfList = [] +if (os.path.isdir(args.dir)): + DirectorMode = 1 + for dirpath, dirnames, filenames in os.walk(os.path.abspath(args.dir)): + for file in filenames: + if (file.endswith("elf") and not file.endswith(args.exclude)): + ElfList.append(os.path.join(dirpath, file)) +else: + print(args.dir + " is not a directory") + exit(1) +#print(ElfList) + +# spawn parallel wsim jobs for each ELF file + +ImperasDVLicenseCount = 8 +with Pool(processes=min(len(ElfList),multiprocessing.cpu_count(), ImperasDVLicenseCount)) as pool: + num_fail = 0 + results = {} + for elf in ElfList: + results[elf] = pool.apply_async(run_test_case,(elf,)) + for (elf,result) in results.items(): + try: + num_fail+=result.get(timeout=TIMEOUT_DUR) + except TimeoutError: + num_fail+=1 + print(f"{bcolors.FAIL}%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (elf, TIMEOUT_DUR)) + +if (num_fail == 0): + print(f"{bcolors.OKGREEN}SUCCESS! All tests ran without failures{bcolors.ENDC}") +else: + print(f"{bcolors.FAIL}Completed %d tests with %d failures{bcolors.ENDC}" % (len(ElfList), num_fail)) + diff --git a/bin/regression-wally b/bin/regression-wally index 91db54684..a150c1064 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -47,6 +47,11 @@ tests_buildrootboot = [ "WallyHostname login: ", "buildroot_uart.out"] ] +tests_buildrootbootlockstep = [ + ["buildroot", ["buildroot"], [f"+INSTR_LIMIT=600000000 --lockstep"], # boot entire buildroot Linux to login prompt + "WallyHostname login: ", "buildroot_uart.out"] + ] + # Separate out floating-point tests for RV64 to speed up coverage tests64gc_nofp = [ @@ -345,9 +350,12 @@ 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) + # addTests(tests_buildrootboot, defaultsim) # non-lockstep with Verilator runs in about 2 hours + addTests(tests_buildrootbootlockstep, "questa") # lockstep with Questa and ImperasDV runs overnight if (coverage): # only run RV64GC tests on Questa in coverage mode addTests(tests64gc_nofp, "questa") @@ -361,26 +369,43 @@ else: addTests(tests64gc_nofp, sim) addTests(tests64gc_fp, sim) -# run derivative configurations in nightly regression +# run derivative configurations and lockstep tests in nightly regression if (nightly): addTests(derivconfigtests, defaultsim) + sim_log = WALLY + "/sim/questa/logs/lockstep_coverage.log" + tc = TestCase( + name="lockstep_coverage", + variant="rv64gc", + cmd="iterelf " + WALLY + "/tests/coverage > " + sim_log, + grepstr="SUCCESS! All tests ran without failures", + grepfile = sim_log) + configs.append(tc) + sim_log = WALLY + "/sim/questa/logs/lockstep_wally-riscv-arch-test.log" + tc = TestCase( + name="lockstep_wally-riscv-arch-test", + variant="rv64gc", + cmd="iterelf " + WALLY + "/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege > " + sim_log, + grepstr="SUCCESS! All tests ran without failures", + grepfile = sim_log) + configs.append(tc) # testfloat tests if (testfloat): # for testfloat alone, just run testfloat tests configs = [] if (testfloat or nightly): # for nightly, run testfloat along with othres + testfloatsim = "questa" # change to Verilator when Issue #707 about testfloat not running Verilator is resolved testfloatconfigs = ["fdqh_ieee_rv64gc", "fdq_ieee_rv64gc", "fdh_ieee_rv64gc", "fd_ieee_rv64gc", "fh_ieee_rv64gc", "f_ieee_rv64gc", "fdqh_ieee_rv32gc", "f_ieee_rv32gc"] for config in testfloatconfigs: tests = ["div", "sqrt", "add", "sub", "mul", "cvtint", "cvtfp", "fma", "cmp"] if ("f_" in config): tests.remove("cvtfp") for test in tests: - sim_log = WALLY + "/sim/questa/logs/"+config+"_"+test+".log" # TODO: Change hardcoded questa log directory to simulator + sim_log = WALLY + "/sim/" + testfloatsim + "/logs/"+config+"_"+test+".log" tc = TestCase( name=test, variant=config, - cmd="wsim --tb testbench_fp " + config + " " + test + " > " + sim_log, + cmd="wsim --tb testbench_fp --sim " + testfloatsim + " " + config + " " + test + " > " + sim_log, grepstr="All Tests completed with 0 errors", grepfile = sim_log) configs.append(tc) diff --git a/bin/wsim b/bin/wsim index 5f4a45646..655d8c256 100755 --- a/bin/wsim +++ b/bin/wsim @@ -14,44 +14,6 @@ import argparse import os - -def LaunchSim(ElfFile, flags): - cd = "cd $WALLY/sim/" +args.sim - - # per-simulator launch - if (args.sim == "questa"): - # 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 - 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\"" - else: # launch Questa in batch mode - cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" - print("Running Questa with command: " + cmd) - os.system(cmd) - 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}'") - elif (args.sim == "vcs"): - print(f"Running VCS on " + args.config + " " + args.testsuite) - if (args.gui): - args.args += "gui" - if (args.args == ""): - vcsargs = "" - else: - vcsargs = " --args " + args.args - if (ElfFile != ""): - ElfFile = " --elffile " + ElfFile - cmd = cd + "; ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags - print(cmd) - os.system(cmd) - - ######################## # main wsim script ######################## @@ -60,6 +22,7 @@ def LaunchSim(ElfFile, flags): parser = argparse.ArgumentParser() parser.add_argument("config", help="Configuration file") parser.add_argument("testsuite", help="Test suite or ELF file") +parser.add_argument("--elf", "-e", help="ELF File name", default="") parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilator", "vcs"], default="questa") parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench") parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") @@ -70,26 +33,14 @@ parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_ 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) parser.add_argument("--covlog", "-d", help="Log coverage after n instructions.", default=0) -parser.add_argument("--elfext", "-e", help="When searching for elf files only includes ones which end in this extension", default=".elf") args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") ElfFile="" DirectorMode = 0 -ElfList = [] WALLY = os.environ.get('WALLY') -if(os.path.isfile(args.testsuite)): - ElfFile = "+ElfFile=" + args.testsuite - args.testsuite = "none" - ElfList.append("+ElfFile=" + args.testsuite) -elif(os.path.isdir(args.testsuite)): - DirectorMode = 1 - for dirpath, dirnames, filenames in os.walk(args.testsuite): - for file in filenames: - if file.endswith(args.elfext): - ElfList.append("+ElfFile=" + os.path.join(dirpath, file)) - args.testsuite = "none" -print(ElfList) +if(os.path.isfile(args.elf)): + ElfFile = "+ElfFile=" + os.path.abspath(args.elf) # Validate arguments if (args.gui or args.coverage or args.fcov or args.lockstep): @@ -135,10 +86,38 @@ for d in ["logs", "wkdir", "cov"]: os.mkdir(regressionDir+args.sim+"/"+d) except: pass - -if(DirectorMode): - for ElfFile in ElfList: - LaunchSim(ElfFile, flags) -else: - LaunchSim(ElfFile, flags) +cd = "cd $WALLY/sim/" +args.sim + +# per-simulator launch +if (args.sim == "questa"): + # 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 + 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\"" + else: # launch Questa in batch mode + cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" + print("Running Questa with command: " + cmd) + os.system(cmd) +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}'") +elif (args.sim == "vcs"): + print(f"Running VCS on " + args.config + " " + args.testsuite) + if (args.gui): + args.args += "gui" + if (args.args == ""): + vcsargs = "" + else: + vcsargs = " --args " + args.args + if (ElfFile != ""): + ElfFile = " --elffile " + ElfFile + cmd = cd + "; " + prefix + " ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags + print(cmd) + os.system(cmd) diff --git a/config/derivlist.txt b/config/derivlist.txt index 7bd878aaf..2fac6bcc2 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -35,6 +35,7 @@ # If is not empty, all the list of parameter changes in the inherited # configuration are also applied to this configuration + # buildroot is used for the Linux boot deriv buildroot rv64gc RESET_VECTOR 64'h1000 @@ -1654,4 +1655,17 @@ IDIV_ON_FPU 1 deriv fdqh_ieee_div_4_4i_rv64gc fdqh_ieee_div_4_4_rv64gc IDIV_ON_FPU 1 - +# imperas used for a smart memory +# VCS doesn't like removing the bootrom, but make it tiny in a random unused location +derive imperas rv64gc +ICACHE_SUPPORTED 0 +DCACHE_SUPPORTED 0 +VIRTMEM_SUPPORTED 0 +ZAAMO_SUPPORTED 0 +ZALRSC_SUPPORTED 0 +ZICBOM_SUPPORTED 0 +ZICBOZ_SUPPORTED 0 +SVPBMT_SUPPORTED 0 +SVNAPOT_SUPPORTED 0 +BOOTROM_BASE 64'h700012340010 +BOOTROM_RANGE 64'h10 diff --git a/config/shared/config-shared.vh b/config/shared/config-shared.vh index 44bf77eac..91e1d4100 100644 --- a/config/shared/config-shared.vh +++ b/config/shared/config-shared.vh @@ -97,13 +97,18 @@ localparam RK = LOGR*DIVCOPIES; // r*k bits localparam FPDIVMINb = NF + 2; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right localparam DIVMINb = ((FPDIVMINb>> P.LOGR; + assign UnsignedQuotM = {3'b000, PreUmM[P.DIVb:P.DIVb-P.INTDIVb]}; - assign W = $signed(Sum) >>> P.LOGR; - assign UnsignedQuotM = {3'b000, PreUmM}; // Integer remainder: sticky and sign correction muxes assign NegQuotM = AsM ^ BsM; // Integer Quotient is negative - mux2 #(P.DIVb+4) normremdmux(W, W+D, NegStickyM, NormRemDM); - mux2 #(P.DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM); - mux2 #(P.DIVb+4) quotresmux(UnsignedQuotM, -UnsignedQuotM, NegQuotM, NormQuotM); + mux2 #(P.INTDIVb+4) normremdmux(W, W+DTrunc, NegStickyM, NormRemDM); + // Select quotient or remainder and do normalization shift - mux2 #(P.DIVb+4) presresultmux(NormQuotM, NormRemM, RemOpM, PreResultM); - assign PreIntResultM = $signed(PreResultM >>> IntNormShiftM); + mux2 #(P.INTDIVb+4) presresultmux(UnsignedQuotM, NormRemDM, RemOpM, PreResultM); + assign PreResultShiftedM = PreResultM >> IntNormShiftM; + mux2 #(P.INTDIVb+4) preintresultmux(PreResultShiftedM, -PreResultShiftedM,AsM ^ (BsM&~RemOpM), PreIntResultM); // special case logic // terminates immediately when B is Zero (div 0) or |A| has more leading 0s than |B| diff --git a/src/fpu/fdivsqrt/fdivsqrtpreproc.sv b/src/fpu/fdivsqrt/fdivsqrtpreproc.sv index 9156005fd..737d9089a 100644 --- a/src/fpu/fdivsqrt/fdivsqrtpreproc.sv +++ b/src/fpu/fdivsqrt/fdivsqrtpreproc.sv @@ -119,7 +119,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) ( ////////////////////////////////////////////////////// if (P.IDIV_ON_FPU) begin:intrightshift // Int Supported - logic [P.DIVBLEN-1:0] ZeroDiff, p; + logic [P.DIVBLEN-1:0] ZeroDiff,p; // calculate number of fractional bits p assign ZeroDiff = mE - ell; // Difference in number of leading zeros @@ -218,8 +218,8 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) ( logic RemOpE; /* verilator lint_off WIDTH */ - assign IntDivNormShiftE = P.DIVb - (CyclesE * P.RK - P.LOGR); // b - rn, used for integer normalization right shift. n = (Cycles * k - 1) - assign IntRemNormShiftE = mE + (P.DIVb-(P.XLEN-1)); // m + b - (N-1) for remainder normalization shift + assign IntDivNormShiftE = P.INTDIVb - (CyclesE * P.RK - P.LOGR); // b - rn, used for integer normalization right shift. n = (Cycles * k - 1) + assign IntRemNormShiftE = mE + (P.INTDIVb-(P.XLEN-1)); // m + b - (N-1) for remainder normalization shift /* verilator lint_on WIDTH */ assign RemOpE = Funct3E[1]; mux2 #(P.DIVBLEN) normshiftmux(IntDivNormShiftE, IntRemNormShiftE, RemOpE, IntNormShiftE); diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index da56a21a0..7a0d2c4a6 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -172,7 +172,7 @@ module hptw import cvw::*; #(parameter cvw_t P) ( mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataM when ADUE = 0 because UpdatePTE = 0 flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); - assign SaveHPTWAdr = WalkerState == L0_ADR; + assign SaveHPTWAdr = (NextWalkerState == L0_RD | NextWalkerState == L1_RD | NextWalkerState == L2_RD | NextWalkerState == L3_RD); // save the HPTWAdr when the walker is about to read the PTE at any level; the last level read is the one to write during UpdatePTE assign SelHPTWWriteAdr = UpdatePTE | HPTWRW[0]; mux2 #(P.PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr); diff --git a/testbench/Makefile b/testbench/Makefile new file mode 100644 index 000000000..87870b451 --- /dev/null +++ b/testbench/Makefile @@ -0,0 +1,12 @@ +# Makefile for testbench to create .memfile, .objdump.addr, and .objdump.lab from an ELF +# David_Harris@hmc.edu 3 July 2024 +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +%.elf.memfile: %.elf + riscv64-unknown-elf-elf2hex --bit-width $(if $(findstring rv32,$*),32,64) --input $< --output $@ + +%.elf.objdump.addr: %.elf.objdump + extractFunctionRadix.sh $< + +%.elf.objdump: %.elf + riscv64-unknown-elf-objdump -S -D $< > $@ \ No newline at end of file diff --git a/testbench/testbench.sv b/testbench/testbench.sv index f6087da1b..e65fed554 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -54,11 +54,14 @@ module testbench; `ifdef VERILATOR import "DPI-C" function string getenvval(input string env_name); string RISCV_DIR = getenvval("RISCV"); // "/opt/riscv"; + string WALLY_DIR = getenvval("WALLY"); // ~/cvw typical `elsif VCS import "DPI-C" function string getenv(input string env_name); string RISCV_DIR = getenv("RISCV"); // "/opt/riscv"; + string WALLY_DIR = getenv("WALLY"); `else string RISCV_DIR = "$RISCV"; // "/opt/riscv"; + string WALLY_DIR = "$WALLY"; `endif `include "parameter-defs.vh" @@ -382,7 +385,7 @@ module testbench; // declare memory labels that interest us, the updateProgramAddrLabelArray task will find // the addr of each label and fill the array. To expand, add more elements to this array // and initialize them to zero (also initilaize them to zero at the start of the next test) - updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); + updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, memfilename, WALLY_DIR, ProgramAddrLabelArray); end `ifdef VERILATOR // this macro is defined when verilator is used // Simulator Verilator has an issue that the validate logic below slows runtime 110x if it is @@ -488,7 +491,12 @@ module testbench; $display("Error: Could not open file %s", memfilename); $finish; end - readResult = $fread(dut.uncoregen.uncore.bootrom.bootrom.memory.ROM, memFile); + if (P.BOOTROM_SUPPORTED) + readResult = $fread(dut.uncoregen.uncore.bootrom.bootrom.memory.ROM, memFile); + else begin + $display("Buildroot test requires BOOTROM_SUPPORTED"); + $finish; + end $fclose(memFile); memFile = $fopen(memfilename, "rb"); if (memFile == 0) begin @@ -931,10 +939,15 @@ endmodule task automatic updateProgramAddrLabelArray; /* verilator lint_off WIDTHTRUNC */ /* verilator lint_off WIDTHEXPAND */ - input string ProgramAddrMapFile, ProgramLabelMapFile; + input string ProgramAddrMapFile, ProgramLabelMapFile, memfilename, WALLY_DIR; inout integer ProgramAddrLabelArray [string]; // Gets the memory location of begin_signature integer ProgramLabelMapFP, ProgramAddrMapFP; + string cmd; + + // if memfile, label, or addr files are out of date or don't exist, generate them + cmd = {"make -s -f ", WALLY_DIR, "/testbench/Makefile ", memfilename, " ", ProgramAddrMapFile}; + $system(cmd); ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r"); diff --git a/testbench/tests.vh b/testbench/tests.vh index 279f765be..6a78dcd3a 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -1802,6 +1802,7 @@ string imperas32f[] = '{ }; + string arch64d_fma[] = '{ `RISCVARCHTEST, //"rv64i_m/D/src/fmadd.d_b15-01.S",