cvw/tests/testgen/covergen.py

208 lines
7.1 KiB
Python
Executable File

#!/usr/bin/python3
##################################
# covergen.py
#
# David_Harris@hmc.edu 27 March 2024
#
# Generate directed tests for functional coverage
##################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen):
rdval = randint(0, 2**xlen-1)
lines = "\n# Testcase " + str(desc) + "\n"
lines = lines + "li x" + str(rd) + ", MASK_XLEN(" + formatstr.format(rdval) + ") # initialize rd to a random value that should get changed\n"
lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n"
lines = lines + "li x" + str(rs2) + ", MASK_XLEN(" + formatstr.format(rs2val) + ") # initialize rs2 to a random value\n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\n"
f.write(lines)
def make_cp_rd(rd, test, storecmd, xlen):
rs1 = randint(0, 31)
rs2 = randint(0, 31)
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cp_rd (Test destination rd = x" + str(rd) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cp_rs1(rs1, test, storecmd, xlen):
rd = randint(0, 31)
rs2 = randint(0, 31)
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cp_rs1 (Test source rs1 = x" + str(rs1) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cp_rs2(rs2, test, storecmd, xlen):
rd = randint(0, 31)
rs1 = randint(0, 31)
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cp_rs2 (Test source rs2 = x" + str(rs2) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cmp_rd_rs1(r, test, storecmd, xlen):
rd = r
rs1 = r
rs2 = randint(0, 31)
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cmp_rd_rs1 (Test destination rd = source rs1 = x" + str(r) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cmp_rd_rs2(r, test, storecmd, xlen):
rd = r
rs1 = randint(0, 31)
rs2 = r
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cmp_rd_rs2 (Test destination rd = source rs2 = x" + str(r) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cmp_rd_rs1_rs2(r, test, storecmd, xlen):
rd = r
rs1 = r
rs2 = r
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cmp_rd_rs1_rs2 (Test destination rd = source rs1 = source rs2 = x" + str(r) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cp_gpr_hazard(test, storecmd, xlen):
rs1val = randint(0, 2**xlen-1)
rs2val = randint(0, 2**xlen-1)
desc = "cp_gpr_hazard"
writeCovVector(desc, 20, 21, 22, rs1val, rs2val, test, storecmd, xlen)
lines = test + " x23, x22, x20 # RAW\n"
lines = lines + test + " x22, x23, x20 # WAR\n"
lines = lines + test + " x22, x21, x20 # WAW\n"
f.write(lines)
def make_cp_rs1_maxvals(test, storecmd, xlen):
for rs1val in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
rd = randint(1, 31)
rs1 = randint(0, 31)
rs2 = randint(0, 31)
rs2val = randint(0, 2**xlen-1)
desc = "cp_rs1_maxvals (rs1 = " + str(rs1val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def make_cp_rs2_maxvals(test, storecmd, xlen):
for rs2val in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
rd = randint(1, 31)
rs1 = randint(0, 31)
rs2 = randint(0, 31)
rs1val = randint(0, 2**xlen-1)
desc = "cp_rs2_maxvals (rs2 = " + str(rs2val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen)
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen):
rdval = randint(0, 2**xlen-1)
lines = "\n# Testcase " + str(desc) + "\n"
lines = lines + "li x" + str(rd) + ", MASK_XLEN(" + formatstr.format(rdval) + ") # initialize rd to a random value that should get changed\n"
lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n"
lines = lines + "li x" + str(rs2) + ", MASK_XLEN(" + formatstr.format(rs2val) + ") # initialize rs2 to a random value\n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\n"
f.write(lines)
def write_rtype_arith_vectors(test, storecmd, xlen):
for r in range(32):
make_cp_rd(r, test, storecmd, xlen)
for r in range(32):
make_cp_rs1(r, test, storecmd, xlen)
for r in range(32):
make_cp_rs2(r, test, storecmd, xlen)
for r in range(32):
make_cmp_rd_rs2(r, test, storecmd, xlen)
for r in range(32):
make_cmp_rd_rs1(r, test, storecmd, xlen)
for r in range(32):
make_cmp_rd_rs1_rs2(r, test, storecmd, xlen)
make_cp_gpr_hazard(test, storecmd, xlen)
make_cp_rs1_maxvals(test, storecmd, xlen)
make_cp_rs2_maxvals(test, storecmd, xlen)
##################################
# main body
##################################
# change these to suite your tests
rtests = ["ADD", "SUB", "SLT", "SLTU", "XOR"]
tests = rtests
author = "David_Harris@hmc.edu"
xlens = [64]
numrand = 3
# setup
seed(0) # make tests reproducible
# generate files for each test
for xlen in xlens:
formatstrlen = str(int(xlen/4))
formatstr = "0x{:0" + formatstrlen + "x}" # format as xlen-bit hexadecimal number
formatrefstr = "{:08x}" # format as xlen-bit hexadecimal number with no leading 0x
if (xlen == 32):
storecmd = "sw"
wordsize = 4
else:
storecmd = "sd"
wordsize = 8
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]
corners = [0, 1, 2**(xlen)-1]
pathname = "../wally-riscv-arch-test/riscv-test-suite/rv" + str(xlen) + "i_m/I/"
basename = "WALLY-COV-" + test
fname = pathname + "src/" + basename + ".S"
# print custom header part
f = open(fname, "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("covergen_header.S", "r")
for line in h:
f.write(line)
# print directed and random test vectors
# Coverage for R-type arithmetic instructions
if (test not in rtests):
exit("Error: %s not implemented yet" % test)
else:
write_rtype_arith_vectors(test, storecmd, xlen)
# print footer
line = "\n.EQU NUMTESTS," + str(1) + "\n\n"
f.write(line)
h = open("covergen_footer.S", "r")
for line in h:
f.write(line)
# Finish
# lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
# lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
f.write(lines)
f.close()