Merge pull request #983 from jordancarlin/remove-old-scripts

Remove more old scripts/files
This commit is contained in:
David Harris 2024-10-01 13:02:17 -07:00 committed by GitHub
commit 3852b08fce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 51 additions and 4959 deletions

View File

@ -1,42 +0,0 @@
94e1819300002197
4281420141014081
4481440143814301
4681460145814501
4881480147814701
4a814a0149814901
4c814c014b814b01
4e814e014d814d01
0110011b4f814f01
059b45011161016e
0004063705fe0010
05a000ef8006061b
0ff003930000100f
4e952e3110060e37
c602829b0053f2b7
2023fe02dfe312fd
829b0053f2b7007e
fe02dfe312fdc602
4de31efd000e2023
059bf1402573fdd0
0000061705e20870
0010029b01260613
11010002806702fe
84b2842ae426e822
892ee04aec064505
06e000ef07e000ef
979334fd02905563
07930177d4930204
4089093394be2004
04138522008905b3
19e3014000ef2004
64a2644260e2fe94
6749808261056902
dfed8b8510472783
2423479110a73823
10472783674910f7
20058693ffed8b89
05a1118737836749
fed59be3fef5bc23
1047278367498082
67c98082dfed8b85
0000808210a7a023

View File

@ -1,11 +0,0 @@
module BUFGCE (input logic I, input logic CE, output logic O);
logic CE_Q;
always_latch begin
if(~I) begin
CE_Q <= CE;
end
end
assign O = CE_Q & I;
endmodule

View File

@ -1,32 +0,0 @@
module BUFGCE_DIV #(parameter string DivideAmt = "1")
(input logic I, input logic CLR, input logic CE, output logic O);
integer PulseCount = 0;
logic Q;
always_ff @(posedge I, posedge CLR) begin
if(CLR) PulseCount <= 0;
else begin
if(PulseCount < (DivideAmt.atoi()/2 - 1))
PulseCount <= PulseCount + 1;
else
PulseCount <= 0;
end
end
assign zero = PulseCount == 0;
flopenr #(1) ToggleFlipFLop
(.d(~Q),
.q(Q),
.clk(I),
.reset(CLR), // reset when told by outside
.en(zero)); // only update when counter overflows
if (DivideAmt != "1")
assign O = Q;
else
assign O = I;
endmodule

View File

@ -1,4 +0,0 @@
module BUFGMUX(input logic I1, input logic I0, input logic S, output logic O);
assign O = S ? I1 : I0;
endmodule

View File

@ -1,56 +0,0 @@
Procedure for Runnning SoftFloat/TestFloat with Wally
1.) First, compile SoftFloat and TestFloat by going to the addins
directory and finding the specific build directory (e.g.,
Linux_x86_64-GCC. Currently, we are using v3e of
SoftFloat/TestFloat. I am not sure of the order, but I always compile
SoftFloat first as I believe TestFloat uses the static library
SoftFloat creates.
2.) Once compiled both, go to the tests/fp directory and run the
create_vectors.sh Linux script. In the past, we have automated this,
but I believe this has fallen into more of a manual state lately.
3.) Then, run remove_spaces.sh which will remove spaces from the
output and put underscores between vectors (this helps differentiate
the vectors that are generated). Again, this can be combined with
Step 2.
4.) TestFloat is run from wally/cvw/sim and sim-testfloat-batch with
its respective test. The format is ./sim-testfloat-add add. All of
the tests are listed below. This can be augmented or added to for
other FP tests given by the great SoftFloat/TestFloat output.
cvtint - test integer conversion unit (fcvtint)
cvtfp - test floating-point conversion unit (fcvtfp)
cmp - test comparison unit's LT, LE, EQ opperations (fcmp)
add - test addition
fma - test fma
mul - test mult with fma
sub - test subtraction
div - test division
sqrt - test square root
all - test everything
4a.) Each test will test all its vectors - if you want to test a
subset of the vectors (e.g., only binary16), you should modify the
testfloat.do in the sim directory. Change the TEST_SIZE="all" to the
specific test you want to run. For example, if you want to run only
binary16, you should set this variable to TEST_SIZE="HP".
4b.) If you want to turn off the generation of wlf files while running
sim-testfloat-batch, you can modify testfloat.do in the sim
directory. Inside this DO file, modify the WAV file to 0 --> i.e.,
set "quietly set WAV 0;"

View File

@ -1,194 +0,0 @@
#!/usr/bin/env python3
##################################
#
# regression-wally
# David_Harris@Hmc.edu 25 January 2021
# Modified by Jarred Allen <jaallen@g.hmc.edu>
#
# Run a regression with multiple configurations in parallel and exit with
# non-zero status code if an error happened, as well as printing human-readable
# output.
#
##################################
import sys,os,shutil
import argparse
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
from collections import namedtuple
regressionDir = os.path.dirname(os.path.abspath(__file__))
os.chdir(regressionDir)
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
# name: the name of this test configuration (used in printing human-readable
# output and picking logfile names)
# cmd: the command to run to test (should include the logfile as '{}', and
# the command needs to write to that file)
# grepstr: the string to grep through the log file for. The test succeeds iff
# grep finds that string in the logfile (is used by grep, so it may
# be any pattern grep accepts, see `man 1 grep` for more info).
# edit this list to add more test cases
configs = [
TestCase(
name="lints",
variant="all",
cmd="./lint-wally | tee {}",
grepstr="All lints run with no errors or warnings"
)
]
import os
from multiprocessing import Pool, TimeoutError
def search_log_for_text(text, logfile):
"""Search through the given log file for text, returning True if it is found or False if it is not"""
grepcmd = "grep -e '%s' '%s' > /dev/null" % (text, logfile)
return os.system(grepcmd) == 0
def run_test_case(config):
"""Run the given test case, and return 0 if the test suceeds and 1 if it fails"""
logname = "logs/"+config.variant+"_"+config.name+".log"
cmd = config.cmd.format(logname)
print(cmd)
os.chdir(regressionDir)
os.system(cmd)
if search_log_for_text(config.grepstr, logname):
print(f"{bcolors.OKGREEN}%s_%s: Success{bcolors.ENDC}" % (config.variant, config.name))
return 0
else:
print(f"{bcolors.FAIL}%s_%s: Failures detected in output{bcolors.ENDC}" % (config.variant, config.name))
print(" Check %s" % logname)
return 1
def main():
"""Run the tests and count the failures"""
TIMEOUT_DUR = 10800 # 3 hours
global configs
try:
os.chdir(regressionDir)
os.mkdir("logs")
#print(os.getcwd())
#print(regressionDir)
except:
pass
try:
shutil.rmtree("wkdir")
except:
pass
finally:
os.mkdir("wkdir")
parser = argparse.ArgumentParser(description='Runs embench with sweeps of branch predictor sizes and types.')
mode = parser.add_mutually_exclusive_group()
mode.add_argument('-r', '--ras', action='store_const', help='Sweep size of return address stack (RAS).', default=False, const=True)
mode.add_argument('-d', '--direction', action='store_const', help='Sweep size of direction prediction (2-bit, Gshare, local, etc).', default=False, const=True)
mode.add_argument('-t', '--target', action='store_const', help='Sweep size of branch target buffer (BTB).', default=False, const=True)
mode.add_argument('-c', '--iclass', action='store_const', help='Sweep size of classification (BTB) Same as -t.', default=False, const=True)
args = parser.parse_args()
if(args.direction):
# for direction predictor size sweep
bpdSize = [6, 8, 10, 12, 14, 16]
#bpdType = ['twobit', 'gshare', 'global', 'gshare_basic', 'global_basic', 'local_basic']
bpdType = ['twobit', 'gshare']
for CurrBPType in bpdType:
for CurrBPSize in bpdSize:
name = CurrBPType+str(CurrBPSize)
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=" + str(bpdType.index(CurrBPType)) + "+define+BPRED_SIZE=" + str(CurrBPSize)
tc = TestCase(
name=name,
variant="rv32gc",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
grepstr="")
configs.append(tc)
if(args.target):
# BTB and class size sweep
bpdSize = [6, 8, 10, 12, 14, 16]
for CurrBPSize in bpdSize:
name = 'BTB'+str(CurrBPSize)
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+RAS_SIZE=16+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE"
tc = TestCase(
name=name,
variant="rv32gc",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
grepstr="")
configs.append(tc)
if(args.iclass):
# BTB and class size sweep
bpdSize = [6, 8, 10, 12, 14, 16]
for CurrBPSize in bpdSize:
name = 'class'+str(CurrBPSize)
configOptions = "+define+INSTR_CLASS_PRED=1 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+RAS_SIZE=16+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE"
tc = TestCase(
name=name,
variant="rv32gc",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
grepstr="")
configs.append(tc)
# ras size sweep
if(args.ras):
bpdSize = [2, 3, 4, 6, 10, 16]
for CurrBPSize in bpdSize:
name = 'RAS'+str(CurrBPSize)
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=16" + "+define+RAS_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE+define+RAS_OVERRIDE"
tc = TestCase(
name=name,
variant="rv32gc",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
grepstr="")
configs.append(tc)
# bpdSize = [6, 8, 10, 12, 14, 16]
# LHRSize = [4, 8, 10]
# bpdType = ['local_repair']
# for CurrBPType in bpdType:
# for CurrBPSize in bpdSize:
# for CurrLHRSize in LHRSize:
# name = str(CurrLHRSize)+CurrBPType+str(CurrBPSize)
# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_TYPE=\"BP_" + CurrBPType.upper() + "\" +define+BPRED_SIZE=" + str(CurrBPSize) + " +define+BPRED_NUM_LHR=" + str(CurrLHRSize) + " "
# tc = TestCase(
# name=name,
# variant="rv32gc",
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
# grepstr="")
# configs.append(tc)
# 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
with Pool(processes=min(len(configs),40)) as pool:
num_fail = 0
results = {}
for config in configs:
results[config] = pool.apply_async(run_test_case,(config,))
for (config,result) in results.items():
try:
num_fail+=result.get(timeout=TIMEOUT_DUR)
except TimeoutError:
num_fail+=1
print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (config.variant, config.name, TIMEOUT_DUR))
# Count the number of failures
if num_fail:
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)
else:
print(f"{bcolors.OKGREEN}SUCCESS! All tests ran without failures{bcolors.ENDC}")
return num_fail
if __name__ == '__main__':
exit(main())

