This commit is contained in:
Rose Thompson 2024-07-22 17:48:34 -05:00
commit 94a1ce32e7
11 changed files with 204 additions and 338 deletions

View file

@ -282,6 +282,22 @@ def addTests(tests, sim):
grepfile = grepfile) grepfile = grepfile)
configs.append(tc) configs.append(tc)
def addLockstepTestsByDir(dir, config, sim):
sim_logdir = WALLY+ "/sim/" + sim + "/logs/"
cmdPrefix="wsim --sim " + sim + " " + coverStr + " " + config
for file in os.listdir(dir):
if file.endswith(".elf"):
fullfile = os.path.join(dir, file)
sim_log = sim_logdir + config + "_" + file
grepstring = ""
tc = TestCase(
name=file,
variant=config,
cmd=cmdPrefix + " " + fullfile + " > " + sim_log,
grepstr="Mismatches : 0",
grepfile = sim_log)
configs.append(tc)
def search_log_for_text(text, grepfile): def search_log_for_text(text, grepfile):
"""Search through the given log file for text, returning True if it is found or False if it is not""" """Search through the given log file for text, returning True if it is found or False if it is not"""
grepwarn = "grep -H Warning: " + grepfile grepwarn = "grep -H Warning: " + grepfile
@ -332,14 +348,15 @@ args = parser.parse_args()
if (args.nightly): if (args.nightly):
nightMode = "--nightly"; nightMode = "--nightly";
# sims = [defaultsim] # uncomment to use only the default simulator sims = ["questa", "verilator", "vcs"] # exercise all simulators; can omit a sim if no license is available
sims = ["questa", "verilator", "vcs"] # uncomment to exercise all simulators
else: else:
nightMode = "" nightMode = ""
sims = [defaultsim] sims = [defaultsim]
if (args.ccov): # only run RV64GC tests in coverage mode if (args.ccov): # only run RV64GC tests in coverage mode
coverStr = '--ccov' coverStr = '--ccov'
elif (args.fcov): # only run RV64GC tests in lockstep in coverage mode
coverStr = '--fcov'
else: else:
coverStr = '' coverStr = ''
@ -362,10 +379,20 @@ if (args.buildroot):
addTests(tests_buildrootbootlockstep, "questa") # lockstep with Questa and ImperasDV runs overnight addTests(tests_buildrootbootlockstep, "questa") # lockstep with Questa and ImperasDV runs overnight
if (args.ccov): # only run RV64GC tests on Questa in code coverage mode if (args.ccov): # only run RV64GC tests on Questa in code coverage mode
addTests(tests64gc_nofp, "questa") addTests(tests64gc_nofp, coveragesim)
if (args.fp): if (args.fp):
addTests(tests64gc_fp, "questa") addTests(tests64gc_fp, coveragesim)
else: elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional coverage mode
addLockstepTestsByDir(WALLY+"/tests/functcov/rv64/I", "rv64gc", coveragesim)
#sim_log = WALLY + "/sim/questa/logs/fcov.log"
#tc = TestCase(
# name="lockstep_functcov",
# variant="rv64gc",
# cmd="iterelf " + WALLY + "/tests/functcov/rv64/I > " + sim_log,
# grepstr="SUCCESS! All tests ran without failures",
# grepfile = sim_log)
#configs.append(tc)
else:
for sim in sims: for sim in sims:
if (not (args.buildroot and sim == defaultsim)): # skip short buildroot sim if running long one if (not (args.buildroot and sim == defaultsim)): # skip short buildroot sim if running long one
addTests(tests_buildrootshort, sim) addTests(tests_buildrootshort, sim)
@ -375,7 +402,6 @@ else:
# run derivative configurations and lockstep tests in nightly regression # run derivative configurations and lockstep tests in nightly regression
if (args.nightly): if (args.nightly):
addTests(derivconfigtests, defaultsim)
sim_log = WALLY + "/sim/questa/logs/lockstep_coverage.log" sim_log = WALLY + "/sim/questa/logs/lockstep_coverage.log"
tc = TestCase( tc = TestCase(
name="lockstep_coverage", name="lockstep_coverage",
@ -393,6 +419,7 @@ if (args.nightly):
grepstr="SUCCESS! All tests ran without failures", grepstr="SUCCESS! All tests ran without failures",
grepfile = sim_log) grepfile = sim_log)
configs.append(tc) configs.append(tc)
addTests(derivconfigtests, defaultsim)
# testfloat tests # testfloat tests
if (args.testfloat): # for testfloat alone, just run testfloat tests if (args.testfloat): # for testfloat alone, just run testfloat tests
@ -474,16 +501,24 @@ def main():
if args.ccov: if args.ccov:
TIMEOUT_DUR = 20*60 # seconds TIMEOUT_DUR = 20*60 # seconds
os.system('rm -f questa/cov/*.ucdb') os.system('rm -f questa/cov/*.ucdb')
elif args.nightly in sys.argv: elif args.fcov:
TIMEOUT_DUR = 1*60
os.system('rm -f questa/fcov_ucdb/* questa/fcov_logs/* questa/fcov/*')
elif args.nightly:
TIMEOUT_DUR = 60*1440 # 1 day TIMEOUT_DUR = 60*1440 # 1 day
elif args.testfloat in sys.argv: elif args.testfloat:
TIMEOUT_DUR = 30*60 # seconds TIMEOUT_DUR = 30*60 # seconds
else: else:
TIMEOUT_DUR = 10*60 # seconds TIMEOUT_DUR = 10*60 # seconds
# Scale the number of concurrent processes to the number of test cases, but # Scale the number of concurrent processes to the number of test cases, but
# max out at a limited number of concurrent processes to not overwhelm the system # max out at a limited number of concurrent processes to not overwhelm the system
with Pool(processes=min(len(configs),multiprocessing.cpu_count())) as pool: # right now fcov, ccov, nightly all use Imperas
if (args.ccov or args.fcov or args.nightly):
ImperasDVLicenseCount = 8 # limit number of concurrent processes to avoid overloading ImperasDV licenses
else:
ImperasDVLicenseCount = 10000 # effectively no license limit for non-lockstep tests
with Pool(processes=min(len(configs),multiprocessing.cpu_count(), ImperasDVLicenseCount)) as pool:
num_fail = 0 num_fail = 0
results = {} results = {}
for config in configs: for config in configs:
@ -498,6 +533,8 @@ def main():
# Coverage report # Coverage report
if args.ccov: if args.ccov:
os.system('make QuestaCodeCoverage') os.system('make QuestaCodeCoverage')
if args.fcov:
os.system('make QuestaFunctCoverage')
# Count the number of failures # Count the number of failures
if num_fail: if num_fail:
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)

