mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge pull request #1189 from jordancarlin/refactor_run_vcs
Refactor run_vcs
This commit is contained in:
commit
2a3af5425e
@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Modification by Oklahoma State University & Harvey Mudd College
|
# Modification by Oklahoma State University & Harvey Mudd College
|
||||||
# Use with Testbench
|
# Use with Testbench
|
||||||
# James Stine, 2008; David Harris 2021
|
# James Stine, 2008; David Harris 2021; Jordan Carlin 2024
|
||||||
# Go Cowboys!!!!!!
|
# Go Cowboys!!!!!!
|
||||||
#
|
#
|
||||||
# Takes 1:10 to run RV64IC tests using gui
|
# Takes 1:10 to run RV64IC tests using gui
|
||||||
|
140
sim/vcs/run_vcs
140
sim/vcs/run_vcs
@ -2,24 +2,33 @@
|
|||||||
|
|
||||||
# run_vcs
|
# run_vcs
|
||||||
# David_Harris@hmc.edu 2 July 2024
|
# David_Harris@hmc.edu 2 July 2024
|
||||||
|
# Modified Jordan Carlin jcarlin@hmc.edu Dec 9 2024
|
||||||
# Run VCS on a given file, passing appropriate flags
|
# Run VCS on a given file, passing appropriate flags
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Global variables
|
||||||
|
WALLY = os.environ.get('WALLY')
|
||||||
|
simdir = f"{WALLY}/sim/vcs"
|
||||||
|
cfgdir = f"{WALLY}/config"
|
||||||
|
srcdir = f"{WALLY}/src"
|
||||||
|
tbdir = f"{WALLY}/testbench"
|
||||||
|
logdir = f"{simdir}/logs"
|
||||||
|
|
||||||
# run a Linux command and return the result as a string in a form that VCS can use
|
# run a Linux command and return the result as a string in a form that VCS can use
|
||||||
def runfindcmd(cmd):
|
def runFindCommand(cmd):
|
||||||
# print("Executing: " + str(cmd) )
|
res = subprocess.check_output(cmd, shell=True, )
|
||||||
res = subprocess.check_output(cmd, shell=True)
|
|
||||||
res = str(res)
|
res = str(res)
|
||||||
res = res.replace("\\n", " ") # replace newline with space
|
res = res.replace("\\n", " ") # replace newline with space
|
||||||
res = res.replace("\'", "") # strip off quotation marks
|
res = res.replace("\'", "") # strip off quotation marks
|
||||||
res = res[1:] # strip off leading b from byte string
|
res = res[1:] # strip off leading b from byte string
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def parseArgs():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("config", help="Configuration file")
|
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("testsuite", help="Test suite (or none, when running a single ELF file) ")
|
||||||
@ -30,70 +39,81 @@ parser.add_argument("--args", "-a", help="Optional arguments passed to simulator
|
|||||||
parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", default="")
|
parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", default="")
|
||||||
parser.add_argument("--define", "-d", help="Optional define macros passed to simulator", default="")
|
parser.add_argument("--define", "-d", help="Optional define macros passed to simulator", default="")
|
||||||
parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true")
|
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") # GUI not yet implemented
|
||||||
#parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true")
|
return parser.parse_args()
|
||||||
args = parser.parse_args()
|
|
||||||
print("run_vcs Config=" + args.config + " tests=" + args.testsuite + " lockstep=" + str(args.lockstep) + " args='" + args.args + "' params='" + args.params + "'" + " define='" + args.define + "'")
|
|
||||||
|
|
||||||
cfgdir = "$WALLY/config"
|
def createDirs(args):
|
||||||
srcdir = "$WALLY/src"
|
wkdir = f"{simdir}/wkdir/{args.config}_{args.testsuite}"
|
||||||
tbdir = "$WALLY/testbench"
|
covdir = f"{simdir}/cov/{args.config}_{args.testsuite}"
|
||||||
wkdir = "$WALLY/sim/vcs/wkdir/" + args.config + "_" + args.testsuite
|
os.makedirs(wkdir, exist_ok=True)
|
||||||
covdir = "$WALLY/sim/vcs/cov/" + args.config + "_" + args.testsuite
|
os.makedirs(covdir, exist_ok=True)
|
||||||
logdir = "$WALLY/sim/vcs/logs"
|
os.makedirs(logdir, exist_ok=True)
|
||||||
|
return wkdir, covdir
|
||||||
|
|
||||||
os.system("mkdir -p " + wkdir)
|
def generateFileList():
|
||||||
os.system("mkdir -p " + covdir)
|
rtlsrc_cmd = f'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"'
|
||||||
os.system("mkdir -p " + logdir)
|
rtlsrc_files = runFindCommand(rtlsrc_cmd)
|
||||||
|
tbcommon_cmd = f'find {tbdir}/common -name "*.sv"'
|
||||||
|
tbcommon_files = runFindCommand(tbcommon_cmd)
|
||||||
|
tb_file = f'{tbdir}/{args.tb}.sv'
|
||||||
|
return f"{tb_file} {rtlsrc_files} {tbcommon_files}"
|
||||||
|
|
||||||
# Find RTL source files
|
def processArgs(wkdir, args):
|
||||||
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"'
|
compileOptions = []
|
||||||
rtlsrc_files = runfindcmd(rtlsrc_cmd)
|
simvOptions = []
|
||||||
tbcommon_cmd = 'find ' + tbdir+'/common -name "*.sv" ! -path "' + tbdir+'/common/wallyTracer.sv"'
|
if args.lockstep:
|
||||||
tbcommon_files = runfindcmd(tbcommon_cmd)
|
compileOptions.extend(["+incdir+$IMPERAS_HOME/ImpPublic/include/host",
|
||||||
tb_file = tbdir + "/" + args.tb + ".sv"
|
"+incdir+$IMPERAS_HOME/ImpProprietary/include/host",
|
||||||
RTL_FILES = tb_file + ' ' + str(rtlsrc_files) + ' ' + str(tbcommon_files)
|
"$IMPERAS_HOME/ImpPublic/source/host/rvvi/*.sv",
|
||||||
|
"$IMPERAS_HOME/ImpProprietary/source/host/idv/*.sv"])
|
||||||
|
simvOptions.append("-sv_lib $IMPERAS_HOME/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model")
|
||||||
|
if args.ccov:
|
||||||
|
compileOptions.extend(["-cm line+cond+branch+fsm+tgl", f"-cm_log {wkdir}/coverage.log", f"-cm_dir {wkdir}/coverage"])
|
||||||
|
if args.params:
|
||||||
|
compileOptions.append(setupParamOverrides(wkdir, args))
|
||||||
|
if args.define:
|
||||||
|
compileOptions.append(args.define)
|
||||||
|
# if args.gui:
|
||||||
|
# compileOptions.append("-debug_access+all+reverse -kdb +vcs+vcdpluson")
|
||||||
|
compileOptions = " ".join(compileOptions)
|
||||||
|
simvOptions = " ".join(simvOptions)
|
||||||
|
return compileOptions, simvOptions
|
||||||
|
|
||||||
# Include directories
|
def setupParamOverrides(wkdir, args):
|
||||||
INCLUDE_PATH="+incdir+" + cfgdir + "/" + args.config + " +incdir+" + cfgdir + "/deriv/" + args.config + " +incdir+" + cfgdir + "/shared +incdir+$WALLY/tests +incdir+" + tbdir + " +incdir+" + srcdir
|
paramOverrideFile = os.path.join(wkdir, "param_overrides.txt")
|
||||||
|
with open(paramOverrideFile, "w") as f:
|
||||||
# lockstep mode
|
|
||||||
if (args.lockstep):
|
|
||||||
LOCKSTEP_OPTIONS = " +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.ccov):
|
|
||||||
COV_OPTIONS = "-cm line+cond+branch+fsm+tgl -cm_log " + wkdir + "/coverage.log -cm_dir " + wkdir + "/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():
|
for param in args.params.split():
|
||||||
[param, value] = param.split("=")
|
[param, value] = param.split("=")
|
||||||
if "\\'" in value: # for bit values
|
if fr"\'" in value: # for bit values
|
||||||
value = value.replace("\\'", "'")
|
value = value.replace(fr"\'", "'")
|
||||||
else: # for strings
|
else: # for strings
|
||||||
value = "\"" + value + "\""
|
value = f'"{value}"'
|
||||||
# print("param=" + param + " value=" + value)
|
f.write(f"assign {value} {args.tb}/{param}\n")
|
||||||
f.write("assign " + value + " " + args.tb + "/" + param + "\n")
|
return f" -parameters {wkdir}/param_overrides.txt "
|
||||||
f.close()
|
|
||||||
PARAM_OVERRIDES=" -parameters " + wkdir + "/param_overrides.txt "
|
|
||||||
|
|
||||||
# Simulation commands
|
def setupCommands(wkdir, rtlFiles, compileOptions, simvOptions, args):
|
||||||
OUTPUT="sim_out"
|
includePath=f"+incdir+{cfgdir}/{args.config} +incdir+{cfgdir}/deriv/{args.config} +incdir+{cfgdir}/shared +incdir+$WALLY/tests +incdir+{tbdir} +incdir+{srcdir}"
|
||||||
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 + " " + args.define + " " + PARAM_OVERRIDES + INCLUDE_PATH # Disabled Debug flags; add them back for a GUI mode -debug_access+all+reverse -kdb +vcs+vcdpluson
|
vcsStandardFlags = "+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"
|
||||||
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"
|
vcsCMD = f"vcs {vcsStandardFlags} -top {args.tb} {compileOptions} -Mdir={wkdir} {includePath} {srcdir}/cvw.sv {rtlFiles} -o {wkdir}/sim_out -work {wkdir} -Mlib={wkdir} -l {logdir}/{args.config}_{args.testsuite}.log"
|
||||||
SIMV_CMD= wkdir + "/" + OUTPUT + " +TEST=" + args.testsuite + " " + args.args + " -no_save " + LOCKSTEP_SIMV
|
simvCMD = f"{wkdir}/sim_out +TEST={args.testsuite} {args.args} -no_save {simvOptions}"
|
||||||
|
return vcsCMD, simvCMD
|
||||||
|
|
||||||
# Run simulation
|
def runVCS(wkdir, vcsCMD, simvCMD):
|
||||||
print("Executing: " + str(VCS) )
|
print(f"Executing: {vcsCMD}")
|
||||||
subprocess.run(VCS, shell=True)
|
subprocess.run(vcsCMD, shell=True)
|
||||||
subprocess.run(SIMV_CMD, shell=True)
|
subprocess.run(simvCMD, shell=True)
|
||||||
if (args.ccov):
|
if (args.ccov):
|
||||||
COV_RUN = "urg -dir " + wkdir + "/coverage.vdb -format text -report IndividualCovReport/" + args.config + "_" + args.testsuite
|
COV_RUN = f"urg -dir {wkdir}/coverage.vdb -format text -report IndividualCovReport/{args.config}_{args.testsuite}"
|
||||||
subprocess.run(COV_RUN, shell=True)
|
subprocess.run(COV_RUN, shell=True)
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
print(f"run_vcs Config={args.config} tests={args.testsuite} lockstep={args.lockstep} args='{args.args}' params='{args.params}' define='{args.define}'")
|
||||||
|
wkdir, covdir = createDirs(args)
|
||||||
|
rtlFiles = generateFileList()
|
||||||
|
compileOptions, simvOptions = processArgs(wkdir, args)
|
||||||
|
vcsCMD, simvCMD = setupCommands(wkdir, rtlFiles, compileOptions, simvOptions, args)
|
||||||
|
runVCS(wkdir, vcsCMD, simvCMD)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = parseArgs()
|
||||||
|
sys.exit(main(args))
|
||||||
|
Loading…
Reference in New Issue
Block a user