View File

@ -1,42 +0,0 @@
#!/usr/bin/env python3
import sys, os, subprocess
def main():
RISCV = os.environ.get("RISCV")
maxGoodCount = 400e6 # num instrs that execute sucessfully starting from 0
currInstrCount = maxGoodCount
linuxTestvectors = RISCV+"/linux-testvectors"
if not os.path.exists(linuxTestvectors):
sys.stderr.write("Error: Linux testvectors not found at "+linuxTestvectors+"\n")
exit(1)
checkpointList = [int(fileName.strip('checkpoint')) for fileName in os.listdir(linuxTestvectors) if 'checkpoint' in fileName]
checkpointList.sort()
logDir = "./logs/buildrootBugFinderLogs/"
os.system("mkdir -p "+logDir)
summaryLogFilePath = logDir+"summary.log"
summaryLogFile = open(summaryLogFilePath,'w')
summaryLogFile.close()
while True:
checkpointList = [checkpoint for checkpoint in checkpointList if checkpoint > currInstrCount]
if len(checkpointList)==0:
break
checkpoint = checkpointList[0]
logFile = logDir+"checkpoint"+str(checkpoint)+".log"
runCommand="{\nvsim -c <<!\ndo wally-batch.do buildroot buildroot "+RISCV+" 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
print(runCommand)
os.system(runCommand)
try:
logOutput = subprocess.check_output(["grep","-e","Reached",logFile])
currInstrCount = int(str(logOutput).strip('b').strip('\'').strip('\\n').split(' ')[-2])
except subprocess.CalledProcessError:
currInstrCount = checkpoint
summaryStr="Checkpoint "+str(checkpoint)+" reached "+str(currInstrCount)+" instrs\n"
summaryLogFile = open(summaryLogFilePath,'a')
summaryLogFile.write(summaryStr)
summaryLogFile.close()
return 0
if __name__ == '__main__':
exit(main())

3
sim/xcelium/README.md Normal file
View File

@ -0,0 +1,3 @@
## Xcelium Simulation with CVW
NOTE: Xcelium is not regularly tested and may not work correctly. It is also not integrated with the `wsim` command used for CVW, so the config and testsuite must be manually modified in `wally.xrun` and it does not support all of the other options provided by `wsim `.

View File

