mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge pull request #947 from davidharrishmc/main
Recreate coverage improvements
This commit is contained in:
commit
f365e460f8
@ -232,8 +232,8 @@ bpredtests = [
|
||||
# list of tests not supported by ImperasDV yet that should be waived during lockstep testing
|
||||
lockstepwaivers = [
|
||||
"WALLY-q-01.S_ref.elf", # Q extension is not supported by ImperasDV
|
||||
"WALLY-cbom-01.S_ref.elf", # cbom extension is not supported by ImperasDV because there is no cache model in ImperasDV
|
||||
"coverage_ieu.elf" # Issue 881: ImperasDV misinterprets 0x6BF05013 as a grevi rather than an illegal instruction
|
||||
"WALLY-cbom-01.S_ref.elf" #, # cbom extension is not supported by ImperasDV because there is no cache model in ImperasDV
|
||||
# "coverage_ieu.elf" # Issue 881: ImperasDV misinterprets 0x6BF05013 as a grevi rather than an illegal instruction
|
||||
]
|
||||
|
||||
##################################
|
||||
@ -408,7 +408,8 @@ if (args.ccov): # only run RV64GC tests on Questa in code coverage mode
|
||||
if (args.fp):
|
||||
addTests(tests64gc_fp, coveragesim)
|
||||
elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional coverage mode
|
||||
addLockstepTestsByDir(WALLY+"/tests/functcov/rv64/I", "rv64gc", coveragesim)
|
||||
# addLockstepTestsByDir(WALLY+"/tests/functcov/rv64/I", "rv64gc", coveragesim)
|
||||
addLockstepTestsByDir(WALLY+"/addins/cvw-arch-verif/tests/rv32/I", "rv32gc", coveragesim)
|
||||
elif (args.fcovrvvi): # only run RV64GC tests on Questa in rvvi coverage mode
|
||||
addTests(tests64gc_nofp, coveragesim)
|
||||
if (args.fp):
|
||||
@ -545,7 +546,8 @@ def main():
|
||||
if args.ccov:
|
||||
os.system('make QuestaCodeCoverage')
|
||||
if args.fcov:
|
||||
os.system('make QuestaFunctCoverage')
|
||||
#os.system('make QuestaFunctCoverage')
|
||||
os.system('make -f '+WALLY+'/addins/cvw-arch-verif/Makefile merge')
|
||||
if args.fcovrvvi:
|
||||
os.system('make QuestaFunctCoverageRvvi')
|
||||
# Count the number of failures
|
||||
|
16
bin/wsim
16
bin/wsim
@ -27,8 +27,8 @@ parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilat
|
||||
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("--ccov", "-c", help="Code Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", "-f", help="Functional Coverage, implies lockstep", action="store_true")
|
||||
parser.add_argument("--fcov2", "-f2", help="Functional Coverage, implies lockstep", action="store_true")
|
||||
parser.add_argument("--fcovimp", "-f2", help="Functional Coverage with Imperas licensed riscvISACOV, implies lockstep", action="store_true")
|
||||
parser.add_argument("--fcov", "-f", help="Functional Coverage with cvw-arch-verif, implies lockstep", action="store_true")
|
||||
parser.add_argument("--fcovrvvi", "-fr", help="Functional Coverage RVVI", action="store_true")
|
||||
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
|
||||
parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", default="")
|
||||
@ -68,7 +68,7 @@ if(args.testsuite.endswith('.elf') and args.elf == ""): # No --elf argument; che
|
||||
|
||||
|
||||
# Validate arguments
|
||||
if (args.gui or args.ccov or args.fcov or args.fcov2 or args.fcovrvvi or args.lockstep):
|
||||
if (args.gui or args.ccov or args.fcov or args.fcovimp or args.fcovrvvi or args.lockstep):
|
||||
if args.sim not in ["questa", "vcs"]:
|
||||
print("Option only supported for Questa and VCS")
|
||||
exit(1)
|
||||
@ -85,7 +85,7 @@ if (args.tb == "testbench_fp"):
|
||||
# if lockstep is enabled, then we need to pass the Imperas lockstep arguments
|
||||
if(int(args.locksteplog) >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
if((args.lockstep or args.fcov or args.fcov2) and args.sim == "questa"):
|
||||
if((args.lockstep or args.fcov or args.fcovimp) and args.sim == "questa"):
|
||||
prefix = "IMPERAS_TOOLS=" + WALLY + "/config/"+args.config+"/imperas.ic"
|
||||
prefix = "MTI_VCO_MODE=64 " + prefix
|
||||
else:
|
||||
@ -94,13 +94,13 @@ else:
|
||||
if (args.lockstep):
|
||||
if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog)
|
||||
else: ImperasPlusArgs = ""
|
||||
if(args.fcov):
|
||||
if(args.fcovimp):
|
||||
CovEnableStr = "1" if int(args.covlog) > 0 else "0"
|
||||
if(args.covlog >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr
|
||||
suffix = ""
|
||||
if(args.fcov2):
|
||||
if(args.fcov):
|
||||
CovEnableStr = "1" if int(args.covlog) > 0 else "0";
|
||||
if(args.covlog >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
@ -121,8 +121,8 @@ if (args.ccov):
|
||||
flags += " --ccov"
|
||||
if (args.fcov):
|
||||
flags += " --fcov"
|
||||
if (args.fcov2):
|
||||
flags += " --fcov2"
|
||||
if (args.fcovimp):
|
||||
flags += " --fcovimp"
|
||||
if (args.fcovrvvi):
|
||||
flags += "--fcovrvvi"
|
||||
|
||||
|
@ -111,9 +111,9 @@
|
||||
|
||||
# Add Imperas simulator application instruction tracing
|
||||
# uncomment these to provide tracing
|
||||
--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||
--override cpu/debugflags=6 --override cpu/verbose=1
|
||||
--override cpu/show_c_prefix=T
|
||||
#--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||
#--override cpu/debugflags=6 --override cpu/verbose=1
|
||||
#--override cpu/show_c_prefix=T
|
||||
|
||||
# Store simulator output to logfile
|
||||
--output imperas.log
|
||||
|
@ -115,8 +115,8 @@ if {[lcheck lst "--fcovrvvi"]} {
|
||||
set FCdefineRVVI_COVERAGE "+define+RVVI_COVERAGE"
|
||||
}
|
||||
|
||||
# if --fcov found set flag and remove from list
|
||||
if {[lcheck lst "--fcov"]} {
|
||||
# if --fcovimp found set flag and remove from list
|
||||
if {[lcheck lst "--fcovimp"]} {
|
||||
set FunctCoverage 1
|
||||
set FCvlog "+define+INCLUDE_TRACE2COV \
|
||||
+define+IDV_INCLUDE_TRACE2COV \
|
||||
@ -135,15 +135,17 @@ if {[lcheck lst "--fcov"]} {
|
||||
|
||||
}
|
||||
|
||||
# if --fcov2 found set flag and remove from list
|
||||
if {[lcheck lst "--fcov2"]} {
|
||||
# if --fcov found set flag and remove from list
|
||||
if {[lcheck lst "--fcov"]} {
|
||||
set FunctCoverage 1
|
||||
set FCvlog "+define+INCLUDE_TRACE2COV \
|
||||
+define+IDV_INCLUDE_TRACE2COV \
|
||||
+define+COVER_BASE_RV32I \
|
||||
+define+COVER_LEVEL_DV_PR_EXT \
|
||||
+incdir+$env(WALLY)/addins/riscvISACOV/source \
|
||||
+incdir+$env(WALLY)/addins/cvw-arch-verif/fcov/RV32"
|
||||
"
|
||||
# +incdir+$env(WALLY)/addins/cvw-arch-verif/fcov/rv32 \
|
||||
|
||||
set FCvopt "+TRACE2COV_ENABLE=1 +IDV_TRACE2COV=1"
|
||||
# Uncomment various cover statements below to control which extensions get functional coverage
|
||||
lappend FCdefineCOVER_EXTS "+define+COVER_RV32I"
|
||||
@ -165,7 +167,6 @@ if {[lcheck lst "--lockstep"] || $FunctCoverage == 1} {
|
||||
${IMPERAS_HOME}/ImpPublic/source/host/rvvi/*.sv \
|
||||
${IMPERAS_HOME}/ImpProprietary/source/host/idv/*.sv"
|
||||
set SVLib "-sv_lib ${IMPERAS_HOME}/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model"
|
||||
#set OtherFlags $::env(OTHERFLAGS) # not working 7/15/24 dh; this should be the way to pass things like --verbose (Issue 871)
|
||||
}
|
||||
|
||||
# Set PlusArgs passed using the --args flag
|
||||
@ -202,7 +203,7 @@ if {$DEBUG > 0} {
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI}/common +incdir+${FCRVVI}"
|
||||
set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI} +incdir+${FCRVVI}/rv32 +incdir+${FCRVVI}/common +incdir+${FCRVVI}"
|
||||
set SOURCES "${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv"
|
||||
vlog -lint +nowarnRDGN -work ${WKDIR} {*}${INC_DIRS} {*}${FCvlog} {*}${FCdefineCOVER_EXTS} {*}${lockstepvlog} ${FCdefineRVVI_COVERAGE} {*}${SOURCES} -suppress 2244 -suppress 2282 -suppress 2583 -suppress 7063,2596,13286
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
#all:
|
||||
# ./covergen.py
|
||||
# cd ../riscof; make wally-riscv-arch-test
|
||||
# cd ../../sim; make memfiles
|
||||
|
||||
CEXT := c
|
||||
CPPEXT := cpp
|
||||
AEXT := s
|
||||
SEXT := S
|
||||
SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\)
|
||||
#SRCS = $(wildcard *.S)
|
||||
#PROGS = $(patsubst %.S,%,$(SRCS))
|
||||
SRCDIR = ${WALLY}/tests/functcov/rv64/I
|
||||
SRCEXT = S
|
||||
SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort)
|
||||
OBJEXT = elf
|
||||
OBJECTS := $(SOURCES:.$(SEXT)=.$(OBJEXT))
|
||||
|
||||
all:
|
||||
./covergen.py
|
||||
make build
|
||||
|
||||
build: $(OBJECTS)
|
||||
|
||||
%.elf.objdump: %.elf
|
||||
|
||||
# Change many things if bit width isn't 64
|
||||
$(SRCDIR)/%.elf: $(SRCDIR)/%.$(SEXT)
|
||||
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \
|
||||
-nostartfiles -T${WALLY}/examples/link/link.ld $<
|
||||
riscv64-unknown-elf-objdump -S -D $@ > $@.objdump
|
||||
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile
|
||||
extractFunctionRadix.sh $@.objdump
|
||||
|
||||
clean:
|
||||
rm -f ${SRCDIR}/*.elf ${SRCDIR}/*.objdump ${SRCDIR}/*.addr *${SRCDIR}/.lab ${SRCDIR}/*.memfile
|
||||
|
||||
|
||||
|
@ -1,491 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
##################################
|
||||
# covergen.py
|
||||
#
|
||||
# David_Harris@hmc.edu 27 March 2024
|
||||
#
|
||||
# Generate directed tests for functional coverage
|
||||
##################################
|
||||
|
||||
##################################
|
||||
# libraries
|
||||
##################################
|
||||
from datetime import datetime
|
||||
from random import randint
|
||||
from random import seed
|
||||
from random import getrandbits
|
||||
import os
|
||||
import re
|
||||
|
||||
##################################
|
||||
# functions
|
||||
##################################
|
||||
|
||||
def shiftImm(imm, xlen):
|
||||
imm = imm % xlen
|
||||
return str(imm)
|
||||
|
||||
def signedImm12(imm):
|
||||
imm = imm % pow(2, 12)
|
||||
if (imm & 0x800):
|
||||
imm = imm - 0x1000
|
||||
return str(imm)
|
||||
|
||||
def unsignedImm20(imm):
|
||||
imm = imm % pow(2, 20)
|
||||
return str(imm)
|
||||
|
||||
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen):
|
||||
lines = "\n# Testcase " + str(desc) + "\n"
|
||||
if (rs1val < 0):
|
||||
rs1val = rs1val + 2**xlen
|
||||
if (rs2val < 0):
|
||||
rs2val = rs2val + 2**xlen
|
||||
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):
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\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"
|
||||
elif (test in shiftitype):
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
|
||||
if (test in shiftiwtype):
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, 32) + " # perform operation\n"
|
||||
else:
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n"
|
||||
elif (test in itype):
|
||||
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"
|
||||
elif (test in loaditype):#["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
|
||||
if (rs1 != 0):
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
|
||||
lines = lines + "la x" + str(rs1) + ", scratch" + " # base address \n"
|
||||
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # sub immediate from rs1 to counter offset\n"
|
||||
if (xlen == 32):
|
||||
storeop = "sw"
|
||||
else:
|
||||
storeop = "sd"
|
||||
lines = lines + storeop + " x" + str(rs2) + ", " + signedImm12(immval) +" (x" + str(rs1) + ") # store value to put someting in memory\n"
|
||||
lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation\n"
|
||||
# lines = lines + test + " x" + str(rd) + ", 0(x" + str(rs1) + ") # perform operation\n"
|
||||
elif (test in stype):#["sb", "sh", "sw", "sd"]
|
||||
if (rs1 != 0):
|
||||
if (rs2 == rs1): # make sure registers are different so they don't conflict
|
||||
rs2 = (rs1 + 1) % 32
|
||||
if (rs2 == 0):
|
||||
rs2 = 1
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
|
||||
lines = lines + "la x" + str(rs1) + ", scratch" + " # base address \n"
|
||||
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # sub immediate from rs1 to counter offset\n"
|
||||
lines = lines + test + " x" + str(rs2) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n"
|
||||
elif (test in btype):#["beq", "bne", "blt", "bge", "bltu", "bgeu"]
|
||||
for same in range(2):
|
||||
if (same):
|
||||
rs1val = rs2val
|
||||
lines = lines + "# same values in both registers\n"
|
||||
lines = lines + "nop\n"
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\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_btype_" + str(immval) + str(same) + " # perform operation \n"
|
||||
lines = lines + "addi x0, x1, 1\n"
|
||||
lines = lines + "some_label_for_btype_" + str(immval)+ str(same) + ":\n"
|
||||
lines = lines + "addi x0, x2, 2\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:
|
||||
pass
|
||||
#print("Error: %s type not implemented yet" % test)
|
||||
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():
|
||||
rs1 = randint(1, 31)
|
||||
rs2 = randint(1, 31)
|
||||
# choose rd that is different than rs1 and rs2
|
||||
rd = rs1
|
||||
while (rd == rs1 or rd == rs2):
|
||||
rd = randint(1, 31)
|
||||
rd = randint(1, 31)
|
||||
rs1val = randint(0, 2**xlen-1)
|
||||
rs2val = randint(0, 2**xlen-1)
|
||||
immval = randint(0, 2**xlen-1)
|
||||
rdval = randint(0, 2**xlen-1)
|
||||
return [rs1, rs2, rd, rs1val, rs2val, immval, rdval]
|
||||
|
||||
def make_rd(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rd (Test destination rd = x" + str(r) + ")"
|
||||
writeCovVector(desc, rs1, rs2, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs1 (Test source rs1 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs2 (Test source rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, rs1, r, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs1(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs1 (Test rd = rs1 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs2 (Test rd = rs1 = x" + str(r) + ")"
|
||||
writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs1_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs1_rs2 (Test rd = rs1 = rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rs1_rs2 (Test rs1 = rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, r, rd, rs1val, rs2val, immval, rdval, test, 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]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs1_maxvals (Test source rs1 value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, v, rs2val, immval, rdval, test, 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]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs2_maxvals (Test source rs2 value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, v, immval, rdval, test, 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]:
|
||||
# rs1 = 0, 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, 0, rd, v, rs2val, 0, 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, v, 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, v, -1, -1, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs1_eqval(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rdm_rs1_eqval (Test rs1 = rd = " + hex(rs1val) + ")"
|
||||
writeCovVector(desc, rs1, 0, rd, rdval, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs2_eqval(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs2_eqval (Test rs2 = rd = " + hex(rs2val) + ")"
|
||||
writeCovVector(desc, 0, rs2, rd, rs1val, rdval, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1_rs2_eqval(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rs1_rs2_eqval (Test rs1 = rs2 = " + hex(rs1val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs1val, immval, rdval, test, xlen)
|
||||
|
||||
def make_cp_gpr_hazard(test, xlen):
|
||||
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, xlen):
|
||||
for v in [1, -1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
rs1val = abs(rs1val % 2**(xlen-1)) * v;
|
||||
desc = "cp_rs1_sign (Test source rs1 value = " + hex(rs1val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs2_sign(test, xlen):
|
||||
for v in [1, -1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
rs2val = abs(rs2val % 2**(xlen-1)) * v;
|
||||
desc = "cp_rs2_sign (Test source rs2 value = " + hex(rs2val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_cr_rs1_rs2_sign(test, xlen):
|
||||
for v1 in [1, -1]:
|
||||
for v2 in [1, -1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
rs1val = abs(rs1val % 2**(xlen-1)) * v1;
|
||||
rs2val = abs(rs2val % 2**(xlen-1)) * v2;
|
||||
desc = "cr_rs1_rs2 (Test source rs1 = " + hex(rs1val) + " rs2 = " + hex(rs2val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, 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 make_j_imm_ones_zeros(test, xlen):
|
||||
for align in range(2,19):
|
||||
lines = "\n# Testcase cp_imm_ones_zeros " + str(align) + "\n"
|
||||
lines = lines + "li x1, " + formatstr.format(randint(0, 2**xlen-1)) + "\n"
|
||||
lines = lines + "jal x20, 1f # jump to aligned address to stress immediate\n"
|
||||
lines = lines + ".align " + str(align) + "\n"
|
||||
lines = lines + "1:\n"
|
||||
f.write(lines)
|
||||
|
||||
def make_offset(test, xlen):
|
||||
if (test in btype):
|
||||
lines = "\n# Testcase cp_offset\n"
|
||||
lines = lines + "j 2f # jump past backward branch target\n"
|
||||
lines = lines + "1: j 3f # backward branch target: jump past backward branch\n"
|
||||
lines = lines + "2: " + test + " x0, x0, 1b # backward branch\n"
|
||||
lines = lines + "3: nop # done with sequence\n"
|
||||
f.write(lines)
|
||||
|
||||
def make_mem_hazard(test, xlen):
|
||||
lines = "\n# Testcase mem_hazard (no dependency)\n"
|
||||
lines = lines + "la x1, scratch\n"
|
||||
lines = lines + test + " x2, 0(x1)\n"
|
||||
f.write(lines)
|
||||
|
||||
def make_cr_rs1_imm(test, xlen):
|
||||
desc = "cp_cr_rs1_imm"
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
for s1 in range(2):
|
||||
for s2 in range(3):
|
||||
if (s1):
|
||||
rs1v = -abs(rs1val)
|
||||
else:
|
||||
rs1v = abs(rs1val)
|
||||
if (s2 == 0):
|
||||
immv = 0
|
||||
elif (s2 == 1):
|
||||
immv = abs(immval)
|
||||
else:
|
||||
immv = -abs(immval)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1v, rs2val, immv, rdval, test, xlen)
|
||||
|
||||
def make_imm_shift(test, xlen):
|
||||
desc = "cp_imm_shift"
|
||||
for shift in range(0, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, shift, rdval, test, xlen)
|
||||
|
||||
def write_tests(coverpoints, test, xlen):
|
||||
for coverpoint in coverpoints:
|
||||
if (coverpoint == "cp_asm_count"):
|
||||
pass
|
||||
elif (coverpoint == "cp_rd"):
|
||||
make_rd(test, xlen)
|
||||
elif (coverpoint == "cp_rs1"):
|
||||
make_rs1(test, xlen)
|
||||
elif (coverpoint == "cp_rs2"):
|
||||
make_rs2(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1"):
|
||||
make_rd_rs1(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs2"):
|
||||
make_rd_rs2(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1_rs2"):
|
||||
make_rd_rs1_rs2(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1_eq"):
|
||||
pass # duplicate of cmp_rd_rs1
|
||||
elif (coverpoint == "cmp_rd_rs2_eq"):
|
||||
pass # duplicate of cmp_rd_rs2
|
||||
elif (coverpoint == "cmp_rs1_rs2_eq"):
|
||||
make_rs1_rs2(test, xlen)
|
||||
elif (coverpoint == "cp_rs1_maxvals"):
|
||||
make_rs1_maxvals(test, xlen)
|
||||
elif (coverpoint == "cp_rs2_maxvals"):
|
||||
make_rs2_maxvals(test, xlen)
|
||||
elif (coverpoint == "cp_rd_maxvals"):
|
||||
make_rd_maxvals(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1_eqval"):
|
||||
make_rd_rs1_eqval(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs2_eqval"):
|
||||
make_rd_rs2_eqval(test, xlen)
|
||||
elif (coverpoint == "cmp_rs1_rs2_eqval"):
|
||||
make_rs1_rs2_eqval(test, xlen)
|
||||
elif (coverpoint == "cp_rs1_sign"):
|
||||
make_rs1_sign(test, xlen)
|
||||
elif (coverpoint == "cp_rs2_sign"):
|
||||
make_rs2_sign(test, xlen)
|
||||
elif (coverpoint == "cp_rd_sign"):
|
||||
pass #TODO hope already covered by rd_maxvals
|
||||
elif (coverpoint == "cr_rs1_rs2"):
|
||||
make_cr_rs1_rs2_sign(test, xlen)
|
||||
elif (coverpoint == "cp_gpr_hazard"):
|
||||
make_cp_gpr_hazard(test, xlen)
|
||||
elif (coverpoint == "cp_rs1_toggle"):
|
||||
pass #TODO toggle not needed and seems to be covered by other things
|
||||
elif (coverpoint == "cp_rs2_toggle"):
|
||||
pass #TODO toggle not needed and seems to be covered by other things
|
||||
elif (coverpoint == "cp_rd_toggle"):
|
||||
pass #TODO toggle not needed and seems to be covered by other things
|
||||
elif (coverpoint == "cp_imm_sign"):
|
||||
make_imm_zero(test, xlen)
|
||||
elif (coverpoint == "cr_rs1_imm"):
|
||||
make_cr_rs1_imm(test, xlen)
|
||||
elif (coverpoint == "cp_imm_ones_zeros"):
|
||||
if (test in jtype):
|
||||
make_j_imm_ones_zeros(test, xlen)
|
||||
elif (coverpoint == "cp_mem_hazard"):
|
||||
make_mem_hazard(test, xlen)
|
||||
elif (coverpoint == "cp_imm_zero"):
|
||||
make_imm_zero(test, xlen)
|
||||
elif (coverpoint == "cp_mem_unaligned"):
|
||||
pass # seems this should be part of privileged tests
|
||||
elif (coverpoint == "cp_offset"):
|
||||
make_offset(test, xlen)
|
||||
elif (coverpoint == "cr_nord_rs1_rs2"):
|
||||
pass #TODO (not if crosses are not needed)
|
||||
elif (coverpoint == "cp_imm_shift"):
|
||||
make_imm_shift(test, xlen)
|
||||
elif (coverpoint == "cp_rd_boolean"):
|
||||
pass # covered by other generators
|
||||
else:
|
||||
print("Warning: " + coverpoint + " not implemented yet for " + test)
|
||||
|
||||
def getcovergroups(coverdefdir, coverfiles):
|
||||
coverpoints = {}
|
||||
curinstr = ""
|
||||
for coverfile in coverfiles:
|
||||
coverfile = coverdefdir + "/" + coverfile + "_coverage.svh"
|
||||
f = open(coverfile, "r")
|
||||
for line in f:
|
||||
m = re.search(r'cp_asm_count.*\"(.*)"', line)
|
||||
if (m):
|
||||
# if (curinstr != ""):
|
||||
# print(curinstr + ": " + str(coverpoints[curinstr]))
|
||||
curinstr = m.group(1)
|
||||
coverpoints[curinstr] = []
|
||||
m = re.search("\s*(\S+) :", line)
|
||||
if (m):
|
||||
coverpoints[curinstr].append(m.group(1))
|
||||
f.close()
|
||||
print(coverpoints)
|
||||
return coverpoints
|
||||
|
||||
##################################
|
||||
# main body
|
||||
##################################
|
||||
|
||||
# change these to suite your tests
|
||||
riscv = os.environ.get("RISCV")
|
||||
coverdefdir = riscv+"/ImperasDV-OpenHW/Imperas/ImpProprietary/source/host/riscvISACOV/source/coverage";
|
||||
#coverfiles = ["RV64I", "RV64M", "RV64A", "RV64C", "RV64F", "RV64D"] # add more later
|
||||
coverfiles = ["RV64I"] # add more later
|
||||
rtype = ["add", "sub", "sll", "slt", "sltu", "xor", "srl", "sra", "or", "and",
|
||||
"addw", "subw", "sllw", "srlw", "sraw"
|
||||
"mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu",
|
||||
"mulw", "divw", "divuw", "remw", "remuw"]
|
||||
loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
|
||||
shiftitype = ["slli", "srli", "srai", "slliw", "srliw", "sraiw"]
|
||||
shiftiwtype = ["slliw", "srliw", "sraiw"]
|
||||
itype = ["addi", "slti", "sltiu", "xori", "ori", "andi", "addiw"]
|
||||
stype = ["sb", "sh", "sw", "sd"]
|
||||
btype = ["beq", "bne", "blt", "bge", "bltu", "bgeu"]
|
||||
jtype = ["jal"]
|
||||
jalrtype = ["jalr"]
|
||||
utype = ["lui", "auipc"]
|
||||
# TODO: auipc missing, check whatelse is missing in ^these^ types
|
||||
|
||||
coverpoints = getcovergroups(coverdefdir, coverfiles)
|
||||
|
||||
author = "David_Harris@hmc.edu"
|
||||
xlens = [64]
|
||||
numrand = 3
|
||||
|
||||
# setup
|
||||
seed(0) # make tests reproducible
|
||||
|
||||
# generate files for each test
|
||||
for xlen in xlens:
|
||||
formatstrlen = str(int(xlen/4))
|
||||
formatstr = "0x{:0" + formatstrlen + "x}" # format as xlen-bit hexadecimal number
|
||||
formatrefstr = "{:08x}" # format as xlen-bit hexadecimal number with no leading 0x
|
||||
if (xlen == 32):
|
||||
storecmd = "sw"
|
||||
wordsize = 4
|
||||
else:
|
||||
storecmd = "sd"
|
||||
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():
|
||||
basename = "WALLY-COV-" + test
|
||||
fname = pathname + "/" + basename + ".S"
|
||||
|
||||
# print custom header part
|
||||
f = open(fname, "w")
|
||||
line = "///////////////////////////////////////////\n"
|
||||
f.write(line)
|
||||
line="// "+fname+ "\n// " + author + "\n"
|
||||
f.write(line)
|
||||
line ="// Created " + str(datetime.now()) + "\n"
|
||||
f.write(line)
|
||||
|
||||
# insert generic header
|
||||
h = open("covergen_header.S", "r")
|
||||
for line in h:
|
||||
f.write(line)
|
||||
|
||||
# print directed and random test vectors
|
||||
# Coverage for R-type arithmetic instructions
|
||||
#if (test not in rtests):
|
||||
# exit("Error: %s not implemented yet" % test)
|
||||
#else:
|
||||
# write_rtype_arith_vectors(test, xlen)
|
||||
write_tests(coverpoints[test], test, xlen)
|
||||
|
||||
# print footer
|
||||
line = "\n.EQU NUMTESTS," + str(1) + "\n\n"
|
||||
f.write(line)
|
||||
h = open("covergen_footer.S", "r")
|
||||
for line in h:
|
||||
f.write(line)
|
||||
|
||||
# Finish
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
|
||||
self_loop:
|
||||
j self_loop
|
||||
|
||||
.data
|
||||
|
||||
.align 4
|
||||
scratch:
|
||||
.bss 8
|
||||
|
||||
.end
|
@ -1,12 +0,0 @@
|
||||
//
|
||||
// Copyright (C) 2024 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
///////////////////////////////////////////
|
||||
|
||||
.section .text.init
|
||||
.globl rvtest_entry_point
|
||||
|
||||
rvtest_entry_point:
|
||||
|
||||
|
@ -8,7 +8,7 @@ This folder consists of all the required files and tools to generate Q tests for
|
||||
|
||||
NOTE : Only some of the IBM tests are currently supporting Quad testing.
|
||||
|
||||
Tests which are working : ibm1, ibm9,ibm21,ibm23,ibm24,ibm25,ibm26,ibm27,ibm28,ibm29
|
||||
Tests which are implemented in riscv-isac/riscv_isac/fp_dataset.py : ibm1, ibm9,ibm21,ibm23,ibm24,ibm25,ibm26,ibm27,ibm28,ibm29
|
||||
These ibm tests can be included in the riscv-ctg tests generation command, along with riscof.
|
||||
|
||||
The tests which are currently breaking due to overflow errors are : ibm2,ibm3,ibm4,ibm5,ibm6,ibm7,ibm8,ibm10,ibm11,ibm12,ibm13,ibm14,ibm15,ibm16,ibm17,ibm18,ibm19,ibm20,ibm22
|
||||
@ -26,7 +26,7 @@ TO DO:
|
||||
Debug why fadd.q_b1 doesn't match Sail vs. Spike
|
||||
Run the q test on Wally RTL
|
||||
Make more tests from the working datasets
|
||||
Get other datasets working by using softfloat to do quad math
|
||||
Get other fp_dataset.py datasets working by using softfloat to do quad math
|
||||
Push changes back to riscv-ctg and riscv-isac and remove them from wally-riscv-arch/tsts/riscv-test-suite/rv64i_m/Q
|
||||
|
||||
|
||||
|
@ -393,7 +393,7 @@ def ibm_b1(flen, iflen, opcode, ops):
|
||||
qinfinity + qdefaultnan + [qqnan[0], qqnan[1]] + \
|
||||
[qsnan[0], qsnan[1]] + qone
|
||||
else:
|
||||
logger.error('Invalid iflen value!')
|
||||
logger.error('Invalid iflen value is ' + iflen)
|
||||
sys.exit(1)
|
||||
|
||||
# the following creates a cross product for ops number of variables
|
||||
@ -4073,7 +4073,7 @@ def ibm_b21(flen, iflen, opcode, ops):
|
||||
qinfinity + qdefaultnan + [qqnan[0], qqnan[1]] + \
|
||||
[qsnan[0], qsnan[1]]
|
||||
else:
|
||||
logger.error('Invalid iflen value!')
|
||||
logger.error('Invalid iflen value 2 ' + iflen)
|
||||
sys.exit(1)
|
||||
|
||||
# the following creates a cross product for ops number of variables
|
||||
|
Loading…
Reference in New Issue
Block a user