From 5d34c4e95a2310afc87cbd286566d8cec9ac8181 Mon Sep 17 00:00:00 2001 From: Matthew Otto <106996253+Matthew-Otto@users.noreply.github.com> Date: Fri, 5 Jul 2024 08:22:51 -0500 Subject: [PATCH] merge --- bin/nightly_build.py | 2 +- bin/regression-wally | 31 +- bin/wally-tool-chain-install.sh | 2 +- bin/wsim | 97 ++--- config/derivlist.txt | 4 + sim/vcs/run_vcs | 172 ++++---- src/ebu/ebu.sv | 2 +- testbench/common/wallyTracer.sv | 4 +- testbench/common/watchdog.sv | 14 +- testbench/testbench-imperas.sv | 378 ------------------ testbench/testbench.sv | 5 +- testbench/testbench_fp.sv | 226 ++++++----- tests/riscof/spike/spike_rv64gc_isa.yaml | 6 +- .../riscv-test-suite/rv64i_m/Q/README.md | 7 +- 14 files changed, 282 insertions(+), 668 deletions(-) delete mode 100644 testbench/testbench-imperas.sv 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 0e641dceb..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,20 +312,19 @@ 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 +#defaultsim = "questa" # Default simulator for all other tests; change to Verilator when flow is ready +defaultsim = "verilator" # Default simulator for all other tests 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"; -# sims = [defaultsim] - sims = ["questa", "vcs"] -# sims = ["questa", "verilator", "vcs"] # *** uncomment to exercise all simulators +# sims = [defaultsim] # uncomment to use only the default simulator + sims = ["questa", "verilator", "vcs"] # uncomment to exercise all simulators else: nightMode = "" sims = [defaultsim] @@ -346,23 +345,26 @@ 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: + 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(tests_buildrootshort, defaultsim) addTests(derivconfigtests, defaultsim) -else: - addTests(tests_buildrootshort, defaultsim) + # testfloat tests if (testfloat): # for testfloat alone, just run testfloat tests @@ -433,9 +435,10 @@ def main(): """Run the tests and count the failures""" global configs, coverage os.chdir(regressionDir) - os.system('rm -rf questa/wkdir') - for d in ["questa/logs", "questa/wkdir", "verilator/logs", "verilator/wkdir", "vcs/logs", "vcs/wkdir"]: + dirs = ["questa/logs", "questa/wkdir", "verilator/logs", "verilator/wkdir", "vcs/logs", "vcs/wkdir"] + for d in dirs: try: + os.system('rm -rf %s' % d) os.mkdir(d) except: pass diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 9c38f54d0..88df8cedd 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -46,7 +46,7 @@ sudo mkdir -p $RISCV # Update and Upgrade tools (see https://itsfoss.com/apt-update-vs-upgrade/) sudo apt update -y sudo apt upgrade -y -sudo apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev libglib2.0-dev python3-pip pkg-config opam z3 zlib1g-dev automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils bc mutt ssmtp cmake gfortran usbutils +sudo apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev libglib2.0-dev python3-pip pkg-config opam z3 zlib1g-dev automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils bc mutt ssmtp gfortran cmake libboost-all-dev # Other python libraries used through the book. sudo -H pip3 install sphinx sphinx_rtd_theme matplotlib scipy scikit-learn adjustText lief markdown pyyaml sudo -H pip3 install riscv_isac # to generate new tests, such as quads with fp_dataset.py diff --git a/bin/wsim b/bin/wsim index 9884992e4..6a3963319 100755 --- a/bin/wsim +++ b/bin/wsim @@ -14,38 +14,16 @@ import argparse import os -def LaunchSim(ElfFile): - # Launch selected simulator + +def LaunchSim(ElfFile, flags): cd = "cd $WALLY/sim/" +args.sim - # ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running - # functional coverage and imply it. + + # per-simulator launch if (args.sim == "questa"): - if (args.lockstep): - prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" - if(int(args.locksteplog) >= 1): EnableLog = 1 - else: EnableLog = 0 - if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) - else: ImperasPlusArgs = "" - if(args.fcov): - CovEnableStr = "1" if int(args.covlog) > 0 else "0"; - if(args.covlog >= 1): EnableLog = 1 - else: EnableLog = 0 - ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; - suffix = "" - else: - CovEnableStr = "" - suffix = "--lockstep" - else: - prefix = "" - ImperasPlusArgs = "" - suffix = "" + # 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 + " " + suffix + " " + ImperasPlusArgs - if (args.coverage): - cmd += " --coverage" - if (args.fcov): - cmd += " --fcov" + 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\"" @@ -58,24 +36,26 @@ def LaunchSim(ElfFile): elif (args.sim == "verilator"): # PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i print(f"Running Verilator on {args.config} {args.testsuite}") - if (args.coverage): - print("Coverage option not available for Verilator") - exit(1) - if (args.gui): - print("GUI option not available for Verilator") - exit(1) 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" - elif (args.coverage): - args.args += "coverage" - cmd = cd + "; ./run_vcs " + args.config + " " + args.testsuite + " " + args.args + 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 +######################## + # Parse arguments parser = argparse.ArgumentParser() parser.add_argument("config", help="Configuration file") @@ -96,6 +76,7 @@ print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim ElfFile="" DirectorMode = 0 ElfList = [] +WALLY = os.environ.get('WALLY') if(os.path.isfile(args.testsuite)): ElfFile = "+ElfFile=" + args.testsuite @@ -111,21 +92,43 @@ elif(os.path.isdir(args.testsuite)): print(ElfList) # Validate arguments -if (args.gui): +if (args.gui or args.coverage or args.fcov or args.lockstep): if args.sim not in ["questa", "vcs"]: - print("GUI option only supported for Questa and VCS") - exit(1) - -if (args.coverage): - if args.sim not in ["questa", "vcs"]: - print("Coverage option only available for Questa and VCS") + print("Option only supported for Questa and VCS") exit(1) if (args.vcd): args.args += " -DMAKEVCD=1" +# if lockstep is enabled, then we need to pass the Imperas lockstep arguments +if(int(args.locksteplog) >= 1): EnableLog = 1 +else: EnableLog = 0 +if (args.lockstep): + prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic" + if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog) + else: ImperasPlusArgs = "" + if(args.fcov): + CovEnableStr = "1" if int(args.covlog) > 0 else "0"; + if(args.covlog >= 1): EnableLog = 1 + else: EnableLog = 0 + ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr; + suffix = "" + else: + CovEnableStr = "" + suffix = "--lockstep" +else: + prefix = "" + ImperasPlusArgs = "" + suffix = "" +flags = suffix + " " + ImperasPlusArgs + +# other flags +if (args.coverage): + flags += " --coverage" +if (args.fcov): + flags += " --fcov" + # create the output sub-directories. -WALLY = os.environ.get('WALLY') regressionDir = WALLY + '/sim/' for d in ["logs", "wkdir", "cov"]: try: @@ -135,7 +138,7 @@ for d in ["logs", "wkdir", "cov"]: if(DirectorMode): for ElfFile in ElfList: - LaunchSim(ElfFile) + LaunchSim(ElfFile, flags) else: - LaunchSim(ElfFile) + LaunchSim(ElfFile, flags) diff --git a/config/derivlist.txt b/config/derivlist.txt index 82aa097fb..56b2ca294 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -811,11 +811,13 @@ deriv f_rv32gc rv32gc D_SUPPORTED 0 ZCD_SUPPORTED 0 ZFH_SUPPORTED 0 +ZCD_SUPPORTED 0 deriv fh_rv32gc rv32gc D_SUPPORTED 0 ZCD_SUPPORTED 0 ZFH_SUPPORTED 1 +ZCD_SUPPORTED 0 deriv fd_rv32gc rv32gc ZFH_SUPPORTED 0 @@ -835,11 +837,13 @@ deriv f_rv64gc rv64gc D_SUPPORTED 0 ZCD_SUPPORTED 0 ZFH_SUPPORTED 0 +ZCD_SUPPORTED 0 deriv fh_rv64gc rv64gc D_SUPPORTED 0 ZCD_SUPPORTED 0 ZFH_SUPPORTED 1 +ZCD_SUPPORTED 0 deriv fd_rv64gc rv64gc ZFH_SUPPORTED 0 diff --git a/sim/vcs/run_vcs b/sim/vcs/run_vcs index 80385f6ba..a9e9c2fca 100755 --- a/sim/vcs/run_vcs +++ b/sim/vcs/run_vcs @@ -1,118 +1,84 @@ -#!/bin/bash -# VCS Compilation for WALLY -# Divya Kohli, Rose Thompson, David Harris 2024 -# Note: VCS produces warning about unsupported Linux Version, but runs successfully +#!/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 -# Color Definitions -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color -# Directories -CFG="${WALLY}/config" -SRC="${WALLY}/src" -TB="${WALLY}/testbench" +import argparse +import os +import subprocess -# Set CONFIG_VARIANT from the first script argument -CONFIG_VARIANT=${1} -# Set TESTSUITE from the second script argument -TESTSUITE=$2 +# 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 -WKDIR="wkdir/${1}_${2}" -COV="cov/${1}_${2}" -LOGS="logs" +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 + "'") -if [ ${TESTSUITE} = "buildroot" ]; then - shift 2 - PLUSARGS="$*" -fi +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" -clean_logs() { - echo -e "${YELLOW}Cleaning up workspace...${NC}" - rm -rf wkdir logs cov -} -clean_simprofile() { - echo -e "${YELLOW}Cleaning up simprofile_dir...${NC}" - rm -rf simprofile_dir* profileReport* -} +os.system("mkdir -p " + wkdir) +os.system("mkdir -p " + covdir) +os.system("mkdir -p " + logdir) -#clean_simprofile -#clean_logs -# Function to create a directory if it does not exist -create_directory() { - local dir=$1 # Local variable for directory name +# 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) - if [ ! -d "$dir" ]; then - mkdir -p "$dir" - if [ $? -eq 0 ]; then - echo "Directory $dir created successfully." - else - echo "Failed to create directory $dir." - exit 1 - fi - else - echo "Directory $dir already exists." - fi -} +# Include directories +INCLUDE_PATH="+incdir+" + cfgdir + "/" + args.config + " +incdir+" + cfgdir + "/deriv/" + args.config + " +incdir+" + cfgdir + "/shared +incdir+$WALLY/tests +incdir+" + tbdir + " +incdir+" + srcdir -# Create or verify WKDIR, COV, and LOGS directories -create_directory "$WKDIR" -create_directory "$COV" -create_directory "$LOGS" +# 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 = "" -# Ensure the working directory exists -if [ ! -d "$WKDIR" ]; then - echo -e "${YELLOW}Directory $WKDIR does not exist. Creating it now...${NC}" - mkdir -p "$WKDIR" && echo -e "${GREEN}Directory $WKDIR created successfully.${NC}" || { - echo -e "${RED}Failed to create directory $WKDIR.${NC}" - exit 1 - } -else - echo -e "${GREEN}Directory $WKDIR already exists.${NC}" -fi +# 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 = "" -# GUI option handling -GUI="" -if [ "$3" = "gui" ]; then - GUI="-gui" -else - GUI="" -fi - -# Collect include directories -INCLUDE_DIRS=$(find ${SRC} -type d | xargs -I {} echo -n "{} ") -INCLUDE_PATH="+incdir+${CFG}/${CONFIG_VARIANT} +incdir+${CFG}/deriv/${CONFIG_VARIANT} +incdir+${CFG}/shared +incdir+../../tests +define+ +incdir+${TB} ${SRC}/cvw.sv +incdir+${SRC}" - -# Prepare RTL files avoiding certain paths -RTL_FILES="$INCLUDE_DIRS $(find ${SRC} -name "*.sv" ! -path "${SRC}/generic/mem/rom1p1r_128x64.sv" ! -path "${SRC}/generic/mem/ram2p1r1wbe_128x64.sv" ! -path "${SRC}/generic/mem/rom1p1r_128x32.sv" ! -path "${SRC}/generic/mem/ram2p1r1wbe_2048x64.sv") ${TB}/testbench.sv $(find ${TB}/common -name "*.sv" ! -path "${TB}/common/wallyTracer.sv")" - -# Simulation and Coverage Commands +# 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 +vcs+vcdpluson -suppress +warn -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse -ntb_opts sensitive_dyn ${INCLUDE_PATH} $RTL_FILES" -SIMV_CMD="./${WKDIR}/$OUTPUT +TEST=${TESTSUITE} ${PLUSARGS}" -COV_FILES="${TB}/coverage/test_pmp_coverage.sv" -COV_OPTIONS="-cm line+cond+branch+fsm+tgl -cm_log ${WKDIR}/coverage.log -cm_dir ${WKDIR}/COVERAGE" -### CODE COVERAGE REPORT in IndividualCovReport in XML format -#COV_RUN="urg -dir ${WKDIR}/COVERAGE.vdb -report IndividualCovReport/${CONFIG_VARIANT}_${TESTSUITE}" -### CODE COVERAGE REPORT in IndividualCovReport in text format -COV_RUN="urg -dir ./${WKDIR}/COVERAGE.vdb -format text -report IndividualCovReport/${CONFIG_VARIANT}_${TESTSUITE}" +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 - -# Clean and run simulation with VCS - -if [ "$3" = "coverage" ]; then - echo -e "${YELLOW}#### Running VCS Simulation with Coverage ####${NC}" - # Code Coverage. - $VCS_CMD -Mdir=${WKDIR} $COV_OPTIONS -o ${WKDIR}/$OUTPUT -Mlib ${WKDIR} -work ${WKDIR} -l "$LOGS/${CONFIG_VARIANT}_${TESTSUITE}.log" - $SIMV_CMD $COV_OPTIONS - $COV_RUN - #cp -rf urgReport $COV - -else - echo -e "${YELLOW}#### Running VCS Simulation ####${NC}" - $VCS_CMD -Mdir=${WKDIR} -o ${WKDIR}/$OUTPUT -work ${WKDIR} -Mlib ${WKDIR} -l "$LOGS/${CONFIG_VARIANT}_${TESTSUITE}.log" - $SIMV_CMD -fi +# 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/src/ebu/ebu.sv b/src/ebu/ebu.sv index 2eec7db58..edf1461bb 100644 --- a/src/ebu/ebu.sv +++ b/src/ebu/ebu.sv @@ -116,7 +116,7 @@ module ebu import cvw::*; #(parameter cvw_t P) ( assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst. assign HTRANS = LSUSelect ? LSUHTRANSOut : IFUSelect ? IFUHTRANSOut: '0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise assign HWRITE = LSUSelect ? LSUHWRITEOut : '0; - assign HPROT = 4'b0011; // not used; see Section 3.7 + assign HPROT = {3'b001, LSUSelect}; // treat as privileged access of either Opcode fetch or Data access assign HMASTLOCK = 1'b0; // no locking supported // data phase muxing. This would be a mux if IFU wrote data. 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-imperas.sv b/testbench/testbench-imperas.sv deleted file mode 100644 index c834483f2..000000000 --- a/testbench/testbench-imperas.sv +++ /dev/null @@ -1,378 +0,0 @@ -/////////////////////////////////////////// -// testbench.sv -// -// Written: David_Harris@hmc.edu 9 January 2021 -// Modified: -// -// Purpose: Wally Testbench and helper modules -// Applies test programs from the riscv-arch-test and Imperas suites -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "config.vh" - - -// This is set from the command line script -// `define USE_IMPERAS_DV - -`ifdef USE_IMPERAS_DV - `include "idv/idv.svh" -`endif - -import cvw::*; - -module testbench; - parameter DEBUG=0; - -`ifdef USE_IMPERAS_DV - import idvPkg::*; - import rvviApiPkg::*; - import idvApiPkg::*; -`endif - - `include "parameter-defs.vh" - - logic clk; - logic reset_ext, reset; - - - logic [P.XLEN-1:0] testadr, testadrNoBase; - string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - logic [31:0] InstrW; - - logic [3:0] dummy; - - logic [P.AHBW-1:0] HRDATAEXT; - logic HREADYEXT, HRESPEXT; - logic HSELEXTSDC; - logic [P.PA_BITS-1:0] HADDR; - logic [P.AHBW-1:0] HWDATA; - logic [P.XLEN/8-1:0] HWSTRB; - logic HWRITE; - logic [2:0] HSIZE; - logic [2:0] HBURST; - logic [3:0] HPROT; - logic [1:0] HTRANS; - logic HMASTLOCK; - logic HCLK, HRESETn; - logic [P.XLEN-1:0] PCW; - logic [31:0] NextInstrE, InstrM; - - string ProgramAddrMapFile, ProgramLabelMapFile; - integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 }; - logic DCacheFlushDone, DCacheFlushStart; - string testName; - string memfilename, testDir, adrstr, elffilename; - - logic [31:0] GPIOIN, GPIOOUT, GPIOEN; - logic UARTSin, UARTSout; - logic SPIIn, SPIOut; - logic [3:0] SPICS; - logic SDCIntr; - - logic HREADY; - logic HSELEXT; - - logic InitializingMemories; - integer ResetCount, ResetThreshold; - logic InReset; - - // Imperas look here. - initial - begin - ResetCount = 0; - ResetThreshold = 2; - InReset = 1; - testadr = 0; - testadrNoBase = 0; - - if ($value$plusargs("testDir=%s", testDir)) begin - memfilename = {testDir, "/ref/ref.elf.memfile"}; - elffilename = {testDir, "/ref/ref.elf"}; - $display($sformatf("%m @ t=%0t: loading testDir %0s", $time, testDir)); - end else begin - $error("Must specify test directory using plusarg testDir"); - end - - if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.RAM); - else $error("Imperas test bench requires BUS."); - - ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"}; - ProgramLabelMapFile = {testDir, "/ref/ref.elf.objdump.lab"}; - - // 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); - $display("Read memfile %s", memfilename); - - end - -`ifdef USE_IMPERAS_DV - - rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); - wallyTracer #(P) wallyTracer(rvvi); - - trace2log idv_trace2log(rvvi); - trace2cov idv_trace2cov(rvvi); - - // enabling of comparison types - trace2api #(.CMP_PC (1), - .CMP_INS (1), - .CMP_GPR (1), - .CMP_FPR (1), - .CMP_VR (0), - .CMP_CSR (1) - ) idv_trace2api(rvvi); - - initial begin - - IDV_MAX_ERRORS = 3; - - // Initialize REF (do this before initializing the DUT) - if (!rvviVersionCheck(RVVI_API_VERSION)) begin - $display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION)); - $fatal; - end - - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); - void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC")); - void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56)); - void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6)); - - if (!rvviRefInit(elffilename)) begin - $display($sformatf("%m @ t=%0t: rvviRefInit failed", $time)); - $fatal; - end - - // Volatile CSRs - void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE - void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE - void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET - void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET - void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME - - // cannot predict this register due to latency between - // pending and taken - void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP - void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP - - // Privileges for PMA are set in the imperas.ic - // volatile (IO) regions are defined here - // only real ROM/RAM areas are BOOTROM and UNCORE_RAM - if (P.CLINT_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE))); - end - if (P.GPIO_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE))); - end - if (P.UART_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE))); - end - if (P.PLIC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE))); - end - if (P.SDC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); - end - if (P.SPI_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE))); - end - - if(P.XLEN==32) begin - void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH - void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH - void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH - void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH - end - - void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!! - - end - - always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1])); - always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5])); - - final begin - void'(rvviRefShutdown()); - end - -`endif - - flopenr #(P.XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); - flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, InstrM, InstrW); - - // check assertions for a legal configuration - riscvassertions #(P) riscvassertions(); - - - // instantiate device to be tested - assign GPIOIN = 0; - assign UARTSin = 1; - - if(P.EXT_MEM_SUPPORTED) begin - ram_ahb #(.BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) - ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), - .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, - .HWSTRB); - end else begin - assign HREADYEXT = 1; - assign HRESPEXT = 0; - assign HRDATAEXT = 0; - end - - if(P.SDC_SUPPORTED) begin : sdcard - // *** fix later -/* -----\/----- EXCLUDED -----\/----- - sdModel sdcard - (.sdClk(SDCCLK), - .cmd(SDCCmd), - .dat(SDCDat)); - - assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz; - assign SDCCmdIn = SDCCmd; - assign SDCDatIn = SDCDat; - -----/\----- EXCLUDED -----/\----- */ - assign SDCIntr = 0; - end else begin - assign SDCIntr = 0; - end - - wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC, - .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, - .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, - .UARTSin, .UARTSout, .SDCIntr, .SPICS, .SPIOut, .SPIIn); - - // Track names of instructions - instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, - dut.core.ifu.InstrRawF[31:0], - dut.core.ifu.InstrD, dut.core.ifu.InstrE, - InstrM, InstrW, - InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); - - // initialize tests - - // generate clock to sequence tests - always - begin - clk = 1; # 5; clk = 0; # 5; - // if ($time % 100000 == 0) $display("Time is %0t", $time); - end - - // check results - assign reset_ext = InReset; - - always @(negedge clk) - begin - InitializingMemories = 0; - if(InReset == 1) begin - // once the test inidicates it's done we need to immediately hold reset for a number of cycles. - if(ResetCount < ResetThreshold) ResetCount = ResetCount + 1; - else begin // hit reset threshold so we remove reset. - InReset = 0; - ResetCount = 0; - end - end - end // always @ (negedge clk) - - - // track the current function or global label - if (DEBUG == 1) begin : FunctionName - FunctionName #(P) FunctionName(.reset(reset), - .clk(clk), - .ProgramAddrMapFile(ProgramAddrMapFile), - .ProgramLabelMapFile(ProgramLabelMapFile)); - end - - // Duplicate copy of pipeline registers that are optimized out of some configurations - mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE); - flopenr #(32) InstrMReg(clk, reset, ~dut.core.ifu.StallM, NextInstrE, InstrM); - - // Termination condition - // terminate on a specific ECALL after li x3,1 for old Imperas tests, *** remove this when old imperas tests are removed - // or sw gp,-56(t0) for new Imperas tests - // or sd gp, -56(t0) - // or on a jump to self infinite loop (6f) for RISC-V Arch tests - logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls - if (P.ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; - else assign ecf = 0; - assign DCacheFlushStart = ecf & - (dut.core.ieu.dp.regf.rf[3] == 1 | - (dut.core.ieu.dp.regf.we3 & - dut.core.ieu.dp.regf.a3 == 3 & - dut.core.ieu.dp.regf.wd3 == 1)) | - ((InstrM == 32'h6f | InstrM == 32'hfc32a423 | InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) | - ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); - - DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), - .start(DCacheFlushStart), - .done(DCacheFlushDone)); - - // initialize the branch predictor - if (P.BPRED_SUPPORTED == 1) - begin - genvar adrindex; - - // Initializing all zeroes into the branch predictor memory. - for(adrindex = 0; adrindex < 1024; adrindex++) begin - initial begin - force dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0; - force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0; - #1; - release dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex]; - release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex]; - end - end - end - - watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck - -endmodule - - -/* verilator lint_on STMTDLY */ -/* verilator lint_on WIDTH */ - - -task automatic updateProgramAddrLabelArray; - input string ProgramAddrMapFile, ProgramLabelMapFile; - inout integer ProgramAddrLabelArray [string]; - // Gets the memory location of begin_signature - integer ProgramLabelMapFP, ProgramAddrMapFP; - ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); - ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r"); - - if (ProgramLabelMapFP & ProgramAddrMapFP) begin // check we found both files - while (!$feof(ProgramLabelMapFP)) begin - string label, adrstr; - integer returncode; - returncode = $fscanf(ProgramLabelMapFP, "%s\n", label); - returncode = $fscanf(ProgramAddrMapFP, "%s\n", adrstr); - if (ProgramAddrLabelArray.exists(label)) - ProgramAddrLabelArray[label] = adrstr.atohex(); - end - end - $fclose(ProgramLabelMapFP); - $fclose(ProgramAddrMapFP); -endtask - diff --git a/testbench/testbench.sv b/testbench/testbench.sv index e1c39a45e..f32f0b879 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -125,10 +125,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 = '{}; @@ -638,7 +637,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 diff --git a/testbench/testbench_fp.sv b/testbench/testbench_fp.sv index 7287e6962..5479e0deb 100644 --- a/testbench/testbench_fp.sv +++ b/testbench/testbench_fp.sv @@ -66,6 +66,7 @@ module testbench_fp; logic [P.FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad logic [P.FLEN-1:0] FpRes, FpCmpRes; // Results from each unit logic [P.XLEN-1:0] IntRes, CmpRes; // Results from each unit + logic [P.Q_LEN-1:0] FpResExtended; // FpRes extended to same length as Ans/Res logic [4:0] FmaFlg, CvtFlg, DivFlg; // Outputed flags logic [4:0] CmpFlg; // Outputed flags logic AnsNaN, ResNaN, NaNGood; @@ -820,13 +821,14 @@ module testbench_fp; end always_comb begin + FpResExtended = {{(P.Q_LEN-P.FLEN){1'b1}}, FpRes}; // select the result to check case (UnitVal) - `FMAUNIT: Res = FpRes; - `DIVUNIT: Res = FpRes; - `CMPUNIT: Res = {{(FLEN > XLEN ? FLEN-XLEN : XLEN-FLEN){1'b0}}, CmpRes}; - `CVTINTUNIT: if (WriteIntVal) Res = {{(FLEN > XLEN ? FLEN-XLEN : XLEN-FLEN){1'b0}}, IntRes}; else Res = FpRes; - `CVTFPUNIT: Res = FpRes; + `FMAUNIT: Res = FpResExtended; + `DIVUNIT: Res = FpResExtended; + `CMPUNIT: Res = {{(Q_LEN-XLEN){1'b0}}, CmpRes}; + `CVTINTUNIT: if (WriteIntVal) Res = {{(Q_LEN-XLEN){1'b0}}, IntRes}; else Res = FpResExtended; + `CVTFPUNIT: Res = FpResExtended; endcase // select the flag to check @@ -965,7 +967,7 @@ module testbench_fp; /////////////////////////////////////////////////////////////////////////////////////////////// // check if result is correct - assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx)); + assign ResMatch = ((Res[P.FLEN-1:0] === Ans[P.FLEN-1:0]) | NaNGood | (NaNGood === 1'bx)); assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx)); assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL); assign FMAop = (OpCtrlVal == `FMAUNIT); @@ -987,7 +989,7 @@ module testbench_fp; // increment the test TestNum += 1; // clear the vectors - for(int i=0; i quad - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = TestVector[8+P.Q_LEN+P.XLEN-1:8+(P.Q_LEN)]; Ans = TestVector[8+(P.Q_LEN-1):8]; end 2'b10: begin // int -> quad // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = {{P.XLEN-32{TestVector[8+P.Q_LEN+32-1]}}, TestVector[8+P.Q_LEN+32-1:8+(P.Q_LEN)]}; Ans = TestVector[8+(P.Q_LEN-1):8]; end 2'b01: begin // quad -> long X = {TestVector[8+P.XLEN+P.Q_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.FLEN > 64 ? P.FLEN-64 : 0){1'b0}}, TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; end 2'b00: begin // quad -> int X = {TestVector[8+32+P.Q_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.FLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}},TestVector[8+(32-1):8]}; end endcase end @@ -1295,25 +1299,25 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( // {Int->Fp?, is the integer a long} casez ({OpCtrl[2:1]}) 2'b11: begin // long -> double - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = TestVector[8+P.D_LEN+P.XLEN-1:8+(P.D_LEN)]; - Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; + Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; end 2'b10: begin // int -> double // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = {{P.XLEN-32{TestVector[8+P.D_LEN+32-1]}}, TestVector[8+P.D_LEN+32-1:8+(P.D_LEN)]}; - Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; + Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; end 2'b01: begin // double -> long - X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+P.XLEN+P.D_LEN-1:8+(P.XLEN)]}; + X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+P.XLEN+P.D_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.FLEN-64){1'b0}}, TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; end 2'b00: begin // double -> int - X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+32+P.D_LEN-1:8+(32)]}; + X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+32+P.D_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.FLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + Ans = {{P.Q_LEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; end endcase end @@ -1321,25 +1325,25 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( // {is the integer a long, is the opperation to an integer} casez ({OpCtrl[2:1]}) 2'b11: begin // long -> single - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = TestVector[8+P.S_LEN+P.XLEN-1:8+(P.S_LEN)]; - Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; + Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; end 2'b10: begin // int -> single // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = {{P.XLEN-32{TestVector[8+P.S_LEN+32-1]}}, TestVector[8+P.S_LEN+32-1:8+(P.S_LEN)]}; - Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; + Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; end 2'b01: begin // single -> long - X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+P.XLEN+P.S_LEN-1:8+(P.XLEN)]}; + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.XLEN+P.S_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.FLEN > 64 ? P.FLEN-64 : 0){1'b0}}, TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; end 2'b00: begin // single -> int - X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+32+P.S_LEN-1:8+(32)]}; + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+32+P.S_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.FLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}},TestVector[8+(32-1):8]}; end endcase end @@ -1347,25 +1351,25 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( // {is the integer a long, is the opperation to an integer} casez ({OpCtrl[2:1]}) 2'b11: begin // long -> half - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = TestVector[8+P.H_LEN+P.XLEN-1:8+(P.H_LEN)]; - Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; + Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; end 2'b10: begin // int -> half // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.FLEN{1'bx}}; + X = {P.Q_LEN{1'bx}}; SrcA = {{P.XLEN-32{TestVector[8+P.H_LEN+32-1]}}, TestVector[8+P.H_LEN+32-1:8+(P.H_LEN)]}; - Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; + Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; end 2'b01: begin // half -> long - X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+P.XLEN+P.H_LEN-1:8+(P.XLEN)]}; + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.XLEN+P.H_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.FLEN > 64 ? P.FLEN-64 : 0){1'b0}}, TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; end 2'b00: begin // half -> int - X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+32+P.H_LEN-1:8+(32)]}; + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+32+P.H_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.FLEN-32{TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; + Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; end endcase end diff --git a/tests/riscof/spike/spike_rv64gc_isa.yaml b/tests/riscof/spike/spike_rv64gc_isa.yaml index 3b186b685..0a939e001 100644 --- a/tests/riscof/spike/spike_rv64gc_isa.yaml +++ b/tests/riscof/spike/spike_rv64gc_isa.yaml @@ -1,12 +1,14 @@ hart_ids: [0] hart0: # ISA: RV64IMAFDQCSUZicboz_Zicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh - ISA: RV64IMAFDQCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh + ISA: RV64IMAFDCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh +# ISA: RV64IMAFDQCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh physical_addr_sz: 56 User_Spec_Version: '2.3' supported_xlen: [64] misa: - reset-val: 0x800000000015112D + reset-val: 0x800000000014112D +# reset-val: 0x800000000015112D rv32: accessible: false rv64: diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/README.md b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/README.md index c624e624b..bee5c000d 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/README.md +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/README.md @@ -22,7 +22,12 @@ riscv-ctg-> This folder consists of the CTG tool which is responsible for genera riscof -> The riscof directory in Wally was changed to include some Quad precision template files for compilation. Along with modification of scripts and yaml files to support FLEN=128 - +TO DO: + Debug why fadd.q_b1 doesn't match Sail vs. Spike + Run the q test on Wally RTL + Make more tests from the working datasets + Get other datasets working by using softfloat to do quad math + Push changes back to riscv-ctg and riscv-isac and remove them from wally-riscv-arch/tsts/riscv-test-suite/rv64i_m/Q Start by installing riscv-ctg via the following commands :