From 1c884338b0ac4c4729c25f5d25192bf449160cc3 Mon Sep 17 00:00:00 2001 From: Domenico Ottolia Date: Tue, 4 May 2021 20:20:22 -0400 Subject: [PATCH] Forgot to add csr permission tests to testbench --- .../testbench/testbench-imperas.sv | 12 +- .../privileged/testgen-CSR-PERMISSIONS.py | 248 ++++++++++++++++++ .../testgen/privileged/testgen-DELEG.py | 86 +++++- 3 files changed, 338 insertions(+), 8 deletions(-) create mode 100644 wally-pipelined/testgen/privileged/testgen-CSR-PERMISSIONS.py diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 32e50731e..cfb87df47 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -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 diff --git a/wally-pipelined/testgen/privileged/testgen-CSR-PERMISSIONS.py b/wally-pipelined/testgen/privileged/testgen-CSR-PERMISSIONS.py new file mode 100644 index 000000000..1cd262458 --- /dev/null +++ b/wally-pipelined/testgen/privileged/testgen-CSR-PERMISSIONS.py @@ -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() + + + + diff --git a/wally-pipelined/testgen/privileged/testgen-DELEG.py b/wally-pipelined/testgen/privileged/testgen-DELEG.py index a0a3dd835..4eecb53b7 100644 --- a/wally-pipelined/testgen/privileged/testgen-DELEG.py +++ b/wally-pipelined/testgen/privileged/testgen-DELEG.py @@ -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"""