diff --git a/wally-pipelined/regression/wally-privileged.do b/wally-pipelined/regression/wally-privileged.do index d969e6728..9e1447a1a 100644 --- a/wally-pipelined/regression/wally-privileged.do +++ b/wally-pipelined/regression/wally-privileged.do @@ -30,34 +30,43 @@ vlib work # default to config/rv64ic, but allow this to be overridden at the command line. For example: # do wally-pipelined.do ../config/rv32ic switch $argc { - 0 {vlog +incdir+../config/rv64ic ../testbench/testbench-privileged.sv ../src/*/*.sv -suppress 2583} - 1 {vlog +incdir+$1 ../testbench/testbench-privileged.sv ../testbench/function_radix.sv ../src/*/*.sv -suppress 2583} + 0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} + 1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../testbench/function_radix.sv ../src/*/*.sv -suppress 2583} } # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals vopt +acc work.testbench -o workopt vsim workopt - view wave - -- display input and output signals as hexidecimal values -do ./wave-dos/default-waves.do - --- Set Wave Output Items +onerror {resume} +add wave -noupdate /testbench/clk +add wave -noupdate /testbench/reset +add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE +quietly WaveActivateNextPane {} 0 TreeUpdate [SetDefaultTree] -WaveRestoreZoom {0 ps} {100 ps} +WaveRestoreCursors {{Cursor 2} {12215488 ns} 0} {{Cursor 4} {22127 ns} 0} +quietly wave cursor active 2 configure wave -namecolwidth 250 -configure wave -valuecolwidth 140 +configure wave -valuecolwidth 513 configure wave -justifyvalue left -configure wave -signalnamewidth 0 +configure wave -signalnamewidth 1 configure wave -snapdistance 10 configure wave -datasetprefix 0 configure wave -rowmargin 4 configure wave -childrowmargin 2 -set DefaultRadix hexadecimal +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits ns +update +WaveRestoreZoom {21993 ns} {22181 ns} -- Run the Simulation -#run 4100 +#run 5000 run -all #quit +noview ../testbench/testbench-imperas.sv +view wave diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index f7a77b6b1..2f0498e00 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -354,7 +354,8 @@ module testbench(); "rv64p/WALLY-MARCHID", "4000", "rv64p/WALLY-MIMPID", "4000", "rv64p/WALLY-MHARTID", "4000", - "rv64p/WALLY-MVENDORID", "4000" + "rv64p/WALLY-MVENDORID", "4000", + "rv64p/WALLY-MEDELEG", "2000" }; string tests32p[] = '{ @@ -368,6 +369,7 @@ module testbench(); "rv32p/WALLY-MIMPID", "4000", "rv32p/WALLY-MHARTID", "4000", "rv32p/WALLY-MVENDORID", "4000" + //"rv32p/WALLY-MEDELEG", "2000" // all 32 bit tests are currently failing, so haven't been able to confirm this test works yet. It should, though. }; string tests64periph[] = '{ diff --git a/wally-pipelined/testgen/privileged/testgen-CAUSE.py b/wally-pipelined/testgen/privileged/testgen-CAUSE.py index c1841db71..9c93a00ae 100644 --- a/wally-pipelined/testgen/privileged/testgen-CAUSE.py +++ b/wally-pipelined/testgen/privileged/testgen-CAUSE.py @@ -61,6 +61,37 @@ def writeVectors(storecmd, returningInstruction): # Supervior timer interrupt: True, 5 # Machine timer interrupt: True, 7 + # if fromMode == "m": + # clintAddr = "0x2004000" + # writeTest(storecmd, f, r, f""" + # li x1, 0x8 + # csrrs x0, {fromMode}status, x1 + + # la x18, {clintAddr} + # lw x11, 0(x18) + # li x1, 1 + # # {storecmd} x1, 0(x18) + + # li x1, 0x80 + # csrrs x0, {fromMode}ie, x1 + # nop + # nop + # nop + # nop + # nop + # nop + # nop + # """, True, 4, f""" + # li x1, 0x80 + # # csrrc x0, {fromMode}ie, x1 + + # li x1, 0x8 + # # csrrc x0, {fromMode}status, x1 + + # la x18, {clintAddr} + # {storecmd} x11, 0(x18) + # """) + # writeTest(storecmd, f, r, f""" # li x10, MASK_XLEN(0x8) # csrrs x0, mstatus, x10 @@ -194,7 +225,7 @@ def writeTest(storecmd, f, r, test, interrupt, code, mode = "m", resetHander = " expected = code if(interrupt): - expected+=(1 << (wordsize - 1)) + expected+=(1 << (xlen - 1)) trapEnd = "" @@ -316,6 +347,8 @@ for xlen in xlens: csrs sedeleg, x9 """ + clintAddr = "0x2004000" + lines += f""" li x30, 0 @@ -328,6 +361,32 @@ for xlen in xlens: j _j_t_begin_{returningInstruction} _j_m_trap_{returningInstruction}: + + #li x1, 0x20 + #csrrw x0, mie, x1 + + li x11, 0x3fffffffffffffff + la x18, {clintAddr} + {storecmd} x11, 0(x18) + + li x1, 0x8 + csrrc x0, mstatus, x1 + + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + sub x1, x2, x3 + csrrs x1, mepc, x0 {"csrr x25, mcause" if testMode == "m" else "li x25, 0xBAD00003"} diff --git a/wally-pipelined/testgen/privileged/testgen-DELEG.py b/wally-pipelined/testgen/privileged/testgen-DELEG.py new file mode 100644 index 000000000..88d99785c --- /dev/null +++ b/wally-pipelined/testgen/privileged/testgen-DELEG.py @@ -0,0 +1,266 @@ +#!/usr/bin/python3 +################################## +# testgen-CAUSE.py +# +# dottolia@hmc.edu 27 Apr 2021 +# +# Generate directed and random test vectors for RISC-V Design Validation. +# +# +################################## +# DOCUMENTATION: +# Most of the comments explaining what everything +# does can be found in testgen-TVAL.py +################################### + +################################## +# libraries +################################## +from datetime import datetime +from random import randint +from random import seed +from random import getrandbits + +################################## +# functions +################################## + +#For instruction-fetch access or page-fault exceptions on systems with variable-length instructions, mtval will contain the virtual address of the portion of the instruction that caused the fault while mepc will point to the beginning of the instruction. + +def randRegs(): + reg1 = randint(1,20) + reg2 = randint(1,20) + reg3 = randint(1,20) + if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2): + return randRegs() + else: + return str(reg1), str(reg2), str(reg3) + +def writeVectors(storecmd): + global testnum + + # User Software Interrupt: True, 0 + # Supervisor Software Interrupt: True, 1 + # Machine Software Interrupt: True, 2 + + # User external input: True, 8 + # Supervisor external input: True, 9 + # Machine externa input: True, 11 + + # Instruction address misaligned: False, 0 + + # Instruction access fault: False, 1 + + # Illegal Instruction + #writeTest(storecmd, f, r, "ecall", False, 11, "m") + + # Breakpoint + writeTest(storecmd, f, r, "ebreak", False, 3) + + # Load Address Misaligned + # writeTest(storecmd, f, r, f""" + # lw x0, 11(x0) + # """, False, 4) + + # # Load Access fault: False, 5 + + # # Store/AMO address misaligned + # writeTest(storecmd, f, r, f""" + # sw x0, 11(x0) + # """, False, 6) + + #writeTest(storecmd, f, r, "ecall", False, 11, "m") + +def writeTest(storecmd, f, r, test, interrupt, code, mode = "m", resetHander = ""): + global testnum + global testMode + global isInterrupts + + if interrupt != isInterrupts: + return + + mask = 1 << code + delegateType = "i" if interrupt else "e" + for mode in (["m", "s", "u"] if testMode == "m" else ["s", "u"]): + for delegated in [True, False]: + labelSuffix = testnum + + f.write(f""" + _start_{labelSuffix}: + + la x1, _j_m_trap_{labelSuffix} + csrw mtvec, x1 + la x1, _j_s_trap_{labelSuffix} + csrw stvec, x1 + + j _j_test_{labelSuffix} + + _j_m_trap_{labelSuffix}: + li x25, 3 + + csrr x1, mepc + addi x1, x1, 4 + csrrw x0, mepc, x1 + bnez x30, _j_finished_{labelSuffix} + mret + + _j_s_trap_{labelSuffix}: + li x25, 1 + + csrr x1, sepc + addi x1, x1, 4 + csrrw x0, sepc, x1 + bnez x30, _j_goto_machine_mode_{labelSuffix} + sret + + _j_goto_machine_mode_{labelSuffix}: + li x30, 1 + {"ebreak" if test is not "ebreak" else "ecall"} + + _j_test_{labelSuffix}: + """) + + original = f""" + li x1, {mask if delegated else 0} + csrw m{delegateType}deleg, x1 + """ + + lines = original + "\n" + test + if mode != "m": + lines = f""" + {original} + + li x1, 0b110000000000 + csrrc x28, {testMode}status, x1 + li x1, 0b{"01" if mode == "s" else "00"}00000000000 + csrrs x28, {testMode}status, x1 + + auipc x1, 0 + addi x1, x1, 16 # x1 is now right after the ret instruction + csrrw x27, {testMode}epc, x1 + {testMode}ret + + # From {testMode}, we're now in {mode} mode... + {test} + """ + + writeTestInner(storecmd, f, r, lines, 1 if delegated else 3) + + f.write(f""" + j _j_goto_machine_mode_{labelSuffix} + """) + + else: + writeTestInner(storecmd, f, r, lines, 3) + + f.write(f""" + _j_finished_{labelSuffix}: + li x30, 0 + """) + + +def writeTestInner(storecmd, f, r, lines, expected): + global testnum + + lines = f""" + li x25, 0xDEADBEA7 + {lines} + """ + + lines += storecmd + " x25, " + str(testnum * wordsize) + "(x6)\n" + f.write(lines) + 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 +################################## + +# change these to suite your tests +author = "dottolia@hmc.edu" +xlens = [32, 64] +numrand = 1; + +# setup +seed(0xD0C0_D0C0_D0C0_D0C0) # 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"]: + for isInterrupts in [True, False]: + imperaspath = "../../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "p/" + basename = "WALLY-" + testMode.upper() + ("I" if isInterrupts else "E") + "DELEG" + fname = imperaspath + "src/" + basename + ".S" + refname = imperaspath + "references/" + basename + ".reference_output" + + # 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) + + # All registers used: + # x19: mtvec old value + # x18: medeleg old value + # x17: mideleg old value + + f.write(f""" + add x7, x6, x0 + csrr x19, mtvec + csrr x18, medeleg + csrr x17, medeleg + """) + + print("\n\n" + basename) + testnum = 0 + for i in range(0, 2): + writeVectors(storecmd) + print(testnum) + + f.write(f""" + csrw mtvec, x19 + csrw medeleg, x18 + csrw mideleg, x17 + """) + + # if we're in supervisor mode, this leaves the ebreak instruction untested (we need a way to) + # get back to machine mode. + + # 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-TVEC.py b/wally-pipelined/testgen/privileged/testgen-TVEC.py index 2e4bb8b98..a6eef5d22 100644 --- a/wally-pipelined/testgen/privileged/testgen-TVEC.py +++ b/wally-pipelined/testgen/privileged/testgen-TVEC.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 ################################## -# testgen-CAUSE.py (new) +# testgen-TVEC.py (new) # # dottolia@hmc.edu 1 Mar 2021 # @@ -25,6 +25,12 @@ from random import randint from random import seed from random import getrandbits +################################## +# setup +################################## + +areVectoredTrapsSupported = True + ################################## # functions ################################## @@ -43,29 +49,6 @@ def randRegs(): def writeVectors(storecmd, returningInstruction): global testnum - if fromMode == "m": - expectedCode = 7 if fromMode == "m" else 5 - clintAddr = "0x2004000" - - writeTest(storecmd, f, r, f""" - li x1, 0x8 - csrrs x0, {fromMode}status, x1 - - la x18, {clintAddr} - lw x11, 0(x18) - li x1, 1 - {storecmd} x1, 0(x18) - - li x1, 0x80 - csrrs x0, {fromMode}ie, x1 - """, True, expectedCode, f""" - la x18, {clintAddr} - {storecmd} x11, 0(x18) - - li x1, 0x80 - csrrc x0, {fromMode}ie, x1 - """) - # Illegal Instruction writeTest(storecmd, f, r, f""" @@ -112,6 +95,35 @@ def writeVectors(storecmd, returningInstruction): ecall """, False, 0) + + if fromMode == "m": + expectedCode = 7 if fromMode == "m" else 5 + clintAddr = "0x2004000" + + writeTest(storecmd, f, r, f""" + li x1, 0x8 + csrrs x0, {fromMode}status, x1 + + la x18, {clintAddr} + lw x11, 0(x18) + li x1, 0x3fffffffffffffff + {storecmd} x1, 0(x18) + + li x1, 0x80 + csrrs x0, {fromMode}ie, x1 + + {storecmd} x0, 0(x18) + """, True, expectedCode, f""" + li x1, 0x80 + csrrc x0, {fromMode}ie, x1 + + li x1, 0x8 + csrrc x0, {fromMode}status, x1 + + la x18, {clintAddr} + {storecmd} x0, 0(x18) + """) + # Instruction page fault: 12 # Load page fault: 13 # Store/AMO page fault: 15 @@ -144,14 +156,13 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""): {test} """ - # We expect x25 to be 0 always. This is because of the code we wrote at the begining - # of this function - - # Store the expected value of x25 to memory and in the .reference_output file lines += f""" {storecmd} x25, {testnum * wordsize}(x6) """ + if not areVectoredTrapsSupported: + expected = 0 + f.write(lines) if (xlen == 32): line = formatrefstr.format(expected)+"\n" @@ -291,7 +302,7 @@ for xlen in xlens: # Set up la x1, _j_m_trap_{returningInstruction} - addi x1, 1 + #addi x1, 1 csrw mtvec, x1 la x1, _j_s_trap_{returningInstruction} csrw stvec, x1