@ -1,158 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADD-SUB-SLT-SLTU-XOR-OR-AND.py
#
# David_Harris@hmc.edu 19 January 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def twoscomp(a):
amsb = a >> (xlen-1)
alsbs = ((1 << (xlen-1)) - 1) & a
if (amsb):
asigned = a - (1<<xlen)
else:
asigned = a
#print("a: " + str(a) + " amsb: "+str(amsb)+ " alsbs: " + str(alsbs) + " asigned: "+str(asigned))
return asigned
def computeExpected(a, b, test, xlen):
asigned = twoscomp(a)
bsigned = twoscomp(b)
if (test == "ADD"):
return a + b
elif (test == "SUB"):
return a - b
elif (test == "SLT"):
return asigned < bsigned
elif (test == "SLTU"):
return a < b
elif (test == "XOR"):
return a ^ b
elif (test == "OR"):
return a | b
elif (test == "AND"):
return a & b
else:
die("bad test name ", test)
# exit(1)
def randRegs():
reg1 = randint(1,31)
reg2 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
return randRegs()
else:
return reg1, reg2, reg3
def writeVector(a, b, storecmd, xlen):
global testnum
expected = computeExpected(a, b, test, xlen)
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg2, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), rs2:x" + str(reg2) + "(" +formatstr.format(b)
lines = lines + "), result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + "li x" + str(reg2) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", x" + str(reg2) + "\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, " + str(reg3) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["ADD", "SUB", "SLT", "SLTU", "XOR", "OR", "AND"]
author = "David_Harris@hmc.edu & Katherine Parry"
xlens = [32, 64]
numrand = 100;
# 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
for test in tests:
corners = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
for a in corners:
for b in corners:
writeVector(a, b, storecmd, xlen)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(xlen)
writeVector(a, b, storecmd, xlen)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,161 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADD-SUB.py
#
# David_Harris@hmc.edu 19 January 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def computeExpected(a, b, test):
if (test == "ADDI"):
return a + b
elif (test == "XORI"):
return a ^ b
elif (test == "ORI"):
return a | b
elif (test == "ANDI"):
return a & b
elif (test == "SLTI"):
return a < b
else:
die("bad test name ", test)
# exit(1)
def evaluateTwoComplement(b, bits):
if (b & (1 << (bits -1))!= 0):
b = b - (1 << bits)
return b
def randRegs():
reg1 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg3 == 6):
return randRegs()
else:
return reg1, reg3
def writeVector(a, b, storecmd):
global testnum
expected = computeExpected(evaluateTwoComplement(a,xlen), evaluateTwoComplement(b, 12), test)
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), imm12:" + "(" +formatstrimm12.format(b)
lines = lines + "), result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", SEXT_IMM(" + formatstrimm12.format(b) + ")\n"
# lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, " +"x" + str(reg3) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["ADDI", "XORI", "ORI", "ANDI", "SLTI"]
author = "Shriya Nadgauda & Ethan Falicov"
xlens = [32, 64]
numrand = 100
# 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
formatstrimm12 = "0x{:03x}" # format as 3-bit hexadecimal number
if (xlen == 32):
storecmd = "sw"
wordsize = 4
else:
storecmd = "sd"
wordsize = 8
for test in tests:
corners1 = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
immBitSize = 12
corners2 = [0, 1, 2, 0xFF, 0x624 % 2**immBitSize, 2**(immBitSize-1)-2, 2**(immBitSize-1)-1,
2**(immBitSize-1), 2**(immBitSize-1)+1, 0xC36 % 2**immBitSize, 2**(immBitSize)-2, 2**(immBitSize)-1]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
for a in corners1:
for b in corners2:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(12)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,182 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADDIW-SLLIW-SRLIW-SRAIW.py
#
# ehedenberg@hmc.edu 4 February 2021
# heavily influenced by Prof Harris Code
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
import sys
##################################
# functions
##################################
def logical_rshift(signed_integer, places):
unsigned_integer=signed_integer%(1<<32)
return unsigned_integer >> places
def toSigned12bit(n):
n=n & 0xfff
if (n&(1<<11)):
n=n|0xfffffffffffff000
return n
def toSigned32bit(n):
n=n & 0xffffffff
if (n&(1<<31)):
n=n|0xffffffff00000000
return n
def computeExpected(a, b, test):
if (test == "ADDIW"):
b=toSigned12bit(b)
return a + b
elif (test == "SLLIW"):
return (a << b)
elif (test == "SRLIW"):
return logical_rshift(a, b)
elif(test == "SRAIW"):
a= toSigned32bit(a)
return a >> b
else:
die("bad test name ", test)
# exit(1)
def randRegs():
reg1 = randint(1,31)
reg2 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
return randRegs()
else:
return reg1, reg2, reg3
def writeVector(a, b, storecmd):
global testnum
expected = computeExpected(a, b, test)
expected = expected % 2**64 # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**64 + expected
#expected=expected+2^32<<32
if (expected >= (2**32)):
expected=expected%(2**32)
expected=toSigned32bit(expected)
reg1, reg2, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), imm:"+formatstr.format(b)
lines = lines + ", result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
#lines = lines + "li x" + str(reg2) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", SEXT_IMM(" + formatstr.format(b) + ")\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, x" + str(reg3) +", "+formatstr.format(expected)+")\n"
#lines = lines + str(b)+"\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["ADDIW", "SLLIW", "SRLIW", "SRAIW"]
author = "Eizabeth Hedenberg"
xlens = [64]
shiftlen=5
addlen=12
numrand = 100
# setup
seed(0) # make tests reproducible
# generate files for each test
for xlen in xlens:
formatstrlen = str(int(xlen/4))
#formatstrlen6=str(int())
formatstr = "0x{:0" + formatstrlen + "x}" # format as xlen-bit hexadecimal number
#formatstr6 = "0x{:0" + "2" + "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
for test in tests:
cornersa = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
#test both confined to top 32 and not
cornersshift=[0, 1, 2, 2**(shiftlen)-1, 2**(shiftlen)-2, 0b00101, 0b01110]
#6 bits: 0, 1, 2, largest, largest -1, largest -2, 21, 46
cornersadd=[0, 1, 2, 2**(addlen-1), 2**(addlen-1)-1, 2**(addlen-1)-2, 2**(addlen-1)+1, 2**(addlen)-2, 2**(addlen)-1, 0b001010010101, 0b101011101111]
#12 bit, 0, 1, 2 argest positive, largest -1, largest -2, largest negative number, -2, -1, random
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
if test=="ADDIW":
for a in cornersa:
for b in cornersadd:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(12)
writeVector(a, b, storecmd)
else:
for a in cornersa:
for b in cornersshift:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(5)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,174 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADDW-SUBW-SLLW-SRLW-SRAW.py
#
# trao@g.hmc.edu 11 February 2021
# Based on testgen-ADD-SUB.py by Prof. David Harris
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
import sys
##################################
# functions
##################################
def logical_rshift(signed_integer, places):
unsigned_integer=signed_integer%(1<<32)
return unsigned_integer >> places
def toSigned12bit(n):
n=n & 0xfff
if (n&(1<<11)):
n=n|0xfffffffffffff000
return n
def toSigned32bit(n):
n=n & 0xffffffff
if (n&(1<<31)):
n=n|0xffffffff00000000
return n
def computeExpected(a, b, test):
if (test == "ADDW"):
return toSigned32bit(a + b)
elif (test == "SUBW"):
return toSigned32bit(a - b)
elif (test == "SLLW"):
b = b & 0x1F
return toSigned32bit(a << b)
elif (test == "SRLW"):
b = b & 0x1F
return toSigned32bit(logical_rshift(a, b))
elif(test == "SRAW"):
a= toSigned32bit(a)
b = b & 0x1F
return toSigned32bit(a >> b)
else:
die("bad test name ", test)
# exit(1)
def randRegs():
reg1 = randint(1,31)
reg2 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
return randRegs()
else:
return reg1, reg2, reg3
def writeVector(a, b, storecmd):
global testnum
expected = computeExpected(a, b, test)
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg2, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), rs2:x" + str(reg2) + "(" +formatstr.format(b)
lines = lines + "), result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + "li x" + str(reg2) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", x" + str(reg2) + "\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, " + str(reg3) +", "+formatstr.format(expected)+")\n"
f.write(lines)
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["ADDW", "SUBW", "SLLW", "SRLW", "SRAW"]
author = "Tejus Rao"
xlens = [64]
shiftlen=5
addlen=32
numrand = 100
# setup
seed(0) # make tests reproducible
# generate files for each test
for xlen in xlens:
formatstrlen = str(int(xlen/4))
#formatstrlen6=str(int())
formatstr = "0x{:0" + formatstrlen + "x}" # format as xlen-bit hexadecimal number
#formatstr6 = "0x{:0" + "2" + "x}" # format as xlen-bit hexadecimal number
formatrefstr = "{:08x}" # format as xlen-bit hexadecimal number with no leading 0x
storecmd = "sd"
wordsize = 8
for test in tests:
cornersa = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
#test both confined to top 32 and not
cornersshift=[0, 1, 2, 2**(shiftlen)-1, 2**(shiftlen)-2, 0b00101, 0b01110]
#6 bits: 0, 1, 2, largest, largest -1, largest -2, 21, 46
cornersadd=[0, 1, 2, 2**(addlen-1), 2**(addlen-1)-1, 2**(addlen-1)-2, 2**(addlen-1)+1, 2**(addlen)-2, 2**(addlen)-1, 0b001010010101, 0b101011101111]
#12 bit, 0, 1, 2 argest positive, largest -1, largest -2, largest negative number, -2, -1, random
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
if test=="ADDW" or test == "SUBW":
for a in cornersa:
for b in cornersadd:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(xlen)
writeVector(a, b, storecmd)
else:
for a in cornersa:
for b in cornersshift:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(5)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,155 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-branch.py
#
# ssanghai@hmc.edu 13th Feb 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def computeExpected(a, b, test):
if (test == "BEQ"):
return 0xcccc if a==b else 0xeeee
elif (test == "BNE"):
return 0xeeee if a==b else 0xcccc
elif (test == "BGEU"):
return 0xcccc if a>=b else 0xeeee
elif (test == "BLT"):
if (1<<(xlen-1)) & a:
a = a -(2**xlen)
if (1<<(xlen-1)) & b:
b = b - (2**xlen)
return 0xcccc if a<b else 0xeeee
elif (test == "BLTU"):
return 0xcccc if a<b else 0xeeee
elif (test == "BGE"):
if (1<<(xlen-1)) & a:
a = a - (2**xlen)
if (1<<(xlen-1)) & b:
b = b - (2**xlen)
return 0xcccc if a>=b else 0xeeee
else:
die("bad test name ", test)
# exit(1)
def randRegs():
reg1 = randint(2,31)
reg2 = randint(2,31)
if (reg1 == 6 or reg2 == 6 or reg1 == reg2):
return randRegs()
else:
return reg1, reg2
label = 0
def writeVector(a, b, storecmd):
global testnum
global label
expected = computeExpected(a, b, test)
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg2 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), rs2:x" + str(reg2) + "(" +formatstr.format(b) + "\n"
lines = lines + "li x1, MASK_XLEN(0xcccc)\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + "li x" + str(reg2) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + test + " x" + str(reg1) + ", x" + str(reg2) + ", " + str(label) + "f\n"
lines = lines + "li x1, MASK_XLEN(0xeeee)\n"
lines = lines + str(label) + ":\n"
lines = lines + storecmd + " x1, " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, x1, "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
label += 1
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["BEQ", "BNE", "BLT", "BGE", "BGEU", "BLTU"]
author = "Shreya Sanghai"
xlens = [32, 64]
numrand = 100
# 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
for test in tests:
corners = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
for a in corners:
for b in corners:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(xlen)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,218 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADD-SUB.py
#
# ushakya@hmc.edu & dottolia@hmc.edu 14 Feb 2021
# Modified: ushakya@hmc.edu 21 April 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def randRegs():
reg1 = randint(1,31)
reg2 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
return randRegs()
else:
return reg1, reg2, reg3
def writeVector(a, b, storecmd):
global testnum
csr = "mscratch"
reg1, reg2, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": " + csr + "\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + "li x" + str(reg2) + ", MASK_XLEN(0)\n"
# Page 6 of unpriviledged spec
# For both CSRRS and CSRRC, if rs1=x0, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects
expected = a
if test == "csrrw":
if testnum == 0:
# this is a corner case (reading and writing same register)
expected = 4
lines += "li x" + str(reg2) + ", MASK_XLEN(" + formatstr.format(0x8) + ")\n"
lines += "la x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(0x4) + ")\n"
lines += "csrrw x" + str(reg3) + ", mtvec, x" + str(reg1) + "\n"
lines += test + " x" + str(reg2) + ", mtvec, x" + str(reg2) + "\n"
lines += "csrrw x0, mtvec, x" + str(reg3) + "\n"
else:
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
elif test == "csrrs": # at some point, try writing a non-zero value first
lines += "csrrw x0, " + csr + ", x0\n" # set csr to 0
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
elif test == "csrrc": # at some point, try writing a non-one value first
allOnes = "0xFFFFFFFF" if xlen == 32 else "0xFFFFFFFFFFFFFFFF"
lines += "li x" + str(reg1) + ", MASK_XLEN(" + allOnes + ")\n"
lines += "csrrw x0, " + csr + ", x" + str(reg1) + "\n" # set csr to all ones
lines += "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
expected = a ^ 0xFFFFFFFF if xlen == 32 else a ^ 0xFFFFFFFFFFFFFFFF
elif test == "csrrwi":
a = a & 0x1F # imm is only 5 bits
lines += test + " x" + str(reg2) + ", " + csr + ", " + str(a) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", " + str(a) + "\n"
expected = a
elif test == "csrrsi": # at some point, try writing a non-zero value first
a = a & 0x1F
lines += "csrrw x0, " + csr + ", x0\n" # set csr to 0
lines += test + " x" + str(reg2) + ", " + csr + ", " + str(a) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", " + str(a) + "\n"
expected = a
elif test == "csrrci": # at some point, try writing a non-one value first
a = a & 0x1F
allOnes = "0xFFFFFFFF" if xlen == 32 else "0xFFFFFFFFFFFFFFFF"
lines += "li x" + str(reg1) + ", MASK_XLEN(" + allOnes + ")\n"
lines += "csrrw x0, " + csr + ", x" + str(reg1) + "\n" # set csr to all ones
lines += test + " x" + str(reg2) + ", " + csr + ", " + str(a) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", " + str(a) + "\n"
expected = a ^ 0xFFFFFFFF if xlen == 32 else a ^ 0xFFFFFFFFFFFFFFFF
lines += storecmd + " x" + str(reg2) + ", " + str(wordsize*testnum) + "(x6)\n"
lines += "RVTEST_IO_ASSERT_GPR_EQ(x7, " + str(reg2) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
def writeSpec(a, storecmd):
global testnum
csr = "mscratch"
reg1 = 3
reg2 = 3
lines = "\n# Testcase " + str(testnum) + ": " + csr + "\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
expected = a
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
lines += test + " x" + str(reg2) + ", " + csr + ", x" + str(reg1) + "\n"
lines += storecmd + " x" + str(reg2) + ", " + str(wordsize*testnum) + "(x6)\n"
lines += "RVTEST_IO_ASSERT_GPR_EQ(x7, " + str(reg2) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
# csrrw, csrrs, csrrc, csrrwi, csrrsi, csrrci
tests = ["csrrw", "csrrs", "csrrc", "csrrwi", "csrrsi", "csrrci"]
author = "ushakya@hmc.edu & dottolia@hmc.edu"
xlens = [32, 64]
numrand = 60;
# setup
seed(0xC365DDEB9173AB42) # 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
for test in tests:
corners = [
0, 1, 2, 0x1E, 0x1F, 0xFF,
0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1
]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test.upper()
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
# test that reading and writing from same register work
if test == "csrrw":
a = getrandbits(xlen)
#writeSpec(a, storecmd)
for a in corners:
for b in corners:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(xlen)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -4\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,286 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-JAL.py
#
# Ben Bracker (bbracker@hmc.edu) 19 January 2021
# Based on testgen-ADD-SUB.py by David Harris
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import choice
from random import seed
from random import getrandbits
from copy import deepcopy
##################################
# helper functions
##################################
def InitTestGroup():
global TestGroup,TestGroupSizes,AllRegs,UnusedRegs,StoreAdrReg
TestGroup += 1
TestGroupSizes.append(0)
UnusedRegs = deepcopy(AllRegs)
oldStoreAdrReg = StoreAdrReg
while ((StoreAdrReg == oldStoreAdrReg) or (StoreAdrReg == 0) or (StoreAdrReg == 31)):
StoreAdrReg = choice(UnusedRegs)
UnusedRegs.remove(StoreAdrReg)
f.write("\n # ---------------------------------------------------------------------------------------------\n")
f.write(" # new register for address of test results\n")
addInst(" la x"+str(StoreAdrReg)+", test_1_res\n")
f.write(" # ---------------------------------------------------------------------------------------------\n")
def registerSelect():
# ensures that rd experiences all possible registers
# *** does not yet ensure that rs experiences all possible registers
# ensures that at least once rd = rs
global UnusedRegs
if len(UnusedRegs)==0:
InitTestGroup()
rd = choice(UnusedRegs)
UnusedRegs.remove(rd)
OtherRegs = deepcopy(UnusedRegs)
if 0 in OtherRegs:
OtherRegs.remove(0)
if len(OtherRegs) == 0:
OtherRegs = deepcopy(AllRegs)
OtherRegs.remove(0)
rs = choice(OtherRegs)
OtherRegs = deepcopy(AllRegs)
OtherRegs.remove(StoreAdrReg)
OtherRegs.remove(rd)
if 0 in OtherRegs:
OtherRegs.remove(0)
if rs in OtherRegs:
OtherRegs.remove(rs)
DataReg = choice(OtherRegs)
OtherRegs.remove(DataReg)
OtherRd = choice(OtherRegs)
return (rd,rs,DataReg,OtherRd)
def addInst(line):
global CurrAdr
f.write(line)
if ("li x" in line) and ("slli x" not in line):
CurrAdr += 8 if (xlen == 32) else 20
elif ("la x" in line):
CurrAdr += 8
else:
CurrAdr += 4
def expectValue(expectReg, expectVal, sigOffset):
global TestGroupSizes
TestGroupSizes[TestGroup-1] += 1
addInst(" "+storecmd+" x"+str(expectReg)+", "+str(wordsize*sigOffset)+"(x"+str(StoreAdrReg)+")\n")
f.write(" RVTEST_IO_ASSERT_GPR_EQ(x"+str(StoreAdrReg+1)+", x"+str(expectReg)+", "+formatstr.format(expectVal)+")\n")
if (xlen == 32):
r.write(formatrefstr.format(expectVal)+"\n")
else:
r.write(formatrefstr.format(expectVal % 2**32)+"\n" + formatrefstr.format(expectVal >> 32)+"\n")
def addJalr(rs,rd,dist):
target = CurrAdr + 20 + dist
target31_12 = CurrAdr >> 12 # 20 bits for lui
target11_0 = target - (target31_12 << 12) # 12 remaining bits
target31_16 = target31_12 >> 4 # lui sign extends, so shift in a leading 0
target15_12 = target31_12 - (target31_16 << 4) # the nibble we just lost
if target11_0 > 0:
offset = randint(-(1<<11)-1,(1<<11)-2-target11_0)
else:
offset = randint(-(1<<11)-1-target11_0,(1<<11)-2)
addInst(" lui x"+str(rs)+", 0x"+imm20formatstr.format(target31_16)+"\n")
addInst(" addi x"+str(rs)+", x"+str(rs)+", SEXT_IMM(0x0"+imm12formatstr.format(target15_12 << 8)+")\n")
addInst(" slli x"+str(rs)+", x"+str(rs)+", SEXT_IMM(4)\n")
addInst(" addi x"+str(rs)+", x"+str(rs)+", SEXT_IMM(0x"+imm12formatstr.format(0xfff&(offset+target11_0+randint(0,1)))+")\n")
addInst(" JALR x"+str(rd)+", x"+str(rs)+", SEXT_IMM(0x"+imm12formatstr.format(0xfff&(-offset))+")\n")
##################################
# test functions
##################################
def writeForwardsJumpVector(spacers,instr):
global TestNum
TestNum += 1
rd, rs, DataReg, OtherRd = registerSelect()
# Header
f.write("\n")
f.write(" # Testcase "+str(TestNum)+"\n")
# Test Code
addInst(" li x"+str(DataReg)+", "+formatstr.format(expected)+"\n")
if (instr=="JAL"):
addInst(" JAL x"+str(rd)+", 1f\n")
elif (instr=="JALR"):
dist = spacers*(8 if (xlen == 32) else 20) # Compute distance from linked adr to target adr
addJalr(rs,rd,dist);
else:
exit("invalid instruction")
LinkAdr = CurrAdr if (rd!=0) else 0 # rd's expected value
for i in range(spacers):
addInst(" li x"+str(DataReg)+", "+formatstr.format(unexpected)+"\n")
f.write("1:\n")
# Store values to be verified
expectValue(rd, LinkAdr, 2*TestNum+0)
expectValue(DataReg, expected, 2*TestNum+1)
def writeBackwardsJumpVector(spacers,instr):
global TestNum
TestNum += 1
rd, rs, DataReg, OtherRd = registerSelect()
# Header
f.write("\n")
f.write(" # Testcase "+str(TestNum)+"\n")
# Test Code
addInst(" JAL x"+str(OtherRd)+", 2f\n")
f.write("1:\n")
addInst(" li x"+str(DataReg)+", "+formatstr.format(expected)+"\n")
addInst(" JAL x"+str(OtherRd)+", 3f\n")
f.write("2:\n")
for i in range(spacers):
addInst(" li x"+str(DataReg)+", "+formatstr.format(unexpected)+"\n")
if (instr=="JAL"):
addInst(" JAL x"+str(rd)+", 1b\n")
elif (instr=="JALR"):
dist = -20 - 4 - (1+spacers)*(8 if (xlen == 32) else 20) # Compute distance from linked adr to target adr
addJalr(rs,rd,dist);
else:
exit("invalid instruction")
LinkAdr = CurrAdr if (rd!=0) else 0 # rd's expected value
f.write("3:\n")
# Store values to be verified
expectValue(rd, LinkAdr, 2*TestNum+0)
expectValue(DataReg, expected, 2*TestNum+1)
def writeChainVector(repetitions,spacers):
global TestNum
TestNum += 1
rd, rs, DataReg,OtherRd = registerSelect()
# Header
f.write("\n")
f.write(" # Testcase "+str(TestNum)+"\n")
# Test Code
addInst(" li x"+str(DataReg)+", "+formatstr.format(expected)+"\n")
for i in range(repetitions):
addInst(" JAL x"+str(OtherRd)+", "+str(3*i+2)+"f\n")
if spacers:
for j in range(i):
addInst(" li x"+str(DataReg)+", "+formatstr.format(unexpected)+"\n")
f.write(str(3*i+1)+":\n")
addInst(" JAL x"+str(OtherRd)+", "+str(3*i+3)+"f\n")
if spacers:
for j in range(i):
addInst(" li x"+str(DataReg)+", "+formatstr.format(unexpected)+"\n")
f.write(str(3*i+2)+":\n")
addInst(" JAL x"+str(rd)+", "+str(3*i+1)+"b\n")
LinkAdr = CurrAdr if (rd!=0) else 0 # rd's expected value
if spacers:
for j in range(i):
addInst(" li x"+str(DataReg)+", "+formatstr.format(unexpected)+"\n")
f.write(str(3*i+3)+":\n")
# Store values to be verified
expectValue(rd, LinkAdr, 2*TestNum+0)
expectValue(DataReg, expected, 2*TestNum+1)
##################################
# main body
##################################
# change these to suite your tests
test = 0
tests = ["JAL","JALR"]
author = "Ben Bracker (bbracker@hmc.edu)"
xlens = [32,64]
numtests = 100
# setup
seed(0) # make tests reproducible
# generate files for each test
for test in tests:
for xlen in xlens:
print(test+" "+str(xlen))
CurrAdr = int("80000108",16)
TestNum = -1
TestGroup = 1
TestGroupSizes = [0]
AllRegs = list(range(0,32))
UnusedRegs = deepcopy(AllRegs)
StoreAdrReg = 6 # matches what's in header script
UnusedRegs.remove(6)
if (xlen==64):
expected = int("fedbca9876540000",16)
unexpected = int("ffff0000ffff0000",16)
else:
expected = int("fedbca98",16)
unexpected = int("ff00ff00",16)
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
imm20formatstr = "{:05x}"
imm12formatstr = "{:03x}"
if (xlen == 32):
storecmd = "sw"
wordsize = 4
else:
storecmd = "sd"
wordsize = 8
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
f.write("///////////////////////////////////////////\n")
f.write("// "+fname+ "\n")
f.write("//\n")
f.write("// This file can be used to test the RISC-V JAL(R) instruction.\n")
f.write("// But be warned that altering the test environment may break this test!\n")
f.write("// In order to work, this test expects that the first instruction (la)\n")
f.write("// be allocated at 0x80000100.\n")
f.write("//\n")
f.write("// " + author + "\n")
f.write("// Created "+str(datetime.now())+"\n")
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed test vectors
if test == "JAL":
for i in range(0,31):
writeForwardsJumpVector(randint(0,4),"JAL")
for i in range(0,31):
writeBackwardsJumpVector(randint(0,4),"JAL")
writeForwardsJumpVector(100,"JAL")
writeBackwardsJumpVector(100,"JAL")
writeChainVector(6,True)
writeChainVector(16,False)
elif test == "JALR":
for i in range(0,31):
writeForwardsJumpVector(randint(0,4),"JALR")
for i in range(0,31):
writeBackwardsJumpVector(randint(0,4),"JALR")
# can't make these latter two too long else 12 bit immediate overflows
# (would need to lui or slli rs to achieve longer ranges)
writeForwardsJumpVector(15,"JALR")
writeBackwardsJumpVector(15,"JALR")
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
f.write(".fill "+str(sum(TestGroupSizes))+", "+str(wordsize)+", -1\n")
f.write("\nRV_COMPLIANCE_DATA_END\n")
f.close()
r.close()

