Added covergen directed coverage generator

This commit is contained in:
David Harris 2024-05-01 14:47:37 -07:00
parent 84b37cacfa
commit e667adf946
6 changed files with 236 additions and 112 deletions

View File

@ -168,6 +168,7 @@ module testbench;
"arch64zknd": if (P.ZKND_SUPPORTED) tests = arch64zknd; "arch64zknd": if (P.ZKND_SUPPORTED) tests = arch64zknd;
"arch64zkne": if (P.ZKNE_SUPPORTED) tests = arch64zkne; "arch64zkne": if (P.ZKNE_SUPPORTED) tests = arch64zkne;
"arch64zknh": if (P.ZKNH_SUPPORTED) tests = arch64zknh; "arch64zknh": if (P.ZKNH_SUPPORTED) tests = arch64zknh;
"wallycov64i": tests = wallycov64i;
endcase endcase
end else begin // RV32 end else begin // RV32
case (TEST) case (TEST)

View File

@ -72,6 +72,59 @@ string tvpaths[] = '{
"pmpadrdecs" "pmpadrdecs"
}; };
string wallycov64i[] = '{
`WALLYTEST,
"rv64i_m/I/src/WALLY-COV-lh.S",
"rv64i_m/I/src/WALLY-COV-srli.S",
"rv64i_m/I/src/WALLY-COV-srai.S",
"rv64i_m/I/src/WALLY-COV-or.S",
"rv64i_m/I/src/WALLY-COV-sra.S",
"rv64i_m/I/src/WALLY-COV-sll.S",
"rv64i_m/I/src/WALLY-COV-slti.S",
"rv64i_m/I/src/WALLY-COV-bne.S",
"rv64i_m/I/src/WALLY-COV-bltu.S",
"rv64i_m/I/src/WALLY-COV-srliw.S",
"rv64i_m/I/src/WALLY-COV-slliw.S",
"rv64i_m/I/src/WALLY-COV-sw.S",
"rv64i_m/I/src/WALLY-COV-sraiw.S",
"rv64i_m/I/src/WALLY-COV-sltu.S",
"rv64i_m/I/src/WALLY-COV-addiw.S",
"rv64i_m/I/src/WALLY-COV-slli.S",
"rv64i_m/I/src/WALLY-COV-beq.S",
"rv64i_m/I/src/WALLY-COV-sd.S",
"rv64i_m/I/src/WALLY-COV-auipc.S",
"rv64i_m/I/src/WALLY-COV-bge.S",
"rv64i_m/I/src/WALLY-COV-sltiu.S",
"rv64i_m/I/src/WALLY-COV-lui.S",
"rv64i_m/I/src/WALLY-COV-lw.S",
"rv64i_m/I/src/WALLY-COV-lwu.S",
"rv64i_m/I/src/WALLY-COV-slt.S",
"rv64i_m/I/src/WALLY-COV-blt.S",
"rv64i_m/I/src/WALLY-COV-addw.S",
"rv64i_m/I/src/WALLY-COV-lb.S",
"rv64i_m/I/src/WALLY-COV-xori.S",
"rv64i_m/I/src/WALLY-COV-addi.S",
"rv64i_m/I/src/WALLY-COV-xor.S",
"rv64i_m/I/src/WALLY-COV-jal.S",
"rv64i_m/I/src/WALLY-COV-sb.S",
"rv64i_m/I/src/WALLY-COV-ld.S",
"rv64i_m/I/src/WALLY-COV-lhu.S",
"rv64i_m/I/src/WALLY-COV-andi.S",
"rv64i_m/I/src/WALLY-COV-ori.S",
"rv64i_m/I/src/WALLY-COV-sub.S",
"rv64i_m/I/src/WALLY-COV-and.S",
"rv64i_m/I/src/WALLY-COV-sh.S",
"rv64i_m/I/src/WALLY-COV-srlw.S",
"rv64i_m/I/src/WALLY-COV-sraw.S",
"rv64i_m/I/src/WALLY-COV-subw.S",
"rv64i_m/I/src/WALLY-COV-sllw.S",
"rv64i_m/I/src/WALLY-COV-jalr.S",
"rv64i_m/I/src/WALLY-COV-lbu.S",
"rv64i_m/I/src/WALLY-COV-add.S",
"rv64i_m/I/src/WALLY-COV-srl.S",
"rv64i_m/I/src/WALLY-COV-bgeu.S"
};
string buildroot[] = '{ string buildroot[] = '{
`BUILDROOT, `BUILDROOT,
"buildroot" "buildroot"

View File

@ -9,7 +9,7 @@ current_dir = $(shell pwd)
#XLEN ?= 64 #XLEN ?= 64
all: root arch32 wally32 arch32e arch64 wally64 all: root arch32 wally32 arch32e arch64 wally64
wally-riscv-arch-test: root wally32 wally64 wally-riscv-arch-test: root wally64 wally32
root: root:
mkdir -p $(work_dir) mkdir -p $(work_dir)

4
tests/testgen/Makefile Normal file
View File

@ -0,0 +1,4 @@
all:
./covergen.py
cd ../riscof; make wally-riscv-arch-test
cd ../../sim; make memfiles

View File

@ -14,134 +14,195 @@ from datetime import datetime
from random import randint from random import randint
from random import seed from random import seed
from random import getrandbits from random import getrandbits
from os import getenv
import re
################################## ##################################
# functions # functions
################################## ##################################
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen): def shiftImm(imm, xlen):
rdval = randint(0, 2**xlen-1) imm = imm % xlen
return str(imm)
def signedImm12(imm):
imm = imm % pow(2, 12)
if (imm & 0x800):
imm = imm - 0x1000
return str(imm)
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen):
lines = "\n# Testcase " + str(desc) + "\n" 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(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" if (test in rtype):
lines = lines + "li x" + str(rs2) + ", MASK_XLEN(" + formatstr.format(rs2val) + ") # initialize rs2 to a random value\n" lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\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"
elif (test in shiftitype):
lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n"
elif (test in itype):
lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n"
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n"
else:
pass
#print("Error: %s type not implemented yet" % test)
f.write(lines) f.write(lines)
def make_cp_rd(rd, test, storecmd, xlen): def randomize():
rs1 = randint(0, 31) rs1 = randint(1, 31)
rs2 = randint(0, 31) rs2 = randint(1, 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) 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) rs1val = randint(0, 2**xlen-1)
desc = "cp_rs2_maxvals (rs2 = " + str(rs2val) + ")" rs2val = randint(0, 2**xlen-1)
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen) immval = randint(0, 2**xlen-1)
rdval = randint(0, 2**xlen-1)
return [rs1, rs2, rd, rs1val, rs2val, immval, rdval]
def make_rd(test, storecmd, xlen):
for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd (Test destination rd = x" + str(r) + ")"
writeCovVector(desc, rs1, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, test, storecmd, xlen): def make_rs1(test, storecmd, xlen):
rdval = randint(0, 2**xlen-1) for r in range(32):
lines = "\n# Testcase " + str(desc) + "\n" [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
lines = lines + "li x" + str(rd) + ", MASK_XLEN(" + formatstr.format(rdval) + ") # initialize rd to a random value that should get changed\n" desc = "cp_rs1 (Test source rs1 = x" + str(r) + ")"
lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n" writeCovVector(desc, r, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
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_rs2(test, storecmd, xlen):
for r in range(32):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rs2 (Test source rs2 = x" + str(r) + ")"
writeCovVector(desc, rs1, r, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
def write_rtype_arith_vectors(test, storecmd, xlen): def make_rd_rs1(test, storecmd, xlen):
for r in range(32): for r in range(32):
make_cp_rd(r, test, storecmd, xlen) [rs1, rs1, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd_rs1 (Test rd = rs1 = x" + str(r) + ")"
writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
def make_rd_rs2(test, storecmd, xlen):
for r in range(32): for r in range(32):
make_cp_rs1(r, test, storecmd, xlen) [rs1, rs1, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd_rs2 (Test rd = rs1 = x" + str(r) + ")"
writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
def make_rd_rs1_rs2(test, storecmd, xlen):
for r in range(32): for r in range(32):
make_cp_rs2(r, test, storecmd, xlen) [rs1, rs1, rd, rs1val, rs2val, immval, rdval] = randomize()
for r in range(32): desc = "cp_rd_rs1_rs2 (Test rd = rs1 = rs2 = x" + str(r) + ")"
make_cmp_rd_rs2(r, test, storecmd, xlen) writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
for r in range(32):
make_cmp_rd_rs1(r, test, storecmd, xlen) def make_rs1_maxvals(test, storecmd, xlen):
for r in range(32): for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
make_cmp_rd_rs1_rs2(r, test, storecmd, xlen) [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
make_cp_gpr_hazard(test, storecmd, xlen) desc = "cp_rs1_maxvals (Test source rs1 value = " + hex(v) + ")"
make_cp_rs1_maxvals(test, storecmd, xlen) writeCovVector(desc, rs1, rs2, rd, v, rs2val, immval, rdval, test, storecmd, xlen)
make_cp_rs2_maxvals(test, storecmd, xlen)
def make_rs2_maxvals(test, storecmd, xlen):
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rs2_maxvals (Test source rs2 value = " + hex(v) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, v, immval, rdval, test, storecmd, xlen)
def make_rd_maxvals(test, storecmd, xlen):
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
writeCovVector(desc, rs1, 0, rd, v, rs2val, immval, rdval, test, storecmd, xlen)
def make_rd_rs1_eqval(test, storecmd, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rdm_rs1_eqval (Test rs1 = rd = " + hex(rs1val) + ")"
writeCovVector(desc, rs1, 0, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
def make_rd_rs2_eqval(test, storecmd, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rd_rs2_eqval (Test rs2 = rd = " + hex(rs2val) + ")"
writeCovVector(desc, 0, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
def make_rs1_rs2_eqval(test, storecmd, xlen):
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
desc = "cmp_rs1_rs2_eqval (Test rs1 = rs2 = " + hex(rs1val) + ")"
writeCovVector(desc, rs1, rs2, rd, rs1val, rs1val, immval, rdval, test, storecmd, xlen)
#def make_cp_gpr_hazard(test, storecmd, xlen):
# pass # *** to be implemented ***
def write_tests(coverpoints, test, storecmd, xlen):
for coverpoint in coverpoints:
if (coverpoint == "cp_asm_count"):
pass
elif (coverpoint == "cp_rd"):
make_rd(test, storecmd, xlen)
elif (coverpoint == "cp_rs1"):
make_rs1(test, storecmd, xlen)
elif (coverpoint == "cp_rs2"):
make_rs2(test, storecmd, xlen)
elif (coverpoint == "cp_rd_rs1"):
make_rd_rs1(test, storecmd, xlen)
elif (coverpoint == "cp_rd_rs2"):
make_rd_rs2(test, storecmd, xlen)
elif (coverpoint == "cp_rd_rs1_rs2"):
make_rd_rs1_rs2(test, storecmd, xlen)
elif (coverpoint == "cp_rs1_maxvals"):
make_rs1_maxvals(test, storecmd, xlen)
elif (coverpoint == "cp_rs2_maxvals"):
make_rs2_maxvals(test, storecmd, xlen)
elif (coverpoint == "cp_rd_maxvals"):
make_rd_maxvals(test, storecmd, xlen)
elif (coverpoint == "cmp_rd_rs1_eqval"):
make_rd_rs1_eqval(test, storecmd, xlen)
elif (coverpoint == "cmp_rd_rs2_eqval"):
make_rd_rs2_eqval(test, storecmd, xlen)
elif (coverpoint == "cmp_rs1_rs2_eqval"):
make_rs1_rs2_eqval(test, storecmd, xlen)
# elif (coverpoint == "cp_gpr_hazard"):
# make_cp_gpr_hazard(test, storecmd, xlen)
else:
print("Error: " + coverpoint + " not implemented yet for " + test)
def getcovergroups(coverdefdir, coverfiles):
coverpoints = {}
curinstr = ""
for coverfile in coverfiles:
coverfile = coverdefdir + "/" + coverfile + "_coverage.svh"
f = open(coverfile, "r")
for line in f:
m = re.search(r'cp_asm_count.*\"(.*)"', line)
if (m):
# if (curinstr != ""):
# print(curinstr + ": " + str(coverpoints[curinstr]))
curinstr = m.group(1)
coverpoints[curinstr] = []
m = re.search("\s*(\S+) :", line)
if (m):
coverpoints[curinstr].append(m.group(1))
f.close()
return coverpoints
################################## ##################################
# main body # main body
################################## ##################################
# change these to suite your tests # change these to suite your tests
rtests = ["ADD", "SUB", "SLT", "SLTU", "XOR"] riscv = getenv("RISCV")
tests = rtests coverdefdir = riscv+"/ImperasDV-OpenHW/Imperas/ImpProprietary/source/host/riscvISACOV/source/coverage";
#coverfiles = ["RV64I", "RV64M", "RV64A", "RV64C", "RV64F", "RV64D"] # add more later
coverfiles = ["RV64I"] # add more later
rtype = ["add", "sub", "sll", "slt", "sltu", "xor", "srl", "sra", "or", "and",
"addw", "subw", "sllw", "srlw", "sraw"
"mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu",
"mulw", "divw", "divuw", "remw", "remuw"]
loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
shiftitype = ["slli", "srli", "srai"]
itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"]
stypes = ["sb", "sh", "sw", "sd"]
btypes = ["beq", "bne", "blt", "bge", "bltu", "bgeu"]
coverpoints = getcovergroups(coverdefdir, coverfiles)
author = "David_Harris@hmc.edu" author = "David_Harris@hmc.edu"
xlens = [64] xlens = [64]
numrand = 3 numrand = 3
@ -160,7 +221,8 @@ for xlen in xlens:
else: else:
storecmd = "sd" storecmd = "sd"
wordsize = 8 wordsize = 8
for test in tests: for test in coverpoints.keys():
# for test in tests:
# corners = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1, # 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] # 2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1]
corners = [0, 1, 2**(xlen)-1] corners = [0, 1, 2**(xlen)-1]
@ -184,10 +246,11 @@ for xlen in xlens:
# print directed and random test vectors # print directed and random test vectors
# Coverage for R-type arithmetic instructions # Coverage for R-type arithmetic instructions
if (test not in rtests): #if (test not in rtests):
exit("Error: %s not implemented yet" % test) # exit("Error: %s not implemented yet" % test)
else: #else:
write_rtype_arith_vectors(test, storecmd, xlen) # write_rtype_arith_vectors(test, storecmd, xlen)
write_tests(coverpoints[test], test, storecmd, xlen)
# print footer # print footer
line = "\n.EQU NUMTESTS," + str(1) + "\n\n" line = "\n.EQU NUMTESTS," + str(1) + "\n\n"

View File

@ -16,3 +16,6 @@ RVTEST_CODE_BEGIN
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",temp) RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",temp)
la x6, wally_signature
sd x0, 0(x6)