From 6a6ccca3c836a5be16049002214af9cd09585ff2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 8 Apr 2021 13:40:16 -0400 Subject: [PATCH 1/5] fixed sim-wally-32ic --- wally-pipelined/regression/sim-wally-batch-rv32ic | 3 +++ wally-pipelined/regression/sim-wally-rv32ic | 4 +--- wally-pipelined/testbench/testbench-imperas.sv | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) create mode 100755 wally-pipelined/regression/sim-wally-batch-rv32ic diff --git a/wally-pipelined/regression/sim-wally-batch-rv32ic b/wally-pipelined/regression/sim-wally-batch-rv32ic new file mode 100755 index 00000000..b69fb317 --- /dev/null +++ b/wally-pipelined/regression/sim-wally-batch-rv32ic @@ -0,0 +1,3 @@ +vsim -c < Date: Thu, 8 Apr 2021 13:54:42 -0400 Subject: [PATCH 2/5] Updates to WALLY-IE tests --- .../testgen/privileged/testgen-IE.py | 437 +++++++----------- 1 file changed, 177 insertions(+), 260 deletions(-) diff --git a/wally-pipelined/testgen/privileged/testgen-IE.py b/wally-pipelined/testgen/privileged/testgen-IE.py index 67bdf67e..ef8a524c 100644 --- a/wally-pipelined/testgen/privileged/testgen-IE.py +++ b/wally-pipelined/testgen/privileged/testgen-IE.py @@ -3,6 +3,7 @@ # testgen-IE.py # # ushakya@hmc.edu 31 March 2021 +# Modified: 4 April 2021 # # Generate directed and random test vectors for RISC-V Design Validation. ################################## @@ -21,67 +22,212 @@ from random import getrandbits def writeTrapHandlers(storecmd): global testnum - reg1 = 30 - reg2 = 29 - reg3 = 28 - lines = "\n# Trap Handler: Timer Interupt\n" - lines += "_timer_trap_handler:\n" + [reg1, reg2, reg3] = [30, 29, 28] + [reg4, reg5] = [27, 26] + lines = "\n# Trap Handler: Machine Timer Interupt\n" + lines += "_timerM_trap_handler:\n" lines += "li x" + str(reg1) + ", MASK_XLEN(0x2A)\n" - lines += str(storecmd) + " x" + str(reg1) + ", " + str(wordsize*testnum) + "(x6)\n" lines += "la x" + str(reg2) + ", 0x2004000\n" lines += str(storecmd) + " x" + str(reg1) + ", 0(x" + str(reg2) + ")\n" lines += "csrrw x" + str(reg3) + ", mepc, x0\n" lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n" lines += "mret\n" + lines += "\n# Trap Handler: Supervisor Timer Interupt\n" + lines += "_timerS_trap_handler:\n" + lines += "li x" + str(reg4) + ", MASK_XLEN(0x20)\n" + lines += "csrrc x0, mip, x" + str(reg4) + "\n" + lines += "csrrw x" + str(reg5) + ", mepc, x0\n" + lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: User Timer Interupt\n" + lines += "_timerU_trap_handler:\n" + lines += "li x" + str(reg4) + ", MASK_XLEN(0x10)\n" + lines += "csrrc x0, mip, x" + str(reg4) + "\n" + lines += "csrrw x" + str(reg5) + ", mepc, x0\n" + lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: Machine Software Interupt\n" + lines += "_softwareM_trap_handler:\n" + lines += "li x" + str(reg1) + ", MASK_XLEN(0x0)\n" # clear MSIP bit in CLINT + lines += "la x" + str(reg2) + ", 0x2000000\n" + lines += str(storecmd) + " x" + str(reg1) + ", 0(x" + str(reg2) + ")\n" + lines += "csrrw x" + str(reg3) + ", mepc, x0\n" + lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: Supervisor Software Interupt\n" + lines += "_softwareS_trap_handler:\n" + lines += "li x" + str(reg4) + ", MASK_XLEN(0x2)\n" + lines += "csrrc x0, mip, x" + str(reg4) + "\n" + lines += "csrrw x" + str(reg5) + ", mepc, x0\n" + lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: User Software Interupt\n" + lines += "_softwareU_trap_handler:\n" + lines += "li x" + str(reg4) + ", MASK_XLEN(0x1)\n" + lines += "csrrc x0, mip, x" + str(reg4) + "\n" + lines += "csrrw x" + str(reg5) + ", mepc, x0\n" + lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: Machine External Interupt\n" + lines += "_externalM_trap_handler:\n" + #lines += "li x" + str(reg1) + ", MASK_XLEN(0x0)\n" # clear MSIP bit in CLINT + #lines += "la x" + str(reg2) + ", 0x2000000\n" + #lines += str(storecmd) + " x" + str(reg1) + ", 0(x" + str(reg2) + ")\n" + lines += "csrrw x" + str(reg3) + ", mepc, x0\n" + lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: Supervisor External Interupt\n" + lines += "_externalS_trap_handler:\n" + lines += "li x" + str(reg4) + ", MASK_XLEN(0x200)\n" + lines += "csrrc x0, mip, x" + str(reg4) + "\n" + lines += "csrrw x" + str(reg5) + ", mepc, x0\n" + lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + + lines += "\n# Trap Handler: User External Interupt\n" + lines += "_externalU_trap_handler:\n" + lines += "li x" + str(reg4) + ", MASK_XLEN(0x100)\n" + lines += "csrrc x0, mip, x" + str(reg4) + "\n" + lines += "csrrw x" + str(reg5) + ", mepc, x0\n" + lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n" + lines += "mret\n" + f.write(lines) -def writeVector(a, xlen, storecmd): +def getInteruptEnableValues(): + if test == "timerM": + mstatusE = 0x8 + mieE = 0x80 + elif test == "timerS": + mstatusE = 0x2 + mieE = 0x20 + elif test == "timerU": + mstatusE = 0x1 + mieE = 0x10 + elif test == "softwareM": + mstatusE = 0x8 + mieE = 0x8 + elif test == "softwareS": + mstatusE = 0x2 + mieE = 0x2 + elif test == "softwareU": + mstatusE = 0x1 + mieE = 0x1 + elif test == "externalM": + mstatusE = 0x8 + mieE = 0x800 + elif test == "externalS": + mstatusE = 0x2 + mieE = 0x200 + elif test == "externalU": + mstatusE = 0x1 + mieE = 0x100 + return [mstatusE, mieE] + +def getMcause(): + b = 1 << (xlen-1) + if test == "timerM": + b = b + 0x7 + elif test == "timerS": + b = b + 0x5 + elif test == "timerU": + b = b + 0x4 + elif test == "softwareM": + b = b + 0x3 + elif test == "softwareS": + b = b + 0x1 + elif test == "softwareU": + b = b + elif test == "externalM": + b = b + 0xB + elif test == "externalS": + b = b + 0x9 + elif test == "externalU": + b = b + 0x8 + return b + +def writeVectors(a, xlen, storecmd): global testnum [reg1, reg2, reg3] = [1, 2, 3] [reg5, reg8] = [5, 8] [reg9, reg10, reg11, reg12] = [9, 10, 11, 12] - lines = "\n# Testcase 0: Timer Interupt\n" - - # Page 6 of unpriviledged spec - # For both CSRRS and CSRRC, if rs1=x0, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects + lines = f"\n# Testcase {testnum}: {test} Interupt\n" # mcause code - b = 1 << (xlen-1) - b = b + 0x7 - expected = b - lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(b) + ")\n" + expected = getMcause() + lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(expected) + ")\n" if (testnum == 0): expected = 0 + [mstatusE, mieE] = getInteruptEnableValues() # set interupt enable bit in mstatus - lines += "li x" + str(reg3) + ", MASK_XLEN(0x8)\n" + lines += "li x" + str(reg3) + ", MASK_XLEN(" + str(mstatusE) + ")\n" lines += "csrrs x0, mstatus, x" + str(reg3) + "\n" - # set machine timer interupt enable bit in mie - lines += "li x" + str(reg9) + ", MASK_XLEN(0x80)\n" + # set timer interupt enable bit in mie + lines += "li x" + str(reg9) + ", MASK_XLEN(" + str(mieE) + ")\n" lines += "csrrs x0, mie, x" + str(reg3) + "\n" - # Save and set trap handler address for machine mode timer interrupt - lines += "la x" + str(reg5) + ", _timer_trap_handler\n" + # Save and set trap handler address for interrupt + lines += "la x" + str(reg5) + ", _" + test + "_trap_handler\n" # save orignal mtvec address lines += "csrrw x" + str(reg12) + ", mtvec, x" + str(reg5) + "\n" # cause timer interupt - #if (testnum == 0): - lines += "li x" + str(reg8) + ", MASK_XLEN(0)\n" - lines += str(storecmd) + " x" + str(reg8) + ", " + str(wordsize*testnum)+ "(x6)\n" + if test == "timerM": + lines += "li x" + str(reg8) + ", MASK_XLEN(0)\n" + lines += str(storecmd) + " x" + str(reg8) + ", " + str(wordsize*testnum)+ "(x6)\n" + + lines += "la x" + str(reg8) + ", 0x2004000\n" + + lines += "li x" + str(reg3) + ", MASK_XLEN(0)\n" + + # save old value of mtimecmp and then set mtimecmp to zero + lines += "lw x" + str(reg11) + ", 0(x" + str(reg8) + ")\n" + lines += str(storecmd) + " x" + str(reg3) + ", 0(x" + str(reg8) + ")\n" + elif test == "timerS": + lines += "li x" + str(reg3) + ", MASK_XLEN(0x20)\n" + lines += "csrrs x0, mip, x" + str(reg3) + "\n" + elif test == "timerU": + lines += "li x" + str(reg3) + ", MASK_XLEN(0x10)\n" + lines += "csrrs x0, mip, x" + str(reg3) + "\n" - lines += "la x" + str(reg8) + ", 0x2004000\n" + # cause software interupt + if test == "softwareM": + lines += "la x" + str(reg8) + ", 0x2000000\n" # Write to the MSIP bit in CLINT + lines += "li x" + str(reg3) + ", MASK_XLEN(0x1)\n" + lines += str(storecmd) + " x" + str(reg3) + ", 0(x" + str(reg8) + ")\n" + elif test == "softwareS": + lines += "li x" + str(reg3) + ", MASK_XLEN(0x2)\n" + lines += "csrrs x0, mip, x" + str(reg3) + "\n" + elif test == "softwareU": + lines += "li x" + str(reg3) + ", MASK_XLEN(0x1)\n" + lines += "csrrs x0, mip, x" + str(reg3) + "\n" + + # cause external interupt + # Not sure how to cause an external machine interupt yet + # will writing to PLIC just cause it? (where is the ExtIntM located in PLIC) + #if test == "externalM": + #lines += "la x" + str(reg8) + ", 0x2000000\n" # Write to the MSIP bit in CLINT + #lines += "li x" + str(reg3) + ", MASK_XLEN(0x1)\n" + #lines += str(storecmd) + " x" + str(reg3) + ", 0(x" + str(reg8) + ")\n" + if test == "externalS": + lines += "li x" + str(reg3) + ", MASK_XLEN(0x200)\n" + lines += "csrrs x0, mip, x" + str(reg3) + "\n" + elif test == "externalU": + lines += "li x" + str(reg3) + ", MASK_XLEN(0x100)\n" + lines += "csrrs x0, mip, x" + str(reg3) + "\n" - lines += "li x" + str(reg3) + ", MASK_XLEN(0)\n" - - # save old value of mtimecmp and then set mtimecmp to zero - lines += "lw x" + str(reg11) + ", 0(x" + str(reg8) + ")\n" - lines += str(storecmd) + " x" + str(reg3) + ", 0(x" + str(reg8) + ")\n" #lines += "wfi\n" # wait for interupt to be taken lines += "nop\nnop\n" @@ -105,7 +251,7 @@ def writeVector(a, xlen, storecmd): ################################## # change these to suite your tests -tests = ["timer"] +tests = ["timerM", "timerS", "timerU", "softwareM", "softwareS", "softwareU"] author = "ushakya@hmc.edu" xlens = [64, 32] numrand = 100; @@ -149,8 +295,7 @@ for xlen in xlens: # print directed and random test vectors for i in range(0,numrand): a = getrandbits(xlen) - b = getrandbits(xlen) - writeVector(a, xlen, storecmd) + writeVectors(a, xlen, storecmd) writeTrapHandlers(storecmd) @@ -165,231 +310,3 @@ for xlen in xlens: f.write(lines) f.close() r.close() - -""" -#!/usr/bin/python3 -################################## -# testgen-IE.py -# -# ushakya@hmc.edu 24 Mar 2021 -# -# Generate tests for mie CSR for RISC-V Design Validation. -################################## - -################################## -# libraries -################################## -from datetime import datetime -from random import randint -from random import seed -from enum import Enum -from random import getrandbits - -################################## -# functions -################################## - -def randRegs(): - reg1 = randint(1,30) - reg2 = randint(1,30) - reg3 = randint(1,30) - if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2): - return randRegs() - else: - return reg1, reg2, reg3 - -def writeVectors(storecmd): - global testnum - reg1, reg2, reg3 = randRegs() - - # Set interupt enable bit in mstatus - lines = "" - li x2, 0x8 - csrrs x3, mstatus, x2 - "" - - f.write(lines) - - # Save and set trap handler address for machine mode timer interrupt - lines += "" - la x1, _timer_trap_handler - csrrw x31, mtvec, x1 - "" - f.write(lines) - - # Machine Mode Timer Interrupt (when interupt is enabled) - # is this not working because mtimecmp isn't implemented???? - write(f"" - li x2, 0x0 - - li x4, 0x80 - csrrs x0, mie, x4 - - {storecmd} x2, {str(wordsize*testnum)}(x6) - - la x2, 0x2004000 - - li x3, 0x0 - lw x5, 0(x2) - sd x3, 0(x2) - wfi - "", storecmd, True, 4, "m") - - # Supervisor Timer Interrupt - # user timer interupt - - # Machine mode external interrupt (hasn't been connected yet) - - # User external interrupt True, 8 - # Supervisor external interrupt True, 9 - - # Save and set trap handler address for machine mode software interrupt - # lines = "" - # la x1, _interupt_trap_handler - # csrrw x31, mtvec, x1 - # "" - # f.write(lines) - - # Machine Mode software interupt (write to the CLINT) - #write(f"" - # li x6, 0x0 -# -# li x4, 0x8 -# csrrs x0, mie, x4 -# -# li x3, 0x1 -# lw x4, clint -# or x3, x4, x3 -# {storecmd} x3, clint -# "", storecmd, True, 3, "m") - - # supervisor mode software interupt - # user mode software interupt - - # timer interupt trap handler - lines = f"" - _timer_trap_handler: - li x2, 0x2A - {storecmd} x2, {str(wordsize*testnum)}(x6) - la x3, 0x2004000 - {storecmd} x2, 0(x3) - mret - "" - - # software interupt trap handler - #lines += f"" - #_interupt_trap_handler: - #li x6, 0x2A - #li x3, 0x0 - #lw x4, clint - #xor x3, x4, x3 - #{storecmd} x3, 0(clint) - #mret - #"" - lines += storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)" - - f.write(lines) - -def write(lines, storecmd, interrupt, code, mode = "m"): - global testnum - - # generate expected interrupt code - expected = 0 - #(0 if not interrupt else (2**31 if xlen == 32 else 2**63)) + code - # go back and fix expected - - lines = f"" - # Testcase {testnum} - li x31, 0 - {lines} - - {storecmd} x31, {str(wordsize*testnum)}(x6) - # RVTEST_IO_ASSERT_GPR_EQ(x0, 0, {formatstr.format(expected)}) - "" - - #if mode == "s": - # go to supervisor mode - #elif mode == "u": - # go to user mode - - f.write(lines) - - if (xlen == 32): - line = formatrefstr.format(expected)+"" - else: - line = formatrefstr.format(expected % 2**32)+"" + formatrefstr.format(expected >> 32) + "" - r.write(line) - testnum = testnum+1 - -################################## -# main body -################################## - -# name: (interrupt?, code) -# tests = { -# 'User software interrupt': (1, '0'), -# 'Supervisor software interrupt': (1, '1'), -# 'Machine software interrupt': (1, '3'), -# 'User timer interrupt': (1, '4'), -# 'Supervisor timer interrupt': (1, '5'), -# 'Machine timer interrupt': (1, '7'), -# 'User external interrupt': (1, '8'), -# 'Supervisor external interrupt': (1, '9'), -# 'Machine external interrupt': (1, '11'), -# } -author = "Udeema Shakya (ushakya@hmc.edu)" -xlens = [64, 32] -numrand = 60; - -# setup -seed(0xC395DDEB9173AD42) # 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 - - imperaspath = f"../../../imperas-riscv-tests/riscv-test-suite/rv{xlen}p/"" - basename = "WALLY-IE" - fname = imperaspath + "src/" + basename + ".S" - refname = imperaspath + "references/" + basename + ".reference_output" - testnum = 0 - - # print custom header part - f = open(fname, "w") - r = open(refname, "w") - line = "///////////////////////////////////////////" - f.write(line) - lines="// "+fname+ "// " + author + "" - 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) - - # print directed and random test vectors - writeVectors(storecmd) - - - # print footer - h = open("../testgen_footer.S", "r") - for line in h: - f.write(line) - - # Finish - lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1" - lines = lines + "RV_COMPLIANCE_DATA_END" - f.write(lines) - f.close() - r.close() - """ From 27cb94e7af9b6ff8c568310cf4cf87aeeef35514 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Thu, 8 Apr 2021 17:55:25 +0000 Subject: [PATCH 3/5] fixed FPU lint warnings --- wally-pipelined/src/fpu/fpu.sv | 2 +- wally-pipelined/src/fpu/freg.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/fpu/fpu.sv b/wally-pipelined/src/fpu/fpu.sv index e8bfcf57..51d36ac8 100755 --- a/wally-pipelined/src/fpu/fpu.sv +++ b/wally-pipelined/src/fpu/fpu.sv @@ -1,4 +1,4 @@ -`include "../../config/rv64icfd/wally-config.vh" +// `include "../../config/rv64icfd/wally-config.vh" module fpu ( //input logic [2:0] FrmD, diff --git a/wally-pipelined/src/fpu/freg.sv b/wally-pipelined/src/fpu/freg.sv index 04c7efa0..be6828c2 100755 --- a/wally-pipelined/src/fpu/freg.sv +++ b/wally-pipelined/src/fpu/freg.sv @@ -1,4 +1,4 @@ -`include "../../config/rv64icfd/wally-config.vh" +// `include "../../config/rv64icfd/wally-config.vh" module freg1adr ( input logic [2:0] frm, From f4cb92ae713b21ee823983c859cce69983aa1e19 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Thu, 8 Apr 2021 18:03:21 +0000 Subject: [PATCH 4/5] fixed FPU lint warnings --- wally-pipelined/src/fpu/fpu.sv | 3 ++- wally-pipelined/src/fpu/freg.sv | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/fpu/fpu.sv b/wally-pipelined/src/fpu/fpu.sv index 51d36ac8..9d58fd0f 100755 --- a/wally-pipelined/src/fpu/fpu.sv +++ b/wally-pipelined/src/fpu/fpu.sv @@ -1,4 +1,5 @@ -// `include "../../config/rv64icfd/wally-config.vh" + +`include "wally-config.vh" module fpu ( //input logic [2:0] FrmD, diff --git a/wally-pipelined/src/fpu/freg.sv b/wally-pipelined/src/fpu/freg.sv index be6828c2..f9e6e988 100755 --- a/wally-pipelined/src/fpu/freg.sv +++ b/wally-pipelined/src/fpu/freg.sv @@ -1,4 +1,5 @@ -// `include "../../config/rv64icfd/wally-config.vh" + +`include "wally-config.vh" module freg1adr ( input logic [2:0] frm, From 6b2868a8c78a6f8c20c4f975f36b23a3c708091e Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 8 Apr 2021 14:04:01 -0400 Subject: [PATCH 5/5] restored testbench-imperas.sv --- .../testbench/testbench-imperas.sv | 700 ++++++++++++++++++ 1 file changed, 700 insertions(+) create mode 100644 wally-pipelined/testbench/testbench-imperas.sv diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv new file mode 100644 index 00000000..0cc7845a --- /dev/null +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -0,0 +1,700 @@ +/////////////////////////////////////////// +// testbench-imperas.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Wally Testbench and helper modules +// Applies test programs from the Imperas suite +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module testbench(); + parameter DEBUG = 0; + parameter TESTSBP = 0; + + logic clk; + logic reset; + + int test, i, errors, totalerrors; + logic [31:0] sig32[0:10000]; + logic [`XLEN-1:0] signature[0:10000]; + logic [`XLEN-1:0] testadr; + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + logic [`XLEN-1:0] meminit; + + string tests32mmu[] = '{ + "rv32mmu/WALLY-VIRTUALMEMORY", "5000" + }; + + string tests64mmu[] = '{ + "rv64mmu/WALLY-VIRTUALMEMORY", "5000" + }; + + string tests64f[] = '{ + "rv64f/I-FADD-S-01", "2000", + "rv64f/I-FCLASS-S-01", "2000" + }; + + string tests64a[] = '{ + "rv64a/WALLY-AMO", "2110", + "rv64a/WALLY-LRSC", "2110" + }; + string tests64m[] = '{ + "rv64m/I-MUL-01", "3000", + "rv64m/I-MULH-01", "3000", + "rv64m/I-MULHSU-01", "3000", + "rv64m/I-MULHU-01", "3000", + "rv64m/I-MULW-01", "3000" +// "rv64m/I-DIV-01", "3000", +// "rv64m/I-DIVU-01", "3000" + // "rv64m/I-DIVUW-01", "3000", + // "rv64m/I-DIVW-01", "3000", +// "rv64m/I-REM-01", "3000", +// "rv64m/I-REMU-01", "3000", +// "rv64m/I-REMUW-01", "3000", +// "rv64m/I-REMW-01", "3000" + }; + string tests64ic[] = '{ + "rv64ic/I-C-ADD-01", "3000", + "rv64ic/I-C-ADDI-01", "3000", + "rv64ic/I-C-ADDIW-01", "3000", + "rv64ic/I-C-ADDW-01", "3000", + "rv64ic/I-C-AND-01", "3000", + "rv64ic/I-C-ANDI-01", "3000", + "rv64ic/I-C-BEQZ-01", "3000", + "rv64ic/I-C-BNEZ-01", "3000", + "rv64ic/I-C-EBREAK-01", "2000", + "rv64ic/I-C-J-01", "3000", + "rv64ic/I-C-JALR-01", "4000", + "rv64ic/I-C-JR-01", "4000", + "rv64ic/I-C-LD-01", "3420", + "rv64ic/I-C-LDSP-01", "3420", + "rv64ic/I-C-LI-01", "3000", + "rv64ic/I-C-LUI-01", "2000", + "rv64ic/I-C-LW-01", "3110", + "rv64ic/I-C-LWSP-01", "3110", + "rv64ic/I-C-MV-01", "3000", + "rv64ic/I-C-NOP-01", "2000", + "rv64ic/I-C-OR-01", "3000", + "rv64ic/I-C-SD-01", "3000", + "rv64ic/I-C-SDSP-01", "3000", + "rv64ic/I-C-SLLI-01", "3000", + "rv64ic/I-C-SRAI-01", "3000", + "rv64ic/I-C-SRLI-01", "3000", + "rv64ic/I-C-SUB-01", "3000", + "rv64ic/I-C-SUBW-01", "3000", + "rv64ic/I-C-SW-01", "3000", + "rv64ic/I-C-SWSP-01", "3000", + "rv64ic/I-C-XOR-01", "3000" + }; +string tests64iNOc[] = { + "rv64i/I-MISALIGN_JMP-01","2000" + }; + string tests64i[] = '{ + "rv64i/I-ADD-01", "3000", + "rv64i/I-ADDI-01", "3000", + "rv64i/I-ADDIW-01", "3000", + "rv64i/I-ADDW-01", "3000", + "rv64i/I-AND-01", "3000", + "rv64i/I-ANDI-01", "3000", + "rv64i/I-AUIPC-01", "3000", + "rv64i/I-BEQ-01", "4000", + "rv64i/I-BGE-01", "4000", + "rv64i/I-BGEU-01", "4000", + "rv64i/I-BLT-01", "4000", + "rv64i/I-BLTU-01", "4000", + "rv64i/I-BNE-01", "4000", + "rv64i/I-DELAY_SLOTS-01", "2000", + "rv64i/I-EBREAK-01", "2000", + "rv64i/I-ECALL-01", "2000", + "rv64i/I-ENDIANESS-01", "2010", + "rv64i/I-IO-01", "2050", + "rv64i/I-JAL-01", "3000", + "rv64i/I-JALR-01", "4000", + "rv64i/I-LB-01", "4020", + "rv64i/I-LBU-01", "4020", + "rv64i/I-LD-01", "4420", + "rv64i/I-LH-01", "4050", + "rv64i/I-LHU-01", "4050", + "rv64i/I-LUI-01", "2000", + "rv64i/I-LW-01", "4110", + "rv64i/I-LWU-01", "4110", + "rv64i/I-MISALIGN_LDST-01", "2010", + "rv64i/I-NOP-01", "2000", + "rv64i/I-OR-01", "3000", + "rv64i/I-ORI-01", "3000", + "rv64i/I-RF_size-01", "2000", + "rv64i/I-RF_width-01", "2000", + "rv64i/I-RF_x0-01", "2010", + "rv64i/I-SB-01", "4000", + "rv64i/I-SD-01", "4000", + "rv64i/I-SH-01", "4000", + "rv64i/I-SLL-01", "3000", + "rv64i/I-SLLI-01", "3000", + "rv64i/I-SLLIW-01", "3000", + "rv64i/I-SLLW-01", "3000", + "rv64i/I-SLT-01", "3000", + "rv64i/I-SLTI-01", "3000", + "rv64i/I-SLTIU-01", "3000", + "rv64i/I-SLTU-01", "3000", + "rv64i/I-SRA-01", "3000", + "rv64i/I-SRAI-01", "3000", + "rv64i/I-SRAIW-01", "3000", + "rv64i/I-SRAW-01", "3000", + "rv64i/I-SRL-01", "3000", + "rv64i/I-SRLI-01", "3000", + "rv64i/I-SRLIW-01", "3000", + "rv64i/I-SRLW-01", "3000", + "rv64i/I-SUB-01", "3000", + "rv64i/I-SUBW-01", "3000", + "rv64i/I-SW-01", "4000", + "rv64i/I-XOR-01", "3000", + "rv64i/I-XORI-01", "3000", + "rv64i/WALLY-ADD", "4000", + "rv64i/WALLY-SUB", "4000", + "rv64i/WALLY-ADDI", "3000", + "rv64i/WALLY-ANDI", "3000", + "rv64i/WALLY-ORI", "3000", + "rv64i/WALLY-XORI", "3000", + "rv64i/WALLY-SLTI", "3000", + "rv64i/WALLY-SLTIU", "3000", + "rv64i/WALLY-SLLI", "3000", + "rv64i/WALLY-SRLI", "3000", + "rv64i/WALLY-SRAI", "3000", + "rv64i/WALLY-LOAD", "11bf0", + "rv64i/WALLY-JAL", "4000", + "rv64i/WALLY-JALR", "3000", + "rv64i/WALLY-STORE", "3000", + "rv64i/WALLY-ADDIW", "3000", + "rv64i/WALLY-SLLIW", "3000", + "rv64i/WALLY-SRLIW", "3000", + "rv64i/WALLY-SRAIW", "3000", + "rv64i/WALLY-ADDW", "4000", + "rv64i/WALLY-SUBW", "4000", + "rv64i/WALLY-SLLW", "3000", + "rv64i/WALLY-SRLW", "3000", + "rv64i/WALLY-SRAW", "3000", + "rv64i/WALLY-BEQ" ,"5000", + "rv64i/WALLY-BNE", "5000 ", + "rv64i/WALLY-BLTU", "5000 ", + "rv64i/WALLY-BLT", "5000", + "rv64i/WALLY-BGE", "5000 ", + "rv64i/WALLY-BGEU", "5000 ", + "rv64i/WALLY-CSRRW", "4000", + "rv64i/WALLY-CSRRS", "4000", + "rv64i/WALLY-CSRRC", "5000", + "rv64i/WALLY-CSRRWI", "4000", + "rv64i/WALLY-CSRRSI", "4000", + "rv64i/WALLY-CSRRCI", "4000" + + }; + string tests32a[] = '{ + "rv64a/WALLY-AMO", "2110", + "rv64a/WALLY-LRSC", "2110" + }; + string tests32m[] = '{ + "rv32m/I-MUL-01", "2000", + "rv32m/I-MULH-01", "2000", + "rv32m/I-MULHSU-01", "2000", + "rv32m/I-MULHU-01", "2000" +// "rv32m/I-DIV-01", "2000", +// "rv32m/I-DIVU-01", "2000", +// "rv32m/I-REM-01", "2000", +// "rv32m/I-REMU-01", "2000" + }; +string tests32ic[] = '{ + "rv32ic/I-C-ADD-01", "2000", + "rv32ic/I-C-ADDI-01", "2000", + "rv32ic/I-C-AND-01", "2000", + "rv32ic/I-C-ANDI-01", "2000", + "rv32ic/I-C-BEQZ-01", "2000", + "rv32ic/I-C-BNEZ-01", "2000", + "rv32ic/I-C-EBREAK-01", "2000", + "rv32ic/I-C-J-01", "2000", + "rv32ic/I-C-JALR-01", "3000", + "rv32ic/I-C-JR-01", "3000", + "rv32ic/I-C-LI-01", "2000", + "rv32ic/I-C-LUI-01", "2000", + "rv32ic/I-C-LW-01", "2110", + "rv32ic/I-C-LWSP-01", "2110", + "rv32ic/I-C-MV-01", "2000", + "rv32ic/I-C-NOP-01", "2000", + "rv32ic/I-C-OR-01", "2000", + "rv32ic/I-C-SLLI-01", "2000", + "rv32ic/I-C-SRAI-01", "2000", + "rv32ic/I-C-SRLI-01", "2000", + "rv32ic/I-C-SUB-01", "2000", + "rv32ic/I-C-SW-01", "2000", + "rv32ic/I-C-SWSP-01", "2000", + "rv32ic/I-C-XOR-01", "2000" +}; +string tests32iNOc[] = { + "rv32i/I-MISALIGN_JMP-01","2000" +}; +string tests32i[] = { + "rv32i/I-ADD-01", "2000", + "rv32i/I-ADDI-01","2000", + "rv32i/I-AND-01","2000", + "rv32i/I-ANDI-01","2000", + "rv32i/I-AUIPC-01","2000", + "rv32i/I-BEQ-01","3000", + "rv32i/I-BGE-01","3000", + "rv32i/I-BGEU-01","3000", + "rv32i/I-BLT-01","3000", + "rv32i/I-BLTU-01","3000", + "rv32i/I-BNE-01","3000", + "rv32i/I-DELAY_SLOTS-01","2000", + "rv32i/I-EBREAK-01","2000", + "rv32i/I-ECALL-01","2000", + "rv32i/I-ENDIANESS-01","2010", + "rv32i/I-IO-01","2030", + "rv32i/I-JAL-01","3000", + "rv32i/I-JALR-01","3000", + "rv32i/I-LB-01","3020", + "rv32i/I-LBU-01","3020", + "rv32i/I-LH-01","3050", + "rv32i/I-LHU-01","3050", + "rv32i/I-LUI-01","2000", + "rv32i/I-LW-01","3110", + "rv32i/I-MISALIGN_LDST-01","2010", + "rv32i/I-NOP-01","2000", + "rv32i/I-OR-01","2000", + "rv32i/I-ORI-01","2000", + "rv32i/I-RF_size-01","2000", + "rv32i/I-RF_width-01","2000", + "rv32i/I-RF_x0-01","2010", + "rv32i/I-SB-01","3000", + "rv32i/I-SH-01","3000", + "rv32i/I-SLL-01","2000", + "rv32i/I-SLLI-01","2000", + "rv32i/I-SLT-01","2000", + "rv32i/I-SLTI-01","2000", + "rv32i/I-SLTIU-01","2000", + "rv32i/I-SLTU-01","2000", + "rv32i/I-SRA-01","2000", + "rv32i/I-SRAI-01","2000", + "rv32i/I-SRL-01","2000", + "rv32i/I-SRLI-01","2000", + "rv32i/I-SUB-01","2000", + "rv32i/I-SW-01","3000", + "rv32i/I-XOR-01","2000", + "rv32i/I-XORI-01","2000", + "rv32i/WALLY-ADD", "3000", + "rv32i/WALLY-SUB", "3000", + "rv32i/WALLY-ADDI", "2000", + "rv32i/WALLY-ANDI", "2000", + "rv32i/WALLY-ORI", "2000", + "rv32i/WALLY-XORI", "2000", + "rv32i/WALLY-SLTI", "2000", + "rv32i/WALLY-SLTIU", "2000", + "rv32i/WALLY-SLLI", "2000", + "rv32i/WALLY-SRLI", "2000", + "rv32i/WALLY-SRAI", "2000", + "rv32i/WALLY-LOAD", "11c00", + "rv32i/WALLY-SUB", "3000", + "rv32i/WALLY-STORE", "2000", + "rv32i/WALLY-JAL", "3000", + "rv32i/WALLY-JALR", "2000", + "rv32i/WALLY-BEQ" ,"4000", + "rv32i/WALLY-BNE", "4000 ", + "rv32i/WALLY-BLTU", "4000 ", + "rv32i/WALLY-BLT", "4000", + "rv32i/WALLY-BGE", "4000 ", + "rv32i/WALLY-BGEU", "4000 ", + "rv32i/WALLY-CSRRW", "3000", + "rv32i/WALLY-CSRRS", "3000", + "rv32i/WALLY-CSRRC", "4000", + "rv32i/WALLY-CSRRWI", "3000", + "rv32i/WALLY-CSRRSI", "3000", + "rv32i/WALLY-CSRRCI", "3000" + +}; + + string testsBP64[] = '{ + "rv64BP/reg-test", "10000" + }; + + // string tests64p[] = '{ + // "rv64p/WALLY-CAUSE", "3000", + // "rv64p/WALLY-EPC", "3000", + // "rv64p/WALLY-TVAL", "3000" + // }; + + + + string tests64p[] = '{ + "rv64p/WALLY-CAUSE", "3000", + "rv64p/WALLY-EPC", "3000", + "rv64p/WALLY-TVAL", "3000", + "rv64p/WALLY-MARCHID", "4000", + "rv64p/WALLY-MIMPID", "4000", + "rv64p/WALLY-MHARTID", "4000", + "rv64p/WALLY-MVENDORID", "4000" + }; + + + + string tests[]; + string ProgramAddrMapFile, ProgramLabelMapFile; + logic [`AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; + logic [31:0] HADDR; + logic [`AHBW-1:0] HWDATA; + logic HWRITE; + logic [2:0] HSIZE; + logic [2:0] HBURST; + logic [3:0] HPROT; + logic [1:0] HTRANS; + logic HMASTLOCK; + logic HCLK, HRESETn; + logic [`XLEN-1:0] PCW; + + flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); + // pick tests based on modes supported + initial begin + if (`XLEN == 64) begin // RV64 + if (TESTSBP) begin + tests = testsBP64; + end else begin + tests = {tests64i}; + if (`C_SUPPORTED) tests = {tests, tests64ic}; + else tests = {tests, tests64iNOc}; + if (`M_SUPPORTED) tests = {tests, tests64m}; + // if (`F_SUPPORTED) tests = {tests64f, tests}; + // if (`D_SUPPORTED) tests = {tests64d, tests}; + if (`A_SUPPORTED) tests = {tests, tests64a}; + if (`MEM_VIRTMEM) tests = {tests64mmu, tests}; + end + // tests = {tests64a, tests}; + tests = {tests, tests64p}; + end else begin // RV32 + // *** add the 32 bit bp tests + tests = {tests32i}; + if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; + else tests = {tests, tests32iNOc}; + if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; + // if (`F_SUPPORTED) tests = {tests32f, tests}; + if (`A_SUPPORTED) tests = {tests, tests32a}; + if (`MEM_VIRTMEM) tests = {tests32mmu, tests}; + end + + //tests = tests64p; + end + + + string signame, memfilename; + + logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; + logic UARTSin, UARTSout; + + // instantiate device to be tested + assign GPIOPinsIn = 0; + assign UARTSin = 1; + assign HREADYEXT = 1; + assign HRESPEXT = 0; + assign HRDATAEXT = 0; + + wallypipelinedsoc dut(.*); + + // Track names of instructions + instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, + dut.hart.ifu.ic.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, + dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName, + InstrEName, InstrMName, InstrWName); + + // initialize tests + initial + begin + test = 0; + totalerrors = 0; + testadr = 0; + // fill memory with defined values to reduce Xs in simulation + if (`XLEN == 32) meminit = 32'hFEDC0123; + else meminit = 64'hFEDCBA9876543210; + for (i=0; i<=65535; i = i+1) begin + //dut.imem.RAM[i] = meminit; + // dut.uncore.RAM[i] = meminit; + end + // read test vectors into memory + memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; + $readmemh(memfilename, dut.imem.RAM); + $readmemh(memfilename, dut.uncore.dtim.RAM); + ProgramAddrMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.addr"}; + ProgramLabelMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.lab"}; + $display("Read memfile %s", memfilename); + reset = 1; # 42; reset = 0; + end + + // generate clock to sequence tests + always + begin + clk = 1; # 5; clk = 0; # 5; + end + + // check results + always @(negedge clk) + begin + if (dut.hart.priv.EcallFaultM && + (dut.hart.ieu.dp.regf.rf[3] == 1 || (dut.hart.ieu.dp.regf.we3 && dut.hart.ieu.dp.regf.a3 == 3 && dut.hart.ieu.dp.regf.wd3 == 1))) begin + $display("Code ended with ecall with gp = 1"); + #60; // give time for instructions in pipeline to finish + // clear signature to prevent contamination from previous tests + for(i=0; i<10000; i=i+1) begin + sig32[i] = 'bx; + end + + // read signature, reformat in 64 bits if necessary + signame = {"../../imperas-riscv-tests/work/", tests[test], ".signature.output"}; + $readmemh(signame, sig32); + i = 0; + while (i < 10000) begin + if (`XLEN == 32) begin + signature[i] = sig32[i]; + i = i+1; + end else begin + signature[i/2] = {sig32[i+1], sig32[i]}; + i = i + 2; + end + end + + // Check errors + i = 0; + errors = 0; + if (`XLEN == 32) + testadr = (`TIMBASE+tests[test+1].atohex())/4; + else + testadr = (`TIMBASE+tests[test+1].atohex())/8; + /* verilator lint_off INFINITELOOP */ + while (signature[i] !== 'bx) begin + //$display("signature[%h] = %h", i, signature[i]); + if (signature[i] !== dut.uncore.dtim.RAM[testadr+i]) begin + if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin + // report errors unless they are garbage at the end of the sim + // kind of hacky test for garbage right now + errors = errors+1; + $display(" Error on test %s result %d: adr = %h sim = %h, signature = %h", + tests[test], i, (testadr+i)*`XLEN/8, dut.uncore.dtim.RAM[testadr+i], signature[i]); + end + end + i = i + 1; + end + /* verilator lint_on INFINITELOOP */ + if (errors == 0) $display("%s succeeded. Brilliant!!!", tests[test]); + else begin + $display("%s failed with %d errors. :(", tests[test], errors); + totalerrors = totalerrors+1; + end + test = test + 2; + if (test == tests.size()) begin + if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); + else $display("FAIL: %d test programs had errors", totalerrors); + $stop; + end + else begin + memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; + $readmemh(memfilename, dut.imem.RAM); + $readmemh(memfilename, dut.uncore.dtim.RAM); + $display("Read memfile %s", memfilename); + ProgramAddrMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.addr"}; + ProgramLabelMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.lab"}; + reset = 1; # 17; reset = 0; + end + end + end // always @ (negedge clk) + + // track the current function or global label + if (DEBUG == 1) begin : functionRadix + function_radix function_radix(.reset(reset), + .ProgramAddrMapFile(ProgramAddrMapFile), + .ProgramLabelMapFile(ProgramLabelMapFile)); + end + + // initialize the branch predictor + initial begin + $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory); + $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory); + end + +endmodule + +/* verilator lint_on STMTDLY */ +/* verilator lint_on WIDTH */ + +module instrTrackerTB( + input logic clk, reset, FlushE, + input logic [31:0] InstrF, InstrD, + input logic [31:0] InstrE, InstrM, + input logic [31:0] InstrW, +// output logic [31:0] InstrW, + output string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); + + // stage Instr to Writeback for visualization + // flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); + + instrNameDecTB fdec(InstrF, InstrFName); + instrNameDecTB ddec(InstrD, InstrDName); + instrNameDecTB edec(InstrE, InstrEName); + instrNameDecTB mdec(InstrM, InstrMName); + instrNameDecTB wdec(InstrW, InstrWName); +endmodule + +// decode the instruction name, to help the test bench +module instrNameDecTB( + input logic [31:0] instr, + output string name); + + logic [6:0] op; + logic [2:0] funct3; + logic [6:0] funct7; + logic [11:0] imm; + + assign op = instr[6:0]; + assign funct3 = instr[14:12]; + assign funct7 = instr[31:25]; + assign imm = instr[31:20]; + + // it would be nice to add the operands to the name + // create another variable called decoded + + always_comb + casez({op, funct3}) + 10'b0000000_000: name = "BAD"; + 10'b0000011_000: name = "LB"; + 10'b0000011_001: name = "LH"; + 10'b0000011_010: name = "LW"; + 10'b0000011_011: name = "LD"; + 10'b0000011_100: name = "LBU"; + 10'b0000011_101: name = "LHU"; + 10'b0000011_110: name = "LWU"; + 10'b0010011_000: if (instr[31:15] == 0 && instr[11:7] ==0) name = "NOP/FLUSH"; + else name = "ADDI"; + 10'b0010011_001: if (funct7[6:1] == 6'b000000) name = "SLLI"; + else name = "ILLEGAL"; + 10'b0010011_010: name = "SLTI"; + 10'b0010011_011: name = "SLTIU"; + 10'b0010011_100: name = "XORI"; + 10'b0010011_101: if (funct7[6:1] == 6'b000000) name = "SRLI"; + else if (funct7[6:1] == 6'b010000) name = "SRAI"; + else name = "ILLEGAL"; + 10'b0010011_110: name = "ORI"; + 10'b0010011_111: name = "ANDI"; + 10'b0010111_???: name = "AUIPC"; + 10'b0100011_000: name = "SB"; + 10'b0100011_001: name = "SH"; + 10'b0100011_010: name = "SW"; + 10'b0100011_011: name = "SD"; + 10'b0011011_000: name = "ADDIW"; + 10'b0011011_001: name = "SLLIW"; + 10'b0011011_101: if (funct7 == 7'b0000000) name = "SRLIW"; + else if (funct7 == 7'b0100000) name = "SRAIW"; + else name = "ILLEGAL"; + 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; + else if (funct7 == 7'b0100000) name = "SUBW"; + else if (funct7 == 7'b0000001) name = "MULW"; + else name = "ILLEGAL"; + 10'b0111011_001: if (funct7 == 7'b0000000) name = "SLLW"; + else if (funct7 == 7'b0000001) name = "DIVW"; + else name = "ILLEGAL"; + 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; + else if (funct7 == 7'b0100000) name = "SRAW"; + else if (funct7 == 7'b0000001) name = "DIVUW"; + else name = "ILLEGAL"; + 10'b0111011_110: if (funct7 == 7'b0000001) name = "REMW"; + else name = "ILLEGAL"; + 10'b0111011_111: if (funct7 == 7'b0000001) name = "REMUW"; + else name = "ILLEGAL"; + 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; + else if (funct7 == 7'b0000001) name = "MUL"; + else if (funct7 == 7'b0100000) name = "SUB"; + else name = "ILLEGAL"; + 10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL"; + else if (funct7 == 7'b0000001) name = "MULH"; + else name = "ILLEGAL"; + 10'b0110011_010: if (funct7 == 7'b0000000) name = "SLT"; + else if (funct7 == 7'b0000001) name = "MULHSU"; + else name = "ILLEGAL"; + 10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU"; + else if (funct7 == 7'b0000001) name = "MULHU"; + else name = "ILLEGAL"; + 10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR"; + else if (funct7 == 7'b0000001) name = "DIV"; + else name = "ILLEGAL"; + 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; + else if (funct7 == 7'b0000001) name = "DIVU"; + else if (funct7 == 7'b0100000) name = "SRA"; + else name = "ILLEGAL"; + 10'b0110011_110: if (funct7 == 7'b0000000) name = "OR"; + else if (funct7 == 7'b0000001) name = "REM"; + else name = "ILLEGAL"; + 10'b0110011_111: if (funct7 == 7'b0000000) name = "AND"; + else if (funct7 == 7'b0000001) name = "REMU"; + else name = "ILLEGAL"; + 10'b0110111_???: name = "LUI"; + 10'b1100011_000: name = "BEQ"; + 10'b1100011_001: name = "BNE"; + 10'b1100011_100: name = "BLT"; + 10'b1100011_101: name = "BGE"; + 10'b1100011_110: name = "BLTU"; + 10'b1100011_111: name = "BGEU"; + 10'b1100111_000: name = "JALR"; + 10'b1101111_???: name = "JAL"; + 10'b1110011_000: if (imm == 0) name = "ECALL"; + else if (imm == 1) name = "EBREAK"; + else if (imm == 2) name = "URET"; + else if (imm == 258) name = "SRET"; + else if (imm == 770) name = "MRET"; + else name = "ILLEGAL"; + 10'b1110011_001: name = "CSRRW"; + 10'b1110011_010: name = "CSRRS"; + 10'b1110011_011: name = "CSRRC"; + 10'b1110011_101: name = "CSRRWI"; + 10'b1110011_110: name = "CSRRSI"; + 10'b1110011_111: name = "CSRRCI"; + 10'b0101111_010: if (funct7[6:2] == 5'b00010) name = "LR.W"; + else if (funct7[6:2] == 5'b00011) name = "SC.W"; + else if (funct7[6:2] == 5'b00001) name = "AMOSWAP.W"; + else if (funct7[6:2] == 5'b00000) name = "AMOADD.W"; + else if (funct7[6:2] == 5'b00100) name = "AMOAXOR.W"; + else if (funct7[6:2] == 5'b01100) name = "AMOAND.W"; + else if (funct7[6:2] == 5'b01000) name = "AMOOR.W"; + else if (funct7[6:2] == 5'b10000) name = "AMOMIN.W"; + else if (funct7[6:2] == 5'b10100) name = "AMOMAX.W"; + else if (funct7[6:2] == 5'b11000) name = "AMOMINU.W"; + else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.W"; + else name = "ILLEGAL"; + 10'b0101111_011: if (funct7[6:2] == 5'b00010) name = "LR.D"; + else if (funct7[6:2] == 5'b00011) name = "SC.D"; + else if (funct7[6:2] == 5'b00001) name = "AMOSWAP.D"; + else if (funct7[6:2] == 5'b00000) name = "AMOADD.D"; + else if (funct7[6:2] == 5'b00100) name = "AMOAXOR.D"; + else if (funct7[6:2] == 5'b01100) name = "AMOAND.D"; + else if (funct7[6:2] == 5'b01000) name = "AMOOR.D"; + else if (funct7[6:2] == 5'b10000) name = "AMOMIN.D"; + else if (funct7[6:2] == 5'b10100) name = "AMOMAX.D"; + else if (funct7[6:2] == 5'b11000) name = "AMOMINU.D"; + else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.D"; + else name = "ILLEGAL"; + 10'b0001111_???: name = "FENCE"; + default: name = "ILLEGAL"; + endcase +endmodule