View file

@ -30,6 +30,13 @@ QuestaCodeCoverage: questa/ucdb/rv64gc_arch64i.ucdb
# vcover report -recursive questa/ucdb/cov.ucdb > questa/cov/rv64gc_recursive.rpt # vcover report -recursive questa/ucdb/cov.ucdb > questa/cov/rv64gc_recursive.rpt
vcover report -details -threshH 100 -html questa/ucdb/cov.ucdb vcover report -details -threshH 100 -html questa/ucdb/cov.ucdb
QuestaFunctCoverage: ${SIM}/questa/fcov_ucdb/rv64gc_WALLY-COV-add.elf.ucdb
vcover merge -out ${SIM}/questa/fcov_ucdb/fcov.ucdb ${SIM}/questa/fcov_ucdb/rv64gc_WALLY-COV-add.elf.ucdb ${SIM}/questa/fcov_ucdb/rv64gc_WALLY*.ucdb -logfile ${SIM}/questa/fcov_logs/log
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_ucdb/fcov.ucdb -details -cvg | egrep "Coverpoint|Covergroup|Cross|TYPE" > ${SIM}/questa/fcov/fcov.summary.log
grep "TOTAL COVERGROUP COVERAGE" ${SIM}/questa/fcov/fcov.log
imperasdv_cov: imperasdv_cov:
touch ${SIM}/seed0.txt touch ${SIM}/seed0.txt
@ -91,6 +98,7 @@ combine_functcov:
cd ${SIM}/questa/fcov && rm -rf * cd ${SIM}/questa/fcov && rm -rf *
cd ${SIM}/questa/fcov_ucdb && 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 wsim rv64gc ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf --fcov > ${SIM}/questa/fcov_logs/add.log 2>&1
wsim rv64gc ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf --fcov > ${SIM}/questa/fcov_logs/and.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/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/and.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf >> ${SIM}/questa/fcov_logs/add.log 2>&1

View file

@ -1,10 +0,0 @@
#!/bin/bash
#export RISCV=/scratch/moore/RISCV
export IMPERAS_TOOLS=$(pwd)/imperas.ic
export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=100"
#export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000"
#export OTHERFLAGS=""
vsim -do "do wally.do buildroot buildroot testbench --lockstep +acc -GDEBUG=1"

View file

