forked from Github_Repos/cvw
Forgot to add csr permission tests to testbench
This commit is contained in:
parent
682bc7b58e
commit
88ab07d456
@ -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
|
||||
|
||||
|
248
wally-pipelined/testgen/privileged/testgen-CSR-PERMISSIONS.py
Normal file
248
wally-pipelined/testgen/privileged/testgen-CSR-PERMISSIONS.py
Normal 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()
|
||||
|
||||
|
||||
|
||||
|
@ -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"""
|
||||
|
Loading…
Reference in New Issue
Block a user