Forgot to add csr permission tests to testbench

This commit is contained in:
Domenico Ottolia 2021-05-04 20:20:22 -04:00
parent 682bc7b58e
commit 88ab07d456
3 changed files with 338 additions and 8 deletions

View File

@ -362,7 +362,9 @@ module testbench();
"rv64p/WALLY-MVENDORID", "4000",
"rv64p/WALLY-MIE", "3000",
"rv64p/WALLY-MEDELEG", "4000",
"rv64p/WALLY-IP", "2000"
"rv64p/WALLY-IP", "2000",
"rv64p/WALLY-CSR-PERMISSIONS-M", "5000",
"rv64p/WALLY-CSR-PERMISSIONS-S", "3000"
};
string tests32p[] = '{
@ -380,7 +382,9 @@ module testbench();
"rv32p/WALLY-STVEC", "2000",
"rv32p/WALLY-MIE", "3000",
"rv32p/WALLY-MEDELEG", "4000",
"rv32p/WALLY-IP", "3000"
"rv32p/WALLY-IP", "3000",
"rv32p/WALLY-CSR-PERMISSIONS-M", "5000",
"rv32p/WALLY-CSR-PERMISSIONS-S", "3000"
};
string tests64periph[] = '{
@ -428,8 +432,6 @@ module testbench();
if (`MEM_VIRTMEM) tests = {tests, tests64mmu};
end
//tests = {tests64a, tests};
//tests = tests64p;
end else begin // RV32
// *** add the 32 bit bp tests
if (TESTSPERIPH) begin
@ -443,8 +445,6 @@ module testbench();
if (`A_SUPPORTED) tests = {tests, tests32a};
if (`MEM_VIRTMEM) tests = {tests, tests32mmu};
end
//tests = tests32p;
end
end

View File

@ -0,0 +1,248 @@
#!/usr/bin/python3
##################################
# testgen-CSR-PERMISSIONS.py
#
# dottolia@hmc.edu 1 May 2021
#
# Generate directed and random test vectors for RISC-V Design Validation.
# Verify that an illegal instruction is raised when trying to write to csrs of a higher privilege
#
##################################
# DOCUMENTATION:
#
# Most of the comments explaining what everything
# does and the layout of the privileged tests
# can be found in this file
#
###################################
##################################
# libraries
##################################
from datetime import datetime
from random import randint
from random import seed
from random import getrandbits
##################################
# functions
##################################
testCount = 2
def writeVectors(storecmd, testMode):
global testnum
csrs = ["status", "edeleg", "ideleg", "ie", "tvec", "counteren", "scratch", "epc", "cause", "tval", "ip"]
if testMode == "s":
csrs.append("atp")
#csrs = ["status"]
for csrStart in csrs:
for i in range(0, testCount):
a = 1
csr = testMode + csrStart
# only check for CSR changes if testing machine-mode registers
csrWillChange = testMode == "s" or csrStart == "status" or csrStart == "epc" or csrStart == "cause" or csrStart == "tval"
newCSRValue = "" if testMode == "s" else "csrr x24, " + csr
f.write(f"""
li x13, 1
""")
fromModeOptions = ["s", "u"] if testMode == "m" else ["u"]
for fromMode in fromModeOptions:
label = f"""{fromMode}_{csr}_{testnum}"""
endlabel = f"""_j_end_{label}"""
# This is all from testgen-TVAL.py, within the for loop on returningInstruction
#
# x25: mepc value
# x24: new csr value
# x23: original csr value
lines = f"""
li x30, 0
la x1, _m_trap_from_{label}
csrw mtvec, x1
csrr x23, {csr}
j _j_test_{label}
_m_trap_from_{label}:
bnez x30, {endlabel}
csrr x25, mcause
{newCSRValue}
csrrs x20, mepc, x0
addi x20, x20, 4
csrrw x0, mepc, x20
mret
_j_test_{label}:
"""
lines += f"""
li x1, 0b110000000000
csrrc x0, mstatus, x1
li x1, 0b0100000000000
csrrs x0, mstatus, x1
auipc x1, 0
addi x1, x1, 16 # x1 is now right after the mret instruction
csrw mepc, x1
mret
# We're now in supervisor mode...
"""
# Code to bring us down to user mode
if fromMode == "u":
lines += f"""
li x1, 0b110000000000
csrrc x0, sstatus, x1
auipc x1, 0
addi x1, x1, 16 # x1 is now right after the sret instruction
csrw sepc, x1
sret
# We're now in user mode...
"""
f.write(lines)
writeTest(storecmd, f, r, f"""csrrw x1, {csr}, x0""", csrWillChange)
writeTest(storecmd, f, r, f"""csrrw x0, {csr}, x13""", csrWillChange)
writeTest(storecmd, f, r, f"""csrrwi x0, {csr}, {a}""", csrWillChange)
if a != 0:
writeTest(storecmd, f, r, f"""csrrs x0, {csr}, x13""", csrWillChange)
writeTest(storecmd, f, r, f"""csrrc x0, {csr}, x13""", csrWillChange)
writeTest(storecmd, f, r, f"""csrrsi x0, {csr}, {a}""", csrWillChange)
writeTest(storecmd, f, r, f"""csrrci x0, {csr}, {a}""", csrWillChange)
f.write(f"""
li x30, 1
ebreak
{endlabel}:
""")
def writeTest(storecmd, f, r, test, csrWillChange):
global testnum
test = f"""
_jdo{testnum}:
li x25, 0xDEADBEA7
{test}
{storecmd} x25, 0(x7)
addi x7, x7, {wordsize}
"""
# We expect x25 to always be an illegal instruction
expected = 2
f.write(test)
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
if not csrWillChange:
# We expect x24 should be equal to x23
expected = 0
f.write(f"""
sub x25, x24, x23
{storecmd} x25, 0(x7)
addi x7, x7, {wordsize}
""")
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
##################################
author = "dottolia@hmc.edu"
xlens = [32, 64]
# setup
# Change this seed to a different constant value for every test
seed(0xC363DAEB9193AB45) # 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 testMode in ["m", "s"]:
imperaspath = "../../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "p/"
basename = "WALLY-CSR-PERMISSIONS-" + testMode.upper()
fname = imperaspath + "src/" + basename + ".S"
refname = imperaspath + "references/" + basename + ".reference_output"
testnum = 0
storeAddressOffset = 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)
f.write(f"""
add x7, x6, x0
csrr x19, mtvec
""")
writeVectors(storecmd, testMode)
f.write(f"""
csrw mtvec, x19
""")
# 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

@ -43,6 +43,8 @@ def writeVectors(storecmd):
# Supervisor Software Interrupt: True, 1
# Machine Software Interrupt: True, 2
writeTest(storecmd, f, r, "timer-interrupt", True, -1) # code determined inside of writeTest
# User external input: True, 8
# Supervisor external input: True, 9
# Machine externa input: True, 11
@ -92,13 +94,85 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
global testMode
global isInterrupts
beforeTest = ""
if interrupt != isInterrupts:
return
isTimerInterruptTest = test == "timer-interrupt"
delegateType = "i" if interrupt else "e"
for mode in (["m", "s", "u"] if testMode == "m" else ["s", "u"]):
if isTimerInterruptTest:
clintAddr = "0x2004000"
if test == "ecall":
if mode == "m":
code = 7
test = f"""
la x18, {clintAddr}
{storecmd} x0, 0(x18)
"""
elif mode == "s":
code = 5
test = ""
else:
code = 4
test = ""
ieMask = 1 << code
statusMask = 0b1010
beforeTest = f"""
li x1, {statusMask}
csrrs x0, mstatus, x1
li x1, 0b0010
csrrs x0, sstatus, x1
la x18, {clintAddr}
lw x11, 0(x18)
li x1, 0x7fffffffffffffff
{storecmd} x1, 0(x18)
li x1, {ieMask}
csrrs x0, mie, x1
li x1, {ieMask}
csrrs x0, sie, x1
"""
resetHander = f"""
#li x1, 0x80
#csrrc x0, sie, x1
li x1, {ieMask}
csrrc x0, mie, x1
li x1, {ieMask}
csrrc x0, sie, x1
li x1, {statusMask}
csrrc x0, mstatus, x1
li x1, 0b0010
csrrc x0, sstatus, x1
la x18, {clintAddr}
{storecmd} x11, 0(x18)
"""
if mode == "s":
beforeTest += f"""
li x1, {ieMask}
csrrs x0, sip, x1
"""
resetHander += f"""
li x1, {ieMask}
csrrc x0, sip, x1
"""
elif test == "ecall":
if mode == "m":
code = 11
elif mode == "s":
@ -121,6 +195,7 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
j _j_test_{labelSuffix}
_j_m_trap_{labelSuffix}:
{resetHander}
li x25, 3
csrr x1, mepc
@ -130,6 +205,7 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
mret
_j_s_trap_{labelSuffix}:
{resetHander}
li x25, 1
csrr x1, sepc
@ -150,11 +226,12 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
csrw m{delegateType}deleg, x1
"""
lines = original + "\n" + test
if mode != "m":
lines = f"""
{original}
{beforeTest}
li x1, 0b110000000000
csrrc x28, {testMode}status, x1
li x1, 0b{"01" if mode == "s" else "00"}00000000000
@ -176,6 +253,11 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
""")
else:
lines = f"""
{original}
{beforeTest}
{test}
"""
writeTestInner(storecmd, f, r, lines, 3)
f.write(f"""