View File

@ -1,227 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-LOAD.py
#
# Jarred Allen <jaallen@g.hmc.edu> 02 February 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint, seed, getrandbits
##################################
# functions
##################################
def rand_reg():
"""Produce a random register (skipping 6 and 31, since they're used for other things)"""
r = randint(1,29)
if r >= 6:
r += 1
return r
def rand_value(width):
"""Generate a random value which fits in the given width"""
return randint(0, (1 << width) - 1)
def rand_offset():
"""Generate a random offset"""
ret = rand_value(12)
# print("Random offset: %d" % ret)
return ret
def rand_source():
"""Generate a random value for the source register, such that the load address is in the test data"""
ret = randint(1 << 12, (1 << 12) + (1 << 10))
# print("Random source: %d" % ret)
return ret
def add_offset_to_source(source, offset):
"""Find the address from the given source value and offset"""
if offset & 0x800:
offset -= 0x1000
return source + offset
def insert_into_data(test_data, source, offset, value, width, xlen):
"""Insert the given value into the given location of the test data"""
address = add_offset_to_source(source, offset)
# print("Test #%d" % testcase_num)
# print(f"Source: {source}, Offset: {offset}, Value: {value}, Width: {width}, xlen: {xlen}, Addr: {address}")
if address < 0:
return False
word_offset = address % (xlen // 8)
word_address = address - word_offset
if word_address in test_data:
return False
test_data[word_address] = value * (1 << (word_offset*8)) + ((~(((1 << width)-1) << (word_offset*8))) & rand_value(xlen))
# print(f"Word: {hex(test_data[word_address])}")
return True
def align(address, width):
"""Align the address to the given width, in bits"""
return address - (address % (width // 8))
testcase_num = 0
def generate_case(xlen, instruction, load_register, source_register, source_register_value, offset, expected):
"""Produce the specified test case and return it as a pair of strings, where the first is the test case and the second is the output"""
global testcase_num
if xlen == 64:
store = "sd"
elif xlen == 32:
if instruction in ["lwu", "ld"]:
raise Exception("Instruction %s not supported in RV32I" % instruction)
store = "sw"
else:
raise Exception("Unknown xlen value: %s" % xlen)
if offset >= 0x800:
offset -= 0x1000
if widths[instruction] != xlen:
expected = expected % (1 << widths[instruction])
if 'u' not in instruction:
if expected & (1 << (widths[instruction] - 1)):
expected = (expected + ~((1 << widths[instruction]) - 1)) & ((1 << xlen) - 1)
data = f"""# Testcase {testcase_num}: source {offset}(x{source_register} == {source_register_value}), result: x{load_register} == {expected}
la x31, test_data
lui x{source_register}, {source_register_value // (1 << 12)}
addi x{source_register}, x{source_register}, {source_register_value % (1 << 12)}
add x{source_register}, x{source_register}, x31
{instruction} x{load_register}, {offset}(x{source_register})
{store} x{load_register}, {(testcase_num*xlen//8) % 0x800}(x6)
RVTEST_IO_ASSERT_GPR_EQ(x8, x{load_register}, {expected})
"""
testcase_num += 1
if testcase_num*xlen//8 % 0x800 == 0:
data += "# Adjust x6 because we're storing too many things\naddi x6, x6, 1024\naddi x6, x6, 1024\n\n"
if xlen == 32:
reference_output = "{:08x}\n".format(expected)
elif xlen == 64:
reference_output = "{:08x}\n{:08x}\n".format(expected % (1 << 32), expected >> 32)
return (data, reference_output)
def write_header(outfile):
outfile.write(f"""///////////////////////////////////////////
//
// WALLY-LOAD
//
// Author: {author}
//
// Created {str(datetime.now())}
//
""")
outfile.write(open("testgen_header.S", "r").read())
def write_test_data(outfile, test_data, xlen):
# print("Begin writing test data:")
# print("{} entries, from address {} to {}".format(len(test_data), min(test_data.keys()), max(test_data.keys())))
# print(test_data)
outfile.write("""
.align 16
test_data:
""")
if xlen == 32:
data_word = ".word"
elif xlen == 64:
data_word = ".dword"
else:
raise Exception("Unknown xlen: %d" % xlen)
byte_width = xlen // 8
for addr in [0] + sorted(test_data.keys()):
if addr in test_data:
word = f" {data_word} {hex(test_data[addr] % (1 << xlen))} # test_data+{hex(addr)}\n"
else:
word = ""
try:
fill_len = (min(k for k in test_data.keys() if k > addr) - addr) // byte_width - 1
if word == "":
fill_len += 1
fill = f" .fill {fill_len}, {byte_width}, 0x0\n"
except:
fill = ""
case = word+fill
outfile.write(case)
##################################
# main body
##################################
widths = {
"lb": 8,
"lbu": 8,
"lh": 16,
"lhu": 16,
"lw": 32,
"lwu": 32,
"ld": 64,
}
instructions = [i for i in widths]
author = "Jarred Allen"
xlens = [32, 64]
numrand = 100;
# setup
seed(0) # make tests reproducible
for xlen in xlens:
testcase_num = 0
fname = "../../imperas-riscv-tests/riscv-test-suite/rv{}i/src/WALLY-LOAD.S".format(xlen)
refname = "../../imperas-riscv-tests/riscv-test-suite/rv{}i/references/WALLY-LOAD.reference_output".format(xlen)
f = open(fname, "w")
r = open(refname, "w")
write_header(f)
test_data = dict()
corner_values = [0x00, 0xFFFFFFFF, 0x7F, 0x7FFF, 0x7FFFFFFF]
if xlen == 64:
corner_values += [0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF]
corner_offsets = [0x800, 0x000, 0x7FF]
for instruction in instructions:
print("Running xlen: %d, instruction: %s" % (xlen, instruction))
if xlen == 32:
if instruction in ["lwu", "ld"]:
continue
for value in corner_values + [rand_value(widths[instruction]) for _ in range(3)]:
value = value % (1 << widths[instruction])
source_reg = rand_source()
for offset in corner_offsets + [rand_offset() for _ in range(3)]:
offset = align(offset, widths[instruction])
source_reg = align(source_reg, widths[instruction])
if insert_into_data(test_data, source_reg, offset, value, widths[instruction], xlen):
data, output = generate_case(xlen, instruction, rand_reg(), rand_reg(), source_reg, offset, value)
f.write(data)
r.write(output)
while testcase_num % 4:
source = rand_source()
offset = rand_offset()
value = rand_value(widths[instruction])
if insert_into_data(test_data, source, offset, value, widths['lb'], xlen):
data, output = generate_case(xlen, 'lb', rand_reg(), rand_reg(), source, offset, value)
f.write(data)
r.write(output)
f.write("""# ---------------------------------------------------------------------------------------------
RVTEST_IO_WRITE_STR(x31, "Test End\\n")
# ---------------------------------------------------------------------------------------------
RV_COMPLIANCE_HALT
RV_COMPLIANCE_CODE_END
.data
# Input data section
""")
write_test_data(f, test_data, xlen)
f.write("""# Output data section.
RV_COMPLIANCE_DATA_BEGIN
test_1_res:
""")
f.write(f".fill {testcase_num}, {xlen//8}, -1\n")
f.write("\nRV_COMPLIANCE_DATA_END\n")
f.close()
r.close()

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-SLL-SRL-SRA.py
#
# David_Harris@hmc.edu 19 January 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def twoscomp(a):
amsb = a >> (xlen-1)
alsbs = ((1 << (xlen-1)) - 1) & a
if (amsb):
asigned = a - (1<<xlen)
else:
asigned = a
#print("a: " + str(a) + " amsb: "+str(amsb)+ " alsbs: " + str(alsbs) + " asigned: "+str(asigned))
return asigned
def computeExpected(a, b, test, xlen):
asigned = twoscomp(a)
b = b % xlen
if (test == "SLL"):
return a << b
elif (test == "SRL"):
return a >> b
elif (test == "SRA"):
return asigned >> b
else:
die("bad test name ", test)
# exit(1)
def randRegs():
reg1 = randint(1,31)
reg2 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
return randRegs()
else:
return reg1, reg2, reg3
def writeVector(a, b, storecmd, xlen):
global testnum
expected = computeExpected(a, b, test, xlen)
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg2, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), rs2:x" + str(reg2) + "(" +formatstr.format(b)
lines = lines + "), result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + "li x" + str(reg2) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", x" + str(reg2) + "\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, " + str(reg3) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["SLL", "SRL", "SRA"]
author = "David_Harris@hmc.edu"
xlens = [32, 64]
numrand = 48
# 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
for test in tests:
corners = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
if (xlen == 32):
shamt = [0, 1, 2, 3, 4, 8, 15, 16, 29, 30, 31]
else:
shamt = [0, 1, 3, 8, 15, 16, 29, 31, 32, 47, 48, 62, 63]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
for a in corners:
for b in shamt:
writeVector(a, b, storecmd, xlen)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(xlen)
writeVector(a, b, storecmd, xlen)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,189 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADD-SUB.py
#
# David_Harris@hmc.edu 19 January 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def computeExpected(a, b, test):
if (test == "SLLI"):
return a << b
elif (test == "SRLI"):
return srli(a,b)
elif (test == "SRAI"):
return a >> b
else:
die("bad test name ", test)
# exit(1)
def signExt(b, bits):
a_str = bin(b)[2::]
if (a_str[0] == "b"):
a_str = a_str[1:]
if (len(a_str) < 12):
zeroPadding = "0" * (bits - len(a_str))
a_str = zeroPadding + a_str
print( "{:x}, {:s} ".format(b, a_str))
padding = a_str[len(a_str)-1] * (bits - len(a_str))
return int(padding + a_str, 2)
def evaluateTwoComplement(b, bits):
if (b & (1 << (bits -1))!= 0):
b = b - (1 << bits)
return b
def srli(a,b):
if (a < 0):
a = 2**xlen + a
if (b==0):
return a
a_str = bin(a)[2:]
if a_str[0]== "b":
a_str = a_str[1:]
# print(a_str)
numZeroPad = (len(a_str)-abs(b))
out = a_str[:numZeroPad]
if (numZeroPad <= 0):
return 0
print("a: {:b}, b: {:d}, out:{:b}".format(a, b, int(out,2)))
return int(out,2)
def randRegs():
reg1 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg3 == 6):
return randRegs()
else:
return reg1, reg3
def writeVector(a, b, storecmd):
global testnum
expected = computeExpected(evaluateTwoComplement(a, xlen), b, test)
# print( "original {:x}, sign Extended {:x} ".format(b, signExt(b,xlen)))
# print (str(a) + "<" + str(signExt(b,xlen)) + " : " + str(expected))
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), imm5:" + "(" +formatstrimm5.format(b)
lines = lines + "), result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", " + formatstrimm5.format(b) + "\n"
# lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, " +"x" + str(reg3) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["SLLI", "SRLI", "SRAI"]
author = "Shriya Nadgauda & Ethan Falicov"
xlens = [32, 64]
numrand = 100
# 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
formatstrimm5 = "0b{:05b}" # format as 5-bit binary number
if (xlen == 32):
storecmd = "sw"
wordsize = 4
else:
storecmd = "sd"
wordsize = 8
for test in tests:
corners1 = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
immBitSize = 5
corners2 = [0, 1, 2, 0x07, 0x14 % 2**immBitSize, 2**(immBitSize-1)-2, 2**(immBitSize-1)-1,
2**(immBitSize-1), 2**(immBitSize-1)+1, 0x06 % 2**immBitSize, 2**(immBitSize)-2, 2**(immBitSize)-1]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
for a in corners1:
for b in corners2:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(5)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,173 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-ADD-SUB.py
#
# David_Harris@hmc.edu 19 January 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def computeExpected(a, b, test):
if (test == "SLTIU"):
return a < b
else:
die("bad test name ", test)
# exit(1)
def signExt(b, bits):
a_str = bin(b)[2::]
if (a_str[0] == "b"):
a_str = a_str[1:]
if (len(a_str) < 12):
zeroPadding = "0" * (12 - len(a_str))
a_str = zeroPadding + a_str
padding = a_str[0] * (bits - len(a_str))
print( "b {:x}, sign extended {:s} ".format(b, padding + a_str))
return int(padding + a_str, 2)
def evaluateTwoComplement(b, bits):
if (b & (1 << (bits -1))!= 0):
b = b - (1 << bits)
return b
def randRegs():
reg1 = randint(1,31)
reg3 = randint(1,31)
if (reg1 == 6 or reg3 == 6):
return randRegs()
else:
return reg1, reg3
def writeVector(a, b, storecmd):
global testnum
signExtImm = signExt(b,xlen)
if signExtImm < 0:
signExtImm = signExtImm + 2 ** xlen
expected = computeExpected(a, signExtImm, test)
# s
expected = expected % 2**xlen # drop carry if necessary
if (expected < 0): # take twos complement
expected = 2**xlen + expected
reg1, reg3 = randRegs()
lines = "\n# Testcase " + str(testnum) + ": rs1:x" + str(reg1) + "(" + formatstr.format(a)
lines = lines + "), imm12:" + "(" +formatstrimm12.format(b)
lines = lines + "), result rd:x" + str(reg3) + "(" + formatstr.format(expected) +")\n"
lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(a) + ")\n"
lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", SEXT_IMM(" + formatstrimm12.format(b) + ")\n"
# lines = lines + test + " x" + str(reg3) + ", x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(b) + ")\n"
lines = lines + storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
lines = lines + "RVTEST_IO_ASSERT_GPR_EQ(x7, " +"x" + str(reg3) +", "+formatstr.format(expected)+")\n"
f.write(lines)
if (xlen == 32):
line = formatrefstr.format(expected)+"\n"
else:
line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
r.write(line)
testnum = testnum+1
##################################
# main body
##################################
# change these to suite your tests
tests = ["SLTIU"]
author = "Shriya Nadgauda & Ethan Falicov"
xlens = [32, 64]
numrand = 100
# 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
formatstrimm12 = "0x{:03x}" # format as 3-bit hexadecimal number
if (xlen == 32):
storecmd = "sw"
wordsize = 4
else:
storecmd = "sd"
wordsize = 8
for test in tests:
corners1 = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1,
2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
immBitSize = 12
corners2 = [0, 1, 2, 0xFF, 0x624 % 2**immBitSize, 2**(immBitSize-1)-2, 2**(immBitSize-1)-1,
2**(immBitSize-1), 2**(immBitSize-1)+1, 0xC36 % 2**immBitSize, 2**(immBitSize)-2, 2**(immBitSize)-1]
imperaspath = "../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "i/"
basename = "WALLY-" + test
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
# print custom header part
f = open(fname, "w")
r = open(refname, "w")
line = "///////////////////////////////////////////\n"
f.write(line)
lines="// "+fname+ "\n// " + author + "\n"
f.write(lines)
line ="// Created " + str(datetime.now())
f.write(line)
# insert generic header
h = open("testgen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
for a in corners1:
for b in corners2:
writeVector(a, b, storecmd)
for i in range(0,numrand):
a = getrandbits(xlen)
b = getrandbits(12)
writeVector(a, b, storecmd)
# print footer
h = open("testgen_footer.S", "r")
for line in h:
f.write(line)
# Finish
lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()
r.close()

View File

@ -1,282 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-STORE.py
#
# Jessica Torrey <jtorrey@hmc.edu> 03 February 2021
# Thomas Fleming <tfleming@hmc.edu> 03 February 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint, seed, getrandbits
from textwrap import dedent
##################################
# global structures
##################################
size_to_store = {8: "sd", 4: "sw", 2: "sh", 1: "sb"}
size_to_load = {8: "ld", 4: "lw", 2: "lh", 1: "lb"}
store_to_size = {"sd": 8, "sw": 4, "sh": 2, "sb": 1}
testcase_num = 0
signature_len = 2000
signature = [0xff for _ in range(signature_len)]
##################################
# functions
##################################
def rand_reg():
"""
Produce a random register from 1 to 31 (skipping 6, since r6 is used for
other things).
"""
r = randint(1,30)
if r >= 6:
r += 1
return r
def rand_regs():
"""
Generate two random, unequal register numbers (skipping x6).
"""
rs1 = rand_reg()
rs2 = rand_reg()
while rs1 == rs2:
rs2 = rand_reg()
return rs1, rs2
def generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta):
"""
Create assembly code for a given STORE test case, returned as a string.
Generates an `xlen`-bit test case for `instruction` (one of sb, sh, sw, or
sd) that loads `value` into `value_register`, then attempts to store that
value in memory at address (x6 + `base_delta`). The test case
assumes the current base address for the signature is in register x6.
The form of the STORE instruction is as follows:
`instruction` `value_register` `offset`(`addr_register`)
"""
global testcase_num
hex_value = f"{value:0{xlen // 4}x}"
data = f"""# Testcase {testcase_num}: source: x{value_register} (value 0x{hex_value}), destination: {offset}(x{addr_register}) ({base_delta} bytes into signature)
addi x{addr_register}, x6, {base_delta}
li x{value_register}, MASK_XLEN({-offset})
add x{addr_register}, x{addr_register}, x{value_register}
li x{value_register}, 0x{hex_value}
{instruction} x{value_register}, {offset}(x{addr_register})
"""
update_signature(store_to_size[instruction], value, base_delta)
testcase_num += 1
return data
def validate_memory(scratch_register, value_register, value, base_delta, length):
"""
Create assembly code to verify that `length` bytes at mem[x6 + `base_delta`]
store `value`.
Assumes x6 stores the current base address for the signature.
"""
truncated_value = value & (2**(length * 8) - 1)
hex_value = f"{truncated_value:0{length * 2}x}"
load = size_to_load[length]
data = f"""addi x{scratch_register}, x6, {base_delta}
{load} x{value_register}, 0(x{scratch_register})
RVTEST_IO_ASSERT_GPR_EQ(x{scratch_register}, x{value_register}, 0x{hex_value})
"""
return data
def update_signature(length, value, base_delta):
"""
Write the lower `length` bytes of `value` to the little-endian signature
array, starting at byte `base_delta`.
"""
truncated_value = value & (2**(length * 8) - 1)
value_bytes = truncated_value.to_bytes(length, 'little')
#print("n: {}, value: {:x}, trunc: {:x}, length: {}, bd: {:x}".format(testcase_num, value, truncated_value, length, base_delta))
for i in range(length):
signature[base_delta + i] = value_bytes[i]
def write_signature(outfile):
"""
Writes successive 32-bit words from the signature array into a given file.
"""
for i in range(0, signature_len, 4):
word = list(reversed(signature[i:i+4]))
hexword = bytearray(word).hex()
outfile.write(f"{hexword}\n")
def write_header(outfile):
"""
Write the name of the test file, authors, and creation date.
"""
outfile.write(dedent(f"""\
///////////////////////////////////////////
//
// WALLY-STORE
//
// Author: {author}
//
// Created {str(datetime.now())}
"""))
outfile.write(open("testgen_header.S", "r").read())
def write_footer(outfile):
"""
Write necessary closing code, including a data section for the signature.
"""
outfile.write(open("testgen_footer.S", 'r').read())
data_section = dedent(f"""\
\t.fill {signature_len}, 1, -1
RV_COMPLIANCE_DATA_END
""")
outfile.write(data_section)
##################################
# test cases
##################################
def write_basic_tests(outfile, xlen, instr_len, num, base_delta):
"""
Test basic functionality of STORE, using random registers, offsets, and
values.
Creates `num` tests for a single store instruction of length `instr_len`,
writing to memory at consecutive locations, starting `base_delta` bytes from
the start of the signature.
Returns the number of bytes from the start of the signature where testing
ended.
"""
instruction = size_to_store[instr_len]
for i in range(num):
value_register, addr_register = rand_regs()
offset = randint(-2**(12 - 1), 2**(12 - 1) - 1)
value = randint(0, 2**(instr_len * 8) - 1)
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
base_delta += instr_len
return base_delta
def write_random_store_tests(outfile, xlen, instr_len, num, min_base_delta):
"""
Test random access of STORE, using random registers, offsets, values, and
memory locations.
Creates `num` tests for a single store instruction of length `instr_len`,
writing to memory at random locations between `min_base_delta` bytes past
the start of the signature to the end of the signature.
"""
instruction = size_to_store[instr_len]
for i in range(num):
base_delta = randint(min_base_delta, signature_len - 1)
base_delta -= (base_delta % instr_len)
value_register, addr_register = rand_regs()
offset = randint(-2**(12 - 1), 2**(12 - 1) - 1)
value = randint(0, 2**(instr_len * 8) - 1)
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
def write_repeated_store_tests(outfile, xlen, instr_len, num, base_delta):
"""
Test repeated access of STORE, using random registers, offsets, values, and a
single memory location.
Creates `num` tests for a single store instruction of length `instr_len`,
writing to memory `base_delta` bytes past the start of the signature.
"""
instruction = size_to_store[instr_len]
for i in range(num):
value_register, addr_register = rand_regs()
offset = 0
value = (1 << ((2 * i) % xlen))
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
def write_corner_case_tests(outfile, xlen, instr_len, base_delta):
instruction = size_to_store[instr_len]
corner_cases_32 = [0x0, 0x10000001, 0x01111111]
corner_cases_64 = [0x1000000000000001, 0x0111111111111111]
corner_cases = corner_cases_32
if xlen == 64:
corner_cases += corner_cases_64
for offset in corner_cases:
for value in corner_cases:
value_register, addr_register = rand_regs()
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
base_delta += instr_len
return base_delta
##################################
# main body
##################################
instructions = ["sd", "sw", "sh", "sb"]
author = "Jessica Torrey <jtorrey@hmc.edu> & Thomas Fleming <tfleming@hmc.edu>"
xlens = [32, 64]
numrand = 100
# setup
seed(0) # make tests reproducible
for xlen in xlens:
if (xlen == 32):
wordsize = 4
else:
wordsize = 8
fname = f"../../imperas-riscv-tests/riscv-test-suite/rv{xlen}i/src/WALLY-STORE.S"
refname = f"../../imperas-riscv-tests/riscv-test-suite/rv{xlen}i/references/WALLY-STORE.reference_output"
f = open(fname, "w")
r = open(refname, "w")
write_header(f)
base_delta = 0
for instruction in instructions:
if xlen == 32 and instruction == 'sd':
continue
instr_len = store_to_size[instruction]
base_delta = write_basic_tests(f, xlen, instr_len, 5, base_delta)
write_repeated_store_tests(f, xlen, instr_len, 32, base_delta)
write_random_store_tests(f, xlen, instr_len, 5, base_delta + wordsize)
write_footer(f)
write_signature(r)
f.close()
r.close()
# Reset testcase_num and signature
testcase_num = 0
signature = [0xff for _ in range(signature_len)]

View File

@ -1,285 +0,0 @@
#!/usr/bin/env python3
##################################
# testgen-VIRTUALMEMORY.py
#
# Jessica Torrey <jtorrey@hmc.edu> 01 March 2021
# Thomas Fleming <tfleming@hmc.edu> 01 March 2021
#
# Generate an ad-hoc test program for RISC-V Design Validation. Tests the
# functionality of the memory management unit (MMU).
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint, seed, getrandbits
from textwrap import dedent
from virtual_memory_util import *
##################################
# global structures
##################################
testcase_num = 0
signature_len = 2000
signature = [0xff for _ in range(signature_len)]
##################################
# functions
##################################
def rand_reg():
"""
Produce a random register from 1 to 31 (skipping 6, since r6 is used for
other things).
"""
r = randint(1,30)
if r >= 6:
r += 1
return r
def rand_regs():
"""
Generate two random, unequal register numbers (skipping x6).
"""
rs1 = rand_reg()
rs2 = rand_reg()
while rs1 == rs2:
rs2 = rand_reg()
return rs1, rs2
def initialize_page_directory()
def generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta):
"""
Create assembly code for a given STORE test case, returned as a string.
Generates an `xlen`-bit test case for `instruction` (one of sb, sh, sw, or
sd) that loads `value` into `value_register`, then attempts to store that
value in memory at address (x6 + `base_delta`). The test case
assumes the current base address for the signature is in register x6.
The form of the STORE instruction is as follows:
`instruction` `value_register` `offset`(`addr_register`)
"""
global testcase_num
hex_value = f"{value:0{xlen // 4}x}"
data = f"""# Testcase {testcase_num}: source: x{value_register} (value 0x{hex_value}), destination: {offset}(x{addr_register}) ({base_delta} bytes into signature)
addi x{addr_register}, x6, {base_delta}
li x{value_register}, MASK_XLEN({-offset})
add x{addr_register}, x{addr_register}, x{value_register}
li x{value_register}, 0x{hex_value}
{instruction} x{value_register}, {offset}(x{addr_register})
"""
#update_signature(store_to_size[instruction], value, base_delta)
testcase_num += 1
return data
def validate_memory(scratch_register, value_register, value, base_delta, length):
"""
Create assembly code to verify that `length` bytes at mem[x6 + `base_delta`]
store `value`.
Assumes x6 stores the current base address for the signature.
"""
truncated_value = value & (2**(length * 8) - 1)
hex_value = f"{truncated_value:0{length * 2}x}"
load = size_to_load[length]
data = f"""addi x{scratch_register}, x6, {base_delta}
{load} x{value_register}, 0(x{scratch_register})
RVTEST_IO_ASSERT_GPR_EQ(x{scratch_register}, x{value_register}, 0x{hex_value})
"""
return data
def update_signature(length, value, base_delta):
"""
Write the lower `length` bytes of `value` to the little-endian signature
array, starting at byte `base_delta`.
"""
truncated_value = value & (2**(length * 8) - 1)
value_bytes = truncated_value.to_bytes(length, 'little')
#print("n: {}, value: {:x}, trunc: {:x}, length: {}, bd: {:x}".format(testcase_num, value, truncated_value, length, base_delta))
for i in range(length):
signature[base_delta + i] = value_bytes[i]
def write_signature(outfile):
"""
Writes successive 32-bit words from the signature array into a given file.
"""
for i in range(0, signature_len, 4):
word = list(reversed(signature[i:i+4]))
hexword = bytearray(word).hex()
outfile.write(f"{hexword}\n")
def write_header(outfile):
"""
Write the name of the test file, authors, and creation date.
"""
outfile.write(dedent(f"""\
///////////////////////////////////////////
//
// WALLY-STORE
//
// Author: {author}
//
// Created {str(datetime.now())}
"""))
outfile.write(open("testgen_header.S", "r").read())
def write_footer(outfile):
"""
Write necessary closing code, including a data section for the signature.
"""
outfile.write(open("testgen_footer.S", 'r').read())
data_section = dedent(f"""\
\t.fill {signature_len}, 1, -1
RV_COMPLIANCE_DATA_END
""")
outfile.write(data_section)
##################################
# test cases
##################################
def write_basic_tests(outfile, xlen, instr_len, num, base_delta):
"""
Test basic functionality of STORE, using random registers, offsets, and
values.
Creates `num` tests for a single store instruction of length `instr_len`,
writing to memory at consecutive locations, starting `base_delta` bytes from
the start of the signature.
Returns the number of bytes from the start of the signature where testing
ended.
"""
instruction = size_to_store[instr_len]
for i in range(num):
value_register, addr_register = rand_regs()
offset = randint(-2**(12 - 1), 2**(12 - 1) - 1)
value = randint(0, 2**(instr_len * 8) - 1)
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
base_delta += instr_len
return base_delta
def write_random_store_tests(outfile, xlen, instr_len, num, min_base_delta):
"""
Test random access of STORE, using random registers, offsets, values, and
memory locations.
Creates `num` tests for a single store instruction of length `instr_len`,
writing to memory at random locations between `min_base_delta` bytes past
the start of the signature to the end of the signature.
"""
instruction = size_to_store[instr_len]
for i in range(num):
base_delta = randint(min_base_delta, signature_len - 1)
base_delta -= (base_delta % instr_len)
value_register, addr_register = rand_regs()
offset = randint(-2**(12 - 1), 2**(12 - 1) - 1)
value = randint(0, 2**(instr_len * 8) - 1)
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
def write_repeated_store_tests(outfile, xlen, instr_len, num, base_delta):
"""
Test repeated access of STORE, using random registers, offsets, values, and a
single memory location.
Creates `num` tests for a single store instruction of length `instr_len`,
writing to memory `base_delta` bytes past the start of the signature.
"""
instruction = size_to_store[instr_len]
for i in range(num):
value_register, addr_register = rand_regs()
offset = 0
value = (1 << ((2 * i) % xlen))
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
def write_corner_case_tests(outfile, xlen, instr_len, base_delta):
instruction = size_to_store[instr_len]
corner_cases_32 = [0x0, 0x10000001, 0x01111111]
corner_cases_64 = [0x1000000000000001, 0x0111111111111111]
corner_cases = corner_cases_32
if xlen == 64:
corner_cases += corner_cases_64
for offset in corner_cases:
for value in corner_cases:
value_register, addr_register = rand_regs()
test = generate_case(xlen, instruction, value_register, value, addr_register, offset, base_delta)
validate = validate_memory(addr_register, value_register, value, base_delta, instr_len)
outfile.write(test)
outfile.write(validate)
base_delta += instr_len
return base_delta
##################################
# main body
##################################
if __name__ == "__main__":
instructions = ["sd", "sw", "sh", "sb"]
author = "Jessica Torrey <jtorrey@hmc.edu> & Thomas Fleming <tfleming@hmc.edu>"
xlens = [32, 64]
numrand = 100
# setup
seed(0) # make tests reproducible
for xlen in xlens:
if (xlen == 32):
wordsize = 4
else:
wordsize = 8
fname = f"../../imperas-riscv-tests/riscv-test-suite/rv{xlen}i/src/WALLY-VIRTUALMEMORY.S"
refname = f"../../imperas-riscv-tests/riscv-test-suite/rv{xlen}i/references/WALLY-VIRTUALMEMORY.reference_output"
f = open(fname, "w")
r = open(refname, "w")
write_header(f)
base_delta = 0
for instruction in instructions:
if xlen == 32 and instruction == 'sd':
continue
instr_len = store_to_size[instruction]
base_delta = write_basic_tests(f, xlen, instr_len, 5, base_delta)
write_repeated_store_tests(f, xlen, instr_len, 32, base_delta)
write_random_store_tests(f, xlen, instr_len, 5, base_delta + wordsize)
write_footer(f)
write_signature(r)
f.close()
r.close()
# Reset testcase_num and signature
testcase_num = 0
signature = [0xff for _ in range(signature_len)]

View File

@ -1,27 +1,58 @@
james.stine@okstate.edu 14 Jan 2022
jcarlin@hmc.edu Sept 2024
These are the testvectors (TV) to test the floating-point unit using
Berkeley TestFloat written originally by John Hauser. TestFloat
requires both TestFloat and SoftFloat.
## TestFloat for CVW
The locations of these tools at time of this README is found here:
TestFloat-3e: http://www.jhauser.us/arithmetic/TestFloat.html
SoftFloat-3e: http://www.jhauser.us/arithmetic/SoftFloat.html
The CVW floating point unit is tested using testvectors from the Berkeley TestFloat suite, written originally by John Hauser.
These tools have been compiled on a x86_64 environment by going into
their respective build/Linux-x86_64-GCC directories and running make.
TestFloat and SoftFloat can be found as submodules in the addins directory, and are linked here:
- TestFloat: https://github.com/ucb-bar/berkeley-testfloat-3
- SoftFloat: https://github.com/ucb-bar/berkeley-softfloat-3
The makefile in the vectors subdirectory of this directory will generate TV
for each rounding mode and operation. It also puts an underscore between each
vector instead of a space to allow SystemVerilog readmemh to read correctly.
### Compiling SoftFloat/TestFloat and Generating Testvectors
The makefile at the top level of this directory will compile SoftFloat and
TestFloat and then generate all of the TVs. It also generates TVs for the
combined integer floating-point divider.
The entire testvector generation process can be performed by running make in this directory.
Although not needed, a case.sh script is included to change the case
of the hex output. This is for those that do not like to see
hexadecimal capitalized :P.
```bash
make --jobs
```
This compiles SoftFloat for an x86_64 environment in its build/Linux-x86_64-GCC directory using the `SPECIALIZE_TYPE=RISCV` flag to get RISC-V behavior. TestFloat is then compiled in its build/Linux-x86_64-GCC directory using this SoftFloat library.
The Makefile in the vectors subdirectory of this directory is then called to generate testvectors for each rounding mode and operation. It also puts an underscore between each vector instead of a space to allow SystemVerilog `$readmemh` to read correctly.
Testvectors for the combined integer floating-point divider are also generated.
Although not needed, a `case.sh` script is included to change the case of the hex output. This is for those that do not like to see hexadecimal capitalized :P.
### Running TestFloat Vectors on Wally
TestFloat is run using the standard Wally simulation commands.
To run all TestFloat tests on many different derived configurations of Wally, use
```bash
regression-wally --testfloat
```
To run a single test, use
```bash
wsim <config> <test> --tb testbench_fp
```
The choices for `<test>` are as follows:
>cvtint - test integer conversion unit (fcvtint)
cvtfp - test floating-point conversion unit (fcvtfp)
cmp - test comparison unit's LT, LE, EQ opperations (fcmp)
add - test addition
fma - test fma
mul - test mult with fma
sub - test subtraction
div - test division
sqrt - test square root
Any config that includes floating point support can be used. Each test will test all its vectors for all precisions supported by the given config.
### Testvector Count
46464 185856 836352 f16_add_rd.tv
46464 185856 836352 f16_add_rne.tv