@ -1,33 +0,0 @@
#!/bin/bash
###########################################
## imperas-one-time.sh
##
## Written: Ross Thompson (ross1728@gmail.com) and Lee Moore (moore@imperas.com)
## Created: 31 January 2023
## Modified: 31 January 2023
##
## Purpose: Run wally with imperas
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-23 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.
################################################################################################
IMPERAS_TOOLS=$(pwd)/imperas.ic \
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
TESTDIR=${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege/src/Lee.S/ \
vsim -do "do wally-imperas.do rv64gc"

View file

@ -1,79 +0,0 @@
# wally.do
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+$env(WALLY)/config/$1 \
+incdir+$env(WALLY)/config/deriv/$1 \
+incdir+$env(WALLY)/config/shared \
+define+USE_IMPERAS_DV \
+define+IDV_INCLUDE_TRACE2COV \
+define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT \
+define+COVER_RV64I \
+define+COVER_RV64M \
+define+COVER_RV64A \
+define+COVER_RV64F \
+define+COVER_RV64D \
+define+COVER_RV64ZICSR \
+define+COVER_RV64C \
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \
\
+incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
\
$env(WALLY)/src/cvw.sv \
$env(WALLY)/testbench/testbench.sv \
$env(WALLY)/testbench/common/*.sv \
$env(WALLY)/src/*/*.sv \
$env(WALLY)/src/*/*/*.sv \
-suppress 2583 \
-suppress 7063 \
+acc
vopt +acc work.testbench -G DEBUG=1 -o workopt
eval vsim workopt +nowarn3829 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
+ElfFile=$env(TESTDIR)/ref/ref.elf $env(OTHERFLAGS) +TRACE2COV_ENABLE=1
coverage save -onexit $env(WALLY)/sim/questa/riscv.ucdb
view wave
#-- display input and output signals as hexidecimal values
# add log -recursive /*
# do wave.do
run -all
noview $env(WALLY)/testbench/testbench-imperas.sv
view wave
#quit -f

View file

@ -1,48 +0,0 @@
# wally.do
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 \
+incdir+../config/shared \
../../external/ImperasDV-HMC/Imperas/ImpPublic/source/host/rvvi/rvviTrace.sv \
../src/cvw.sv \
../testbench/testbench_imperas.sv \
../testbench/common/*.sv \
../src/*/*.sv \
../src/*/*/*.sv \
-suppress 2583 \
-suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt
eval vsim workopt +nowarn3829 -fatal 7 \
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
view wave
#-- display input and output signals as hexidecimal values
add log -recursive /*
do wave.do
run -all
noview ../testbench/testbench_imperas.sv
view wave

View file

@ -1,64 +0,0 @@
# wally.do
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 \
+incdir+../config/shared \
+define+USE_IMPERAS_DV \
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
../src/cvw.sv \
../testbench/testbench-imperas.sv \
../testbench/common/*.sv \
../src/*/*.sv \
../src/*/*/*.sv \
-suppress 2583 \
-suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt
eval vsim workopt +nowarn3829 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
view wave
#-- display input and output signals as hexidecimal values
add log -recursive /*
do wave.do
run -all
noview ../testbench/testbench_imperas.sv
view wave
#quit -f

View file

@ -122,13 +122,14 @@ if {$FunctCoverageIndex >= 0} {
set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV" set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV"
set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I" set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I"
set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT" set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT"
# Uncomment various cover statements below to control which extensions get functional coverage
set FCdefineCOVER_RV64I "+define+COVER_RV64I" set FCdefineCOVER_RV64I "+define+COVER_RV64I"
set FCdefineCOVER_RV64M "+define+COVER_RV64M" #set FCdefineCOVER_RV64M "+define+COVER_RV64M"
set FCdefineCOVER_RV64A "+define+COVER_RV64A" #set FCdefineCOVER_RV64A "+define+COVER_RV64A"
set FCdefineCOVER_RV64F "+define+COVER_RV64F" #set FCdefineCOVER_RV64F "+define+COVER_RV64F"
set FCdefineCOVER_RV64D "+define+COVER_RV64D" #set FCdefineCOVER_RV64D "+define+COVER_RV64D"
set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR" #set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR"
set FCdefineCOVER_RV64C "+define+COVER_RV64C" #set FCdefineCOVER_RV64C "+define+COVER_RV64C"
set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV" set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV"
set FCTRACE2COV "+TRACE2COV_ENABLE=1" set FCTRACE2COV "+TRACE2COV_ENABLE=1"
set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1" set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1"

View file

@ -57,6 +57,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
logic [P.XLEN-1:0] MENVCFGH_REGW; logic [P.XLEN-1:0] MENVCFGH_REGW;
logic [P.XLEN-1:0] TVECWriteValM;
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
@ -152,7 +153,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR); assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR);
// CSRs // CSRs
flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); assign TVECWriteValM = CSRWriteValM[0] ? {CSRWriteValM[P.XLEN-1:6], 6'b000001} : {CSRWriteValM[P.XLEN-1:2], 2'b00};
flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, TVECWriteValM, MTVEC_REGW);
if (P.S_SUPPORTED) begin:deleg // DELEG registers should exist if (P.S_SUPPORTED) begin:deleg // DELEG registers should exist
flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW); flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW);
flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW); flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW);

View file

@ -78,6 +78,7 @@ module csrs import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW; logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW;
logic [P.XLEN-1:0] SENVCFG_WriteValM; logic [P.XLEN-1:0] SENVCFG_WriteValM;
logic [P.XLEN-1:0] TVECWriteValM;
logic [63:0] STIMECMP_REGW; logic [63:0] STIMECMP_REGW;
@ -100,7 +101,8 @@ module csrs import cvw::*; #(parameter cvw_t P) (
assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & STCE & (P.XLEN == 32); assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & STCE & (P.XLEN == 32);
// CSRs // CSRs
flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); assign TVECWriteValM = CSRWriteValM[0] ? {CSRWriteValM[P.XLEN-1:6], 6'b000001} : {CSRWriteValM[P.XLEN-1:2], 2'b00}; // could share this with MTVEC, but reduces to 4-bit AND to mask bits [5:2]
flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, TVECWriteValM, STVEC_REGW);
flopenr #(P.XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); flopenr #(P.XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
flopenr #(P.XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); flopenr #(P.XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
flopenr #(P.XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, {NextCauseM[4], {(P.XLEN-5){1'b0}}, NextCauseM[3:0]}, SCAUSE_REGW); flopenr #(P.XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, {NextCauseM[4], {(P.XLEN-5){1'b0}}, NextCauseM[3:0]}, SCAUSE_REGW);

View file

@ -31,54 +31,73 @@ def signedImm12(imm):
imm = imm - 0x1000 imm = imm - 0x1000
return str(imm) return str(imm)
def signedImm20(imm): def unsignedImm20(imm):
imm = imm % pow(2, 20) imm = imm % pow(2, 20)
if (imm & 0x80000):
imm = imm - 0x100000
return str(imm) return str(imm)
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen): def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen):
lines = "\n# Testcase " + str(desc) + "\n" lines = "\n# Testcase " + str(desc) + "\n"
if (rs1val < 0): if (rs1val < 0):
rs1val = rs1val + 2**xlen rs1val = rs1val + 2**xlen
if (rs2val < 0): if (rs2val < 0):
rs2val = rs2val + 2**xlen rs2val = rs2val + 2**xlen
lines = lines + "li x" + str(rd) + ", " + formatstr.format(rdval) + " # initialize rd to a random value that should get changed\n" lines = lines + "li x" + str(rd) + ", " + formatstr.format(rdval) + " # initialize rd to a random value that should get changed; helps covering rd_toggle\n"
if (test in rtype): if (test in rtype):
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value\n" lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\n"
elif (test in shiftitype): elif (test in shiftitype):
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n"
elif (test in itype): elif (test in itype):
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n"
elif (test in loaditype):#["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"] elif (test in loaditype):#["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
lines = lines + "auipc x" + str(rs1) + ", 0x20" + " # add upper immediate value to pc \n" pass
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # add immediate to lower part of rs1 \n" #lines = lines + "auipc x" + str(rs1) + ", 0x20" + " # add upper immediate value to pc \n"
lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n" #lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # add immediate to lower part of rs1\n"
elif (test in stypes):#["sb", "sh", "sw", "sd"] #lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation\n"
elif (test in stype):#["sb", "sh", "sw", "sd"]
#lines = lines + test + " x" + str(rs2) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n" #lines = lines + test + " x" + str(rs2) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n"
#lines = lines + test + " x" + str(rs2) + ", " "0(x" + str(rs1) + ") # perform operation \n" #lines = lines + test + " x" + str(rs2) + ", " "0(x" + str(rs1) + ") # perform operation \n"
print("Error: %s type not implemented yet" % test) #print("Error: %s type not implemented yet" % test)
elif (test in btypes):#["beq", "bne", "blt", "bge", "bltu", "bgeu"] pass
elif (test in btype):#["beq", "bne", "blt", "bge", "bltu", "bgeu"]
if (randint(1,100) > 50): if (randint(1,100) > 50):
rs1val = rs2val rs1val = rs2val
lines = lines + "# same values in both registers\n" lines = lines + "# same values in both registers\n"
lines = lines + "nop\n" lines = lines + "nop\n"
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value that should get changed\n" lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value that should get changed\n" lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
lines = lines + test + " x" + str(rs1) + ", x" + str(rs2) + ", some_label_for_sb_types_" + str(immval) + "+4" + " # perform operation \n" lines = lines + test + " x" + str(rs1) + ", x" + str(rs2) + ", some_label_for_sb_types_" + str(immval) + "+4" + " # perform operation \n"
lines = lines + "addi x0, x1, 1\n" lines = lines + "addi x0, x1, 1\n"
lines = lines + "some_label_for_sb_types_" + str(immval) + ":\n" lines = lines + "some_label_for_sb_types_" + str(immval) + ":\n"
lines = lines + "addi x0, x2, 2\n" lines = lines + "addi x0, x2, 2\n"
lines = lines + "nop\nnop\nnop\nnop\nnop\n" lines = lines + "nop\nnop\nnop\nnop\nnop\n"
elif (test in jtype):#["jal"]
lines = lines + "jal x" + str(rd) + ", 1f # perform operation\n"
lines = lines + "nop\n"
lines = lines + "1:\n"
elif (test in jalrtype):#["jalr"]
lines = lines + "la x" + str(rs1) + ", 1f\n"
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # add immediate to lower part of rs1\n"
lines = lines + "jalr x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n"
lines = lines + "nop\n"
lines = lines + "1:\n"
elif (test in utype):#["lui", "auipc"]
lines = lines + test + " x" + str(rd) + ", " + unsignedImm20(immval) + " # perform operation\n"
else: else:
pass pass
#print("Error: %s type not implemented yet" % test) #print("Error: %s type not implemented yet" % test)
f.write(lines) f.write(lines)
def writeHazardVector(desc, rs1a, rs2a, rda, rs1b, rs2b, rdb, test):
# consecutive R-type instructions to trigger hazards
lines = "\n# Testcase " + str(desc) + "\n"
lines = lines + test + " x" + str(rda) + ", x" + str(rs1a) + ", x" + str(rs2a) + " # perform first operation\n"
lines = lines + test + " x" + str(rdb) + ", x" + str(rs1b) + ", x" + str(rs2b) + " # perform second operation\n"
f.write(lines)
def randomize(): def randomize():
rs1 = randint(1, 31) rs1 = randint(1, 31)
rs2 = randint(1, 31) rs2 = randint(1, 31)
@ -93,159 +112,191 @@ def randomize():
rdval = randint(0, 2**xlen-1) rdval = randint(0, 2**xlen-1)
return [rs1, rs2, rd, rs1val, rs2val, immval, rdval] return [rs1, rs2, rd, rs1val, rs2val, immval, rdval]
def make_rd(test, storecmd, xlen): def make_rd(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd (Test destination rd = x" + str(r) + ")" desc = "cp_rd (Test destination rd = x" + str(r) + ")"
writeCovVector(desc, rs1, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, r, rs1val, rs2val, immval, rdval, test, xlen)
def make_rs1(test, storecmd, xlen): def make_rs1(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rs1 (Test source rs1 = x" + str(r) + ")" desc = "cp_rs1 (Test source rs1 = x" + str(r) + ")"
writeCovVector(desc, r, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, r, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
def make_rs2(test, storecmd, xlen): def make_rs2(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rs2 (Test source rs2 = x" + str(r) + ")" desc = "cp_rs2 (Test source rs2 = x" + str(r) + ")"
writeCovVector(desc, rs1, r, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, r, rd, rs1val, rs2val, immval, rdval, test, xlen)
def make_rd_rs1(test, storecmd, xlen): def make_rd_rs1(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rd_rs1 (Test rd = rs1 = x" + str(r) + ")" desc = "cmp_rd_rs1 (Test rd = rs1 = x" + str(r) + ")"
writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, xlen)
def make_rd_rs2(test, storecmd, xlen): def make_rd_rs2(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rd_rs2 (Test rd = rs1 = x" + str(r) + ")" desc = "cmp_rd_rs2 (Test rd = rs1 = x" + str(r) + ")"
writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, xlen)
def make_rd_rs1_rs2(test, storecmd, xlen): def make_rd_rs1_rs2(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rd_rs1_rs2 (Test rd = rs1 = rs2 = x" + str(r) + ")" desc = "cmp_rd_rs1_rs2 (Test rd = rs1 = rs2 = x" + str(r) + ")"
writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, xlen)
def make_rs1_rs2(test, storecmd, xlen): def make_rs1_rs2(test, xlen):
for r in range(32): for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rd_rs1_rs2 (Test rs1 = rs2 = x" + str(r) + ")" desc = "cmp_rd_rs1_rs2 (Test rs1 = rs2 = x" + str(r) + ")"
writeCovVector(desc, r, r, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, r, r, rd, rs1val, rs2val, immval, rdval, test, xlen)
def make_rs1_maxvals(test, storecmd, xlen): def make_rs1_maxvals(test, xlen):
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]: for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rs1_maxvals (Test source rs1 value = " + hex(v) + ")" desc = "cp_rs1_maxvals (Test source rs1 value = " + hex(v) + ")"
writeCovVector(desc, rs1, rs2, rd, v, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, v, rs2val, immval, rdval, test, xlen)
def make_rs2_maxvals(test, storecmd, xlen): def make_rs2_maxvals(test, xlen):
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]: for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rs2_maxvals (Test source rs2 value = " + hex(v) + ")" desc = "cp_rs2_maxvals (Test source rs2 value = " + hex(v) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, v, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, rs1val, v, immval, rdval, test, xlen)
def make_rd_maxvals(test, storecmd, xlen): def make_rd_maxvals(test, xlen):
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]: for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
# rs1 = 0, rs2 = v, others are random
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")" desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
writeCovVector(desc, rs1, 0, rd, v, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, 0, rd, v, rs2val, immval, rdval, test, xlen)
# rs1, rs2 = v, others are random
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
writeCovVector(desc, rs1, rs2, rd, v, v, immval, rdval, test, xlen)
# rs1 = all 1s, rs2 = v, others are random
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
writeCovVector(desc, rs1, rs2, rd, -1, v, immval, rdval, test, xlen)
def make_rd_rs1_eqval(test, storecmd, xlen): def make_rd_rs1_eqval(test, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rdm_rs1_eqval (Test rs1 = rd = " + hex(rs1val) + ")" desc = "cmp_rdm_rs1_eqval (Test rs1 = rd = " + hex(rs1val) + ")"
writeCovVector(desc, rs1, 0, rd, rdval, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, 0, rd, rdval, rs2val, immval, rdval, test, xlen)
def make_rd_rs2_eqval(test, storecmd, xlen): def make_rd_rs2_eqval(test, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rd_rs2_eqval (Test rs2 = rd = " + hex(rs2val) + ")" desc = "cmp_rd_rs2_eqval (Test rs2 = rd = " + hex(rs2val) + ")"
writeCovVector(desc, 0, rs2, rd, rs1val, rdval, immval, rdval, test, storecmd, xlen) writeCovVector(desc, 0, rs2, rd, rs1val, rdval, immval, rdval, test, xlen)
def make_rs1_rs2_eqval(test, storecmd, xlen): def make_rs1_rs2_eqval(test, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rs1_rs2_eqval (Test rs1 = rs2 = " + hex(rs1val) + ")" desc = "cmp_rs1_rs2_eqval (Test rs1 = rs2 = " + hex(rs1val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs1val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, rs1val, rs1val, immval, rdval, test, xlen)
#def make_cp_gpr_hazard(test, storecmd, xlen): def make_cp_gpr_hazard(test, xlen):
# pass # *** to be implemented *** for haz in ["raw", "waw", "war"]:
for src in range(2):
[rs1a, rs2a, rda, rs1vala, rs2vala, immvala, rdvala] = randomize()
[rs1b, rs2b, rdb, rs1valb, rs2valb, immvalb, rdvalb] = randomize()
# set up hazard
if (haz == "raw"):
if (src):
rs2b = rda
else:
rs1b = rda
elif (haz == "waw"):
rdb = rda
elif (haz == "war"):
if (src):
rdb = rs2a
else:
rdb = rs1a
desc = "cmp_gpr_hazard " + haz + " test"
writeHazardVector(desc, rs1a, rs2a, rda, rs1b, rs2b, rdb, test)
def make_rs1_sign(test, storecmd, xlen): def make_rs1_sign(test, xlen):
for v in [1, -1]: for v in [1, -1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
rs1val = abs(rs1val % 2**(xlen-1)) * v; rs1val = abs(rs1val % 2**(xlen-1)) * v;
desc = "cp_rs1_sign (Test source rs1 value = " + hex(rs1val) + ")" desc = "cp_rs1_sign (Test source rs1 value = " + hex(rs1val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
def make_rs2_sign(test, storecmd, xlen): def make_rs2_sign(test, xlen):
for v in [1, -1]: for v in [1, -1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
rs2val = abs(rs2val % 2**(xlen-1)) * v; rs2val = abs(rs2val % 2**(xlen-1)) * v;
desc = "cp_rs2_sign (Test source rs2 value = " + hex(rs2val) + ")" desc = "cp_rs2_sign (Test source rs2 value = " + hex(rs2val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
def make_cr_rs1_rs2_sign(test, storecmd, xlen): def make_cr_rs1_rs2_sign(test, xlen):
for v1 in [1, -1]: for v1 in [1, -1]:
for v2 in [1, -1]: for v2 in [1, -1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
rs1val = abs(rs1val % 2**(xlen-1)) * v1; rs1val = abs(rs1val % 2**(xlen-1)) * v1;
rs2val = abs(rs2val % 2**(xlen-1)) * v2; rs2val = abs(rs2val % 2**(xlen-1)) * v2;
desc = "cr_rs1_rs2 (Test source rs1 = " + hex(rs1val) + " rs2 = " + hex(rs2val) + ")" desc = "cr_rs1_rs2 (Test source rs1 = " + hex(rs1val) + " rs2 = " + hex(rs2val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
def write_tests(coverpoints, test, storecmd, xlen): def make_imm_zero(test, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_imm_zero"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, 0, rdval, test, xlen)
def write_tests(coverpoints, test, xlen):
for coverpoint in coverpoints: for coverpoint in coverpoints:
if (coverpoint == "cp_asm_count"): if (coverpoint == "cp_asm_count"):
pass pass
elif (coverpoint == "cp_rd"): elif (coverpoint == "cp_rd"):
make_rd(test, storecmd, xlen) make_rd(test, xlen)
elif (coverpoint == "cp_rs1"): elif (coverpoint == "cp_rs1"):
make_rs1(test, storecmd, xlen) make_rs1(test, xlen)
elif (coverpoint == "cp_rs2"): elif (coverpoint == "cp_rs2"):
make_rs2(test, storecmd, xlen) make_rs2(test, xlen)
elif (coverpoint == "cmp_rd_rs1"): elif (coverpoint == "cmp_rd_rs1"):
make_rd_rs1(test, storecmd, xlen) make_rd_rs1(test, xlen)
elif (coverpoint == "cmp_rd_rs2"): elif (coverpoint == "cmp_rd_rs2"):
make_rd_rs2(test, storecmd, xlen) make_rd_rs2(test, xlen)
elif (coverpoint == "cmp_rd_rs1_rs2"): elif (coverpoint == "cmp_rd_rs1_rs2"):
make_rd_rs1_rs2(test, storecmd, xlen) make_rd_rs1_rs2(test, xlen)
elif (coverpoint == "cmp_rd_rs1_eq"): elif (coverpoint == "cmp_rd_rs1_eq"):
pass # duplicate of cmp_rd_rs1 pass # duplicate of cmp_rd_rs1
elif (coverpoint == "cmp_rd_rs2_eq"): elif (coverpoint == "cmp_rd_rs2_eq"):
pass # duplicate of cmp_rd_rs2 pass # duplicate of cmp_rd_rs2
elif (coverpoint == "cmp_rs1_rs2_eq"): elif (coverpoint == "cmp_rs1_rs2_eq"):
make_rs1_rs2(test, storecmd, xlen) make_rs1_rs2(test, xlen)
elif (coverpoint == "cp_rs1_maxvals"): elif (coverpoint == "cp_rs1_maxvals"):
make_rs1_maxvals(test, storecmd, xlen) make_rs1_maxvals(test, xlen)
elif (coverpoint == "cp_rs2_maxvals"): elif (coverpoint == "cp_rs2_maxvals"):
make_rs2_maxvals(test, storecmd, xlen) make_rs2_maxvals(test, xlen)
elif (coverpoint == "cp_rd_maxvals"): elif (coverpoint == "cp_rd_maxvals"):
make_rd_maxvals(test, storecmd, xlen) make_rd_maxvals(test, xlen)
elif (coverpoint == "cmp_rd_rs1_eqval"): elif (coverpoint == "cmp_rd_rs1_eqval"):
make_rd_rs1_eqval(test, storecmd, xlen) make_rd_rs1_eqval(test, xlen)
elif (coverpoint == "cmp_rd_rs2_eqval"): elif (coverpoint == "cmp_rd_rs2_eqval"):
make_rd_rs2_eqval(test, storecmd, xlen) make_rd_rs2_eqval(test, xlen)
elif (coverpoint == "cmp_rs1_rs2_eqval"): elif (coverpoint == "cmp_rs1_rs2_eqval"):
make_rs1_rs2_eqval(test, storecmd, xlen) make_rs1_rs2_eqval(test, xlen)
elif (coverpoint == "cp_rs1_sign"): elif (coverpoint == "cp_rs1_sign"):
make_rs1_sign(test, storecmd, xlen) make_rs1_sign(test, xlen)
elif (coverpoint == "cp_rs2_sign"): elif (coverpoint == "cp_rs2_sign"):
make_rs2_sign(test, storecmd, xlen) make_rs2_sign(test, xlen)
elif (coverpoint == "cp_rd_sign"): elif (coverpoint == "cp_rd_sign"):
pass #TODO hope already covered by rd_maxvals pass #TODO hope already covered by rd_maxvals
elif (coverpoint == "cr_rs1_rs2"): elif (coverpoint == "cr_rs1_rs2"):
make_cr_rs1_rs2_sign(test, storecmd, xlen) make_cr_rs1_rs2_sign(test, xlen)
elif (coverpoint == "cp_gpr_hazard"):
make_cp_gpr_hazard(test, xlen)
elif (coverpoint == "cp_rs1_toggle"): elif (coverpoint == "cp_rs1_toggle"):
pass #TODO toggle not needed and seems to be covered by other things pass #TODO toggle not needed and seems to be covered by other things
elif (coverpoint == "cp_rs2_toggle"): elif (coverpoint == "cp_rs2_toggle"):
pass #TODO toggle not needed and seems to be covered by other things pass #TODO toggle not needed and seems to be covered by other things
elif (coverpoint == "cp_rd_toggle"): elif (coverpoint == "cp_rd_toggle"):
pass #TODO toggle not needed and seems to be covered by other things pass #TODO toggle not needed and seems to be covered by other things
elif (coverpoint == "cp_gpr_hazard"):
pass #TODO not yet implemented
elif (coverpoint == "cp_imm_sign"): elif (coverpoint == "cp_imm_sign"):
pass #TODO make_imm_zero(test, xlen)
elif (coverpoint == "cr_rs1_imm"): elif (coverpoint == "cr_rs1_imm"):
pass #TODO (not if crosses are not needed) pass #TODO (not if crosses are not needed)
elif (coverpoint == "cp_imm_ones_zeros"): elif (coverpoint == "cp_imm_ones_zeros"):
@ -253,7 +304,7 @@ def write_tests(coverpoints, test, storecmd, xlen):
elif (coverpoint == "cp_mem_hazard"): elif (coverpoint == "cp_mem_hazard"):
pass #TODO pass #TODO
elif (coverpoint == "cp_imm_zero"): elif (coverpoint == "cp_imm_zero"):
pass #TODO make_imm_zero(test, xlen)
elif (coverpoint == "cp_mem_unaligned"): elif (coverpoint == "cp_mem_unaligned"):
pass #TODO pass #TODO
elif (coverpoint == "cp_offset"): elif (coverpoint == "cp_offset"):
@ -303,8 +354,11 @@ rtype = ["add", "sub", "sll", "slt", "sltu", "xor", "srl", "sra", "or", "and",
loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"] loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
shiftitype = ["slli", "srli", "srai"] shiftitype = ["slli", "srli", "srai"]
itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"] itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"]
stypes = ["sb", "sh", "sw", "sd"] stype = ["sb", "sh", "sw", "sd"]
btypes = ["beq", "bne", "blt", "bge", "bltu", "bgeu"] btype = ["beq", "bne", "blt", "bge", "bltu", "bgeu"]
jtype = ["jal"]
jalrtype = ["jalr"]
utype = ["lui", "auipc"]
# TODO: auipc missing, check whatelse is missing in ^these^ types # TODO: auipc missing, check whatelse is missing in ^these^ types
coverpoints = getcovergroups(coverdefdir, coverfiles) coverpoints = getcovergroups(coverdefdir, coverfiles)
@ -327,12 +381,11 @@ for xlen in xlens:
else: else:
storecmd = "sd" storecmd = "sd"
wordsize = 8 wordsize = 8
WALLY = os.environ.get('WALLY')
pathname = WALLY+"/tests/functcov/rv" + str(xlen) + "/I/"
cmd = "mkdir -p " + pathname + " ; rm -f " + pathname + "/*" # make directory and remove old tests in dir
os.system(cmd)
for test in coverpoints.keys(): for test in coverpoints.keys():
# pathname = "../wally-riscv-arch-test/riscv-test-suite/rv" + str(xlen) + "i_m/I/"
WALLY = os.environ.get('WALLY')
pathname = WALLY+"/tests/functcov/rv" + str(xlen) + "/I/"
cmd = "mkdir -p " + pathname
os.system(cmd)
basename = "WALLY-COV-" + test basename = "WALLY-COV-" + test
fname = pathname + "/" + basename + ".S" fname = pathname + "/" + basename + ".S"
@ -340,9 +393,9 @@ for xlen in xlens:
f = open(fname, "w") f = open(fname, "w")
line = "///////////////////////////////////////////\n" line = "///////////////////////////////////////////\n"
f.write(line) f.write(line)
lines="// "+fname+ "\n// " + author + "\n" line="// "+fname+ "\n// " + author + "\n"
f.write(lines) f.write(line)
line ="// Created " + str(datetime.now()) line ="// Created " + str(datetime.now()) + "\n"
f.write(line) f.write(line)
# insert generic header # insert generic header
@ -355,8 +408,8 @@ for xlen in xlens:
#if (test not in rtests): #if (test not in rtests):
# exit("Error: %s not implemented yet" % test) # exit("Error: %s not implemented yet" % test)
#else: #else:
# write_rtype_arith_vectors(test, storecmd, xlen) # write_rtype_arith_vectors(test, xlen)
write_tests(coverpoints[test], test, storecmd, xlen) write_tests(coverpoints[test], test, xlen)
# print footer # print footer
line = "\n.EQU NUMTESTS," + str(1) + "\n\n" line = "\n.EQU NUMTESTS," + str(1) + "\n\n"
@ -366,9 +419,6 @@ for xlen in xlens:
f.write(line) f.write(line)
# Finish # Finish
# lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
# lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close() f.close()