Merge branch 'main' of https://github.com/openhwgroup/cvw into installation

This commit is contained in:
Jordan Carlin 2024-07-18 21:36:00 -07:00
commit 5661dc4a03
16 changed files with 319 additions and 282 deletions

7
.gitignore vendored
View File

@ -193,13 +193,18 @@ config/deriv
docs/docker/buildroot-config-src
docs/docker/testvector-generation
sim/questa/cov
sim/questa/covhtmlreport/
sim/covhtmlreport/
sim/questa/logs
sim/questa/wkdir
sim/questa/ucdb
sim/questa/fcov
sim/questa/fcov_logs
sim/questa/fcov_ucdb
sim/verilator/logs
sim/verilator/wkdir
sim/vcs/logs
sim/vcs/wkdir
sim/vcs/ucdb
benchmarks/coremark/coremark_results.csv
fpga/zsbl/OBJ/*
fpga/zsbl/bin/*

View File

@ -25,90 +25,6 @@ verify:
cd ${SIM}/sim; ./sim-testfloat-batch all
make imperasdv
imperasdv:
iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m
iter-elf.bash --search ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m
imperasdv_cov:
touch ${SIM}/seed0.txt
echo "0" > ${SIM}/seed0.txt
# /opt/riscv/ImperasDV-OpenHW/scripts/cvw/run-elf-cov.bash --verbose --seed 0 --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m
# /opt/riscv/ImperasDV-OpenHW/scripts/cvw/run-elf-cov.bash --elf ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/dut/my.elf --seed ${SIM}/seed0.txt --coverdb ${SIM}/cov/rv64gc_arch64i.ucdb --verbose
# /opt/riscv/ImperasDV-OpenHW/scripts/cvw/run-elf-cov.bash --elf ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/dut/my.elf --seed ${SIM}/seed0.txt --coverdb ${SIM}/questa/riscv.ucdb --verbose
run-elf-cov.bash --elf ${WALLY}/tests/riscvdv/asm_test/riscv_arithmetic_basic_test_0.elf --seed ${SIM}/questa/seed0.txt --coverdb ${SIM}/questa/riscv.ucdb --verbose
vcover report -details -html ${SIM}/questa/riscv.ucdb
funcovreg:
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m --cover
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/I --cover
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege --cover
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/Q --cover
rm -f ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/*/src/*/dut/my.elf
iter-elf.bash --search ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/I --cover
vcover report -details -html ${SIM}/questa/riscv.ucdb
# test_name=riscv_arithmetic_basic_test
riscvdv:
${RISCV}/riscv-python/bin/python3 ${WALLY}/addins/riscv-dv/run.py --test ${test_name} --target rv64gc --output tests/riscvdv --iterations 1 -si questa --iss spike --verbose --cov --seed 0 --steps gen,gcc_compile >> ${SIM}/questa/functcov_logs/${test_name}.log 2>&1
# ${RISCV}/riscv-python/bin/python3 ${WALLY}/addins/riscv-dv/run.py --test ${test_name} --target rv64gc --output tests/riscvdv --iterations 1 -si questa --iss spike --verbose --cov --seed 0 --steps gcc_compile >> ${SIM}/questa/functcov_logs/${test_name}.log 2>&1
# ${RISCV}/riscv-python/bin/python3 ${WALLY}/addins/riscv-dv/run.py --test ${test_name} --target rv64gc --output tests/riscvdv --iterations 1 -si questa --iss spike --verbose --cov --seed 0 --steps iss_sim >> ${SIM}/questa/functcov_logs/${test_name}.log 2>&1
# run-elf.bash --seed ${SIM}/questa/seed0.txt --verbose --elf ${WALLY}/tests/riscvdv/asm_test/${test_name}_0.o >> ${SIM}/questa/functcov_logs/${test_name}.log 2>&1
#run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/riscv.ucdb --elf ${WALLY}/tests/riscvdv/asm_test/${test_name}_0.o >> ${SIM}/questa/functcov_logs/${test_name}.log 2>&1
#cp ${SIM}/questa/riscv.ucdb ${SIM}/questa/functcov_ucdbs/${test_name}.ucdb
riscvdv_functcov:
mkdir -p ${SIM}/questa/functcov_logs
mkdir -p ${SIM}/questa/functcov_ucdbs
cd ${SIM}/questa/functcov_logs && rm -rf *
cd ${SIM}/questa/functcov_ucdbs && rm -rf *
make riscvdv test_name=riscv_arithmetic_basic_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_amo_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_ebreak_debug_mode_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_ebreak_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_floating_point_arithmetic_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_floating_point_mmu_stress_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_floating_point_rand_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_full_interrupt_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_hint_instr_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_illegal_instr_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_invalid_csr_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_jump_stress_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_loop_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_machine_mode_rand_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_mmu_stress_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_no_fence_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_non_compressed_instr_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_pmp_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_privileged_mode_rand_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_rand_instr_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_rand_jump_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_sfence_exception_test >> ${SIM}/questa/functcov.log 2>&1
make riscvdv test_name=riscv_unaligned_load_store_test >> ${SIM}/questa/functcov.log 2>&1
combine_functcov:
mkdir -p ${SIM}/questa/functcov
mkdir -p ${SIM}/questa/functcov_logs
cd ${SIM}/questa/functcov && rm -rf *
run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/functcov/add.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf >> ${SIM}/questa/functcov_logs/add.log 2>&1
run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/functcov/and.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf >> ${SIM}/questa/functcov_logs/add.log 2>&1
run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/functcov/ori.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-ori.elf >> ${SIM}/questa/functcov_logs/add.log 2>&1
vcover merge ${SIM}/questa/functcov/functcov.ucdb ${SIM}/questa/functcov/*.ucdb ${SIM}/questa/functcov_ucdbs/* -suppress 6854 -64
# vcover merge ${SIM}/questa/functcov/functcov.ucdb ${SIM}/questa/functcov_ucdbs/* -suppress 6854 -64
vcover report -details -html ${SIM}/questa/functcov/functcov.ucdb
vcover report ${SIM}/questa/functcov/functcov.ucdb -details -cvg > ${SIM}/questa/functcov/functcov.log
vcover report ${SIM}/questa/functcov/functcov.ucdb -testdetails -cvg > ${SIM}/questa/functcov/functcov.testdetails.log
# vcover report ${SIM}/questa/functcov/functcov.ucdb -details -cvg -below 100 | egrep "Coverpoint|Covergroup|Cross" | grep -v Metric > ${SIM}/questa/functcov/functcov.ucdb.summary.log
vcover report ${SIM}/questa/functcov/functcov.ucdb -details -cvg | egrep "Coverpoint|Covergroup|Cross|TYPE" > ${SIM}/questa/functcov/functcov.summary.log
grep "Total Coverage By Instance" ${SIM}/questa/functcov/functcov.ucdb.log
remove_functcov_artifacts:
rm ${SIM}/questa/riscv.ucdb ${SIM}/questa/functcov.log covhtmlreport/ ${SIM}/questa/functcov_logs/ ${SIM}/questa/functcov_ucdbs/ ${SIM}/questa/functcov/ -rf
collect_functcov: remove_functcov_artifacts riscvdv_functcov combine_functcov
benchmarks:
make coremark
make embench

View File

@ -48,6 +48,10 @@ def run_test_case(elf):
if search_log_for_mismatches(logfile):
print(f"{bcolors.OKGREEN}%s: Success{bcolors.ENDC}" % (cmd))
return 0
elif("WALLY-cbom-01" in elf):
# Remove this when CBO instructions are modeled in ImperasDV
print(f"{bcolors.OKCYAN}%s: Expected mismatch because ImperasDV does not yet model cache for CBO instructions {bcolors.ENDC}" % (cmd))
return 0
else:
print(f"{bcolors.FAIL}%s: Failures detected in output{bcolors.ENDC}" % (cmd))
print(" Check %s" % logfile)

View File

@ -320,7 +320,7 @@ coveragesim = "questa" # Questa is required for code/functional coverage
#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
ccov = '--ccov' in sys.argv
fp = '--fp' in sys.argv
nightly = '--nightly' in sys.argv
testfloat = '--testfloat' in sys.argv
@ -334,8 +334,8 @@ else:
nightMode = ""
sims = [defaultsim]
if (coverage): # only run RV64GC tests in coverage mode
coverStr = '--coverage'
if (ccov): # only run RV64GC tests in coverage mode
coverStr = '--ccov'
else:
coverStr = ''
@ -357,7 +357,7 @@ if (buildroot):
# 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
if (ccov): # only run RV64GC tests on Questa in code coverage mode
addTests(tests64gc_nofp, "questa")
if (fp):
addTests(tests64gc_fp, "questa")
@ -385,7 +385,7 @@ if (nightly):
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,
cmd="iterelf " + WALLY + "/tests/riscof/work/wally-riscv-arch-test/rv64i_m > " + sim_log,
grepstr="SUCCESS! All tests ran without failures",
grepfile = sim_log)
configs.append(tc)
@ -393,7 +393,7 @@ if (nightly):
# testfloat tests
if (testfloat): # for testfloat alone, just run testfloat tests
configs = []
if (testfloat or nightly): # for nightly, run testfloat along with othres
if (testfloat or nightly): # for nightly, run testfloat along with others
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:
@ -458,7 +458,7 @@ if (testfloat or nightly): # for nightly, run testfloat along with othres
def main():
"""Run the tests and count the failures"""
global configs, coverage
global configs, ccov
os.chdir(regressionDir)
dirs = ["questa/logs", "questa/wkdir", "verilator/logs", "verilator/wkdir", "vcs/logs", "vcs/wkdir"]
for d in dirs:
@ -472,7 +472,7 @@ def main():
os.chdir(regressionDir)
os.system('./make-tests.sh | tee ./logs/make-tests.log')
elif '--coverage' in sys.argv:
elif '--ccov' in sys.argv:
TIMEOUT_DUR = 20*60 # seconds
os.system('rm -f questa/cov/*.ucdb')
elif '--nightly' in sys.argv:
@ -497,8 +497,8 @@ def main():
print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (config.variant, config.name, TIMEOUT_DUR))
# Coverage report
if coverage:
os.system('make QuestaCoverage')
if ccov:
os.system('make QuestaCodeCoverage')
# Count the number of failures
if num_fail:
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)

View File

@ -21,13 +21,13 @@ import os
# Parse arguments
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("testsuite", help="Test suite or path to .elf file")
parser.add_argument("--elf", "-e", help="ELF File name; use if name does not end in .elf", 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")
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("--ccov", "-c", help="Code Coverage", action="store_true")
parser.add_argument("--fcov", "-f", help="Functional Coverage", action="store_true")
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true")
parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true")
@ -36,14 +36,27 @@ parser.add_argument("--covlog", "-d", help="Log coverage after n instructions.",
args = parser.parse_args()
print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'")
ElfFile=""
DirectorMode = 0
WALLY = os.environ.get('WALLY')
if(os.path.isfile(args.elf)):
ElfFile = "+ElfFile=" + os.path.abspath(args.elf)
elif (args.elf != ""):
print("ELF file not found: " + args.elf)
exit(1)
if(args.testsuite.endswith('.elf') and args.elf == ""): # No --elf argument; check if testsuite has a .elf extension and use that instead
if (os.path.isfile(args.testsuite)):
ElfFile = "+ElfFile=" + os.path.abspath(args.testsuite)
if ('/' in args.testsuite):
args.testsuite=args.testsuite.rsplit('/', 1)[1] # strip off path if present
else:
print("ELF file not found: " + args.testsuite)
exit(1)
# Validate arguments
if (args.gui or args.coverage or args.fcov or args.lockstep):
if (args.gui or args.ccov or args.fcov or args.lockstep):
if args.sim not in ["questa", "vcs"]:
print("Option only supported for Questa and VCS")
exit(1)
@ -74,14 +87,14 @@ else:
flags = suffix + " " + ImperasPlusArgs
# other flags
if (args.coverage):
flags += " --coverage"
if (args.ccov):
flags += " --ccov"
if (args.fcov):
flags += " --fcov"
# create the output sub-directories.
regressionDir = WALLY + '/sim/'
for d in ["logs", "wkdir", "cov"]:
for d in ["logs", "wkdir", "cov", "ucdb", "fcov", "fcov_ucdb"]:
try:
os.mkdir(regressionDir+args.sim+"/"+d)
except:

View File

@ -31,7 +31,9 @@
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcsu";
riscv,isa-extensions = "imafdc", "sstc", "svinval", "svnapot", "svpbmt", "zba", "zbb", "zbc", "zbs", "zicbom", "zicbop", "zicbopz", "zicntr", "zicsr", "zifencei", "zihpm";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "sstc", "svinval", "svnapot", "svpbmt", "zba", "zbb", "zbc", "zbs", "zicbom", "zicbop", "zicbopz", "zicntr", "zicsr", "zifencei", "zihpm";
riscv,cbom-block-size = <64>;
mmu-type = "riscv,sv48";
interrupt-controller {

View File

@ -1,44 +1,113 @@
# David_Harris@hmc.edu 15 July 2024
# Simulation Makefile for CORE-V-Wally
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
SIM = ${WALLY}/sim
all: riscoftests memfiles coveragetests deriv
# *** Build old tests/imperas-riscv-tests for now;
# Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test
# DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired
#make -C ../tests/imperas-riscv-tests --jobs
#make -C ../tests/imperas-riscv-tests XLEN=64 --jobs
# Only compile Imperas tests if they are installed locally.
# They are usually a symlink to $RISCV/imperas-riscv-tests and only
# get compiled there manually during installation
#make -C ../addins/imperas-riscv-tests
#make -C ../addins/imperas-riscv-tests XLEN=64
#cd ../addins/imperas-riscv-tests; elf2hex.sh
#cd ../addins/imperas-riscv-tests; extractFunctionRadix.sh work/*/*/*.elf.objdump
# Link Linux test vectors
#cd ../tests/linux-testgen/linux-testvectors/;./tvLinker.sh
wally-riscv-arch-test: wallyriscoftests memfiles
QuestaCoverage: questa/cov/rv64gc_arch64i.ucdb
#iter-elf.bash --cover --search ../tests/coverage
vcover merge -out questa/cov/cov.ucdb questa/cov/rv64gc_arch64i.ucdb questa/cov/rv64gc*.ucdb -logfile questa/cov/log
# vcover merge -out questa/cov/cov.ucdb questa/cov/rv64gc_arch64i.ucdb questa/cov/rv64gc*.ucdb questa/cov/buildroot_buildroot.ucdb riscv.ucdb -logfile questa/cov/log
vcover report -details questa/cov/cov.ucdb > questa/cov/rv64gc_coverage_details.rpt
vcover report questa/cov/cov.ucdb -details -instance=/core/ebu. > questa/cov/rv64gc_coverage_ebu.rpt
vcover report questa/cov/cov.ucdb -details -instance=/core/priv. > questa/cov/rv64gc_coverage_priv.rpt
vcover report questa/cov/cov.ucdb -details -instance=/core/ifu. > questa/cov/rv64gc_coverage_ifu.rpt
vcover report questa/cov/cov.ucdb -details -instance=/core/lsu. > questa/cov/rv64gc_coverage_lsu.rpt
vcover report questa/cov/cov.ucdb -details -instance=/core/fpu. > questa/cov/rv64gc_coverage_fpu.rpt
vcover report questa/cov/cov.ucdb -details -instance=/core/ieu. > questa/cov/rv64gc_coverage_ieu.rpt
vcover report questa/cov/cov.ucdb -below 100 -details -instance=/core/ebu. > questa/cov/rv64gc_uncovered_ebu.rpt
vcover report questa/cov/cov.ucdb -below 100 -details -instance=/core/priv. > questa/cov/rv64gc_uncovered_priv.rpt
vcover report questa/cov/cov.ucdb -below 100 -details -instance=/core/ifu. > questa/cov/rv64gc_uncovered_ifu.rpt
vcover report questa/cov/cov.ucdb -below 100 -details -instance=/core/lsu. > questa/cov/rv64gc_uncovered_lsu.rpt
vcover report questa/cov/cov.ucdb -below 100 -details -instance=/core/fpu. > questa/cov/rv64gc_uncovered_fpu.rpt
vcover report questa/cov/cov.ucdb -below 100 -details -instance=/core/ieu. > questa/cov/rv64gc_uncovered_ieu.rpt
vcover report -hierarchical questa/cov/cov.ucdb > questa/cov/rv64gc_coverage_hierarchical.rpt
vcover report -below 100 -hierarchical questa/cov/cov.ucdb > questa/cov/rv64gc_uncovered_hierarchical.rpt
# vcover report -below 100 questa/cov/cov.ucdb > questa/cov/rv64gc_coverage.rpt
# vcover report -recursive questa/cov/cov.ucdb > questa/cov/rv64gc_recursive.rpt
vcover report -details -threshH 100 -html questa/cov/cov.ucdb
QuestaCodeCoverage: questa/ucdb/rv64gc_arch64i.ucdb
vcover merge -out questa/ucdb/cov.ucdb questa/ucdb/rv64gc_arch64i.ucdb questa/ucdb/rv64gc*.ucdb -logfile questa/cov/log
# vcover merge -out questa/ucdb/cov.ucdb questa/ucdb/rv64gc_arch64i.ucdb questa/ucdb/rv64gc*.ucdb questa/ucdb/buildroot_buildroot.ucdb riscv.ucdb -logfile questa/cov/log
vcover report -details questa/ucdb/cov.ucdb > questa/cov/rv64gc_coverage_details.rpt
vcover report questa/ucdb/cov.ucdb -details -instance=/core/ebu. > questa/cov/rv64gc_coverage_ebu.rpt
vcover report questa/ucdb/cov.ucdb -details -instance=/core/priv. > questa/cov/rv64gc_coverage_priv.rpt
vcover report questa/ucdb/cov.ucdb -details -instance=/core/ifu. > questa/cov/rv64gc_coverage_ifu.rpt
vcover report questa/ucdb/cov.ucdb -details -instance=/core/lsu. > questa/cov/rv64gc_coverage_lsu.rpt
vcover report questa/ucdb/cov.ucdb -details -instance=/core/fpu. > questa/cov/rv64gc_coverage_fpu.rpt
vcover report questa/ucdb/cov.ucdb -details -instance=/core/ieu. > questa/cov/rv64gc_coverage_ieu.rpt
vcover report questa/ucdb/cov.ucdb -below 100 -details -instance=/core/ebu. > questa/cov/rv64gc_uncovered_ebu.rpt
vcover report questa/ucdb/cov.ucdb -below 100 -details -instance=/core/priv. > questa/cov/rv64gc_uncovered_priv.rpt
vcover report questa/ucdb/cov.ucdb -below 100 -details -instance=/core/ifu. > questa/cov/rv64gc_uncovered_ifu.rpt
vcover report questa/ucdb/cov.ucdb -below 100 -details -instance=/core/lsu. > questa/cov/rv64gc_uncovered_lsu.rpt
vcover report questa/ucdb/cov.ucdb -below 100 -details -instance=/core/fpu. > questa/cov/rv64gc_uncovered_fpu.rpt
vcover report questa/ucdb/cov.ucdb -below 100 -details -instance=/core/ieu. > questa/cov/rv64gc_uncovered_ieu.rpt
vcover report -hierarchical questa/ucdb/cov.ucdb > questa/cov/rv64gc_coverage_hierarchical.rpt
vcover report -below 100 -hierarchical questa/ucdb/cov.ucdb > questa/cov/rv64gc_uncovered_hierarchical.rpt
# vcover report -below 100 questa/ucdb/cov.ucdb > questa/cov/rv64gc_coverage.rpt
# vcover report -recursive questa/ucdb/cov.ucdb > questa/cov/rv64gc_recursive.rpt
vcover report -details -threshH 100 -html questa/ucdb/cov.ucdb
imperasdv_cov:
touch ${SIM}/seed0.txt
echo "0" > ${SIM}/seed0.txt
# /opt/riscv/ImperasDV-OpenHW/scripts/cvw/run-elf-cov.bash --verbose --seed 0 --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m
# /opt/riscv/ImperasDV-OpenHW/scripts/cvw/run-elf-cov.bash --elf ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/dut/my.elf --seed ${SIM}/seed0.txt --coverdb ${SIM}/cov/rv64gc_arch64i.ucdb --verbose
# /opt/riscv/ImperasDV-OpenHW/scripts/cvw/run-elf-cov.bash --elf ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/I/src/add-01.S/dut/my.elf --seed ${SIM}/seed0.txt --coverdb ${SIM}/questa/riscv.ucdb --verbose
run-elf-cov.bash --elf ${WALLY}/tests/riscvdv/asm_test/riscv_arithmetic_basic_test_0.elf --seed ${SIM}/questa/seed0.txt --coverdb ${SIM}/questa/riscv.ucdb --verbose
vcover report -details -html ${SIM}/questa/riscv.ucdb
funcovreg:
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m --cover
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/I --cover
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege --cover
#iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/Q --cover
rm -f ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/*/src/*/dut/my.elf
iter-elf.bash --search ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/I --cover
vcover report -details -html ${SIM}/questa/riscv.ucdb
riscvdv:
python3 ${WALLY}/addins/riscv-dv/run.py --test ${test_name} --target rv64gc --output tests/riscvdv --iterations 1 -si questa --iss spike --verbose --cov --seed 0 --steps gen,gcc_compile >> ${SIM}/questa/fcov_logs/${test_name}.log 2>&1
# python3 ${WALLY}/addins/riscv-dv/run.py --test ${test_name} --target rv64gc --output tests/riscvdv --iterations 1 -si questa --iss spike --verbose --cov --seed 0 --steps gcc_compile >> ${SIM}/questa/fcov_logs/${test_name}.log 2>&1
# python3 ${WALLY}/addins/riscv-dv/run.py --test ${test_name} --target rv64gc --output tests/riscvdv --iterations 1 -si questa --iss spike --verbose --cov --seed 0 --steps iss_sim >> ${SIM}/questa/fcov_logs/${test_name}.log 2>&1
# run-elf.bash --seed ${SIM}/questa/seed0.txt --verbose --elf ${WALLY}/tests/riscvdv/asm_test/${test_name}_0.o >> ${SIM}/questa/fcov_logs/${test_name}.log 2>&1
riscvdv_functcov:
mkdir -p ${SIM}/questa/fcov_logs
mkdir -p ${SIM}/questa/fcov_ucdbs
cd ${SIM}/questa/fcov_logs && rm -rf *
cd ${SIM}/questa/fcov_ucdbs && rm -rf *
make riscvdv test_name=riscv_arithmetic_basic_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_amo_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_ebreak_debug_mode_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_ebreak_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_floating_point_arithmetic_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_floating_point_mmu_stress_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_floating_point_rand_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_full_interrupt_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_hint_instr_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_illegal_instr_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_invalid_csr_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_jump_stress_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_loop_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_machine_mode_rand_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_mmu_stress_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_no_fence_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_non_compressed_instr_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_pmp_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_privileged_mode_rand_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_rand_instr_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_rand_jump_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_sfence_exception_test >> ${SIM}/questa/fcov.log 2>&1
make riscvdv test_name=riscv_unaligned_load_store_test >> ${SIM}/questa/fcov.log 2>&1
combine_functcov:
mkdir -p ${SIM}/questa/fcov
mkdir -p ${SIM}/questa/fcov_logs
cd ${SIM}/questa/fcov && rm -rf *
cd ${SIM}/questa/fcov_ucdb && rm -rf *
wsim rv64gc ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf --fcov > ${SIM}/questa/fcov_logs/add.log 2>&1
#run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/fcov/add.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf >> ${SIM}/questa/fcov_logs/add.log 2>&1
#run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/fcov/and.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf >> ${SIM}/questa/fcov_logs/add.log 2>&1
#run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/fcov/ori.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-ori.elf >> ${SIM}/questa/fcov_logs/add.log 2>&1
vcover merge ${SIM}/questa/fcov_ucdb/fcov.ucdb ${SIM}/questa/fcov_ucdb/*.ucdb -suppress 6854 -64
vcover report -details -html ${SIM}/questa/fcov_ucdb/fcov.ucdb
vcover report ${SIM}/questa/fcov_ucdb/fcov.ucdb -details -cvg > ${SIM}/questa/fcov/fcov.log
vcover report ${SIM}/questa/fcov_ucdb/fcov.ucdb -testdetails -cvg > ${SIM}/questa/fcov/fcov.testdetails.log
# vcover report ${SIM}/questa/fcov/fcov.ucdb -details -cvg -below 100 | egrep "Coverpoint|Covergroup|Cross" | grep -v Metric > ${SIM}/questa/fcov/fcov.ucdb.summary.log
vcover report ${SIM}/questa/fcov_ucdb/fcov.ucdb -details -cvg | egrep "Coverpoint|Covergroup|Cross|TYPE" > ${SIM}/questa/fcov/fcov.summary.log
grep "Total Coverage By Instance" ${SIM}/questa/fcov/fcov.log
remove_functcov_artifacts:
rm ${SIM}/questa/riscv.ucdb ${SIM}/questa/fcov.log ${SIM}/questa/covhtmlreport/ ${SIM}/questa/fcov_logs/ ${SIM}/questa/fcov_ucdbs/ ${SIM}/questa/fcov/ -rf
collect_functcov: remove_functcov_artifacts riscvdv_functcov combine_functcov
allclean: clean all

View File

@ -8,7 +8,7 @@
#
# Takes 1:10 to run RV64IC tests using gui
# Usage: do wally-batch.do <config> <testcases> <testbench> [-coverage] [+acc] [any number of +value] [any number of -G VAR=VAL]
# Usage: do wally-batch.do <config> <testcases> <testbench> [--ccov] [--fcov] [+acc] [any number of +value] [any number of -G VAR=VAL]
# Example: do wally-batch.do rv64gc arch64i testbench
# Use this wally-batch.do file to run this example.
@ -40,7 +40,7 @@ vlib ${WKDIR}
# Create directory for coverage data
mkdir -p cov
set coverage 0
set ccov 0
set CoverageVoptArg ""
set CoverageVsimArg ""
@ -57,7 +57,8 @@ set FCdefineCOVER_RV64D ""
set FCdefineCOVER_RV64ZICSR ""
set FCdefineCOVER_RV64C ""
set FCdefineIDV_INCLUDE_TRACE2COV ""
set FCTRACE2COV ""
set FCdefineIDV_TRACE2COV ""
set lockstep 0
# ok this is annoying. vlog, vopt, and vsim are very picky about how arguments are passed.
# unforunately it won't allow these to be grouped as one argument per command so they are broken
@ -65,7 +66,7 @@ set lockstep 0
set lockstepvoptstring ""
set SVLib ""
set SVLibPath ""
#set OtherFlags ""
set OtherFlags ""
set ImperasPubInc ""
set ImperasPrivInc ""
set rvviFiles ""
@ -104,9 +105,9 @@ if {$AccIndex >= 0} {
}
# if +coverage found set flag and remove from list
set CoverageIndex [lsearch -exact $lst "--coverage"]
set CoverageIndex [lsearch -exact $lst "--ccov"]
if {$CoverageIndex >= 0} {
set coverage 1
set ccov 1
set CoverageVoptArg "+cover=sbecf"
set CoverageVsimArg "-coverage"
set lst [lreplace $lst $CoverageIndex $CoverageIndex]
@ -129,10 +130,11 @@ if {$FunctCoverageIndex >= 0} {
set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR"
set FCdefineCOVER_RV64C "+define+COVER_RV64C"
set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV"
set FCTRACE2COV "+TRACE2COV_ENABLE=1"
set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1"
set lst [lreplace $lst $FunctCoverageIndex $FunctCoverageIndex]
}
}\
set LockStepIndex [lsearch -exact $lst "--lockstep"]
# 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.
@ -148,13 +150,14 @@ if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0} {
set idvFiles $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/*.sv
set SVLib "-sv_lib"
set SVLibPath $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model
#set OtherFlags $env(OTHERFLAGS)
#set OtherFlags $::env(OTHERFLAGS) # not working 7/15/24 dh; this should be the way to pass things like --verbose (Issue 871)
if {$LockStepIndex >= 0} {
set lst [lreplace $lst $LockStepIndex $LockStepIndex]
}
}
# separate the +args from the -G parameters
foreach otherArg $lst {
if {[string index $otherArg 0] eq "+"} {
@ -166,7 +169,7 @@ foreach otherArg $lst {
if {$DEBUG > 0} {
echo "GUI = $GUI"
echo "coverage = $coverage"
echo "ccov = $ccov"
echo "lockstep = $lockstep"
echo "FunctCoverage = $FunctCoverage"
echo "remaining list = $lst"
@ -193,7 +196,7 @@ set temp3 [lindex $PlusArgs 3]
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${idvFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${idvFiles} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
@ -201,7 +204,7 @@ vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${ParamArgs}
#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg}
#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} +IDV_TRACE2COV=1 +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg}
vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} $temp0 $temp1 $temp2 $temp3 -fatal 7 ${SVLib} ${SVLibPath} -suppress 3829 ${CoverageVsimArg}
vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} $temp0 $temp1 $temp2 $temp3 -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} ${FCTRACE2COV} ${FCdefineIDV_TRACE2COV} -suppress 3829 ${CoverageVsimArg}
# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
# power add generates the logging necessary for said generation.
@ -215,16 +218,25 @@ if { ${GUI} } {
}
}
run -all
# power off -r /dut/core/*
if {$FunctCoverage} {
set UCDB ${WALLY}/sim/questa/fcov_ucdb/${CFG}_${TESTSUITE}.ucdb
coverage save -onexit ${UCDB}
}
if {$coverage || $FunctCoverage} {
set UCDB ${WALLY}/sim/questa/cov/${CFG}_${TESTSUITE}.ucdb
run -all
if {$ccov} {
set UCDB ${WALLY}/sim/questa/ucdb/${CFG}_${TESTSUITE}.ucdb
echo "Saving coverage to ${UCDB}"
do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration
coverage save -instance /testbench/dut/core ${UCDB}
}
# power off -r /dut/core/*
# These aren't doing anything helpful
#profile report -calltree -file wally-calltree.rpt -cutoff 2
#power report -all -bsaif power.saif

View File

@ -30,7 +30,7 @@
module alu import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] A, B, // Operands
input logic W64, // W64-type instruction
input logic W64, UW64, // W64/.uw-type instruction
input logic SubArith, // Subtraction or arithmetic shift
input logic [2:0] ALUSelect, // ALU mux select signal
input logic [3:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
@ -77,7 +77,7 @@ module alu import cvw::*; #(parameter cvw_t P) (
end else assign ZeroCondMaskInvB = CondMaskInvB; // no masking if Zicond is not supported
// Shifts (configurable for rotation)
shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2]));
shifter #(P) sh(.A(CondShiftA), .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2]));
// Condition code flags are based on subtraction output Sum = A-B.
// Overflow occurs when the numbers being subtracted have the opposite sign
@ -113,7 +113,7 @@ module alu import cvw::*; #(parameter cvw_t P) (
P.ZBKB_SUPPORTED | P.ZBKC_SUPPORTED | P.ZBKX_SUPPORTED |
P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED | P.ZKNH_SUPPORTED) begin : bitmanipalu
bitmanipalu #(P) balu(
.A, .B, .W64, .BSelect, .ZBBSelect, .BMUActive,
.A, .B, .W64, .UW64, .BSelect, .ZBBSelect, .BMUActive,
.Funct3, .Funct7, .Rs2E, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult,
.CondMaskB, .CondShiftA, .ALUResult);
end else begin

View File

@ -30,16 +30,16 @@
module bitmanipalu import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] A, B, // Operands
input logic W64, // W64-type instruction
input logic W64, UW64, // W64/.uw-type instruction
input logic [3:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [3:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform
input logic [6:0] Funct7, // Funct7 field for ZKND and ZKNE operations
input logic [4:0] Rs2E, // Register source2 for RNUM of ZKNE/ZKND
input logic LT, // less than flag
input logic LTU, // less than unsigned flag
input logic LT, // less than flag
input logic LTU, // less than unsigned flag
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic BMUActive, // Bit manipulation instruction being executed
input logic BMUActive, // Bit manipulation instruction being executed
input logic [P.XLEN-1:0] PreALUResult, // PreALUResult signals
input logic [P.XLEN-1:0] FullResult, // FullResult signals
output logic [P.XLEN-1:0] CondMaskB, // B is conditionally masked for ZBS instructions
@ -76,7 +76,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
// 0-3 bit Pre-Shift Mux
if (P.ZBA_SUPPORTED) begin: zbapreshift
if (P.XLEN == 64) begin
mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, W64, CondZextA);
mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, UW64, CondZextA);
end else assign CondZextA = A;
assign PreShiftAmt = Funct3[2:1] & {2{PreShift}};
assign CondShiftA = CondZextA << (PreShiftAmt);

View File

@ -36,6 +36,7 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage
output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage
output logic BUW64D, // Indiciates if it is a .uw type B instruction in Decode Stage
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
// Execute stage control signals
@ -60,7 +61,7 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
logic [3:0] BSelectD; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage
logic [3:0] ZBBSelectD; // ZBB mux select signal in Decode stage
`define BMUCTRLW 20
`define BMUCTRLW 21
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
@ -72,209 +73,209 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
// Main Instruction Decoder
always_comb begin
// BALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD
// BALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BUW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_0_1; // default: Illegal bmu instruction;
if (P.ZBA_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D})
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_0_0_0_1_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_0_0_0_1_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_0_0_0_1_0; // sh3add
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_0_1_0_0_0_1_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_0_1_0_0_0_1_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_0_1_0_0_0_1_0; // sh3add
endcase
if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_1_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_1_0; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_1_0; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_1_1_0_0_0_0_0; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_0001_0000_1_1_1_1_0_0_0_0_0; // slli.uw
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_1_0_0_0_1_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_1_0_0_0_1_0; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_1_0_0_0_1_0; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_0001_0000_1_0_0_1_1_0_0_0_0_0; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_0001_0000_1_1_0_1_1_0_0_0_0_0; // slli.uw
endcase
end
if (P.ZBB_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D})
17'b0010011_0110000_001: if ((Rs2D[4:1] == 4'b0010))
BMUControlsD = `BMUCTRLW'b000_0010_0001_1_1_0_1_0_0_0_0_0; // sign extend instruction
BMUControlsD = `BMUCTRLW'b000_0010_0001_1_1_0_0_1_0_0_0_0_0; // sign extend instruction
else if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0]))
BMUControlsD = `BMUCTRLW'b000_0010_0000_1_1_0_1_0_0_0_0_0; // count instruction
BMUControlsD = `BMUCTRLW'b000_0010_0000_1_1_0_0_1_0_0_0_0_0; // count instruction
17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111)
BMUControlsD = `BMUCTRLW'b000_0010_0010_1_1_0_1_0_0_0_0_0; // orc.b
17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0010_0111_1_0_0_1_1_0_0_0_0; // max
17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0010_0111_1_0_0_1_1_0_0_0_0; // maxu
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0010_0011_1_0_0_1_1_0_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0010_0011_1_0_0_1_1_0_0_0_0; // minu
BMUControlsD = `BMUCTRLW'b000_0010_0010_1_1_0_0_1_0_0_0_0_0; // orc.b
17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0010_0111_1_0_0_0_1_1_0_0_0_0; // max
17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0010_0111_1_0_0_0_1_1_0_0_0_0; // maxu
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0010_0011_1_0_0_0_1_1_0_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0010_0011_1_0_0_0_1_1_0_0_0_0; // minu
endcase
if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D})
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0010_0001_1_1_0_1_0_0_0_0_0; // zexth (rv32)
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0010_0001_1_1_0_0_1_0_0_0_0_0; // zexth (rv32)
endcase
else if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0010_0001_1_0_0_1_0_0_0_0_0; // zexth (rv64)
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0010_0001_1_0_0_0_1_0_0_0_0_0; // zexth (rv64)
17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0]))
BMUControlsD = `BMUCTRLW'b000_0010_0000_1_1_1_1_0_0_0_0_0; // count word instruction
BMUControlsD = `BMUCTRLW'b000_0010_0000_1_1_1_1_0_0_0_0_0_0; // count word instruction (clzw/ctzw/cpopw)
endcase
end
if (P.ZBC_SUPPORTED)
casez({OpD, Funct7D, Funct3D})
17'b0110011_0000101_010: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_1_0_0_0_0_0; // clmulr
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_1_0_0_0_0_0; // clmul/clmulh
17'b0110011_0000101_010: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_0_1_0_0_0_0_0; // clmulr
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh
endcase
if (P.ZBKC_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D})
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_1_0_0_0_0_0; // clmul/clmulh
// 17'b0110011_0000101_001: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_1_0_0_0_0_0; // clmul
// 17'b0110011_0000101_011: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_1_0_0_0_0_0; // clmulh
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh
// 17'b0110011_0000101_001: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul
// 17'b0110011_0000101_011: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_0_1_0_0_0_0_0; // clmulh
endcase
end
if (P.ZBS_SUPPORTED) begin // ZBS
casez({OpD, Funct7D, Funct3D})
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_0_0_1_1_0_1_0_0; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_0_0_1_0_0_1_0_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_0_0_1_0_0_1_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_0_0_1_0_0_1_0_0; // bset
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_0_0_0_1_1_0_1_0_0; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_0_0_0_1_0_0_1_0_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_0_0_0_1_0_0_1_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_0_0_0_1_0_0_1_0_0; // bset
endcase
if (P.XLEN==32) // ZBS 64-bit
casez({OpD, Funct7D, Funct3D})
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_1_0_1_1_0_1_0_0; // bclri
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_1_0_1_0_0_1_0_0; // bexti
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_1_0_1_0_0_1_0_0; // binvi
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_1_0_1_0_0_1_0_0; // bseti
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_1_0_0_1_1_0_1_0_0; // bclri
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_1_0_0_1_0_0_1_0_0; // bexti
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_1_0_0_1_0_0_1_0_0; // binvi
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_1_0_0_1_0_0_1_0_0; // bseti
endcase
else if (P.XLEN==64) // ZBS 64-bit
casez({OpD, Funct7D, Funct3D})
17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_1_0_1_1_0_1_0_0; // bclri (rv64)
17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_1_0_1_0_0_1_0_0; // bexti (rv64)
17'b0010011_011010?_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_1_0_1_0_0_1_0_0; // binvi (rv64)
17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_1_0_1_0_0_1_0_0; // bseti (rv64)
17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_0001_0000_1_1_0_0_1_1_0_1_0_0; // bclri (rv64)
17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_0001_0000_1_1_0_0_1_0_0_1_0_0; // bexti (rv64)
17'b0010011_011010?_001: BMUControlsD = `BMUCTRLW'b100_0001_0000_1_1_0_0_1_0_0_1_0_0; // binvi (rv64)
17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_0001_0000_1_1_0_0_1_0_0_1_0_0; // bseti (rv64)
endcase
end
if (P.ZBB_SUPPORTED | P.ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used
casez({OpD, Funct7D, Funct3D})
17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_1_0_0_0_0_0; // sra, srl, sll
17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_1_0_0_0_0_0; // srai, srli, slli
17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_1_0_0_0_0_0; // sraw, srlw, sllw
17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_1_0_0_0_0_0; // sraiw, srliw, slliw
17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_0_1_0_0_0_0_0; // sra, srl, sll
17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_0_1_0_0_0_0_0; // srai, srli, slli
17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_0_1_0_0_0_0_0; // sraw, srlw, sllw
17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_0_1_0_0_0_0_0; // sraiw, srliw, slliw
endcase
if (P.ZBKB_SUPPORTED) begin // ZBKB Bitmanip
casez({OpD,Funct7D, Funct3D})
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0100_0001_1_0_0_1_0_0_0_0_0; // pack
17'b0110011_0000100_111: BMUControlsD = `BMUCTRLW'b000_0100_0001_1_0_0_1_0_0_0_0_0; // packh
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0100_0001_1_0_0_0_1_0_0_0_0_0; // pack
17'b0110011_0000100_111: BMUControlsD = `BMUCTRLW'b000_0100_0001_1_0_0_0_1_0_0_0_0_0; // packh
17'b0010011_0110100_101: if (Rs2D == 5'b00111)
BMUControlsD = `BMUCTRLW'b000_0100_0000_1_1_0_1_0_0_0_0_0; // brev8
BMUControlsD = `BMUCTRLW'b000_0100_0000_1_1_0_0_1_0_0_0_0_0; // brev8
endcase
if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D})
17'b0010011_0000100_001: if (Rs2D == 5'b01111)
BMUControlsD = `BMUCTRLW'b000_0100_0011_1_1_0_1_0_0_0_0_0; //zip
BMUControlsD = `BMUCTRLW'b000_0100_0011_1_1_0_0_1_0_0_0_0_0; //zip
17'b0010011_0000100_101: if (Rs2D == 5'b01111)
BMUControlsD = `BMUCTRLW'b000_0100_0011_1_1_0_1_0_0_0_0_0; //unzip
BMUControlsD = `BMUCTRLW'b000_0100_0011_1_1_0_0_1_0_0_0_0_0; //unzip
endcase
else if (P.XLEN==64)
casez({OpD,Funct7D, Funct3D})
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0100_0101_1_0_1_1_0_0_0_0_0; //packw
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_0100_0101_1_0_1_0_1_0_0_0_0_0; //packw
endcase
end
if (P.ZBB_SUPPORTED | P.ZBKB_SUPPORTED) begin // ZBB and ZBKB shared instructions
casez({OpD, Funct7D, Funct3D})
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0001_0111_1_0_0_1_0_1_0_0_0; // rol
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0001_0111_1_0_0_1_0_1_0_0_0; // ror
17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_0001_0111_1_0_0_1_1_0_0_0_0; // andn
17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_0001_0111_1_0_0_1_1_0_0_0_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0001_0111_1_0_0_1_1_0_0_0_0; // xnor
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0001_0111_1_0_0_0_1_0_1_0_0_0; // rol
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0001_0111_1_0_0_0_1_0_1_0_0_0; // ror
17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_0001_0111_1_0_0_0_1_1_0_0_0_0; // andn
17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_0001_0111_1_0_0_0_1_1_0_0_0_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0001_0111_1_0_0_0_1_1_0_0_0_0; // xnor
17'b0010011_011010?_101: if ((P.XLEN == 32 ^ Funct7D[0]) & (Rs2D == 5'b11000))
BMUControlsD = `BMUCTRLW'b000_0010_0010_1_1_0_1_0_0_0_0_0; // rev8
BMUControlsD = `BMUCTRLW'b000_0010_0010_1_1_0_0_1_0_0_0_0_0; // rev8
endcase
if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D})
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_0_1_0_1_0_0_0; // rori (rv32)
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_0_0_1_0_1_0_0_0; // rori (rv32)
endcase
else if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_0_1_1_0_1_0_0_0; // rolw
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_0_1_1_0_1_0_0_0; // rorw
17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_0_1_0_1_0_0_0; // rori (rv64)
17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_1_1_0_1_0_0_0; // roriw
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_0_1_0_1_0_1_0_0_0; // rolw
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_0_1_0_1_0_1_0_0_0; // rorw
17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_0_0_1_0_1_0_0_0; // rori (rv64)
17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0000_0111_1_1_1_0_1_0_1_0_0_0; // roriw
endcase
end
if (P.ZBKX_SUPPORTED) begin //ZBKX
casez({OpD, Funct7D, Funct3D})
17'b0110011_0010100_100: BMUControlsD = `BMUCTRLW'b000_0110_0000_1_0_0_1_0_0_0_0_0; // xperm8
17'b0110011_0010100_010: BMUControlsD = `BMUCTRLW'b000_0110_0001_1_0_0_1_0_0_0_0_0; // xperm4
17'b0110011_0010100_100: BMUControlsD = `BMUCTRLW'b000_0110_0000_1_0_0_0_1_0_0_0_0_0; // xperm8
17'b0110011_0010100_010: BMUControlsD = `BMUCTRLW'b000_0110_0001_1_0_0_0_1_0_0_0_0_0; // xperm4
endcase
end
if (P.ZKND_SUPPORTED) begin //ZKND
if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D})
17'b0110011_??10101_000: BMUControlsD = `BMUCTRLW'b000_0111_0100_1_0_0_1_0_0_0_0_0; // aes32dsi - final round decrypt
17'b0110011_??10111_000: BMUControlsD = `BMUCTRLW'b000_0111_0000_1_0_0_1_0_0_0_0_0; // aes32dsmi - mid round decrypt
17'b0110011_??10101_000: BMUControlsD = `BMUCTRLW'b000_0111_0100_1_0_0_0_1_0_0_0_0_0; // aes32dsi - final round decrypt
17'b0110011_??10111_000: BMUControlsD = `BMUCTRLW'b000_0111_0000_1_0_0_0_1_0_0_0_0_0; // aes32dsmi - mid round decrypt
endcase
else if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0110011_0011101_000: BMUControlsD = `BMUCTRLW'b000_0111_0100_1_0_0_1_0_0_0_0_0; // aes64ds - decrypt final round
17'b0110011_0011111_000: BMUControlsD = `BMUCTRLW'b000_0111_0000_1_0_0_1_0_0_0_0_0; // aes64dsm - decrypt mid round
17'b0110011_0011101_000: BMUControlsD = `BMUCTRLW'b000_0111_0100_1_0_0_0_1_0_0_0_0_0; // aes64ds - decrypt final round
17'b0110011_0011111_000: BMUControlsD = `BMUCTRLW'b000_0111_0000_1_0_0_0_1_0_0_0_0_0; // aes64dsm - decrypt mid round
17'b0010011_0011000_001: if (Rs2D == 5'b00000)
BMUControlsD = `BMUCTRLW'b000_0111_1000_1_1_0_1_0_0_0_0_0; // aes64im - decrypt keyschdule mixcolumns
BMUControlsD = `BMUCTRLW'b000_0111_1000_1_1_0_0_1_0_0_0_0_0; // aes64im - decrypt keyschdule mixcolumns
endcase
end
if (P.ZKNE_SUPPORTED) begin //ZKNE
if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D})
17'b0110011_??10001_000: BMUControlsD = `BMUCTRLW'b000_0111_0101_1_0_0_1_0_0_0_0_0; // aes32esi - final round encrypt
17'b0110011_??10011_000: BMUControlsD = `BMUCTRLW'b000_0111_0001_1_0_0_1_0_0_0_0_0; // aes32esmi - mid round encrypt
17'b0110011_??10001_000: BMUControlsD = `BMUCTRLW'b000_0111_0101_1_0_0_0_1_0_0_0_0_0; // aes32esi - final round encrypt
17'b0110011_??10011_000: BMUControlsD = `BMUCTRLW'b000_0111_0001_1_0_0_0_1_0_0_0_0_0; // aes32esmi - mid round encrypt
endcase
else if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0110011_0011001_000: BMUControlsD = `BMUCTRLW'b000_0111_0101_1_0_0_1_0_0_0_0_0; // aes64es - encrypt final round
17'b0110011_0011011_000: BMUControlsD = `BMUCTRLW'b000_0111_0001_1_0_0_1_0_0_0_0_0; // aes64esm - encrypt mid round
17'b0110011_0011001_000: BMUControlsD = `BMUCTRLW'b000_0111_0101_1_0_0_0_1_0_0_0_0_0; // aes64es - encrypt final round
17'b0110011_0011011_000: BMUControlsD = `BMUCTRLW'b000_0111_0001_1_0_0_0_1_0_0_0_0_0; // aes64esm - encrypt mid round
endcase
end
if ((P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED) & P.XLEN == 64) begin // ZKND and ZKNE shared instructions
casez({OpD, Funct7D, Funct3D})
17'b0010011_0011000_001: if (Rs2D[4] == 1'b1)
BMUControlsD = `BMUCTRLW'b000_0111_0010_1_0_0_1_0_0_0_0_0; // aes64ks1i - key schedule istr1
17'b0110011_0111111_000: BMUControlsD = `BMUCTRLW'b000_0111_0011_1_0_0_1_0_0_0_0_0; // aes64ks2 - key schedule istr2
BMUControlsD = `BMUCTRLW'b000_0111_0010_1_0_0_0_1_0_0_0_0_0; // aes64ks1i - key schedule istr1
17'b0110011_0111111_000: BMUControlsD = `BMUCTRLW'b000_0111_0011_1_0_0_0_1_0_0_0_0_0; // aes64ks2 - key schedule istr2
endcase
end
if (P.ZKNH_SUPPORTED) begin // ZKNH
casez({OpD, Funct7D, Funct3D})
17'b0010011_0001000_001:
if (Rs2D == 5'b00010) BMUControlsD = `BMUCTRLW'b000_1000_0000_1_0_0_1_0_0_0_0_0; // sha256sig0
else if (Rs2D == 5'b00011) BMUControlsD = `BMUCTRLW'b000_1000_0001_1_0_0_1_0_0_0_0_0; // sha256sig1
else if (Rs2D == 5'b00000) BMUControlsD = `BMUCTRLW'b000_1000_0010_1_0_0_1_0_0_0_0_0; // sha256sum0
else if (Rs2D == 5'b00001) BMUControlsD = `BMUCTRLW'b000_1000_0011_1_0_0_1_0_0_0_0_0; // sha256sum1
if (Rs2D == 5'b00010) BMUControlsD = `BMUCTRLW'b000_1000_0000_1_0_0_0_1_0_0_0_0_0; // sha256sig0
else if (Rs2D == 5'b00011) BMUControlsD = `BMUCTRLW'b000_1000_0001_1_0_0_0_1_0_0_0_0_0; // sha256sig1
else if (Rs2D == 5'b00000) BMUControlsD = `BMUCTRLW'b000_1000_0010_1_0_0_0_1_0_0_0_0_0; // sha256sum0
else if (Rs2D == 5'b00001) BMUControlsD = `BMUCTRLW'b000_1000_0011_1_0_0_0_1_0_0_0_0_0; // sha256sum1
endcase
if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D})
17'b0110011_0101110_000: BMUControlsD = `BMUCTRLW'b000_1000_1000_1_0_0_1_0_0_0_0_0; // sha512sig0h
17'b0110011_0101010_000: BMUControlsD = `BMUCTRLW'b000_1000_1001_1_0_0_1_0_0_0_0_0; // sha512sig0l
17'b0110011_0101111_000: BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_1_0_0_0_0_0; // sha512sig1h
17'b0110011_0101011_000: BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_1_0_0_0_0_0; // sha512sig1l
17'b0110011_0101000_000: BMUControlsD = `BMUCTRLW'b000_1000_1100_1_0_0_1_0_0_0_0_0; // sha512sum0r
17'b0110011_0101001_000: BMUControlsD = `BMUCTRLW'b000_1000_1110_1_0_0_1_0_0_0_0_0; // sha512sum1r
17'b0110011_0101110_000: BMUControlsD = `BMUCTRLW'b000_1000_1000_1_0_0_0_1_0_0_0_0_0; // sha512sig0h
17'b0110011_0101010_000: BMUControlsD = `BMUCTRLW'b000_1000_1001_1_0_0_0_1_0_0_0_0_0; // sha512sig0l
17'b0110011_0101111_000: BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_0_1_0_0_0_0_0; // sha512sig1h
17'b0110011_0101011_000: BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_0_1_0_0_0_0_0; // sha512sig1l
17'b0110011_0101000_000: BMUControlsD = `BMUCTRLW'b000_1000_1100_1_0_0_0_1_0_0_0_0_0; // sha512sum0r
17'b0110011_0101001_000: BMUControlsD = `BMUCTRLW'b000_1000_1110_1_0_0_0_1_0_0_0_0_0; // sha512sum1r
endcase
else if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0010011_0001000_001:
if (Rs2D == 5'b00110) BMUControlsD = `BMUCTRLW'b000_1000_1000_1_0_0_1_0_0_0_0_0; // sha512sig0
else if (Rs2D == 5'b00111) BMUControlsD = `BMUCTRLW'b000_1000_1001_1_0_0_1_0_0_0_0_0; // sha512sig1
else if (Rs2D == 5'b00100) BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_1_0_0_0_0_0; // sha512sum0
else if (Rs2D == 5'b00101) BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_1_0_0_0_0_0; // sha512sum1
if (Rs2D == 5'b00110) BMUControlsD = `BMUCTRLW'b000_1000_1000_1_0_0_0_1_0_0_0_0_0; // sha512sig0
else if (Rs2D == 5'b00111) BMUControlsD = `BMUCTRLW'b000_1000_1001_1_0_0_0_1_0_0_0_0_0; // sha512sig1
else if (Rs2D == 5'b00100) BMUControlsD = `BMUCTRLW'b000_1000_1010_1_0_0_0_1_0_0_0_0_0; // sha512sum0
else if (Rs2D == 5'b00101) BMUControlsD = `BMUCTRLW'b000_1000_1011_1_0_0_0_1_0_0_0_0_0; // sha512sum1
endcase
end
end
// Unpack Control Signals
assign {BALUSelectD, BSelectD, ZBBSelectD, BRegWriteD,BALUSrcBD, BW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD;
assign {BALUSelectD, BSelectD, ZBBSelectD, BRegWriteD,BALUSrcBD, BW64D, BUW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD;
// Pack BALUControl Signals
assign BALUControlD = {RotateD, MaskD, PreShiftD};

View File

@ -56,7 +56,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic [2:0] Funct3E, // Instruction's funct3 field
output logic [6:0] Funct7E, // Instruction's funct7 field
output logic IntDivE, // Integer divide
output logic W64E, // RV64 W-type operation
output logic W64E, UW64E, // RV64 W/.uw-type operation
output logic SubArithE, // Subtraction or arithmetic shift
output logic JumpE, // jump instruction
output logic BranchE, // Branch instruction
@ -158,6 +158,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
logic BUW64D; // Indiciates if it is a .uw type B instruction in Decode Stage
// Extract fields
assign OpD = InstrD[6:0];
@ -326,7 +327,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic BALUSrcBD; // BMU alu src select signal
bmuctrl #(P) bmuctrl(.clk, .reset, .InstrD, .ALUOpD,
.BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.BRegWriteD, .BALUSrcBD, .BW64D, .BUW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.ALUSelectD(PreALUSelectD), .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE);
if (P.ZBA_SUPPORTED) begin
// ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw
@ -350,6 +351,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
assign W64D = BaseW64D;
assign ALUSrcBD = BaseALUSrcBD;
assign SubArithD = BaseSubArithD; // TRUE If B-type or R-type instruction involves inverted operand
assign BUW64D = 1'b0; // no .uw instructions
// tie off unused bit manipulation signals
assign BSelectE = 4'b0000;
@ -417,9 +419,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic
flopenrc #(44) controlregE(clk, reset, FlushE, ~StallE,
{ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, Funct7D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, CZeroD, InstrValidD},
{ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, Funct7E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, CZeroE, InstrValidE});
flopenrc #(45) controlregE(clk, reset, FlushE, ~StallE,
{ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, Funct7D, W64D, BUW64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, CZeroD, InstrValidD},
{ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, Funct7E, W64E, UW64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, CZeroE, InstrValidE});
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);

View File

@ -41,7 +41,7 @@ module datapath import cvw::*; #(parameter cvw_t P) (
input logic [6:0] Funct7E, // Funct7 field of instruction in Execute stage
input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
input logic W64E, // W64-type instruction
input logic W64E,UW64E, // W64/.uw-type instruction
input logic SubArithE, // Subtraction or arithmetic shift
input logic ALUSrcAE, ALUSrcBE, // ALU operands
input logic ALUResultSrcE, // Selects result to pass on to Memory stage
@ -109,7 +109,7 @@ module datapath import cvw::*; #(parameter cvw_t P) (
comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(P) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, Funct7E, Rs2E, BALUControlE, BMUActiveE, CZeroE, ALUResultE, IEUAdrE);
alu #(P) alu(SrcAE, SrcBE, W64E, UW64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, Funct7E, Rs2E, BALUControlE, BMUActiveE, CZeroE, ALUResultE, IEUAdrE);
mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -93,6 +93,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
logic [3:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage
logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage
logic SubArithE; // Subtraction or arithmetic shift
logic UW64E; // .uw-type instruction
logic [6:0] Funct7E;
@ -111,7 +112,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
.StructuralStallD, .LoadStallD, .StoreStallD, .Rs1D, .Rs2D, .Rs2E,
.StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE,
.Funct3E, .Funct7E, .IntDivE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE,
.Funct3E, .Funct7E, .IntDivE, .W64E, .UW64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE,
.BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .CZeroE, .MDUActiveE,
.FCvtIntE, .ForwardAE, .ForwardBE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM,
.StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
@ -120,7 +121,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
.RdW, .RdE, .RdM);
datapath #(P) dp(
.clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .Rs2E, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
.clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .Rs2E, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .UW64E, .SubArithE,
.Funct3E, .Funct7E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .CZeroE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,

View File

@ -462,7 +462,7 @@ module testbench;
integer StartIndex;
integer EndIndex;
integer BaseIndex;
integer memFile;
integer memFile, uncoreMemFile;
integer readResult;
if (P.SDC_SUPPORTED) begin
always @(posedge clk) begin
@ -505,8 +505,16 @@ module testbench;
end
readResult = $fread(dut.uncoregen.uncore.ram.ram.memory.ram.RAM, memFile);
$fclose(memFile);
end else
$readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.ram.RAM);
end else begin
uncoreMemFile = $fopen(memfilename, "r"); // Is there a better way to test if a file exists?
if (uncoreMemFile == 0) begin
$display("Error: Could not open file %s", memfilename);
$finish;
end else begin
$fclose(uncoreMemFile);
$readmemh(memfilename, dut.uncoregen.uncore.ram.ram.memory.ram.RAM);
end
end
if (TEST == "embench") $display("Read memfile %s", memfilename);
end
if (CopyRAM) begin
@ -715,7 +723,7 @@ 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'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GCK"));
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56));
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));

View File

@ -660,7 +660,9 @@ module testbench_fp;
tt0 = $sformatf("%s", Tests[TestNum]);
testname = {pp, tt0};
//$display("Here you are %s", testname);
$display("\n\nRunning %s vectors ", Tests[TestNum]);
// clear the vectors
for(int i=0; i<MAXVECTORS; i++) TestVectors[i] = '1;
$display("\n\nRunning %s vectors ", Tests[TestNum]);
$readmemh(testname, TestVectors);
// set the test index to 0
TestNum = 0;
@ -774,9 +776,9 @@ module testbench_fp;
// Check if the correct answer and result is a NaN
always_comb begin
if (UnitVal === `CVTINTUNIT | UnitVal === `CMPUNIT) begin
// an integer output can't be a NaN
AnsNaN = 1'b0;
ResNaN = 1'b0;
// an integer output can't be a NaN
AnsNaN = 1'b0;
ResNaN = 1'b0;
end
else if (UnitVal === `CVTFPUNIT) begin
case (OpCtrlVal[1:0])
@ -894,11 +896,12 @@ module testbench_fp;
if (reset)
state <= S0;
else
state <= nextstate;
state <= nextstate;
// Increment the vector when Done with each test
if (state == Done)
VectorNum += 1; // increment the vector
if (state == Done) begin
VectorNum += 1; // increment the vector
end
end
@ -982,14 +985,16 @@ module testbench_fp;
$display("TestNum %d VectorNum %d OpCtrl %d", TestNum, VectorNum, OpCtrl[TestNum]);
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h",
X[P.FLEN-1:0], Y[P.FLEN-1:0], Z[P.FLEN-1:0], SrcA, Res[P.FLEN-1:0], ResFlg, Ans[P.FLEN-1:0], AnsFlg);
//$display(" fma.Xs %h Xe %h Xm %h Ys %h Ye %h Ym %h Ss %h Se %h Sm %h", fma.Xs, fma.Xe, fma.Xm, fma.Ys, fma.Ye, fma.Ym, fma.Ss, fma.Se, fma.Sm);
//$display(" readvectors.unpack.X %h Xs %h Xe %h Xm %h", readvectors.unpack.X, readvectors.unpack.Xs, readvectors.unpack.Xe, readvectors.unpack.Xm);
$stop;
end
if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof
if (TestVectors[VectorNum] == '1 & Tests[TestNum] !== "") begin // if reached the eof
// increment the test
TestNum += 1;
// clear the vectors
for(int i=0; i<MAXVECTORS; i++) TestVectors[i] = {P.Q_LEN*4+8{1'bx}};
for(int i=0; i<MAXVECTORS; i++) TestVectors[i] = '1;
// read next files
$readmemh({`PATH, Tests[TestNum]}, TestVectors);
// set the vector index back to 0
@ -999,12 +1004,12 @@ module testbench_fp;
// increment the rounding mode or loop back to rne
if (FrmNum < 4) FrmNum += 1;
else begin
FrmNum = 0;
FrmNum = 0;
// Add some time as a buffer between tests at the end of each test
// (to be removed)
repeat (10)
@(posedge clk);
end
// (to be removed, but as of 7/14/24 breaks Verilator sqrt sim to remove dh)
repeat (10)
@(posedge clk);
end
// if no more Tests - finish
if (Tests[TestNum] === "") begin
$display("\nAll Tests completed with %d errors\n", errors);
@ -1052,9 +1057,9 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
// apply test vectors on rising edge of clk
// Format of vectors Inputs(1/2/3)_AnsFlg
always @(VectorNum) begin
always @(posedge clk) begin
AnsFlg = TestVector[4:0];
//$display("Entering readvectors with VectorNum=%d, TestVector=%x, Unit=%d, Fmt=%d, OpCtrl=%d", VectorNum, TestVector, Unit, Fmt, OpCtrl);
//$display(" Entering readvectors with VectorNum=%d, TestVector=%x, Unit=%d, Fmt=%d, OpCtrl=%d", VectorNum, TestVector, Unit, Fmt, OpCtrl); */
case (Unit)
`FMAUNIT:
case (Fmt)
@ -1076,7 +1081,6 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+4*(P.D_LEN)-1:8+3*(P.D_LEN)]};
Y = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+3*(P.D_LEN)-1:8+2*(P.D_LEN)]};
Z = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+P.D_LEN]};
$display("Read %x %x %x", X, Y, Z);
end
else begin
X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+3*(P.D_LEN)-1:8+2*(P.D_LEN)]};