From f7797d60925a96c4f719a20bd41316a61bf73c7e Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Jul 2024 14:54:46 -0700 Subject: [PATCH 01/14] First version of iterelf running; removed directory support from wsim --- .gitignore | 2 +- bin/iterelf | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/wsim | 95 +++++++++++++++++++------------------------------ 3 files changed, 138 insertions(+), 59 deletions(-) create mode 100755 bin/iterelf diff --git a/.gitignore b/.gitignore index 9a5f1668c..dd152a1d9 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 diff --git a/bin/iterelf b/bin/iterelf new file mode 100755 index 000000000..2f6441e59 --- /dev/null +++ b/bin/iterelf @@ -0,0 +1,100 @@ +#!/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: + shorelf = 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_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (elf, TIMEOUT_DUR)) +print("Completed %d tests with %d failures" % (len(ElfList), num_fail)) + +# *** generate memfiles \ No newline at end of file diff --git a/bin/wsim b/bin/wsim index 6a3963319..c10e5073e 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=" + 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 + "; ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags + print(cmd) + os.system(cmd) From 4528b4ee2a7c1593ca6a35dac743413239306a1d Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Jul 2024 15:10:02 -0700 Subject: [PATCH 02/14] Fix wsim to use absolute path for ELF --- bin/iterelf | 2 +- bin/wsim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/iterelf b/bin/iterelf index 2f6441e59..02b53a230 100755 --- a/bin/iterelf +++ b/bin/iterelf @@ -39,7 +39,7 @@ def run_test_case(elf): if (fields[2] == "ref"): shortelf = fields[1] + "_" + fields[3] else: - shorelf = fields[2] + "_" + fields[3] + 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 diff --git a/bin/wsim b/bin/wsim index c10e5073e..b5957ae67 100755 --- a/bin/wsim +++ b/bin/wsim @@ -40,7 +40,7 @@ DirectorMode = 0 WALLY = os.environ.get('WALLY') if(os.path.isfile(args.elf)): - ElfFile = "+ElfFile=" + args.elf + ElfFile = "+ElfFile=" + os.path.abspath(args.elf) # Validate arguments if (args.gui or args.coverage or args.fcov or args.lockstep): From 9b120bb3aa2ef0d9d533779c9754bfb0393782e1 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Jul 2024 16:34:14 -0700 Subject: [PATCH 03/14] fix timeout in iterelf --- bin/iterelf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/iterelf b/bin/iterelf index 02b53a230..959a98a59 100755 --- a/bin/iterelf +++ b/bin/iterelf @@ -94,7 +94,7 @@ with Pool(processes=min(len(ElfList),multiprocessing.cpu_count(), ImperasDVLicen num_fail+=result.get(timeout=TIMEOUT_DUR) except TimeoutError: num_fail+=1 - print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (elf, TIMEOUT_DUR)) + print(f"{bcolors.FAIL}%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (elf, TIMEOUT_DUR)) print("Completed %d tests with %d failures" % (len(ElfList), num_fail)) # *** generate memfiles \ No newline at end of file From 8645441d004b0da57d5193315c94564d1ca7a083 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Jul 2024 16:52:16 -0700 Subject: [PATCH 04/14] Testbench automatically creates memfile, label, addr files if they are out of date or missing --- testbench/Makefile | 12 ++++++++++++ testbench/testbench.sv | 12 ++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 testbench/Makefile diff --git a/testbench/Makefile b/testbench/Makefile new file mode 100644 index 000000000..8ad71f522 --- /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 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..003d4d9ae 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 @@ -931,10 +934,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 -f ", WALLY_DIR, "/testbench/Makefile ", memfilename, " ", ProgramAddrMapFile}; + $system(cmd); ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r"); From 775930ae4f7b241f31897fdf505827e934e1b344 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 4 Jul 2024 07:36:56 -0700 Subject: [PATCH 05/14] Fixes to memfile generation for rv32. Updated new misa.B in imperas.ic, but need new version of ImperasDV to test --- sim/questa/imperas.ic | 8 +------- testbench/Makefile | 2 +- testbench/testbench.sv | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/sim/questa/imperas.ic b/sim/questa/imperas.ic index 51344b75a..af15cb972 100644 --- a/sim/questa/imperas.ic +++ b/sim/questa/imperas.ic @@ -15,8 +15,8 @@ # bit manipulation --override cpu/add_Extensions=B -#--override cpu/add_implicit_Extensions=B --override cpu/bitmanip_version=1.0.0 +--override cpu/misa_B_Zba_Zbb_Zbs=T # More extensions --override cpu/Zcb=T @@ -60,17 +60,11 @@ --override cpu/misa_Extensions_mask=0x0 # MISA not writable --override cpu/Sstc=T -# unsuccessfully attempt to add B extension (DH 12/21/23) -#--override cpu/add_Extensions="B" -#--override cpu/misa_Extensions=0x0014112F - # Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1 --override cpu/Svadu=T #--override cpu/updatePTEA=F #--override cpu/updatePTED=F - -# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=16 --override cpu/PMP_undefined=T diff --git a/testbench/Makefile b/testbench/Makefile index 8ad71f522..87870b451 100644 --- a/testbench/Makefile +++ b/testbench/Makefile @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 %.elf.memfile: %.elf - riscv64-unknown-elf-elf2hex --bit-width 64 --input $< --output $@ + riscv64-unknown-elf-elf2hex --bit-width $(if $(findstring rv32,$*),32,64) --input $< --output $@ %.elf.objdump.addr: %.elf.objdump extractFunctionRadix.sh $< diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 003d4d9ae..f167482b9 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -941,7 +941,7 @@ task automatic updateProgramAddrLabelArray; string cmd; // if memfile, label, or addr files are out of date or don't exist, generate them - cmd = {"make -f ", WALLY_DIR, "/testbench/Makefile ", memfilename, " ", ProgramAddrMapFile}; + cmd = {"make -s -f ", WALLY_DIR, "/testbench/Makefile ", memfilename, " ", ProgramAddrMapFile}; $system(cmd); ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); From 12717a65f21bf9d31b8c15f50e336a7d5b7336ea Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 4 Jul 2024 12:29:59 -0700 Subject: [PATCH 06/14] Fixed location of imperas.ic with new misa_B_Zba_Zbb_Zbs --- sim/imperas.ic | 8 +--- sim/questa/imperas.ic | 109 ------------------------------------------ 2 files changed, 1 insertion(+), 116 deletions(-) delete mode 100644 sim/questa/imperas.ic diff --git a/sim/imperas.ic b/sim/imperas.ic index 51344b75a..af15cb972 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -15,8 +15,8 @@ # bit manipulation --override cpu/add_Extensions=B -#--override cpu/add_implicit_Extensions=B --override cpu/bitmanip_version=1.0.0 +--override cpu/misa_B_Zba_Zbb_Zbs=T # More extensions --override cpu/Zcb=T @@ -60,17 +60,11 @@ --override cpu/misa_Extensions_mask=0x0 # MISA not writable --override cpu/Sstc=T -# unsuccessfully attempt to add B extension (DH 12/21/23) -#--override cpu/add_Extensions="B" -#--override cpu/misa_Extensions=0x0014112F - # Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1 --override cpu/Svadu=T #--override cpu/updatePTEA=F #--override cpu/updatePTED=F - -# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=16 --override cpu/PMP_undefined=T diff --git a/sim/questa/imperas.ic b/sim/questa/imperas.ic deleted file mode 100644 index af15cb972..000000000 --- a/sim/questa/imperas.ic +++ /dev/null @@ -1,109 +0,0 @@ -#--mpdconsole -#--gdbconsole -#--showoverrides -#--showcommands - -# Core settings ---override cpu/priv_version=1.12 ---override cpu/user_version=20191213 -# arch ---override cpu/mimpid=0x100 ---override cpu/mvendorid=0x602 ---override cpu/marchid=0x24 ---override refRoot/cpu/tvec_align=64 ---override refRoot/cpu/envcfg_mask=1 # dh 1/26/24 this should be deleted when ImperasDV is updated to allow envcfg.FIOM to be written - -# bit manipulation ---override cpu/add_Extensions=B ---override cpu/bitmanip_version=1.0.0 ---override cpu/misa_B_Zba_Zbb_Zbs=T - -# More extensions ---override cpu/Zcb=T ---override cpu/Zicond=T ---override cpu/Zfh=T ---override cpu/Zfa=T - -# Cache block operations ---override cpu/Zicbom=T ---override cpu/Zicbop=T ---override cpu/Zicboz=T ---override cmomp_bytes=64 # Zic64b ---override cmoz_bytes=64 # Zic64b ---override lr_sc_grain=8 # Za64rs requires <=64; we use native word size - -# 64 KiB continuous huge pages supported ---override cpu/Svpbmt=T ---override cpu/Svnapot_page_mask=65536 - -# SV39 and SV48 supported ---override cpu/Sv_modes=768 - ---override cpu/Svinval=T - - -# 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=T # Zicclsm (should be true) ---override cpu/ignore_non_leaf_DAU=1 ---override cpu/wfi_is_nop=T ---override cpu/misa_Extensions_mask=0x0 # MISA not writable ---override cpu/Sstc=T - -# Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1 ---override cpu/Svadu=T -#--override cpu/updatePTEA=F -#--override cpu/updatePTED=F - ---override cpu/PMP_registers=16 ---override cpu/PMP_undefined=T - -# PMA Settings -# 'r': read access allowed -# 'w': write access allowed -# 'x': execute access allowed -# 'a': aligned access required -# 'A': atomic instructions NOT allowed (actually USER1 privilege needed) -# 'P': push/pop instructions NOT allowed (actually USER2 privilege needed) -# '1': 1-byte accesses allowed -# '2': 2-byte accesses allowed -# '4': 4-byte accesses allowed -# '8': 8-byte accesses allowed -# '-', space: ignored (use for input string formatting). -# -# SVxx Memory 0x0000000000 0x7FFFFFFFFF -# ---callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ---a-- ---- " # INITIAL ---callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 " # BOOTROM ---callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw-aA- --48 " # SDC ---callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw-aA- 1248 " # CLINT ---callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw-aA- --4- " # PLIC ---callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF ---callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF ---callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF -#--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwxaA- 1248 " # UNCORE_RAM ---callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM - -# Enable the Imperas instruction coverage -#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0 -#-override refRoot/cpu/cv/cover=basic -#-override refRoot/cpu/cv/extensions=RV32I - -# Add Imperas simulator application instruction tracing ---verbose -#--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 300000000 ---override cpu/debugflags=6 --override cpu/verbose=1 ---override cpu/show_c_prefix=T - -# Store simulator output to logfile ---output imperas.log From 873bd61296b08544b66e1e3272c97bcbb41b6dd2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 4 Jul 2024 12:30:11 -0700 Subject: [PATCH 07/14] Fixed perl path in derivgen --- bin/derivgen.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/derivgen.pl b/bin/derivgen.pl index dbb856781..88b9be04a 100755 --- a/bin/derivgen.pl +++ b/bin/derivgen.pl @@ -1,4 +1,4 @@ -#!/bin/perl -W +#!/usr/bin/perl -W ########################################### ## derivgen.pl From 604f9d3a4551fc22448e64b25a70669de508af54 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 4 Jul 2024 12:31:00 -0700 Subject: [PATCH 08/14] Fixed imperas.ic prefix for vcs --- bin/wsim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/wsim b/bin/wsim index b5957ae67..169f76a7a 100755 --- a/bin/wsim +++ b/bin/wsim @@ -118,6 +118,6 @@ elif (args.sim == "vcs"): vcsargs = " --args " + args.args if (ElfFile != ""): ElfFile = " --elffile " + ElfFile - cmd = cd + "; ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags + cmd = cd + "; " + prefix + " ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags print(cmd) os.system(cmd) From ced803834352117b20c8a99012f27ce364be5fcf Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 5 Jul 2024 08:34:28 -0700 Subject: [PATCH 09/14] Defined memory to be inaccessible by default --- sim/imperas.ic | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index af15cb972..6ea5725a0 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -83,6 +83,7 @@ # # SVxx Memory 0x0000000000 0x7FFFFFFFFF # +--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0xFFFFFFFFFFFFFFFFFF -attributes " ---a-- ---- " # All memory inaccessible unless defined otherwise --callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ---a-- ---- " # INITIAL --callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 " # BOOTROM --callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw-aA- --48 " # SDC @@ -91,7 +92,6 @@ --callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF --callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF --callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF -#--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwxaA- 1248 " # UNCORE_RAM --callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM # Enable the Imperas instruction coverage @@ -100,8 +100,8 @@ #-override refRoot/cpu/cv/extensions=RV32I # Add Imperas simulator application instruction tracing ---verbose -#--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 300000000 +# uncomment these to provide tracing +#--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000 --override cpu/debugflags=6 --override cpu/verbose=1 --override cpu/show_c_prefix=T From 9279b2d56ac2dc0fbf7896c3cf9074e142e8b20d Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 5 Jul 2024 09:13:18 -0700 Subject: [PATCH 10/14] Added imperas configuration for Lee --- config/derivlist.txt | 15 ++++++++++++++- testbench/testbench.sv | 7 ++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/config/derivlist.txt b/config/derivlist.txt index 7bd878aaf..db8207387 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,16 @@ 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 +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'h4 +BOOTROM_RANGE 64'h0 diff --git a/testbench/testbench.sv b/testbench/testbench.sv index f167482b9..e65fed554 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -491,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 From ffb248dc656f08cc9cd0a3f4ecf13b112e9b93fb Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 5 Jul 2024 21:32:57 -0700 Subject: [PATCH 11/14] Fixed issue 868 about tlbmisc.S coverage test failing due to HPTW writing wrong address when updateing A bit --- src/mmu/hptw.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From 02a7a1696bd2bdc490efa88ee5ca761d59c84b68 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 5 Jul 2024 21:35:10 -0700 Subject: [PATCH 12/14] git ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd152a1d9..3eba7966b 100644 --- a/.gitignore +++ b/.gitignore @@ -237,3 +237,4 @@ tests/functcov tests/functcov/* tests/functcov/*/* sim/vcs/simprofile* +sim/verilator/verilator.log From bcbe9eec817de11ae0fc371d0b26f50faf91a3ec Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 5 Jul 2024 22:13:34 -0700 Subject: [PATCH 13/14] Added lockstep simulations for coverage, wally-riscv-arch-test, buildroot boot to nightly / buildroot regression --- bin/iterelf | 7 +++++-- bin/regression-wally | 33 +++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/bin/iterelf b/bin/iterelf index 959a98a59..af284a858 100755 --- a/bin/iterelf +++ b/bin/iterelf @@ -95,6 +95,9 @@ with Pool(processes=min(len(ElfList),multiprocessing.cpu_count(), ImperasDVLicen except TimeoutError: num_fail+=1 print(f"{bcolors.FAIL}%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (elf, TIMEOUT_DUR)) -print("Completed %d tests with %d failures" % (len(ElfList), num_fail)) -# *** generate memfiles \ No newline at end of file +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 4842a15d5..8225968aa 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) From 9098a55ea39774eeee71d7358b4437d22dac0e9b Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 6 Jul 2024 05:36:12 -0700 Subject: [PATCH 14/14] Fixed lint error in imperas derived config --- config/derivlist.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/derivlist.txt b/config/derivlist.txt index db8207387..2fac6bcc2 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -1656,6 +1656,7 @@ 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 @@ -1666,5 +1667,5 @@ ZICBOM_SUPPORTED 0 ZICBOZ_SUPPORTED 0 SVPBMT_SUPPORTED 0 SVNAPOT_SUPPORTED 0 -BOOTROM_BASE 64'h4 -BOOTROM_RANGE 64'h0 +BOOTROM_BASE 64'h700012340010 +BOOTROM_RANGE 64'h10