mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-02 09:45:18 +00:00
Merge branch 'main' of https://github.com/openhwgroup/cvw into installation
This commit is contained in:
commit
2f1a101735
1
.gitignore
vendored
1
.gitignore
vendored
@ -243,3 +243,4 @@ tests/functcov/*
|
||||
tests/functcov/*/*
|
||||
sim/vcs/simprofile*
|
||||
sim/verilator/verilator.log
|
||||
/fpga/rvvidaemon/rvvidaemon
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -24,3 +24,7 @@
|
||||
[submodule "addins/ahbsdc"]
|
||||
path = addins/ahbsdc
|
||||
url = https://github.com/JacobPease/ahbsdc.git
|
||||
[submodule "addins/verilog-ethernet"]
|
||||
sparseCheckout = true
|
||||
path = addins/verilog-ethernet
|
||||
url = https://github.com/ross144/verilog-ethernet.git
|
||||
|
3
addins/README.md
Normal file
3
addins/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
verilog-ethernet contains many ethernet devices. Wally's synthesizable RVVI interface only requires a small subset of these files.
|
||||
To do a sparse checkout of this repo copy sparse-checkout to cvw/.git/modules/addins/verilog-ethernet/info
|
||||
This will make the working directory only contain the necessary files.
|
17
addins/sparse-checkout
Normal file
17
addins/sparse-checkout
Normal file
@ -0,0 +1,17 @@
|
||||
rtl/eth_mac_mii_fifo.sv
|
||||
rtl/eth_mac_mii.sv
|
||||
rtl/mii_phy_if.sv
|
||||
rtl/ssio_ddr_in.sv
|
||||
rtl/ssio_sdr_in.sv
|
||||
rtl/eth_mac_1g.sv
|
||||
rtl/axis_gmii_rx.sv
|
||||
rtl/lfsr.sv
|
||||
rtl/eth_axis_tx.sv
|
||||
rtl/mac_ctrl_tx.sv
|
||||
rtl/axis_gmii_tx.sv
|
||||
rtl/mac_ctrl_rx.sv
|
||||
rtl/mac_pause_ctrl_tx.sv
|
||||
rtl/mac_pause_ctrl_rx.sv
|
||||
lib/axis/rtl/axis_async_fifo_adapter.sv
|
||||
lib/axis/rtl/axis_adapter.sv
|
||||
lib/axis/rtl/axis_async_fifo.sv
|
1
addins/verilog-ethernet
Submodule
1
addins/verilog-ethernet
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c180b22ed5f4112d0ef35b2c5ac1acc45f9ebb5d
|
@ -11,6 +11,7 @@
|
||||
#
|
||||
##################################
|
||||
import sys,os,shutil
|
||||
import argparse
|
||||
import multiprocessing
|
||||
from collections import namedtuple
|
||||
from multiprocessing import Pool, TimeoutError
|
||||
@ -281,6 +282,22 @@ def addTests(tests, sim):
|
||||
grepfile = grepfile)
|
||||
configs.append(tc)
|
||||
|
||||
def addLockstepTestsByDir(dir, config, sim):
|
||||
sim_logdir = WALLY+ "/sim/" + sim + "/logs/"
|
||||
cmdPrefix="wsim --sim " + sim + " " + coverStr + " " + config
|
||||
for file in os.listdir(dir):
|
||||
if file.endswith(".elf"):
|
||||
fullfile = os.path.join(dir, file)
|
||||
sim_log = sim_logdir + config + "_" + file + ".log"
|
||||
grepstring = ""
|
||||
tc = TestCase(
|
||||
name=file,
|
||||
variant=config,
|
||||
cmd=cmdPrefix + " " + fullfile + " > " + sim_log,
|
||||
grepstr="Mismatches : 0",
|
||||
grepfile = sim_log)
|
||||
configs.append(tc)
|
||||
|
||||
def search_log_for_text(text, grepfile):
|
||||
"""Search through the given log file for text, returning True if it is found or False if it is not"""
|
||||
grepwarn = "grep -H Warning: " + grepfile
|
||||
@ -320,22 +337,26 @@ coveragesim = "questa" # Questa is required for code/functional coverage
|
||||
#defaultsim = "questa" # Default simulator for all other tests; change to Verilator when flow is ready
|
||||
defaultsim = "verilator" # Default simulator for all other tests
|
||||
|
||||
ccov = '--ccov' in sys.argv
|
||||
fp = '--fp' in sys.argv
|
||||
nightly = '--nightly' in sys.argv
|
||||
testfloat = '--testfloat' in sys.argv
|
||||
buildroot = '--buildroot' in sys.argv
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--ccov", help="Code Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", help="Functional Coverage", action="store_true")
|
||||
parser.add_argument("--nightly", help="Run large nightly regression", action="store_true")
|
||||
parser.add_argument("--buildroot", help="Include Buildroot Linux boot test (takes many hours, done along with --nightly)", action="store_true")
|
||||
parser.add_argument("--testfloat", help="Include Testfloat floating-point unit tests", action="store_true")
|
||||
parser.add_argument("--fp", help="Include floating-point tests in coverage (slower runtime)", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
if (nightly):
|
||||
if (args.nightly):
|
||||
nightMode = "--nightly";
|
||||
# sims = [defaultsim] # uncomment to use only the default simulator
|
||||
sims = ["questa", "verilator", "vcs"] # uncomment to exercise all simulators
|
||||
sims = ["questa", "verilator", "vcs"] # exercise all simulators; can omit a sim if no license is available
|
||||
else:
|
||||
nightMode = ""
|
||||
sims = [defaultsim]
|
||||
|
||||
if (ccov): # only run RV64GC tests in coverage mode
|
||||
if (args.ccov): # only run RV64GC tests in coverage mode
|
||||
coverStr = '--ccov'
|
||||
elif (args.fcov): # only run RV64GC tests in lockstep in coverage mode
|
||||
coverStr = '--fcov'
|
||||
else:
|
||||
coverStr = ''
|
||||
|
||||
@ -353,25 +374,34 @@ configs = [
|
||||
|
||||
|
||||
# run full buildroot boot simulation (slow) if buildroot flag is set. Start it early to overlap with other tests
|
||||
if (buildroot):
|
||||
if (args.buildroot):
|
||||
# addTests(tests_buildrootboot, defaultsim) # non-lockstep with Verilator runs in about 2 hours
|
||||
addTests(tests_buildrootbootlockstep, "questa") # lockstep with Questa and ImperasDV runs overnight
|
||||
|
||||
if (ccov): # only run RV64GC tests on Questa in code coverage mode
|
||||
addTests(tests64gc_nofp, "questa")
|
||||
if (fp):
|
||||
addTests(tests64gc_fp, "questa")
|
||||
else:
|
||||
if (args.ccov): # only run RV64GC tests on Questa in code coverage mode
|
||||
addTests(tests64gc_nofp, coveragesim)
|
||||
if (args.fp):
|
||||
addTests(tests64gc_fp, coveragesim)
|
||||
elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional coverage mode
|
||||
addLockstepTestsByDir(WALLY+"/tests/functcov/rv64/I", "rv64gc", coveragesim)
|
||||
#sim_log = WALLY + "/sim/questa/logs/fcov.log"
|
||||
#tc = TestCase(
|
||||
# name="lockstep_functcov",
|
||||
# variant="rv64gc",
|
||||
# cmd="iterelf " + WALLY + "/tests/functcov/rv64/I > " + sim_log,
|
||||
# grepstr="SUCCESS! All tests ran without failures",
|
||||
# grepfile = sim_log)
|
||||
#configs.append(tc)
|
||||
else:
|
||||
for sim in sims:
|
||||
if (not (buildroot and sim == defaultsim)): # skip shot buildroot sim if running long one
|
||||
if (not (args.buildroot and sim == defaultsim)): # skip short buildroot sim if running long one
|
||||
addTests(tests_buildrootshort, sim)
|
||||
addTests(tests, sim)
|
||||
addTests(tests64gc_nofp, sim)
|
||||
addTests(tests64gc_fp, sim)
|
||||
|
||||
# run derivative configurations and lockstep tests in nightly regression
|
||||
if (nightly):
|
||||
addTests(derivconfigtests, defaultsim)
|
||||
if (args.nightly):
|
||||
sim_log = WALLY + "/sim/questa/logs/lockstep_coverage.log"
|
||||
tc = TestCase(
|
||||
name="lockstep_coverage",
|
||||
@ -389,11 +419,12 @@ if (nightly):
|
||||
grepstr="SUCCESS! All tests ran without failures",
|
||||
grepfile = sim_log)
|
||||
configs.append(tc)
|
||||
addTests(derivconfigtests, defaultsim)
|
||||
|
||||
# testfloat tests
|
||||
if (testfloat): # for testfloat alone, just run testfloat tests
|
||||
if (args.testfloat): # for testfloat alone, just run testfloat tests
|
||||
configs = []
|
||||
if (testfloat or nightly): # for nightly, run testfloat along with others
|
||||
if (args.testfloat or args.nightly): # for nightly, run testfloat along with others
|
||||
testfloatsim = "questa" # change to Verilator when Issue #707 about testfloat not running Verilator is resolved
|
||||
testfloatconfigs = ["fdqh_ieee_rv64gc", "fdq_ieee_rv64gc", "fdh_ieee_rv64gc", "fd_ieee_rv64gc", "fh_ieee_rv64gc", "f_ieee_rv64gc", "fdqh_ieee_rv32gc", "f_ieee_rv32gc"]
|
||||
for config in testfloatconfigs:
|
||||
@ -458,7 +489,7 @@ if (testfloat or nightly): # for nightly, run testfloat along with others
|
||||
|
||||
def main():
|
||||
"""Run the tests and count the failures"""
|
||||
global configs, ccov
|
||||
global configs, args
|
||||
os.chdir(regressionDir)
|
||||
dirs = ["questa/logs", "questa/wkdir", "verilator/logs", "verilator/wkdir", "vcs/logs", "vcs/wkdir"]
|
||||
for d in dirs:
|
||||
@ -467,24 +498,27 @@ def main():
|
||||
os.mkdir(d)
|
||||
except:
|
||||
pass
|
||||
|
||||
if '--makeTests' in sys.argv:
|
||||
os.chdir(regressionDir)
|
||||
os.system('./make-tests.sh | tee ./logs/make-tests.log')
|
||||
|
||||
elif '--ccov' in sys.argv:
|
||||
if args.ccov:
|
||||
TIMEOUT_DUR = 20*60 # seconds
|
||||
os.system('rm -f questa/cov/*.ucdb')
|
||||
elif '--nightly' in sys.argv:
|
||||
elif args.fcov:
|
||||
TIMEOUT_DUR = 1*60
|
||||
os.system('rm -f questa/fcov_ucdb/* questa/fcov_logs/* questa/fcov/*')
|
||||
elif args.nightly:
|
||||
TIMEOUT_DUR = 60*1440 # 1 day
|
||||
elif '--testfloat' in sys.argv:
|
||||
elif args.testfloat:
|
||||
TIMEOUT_DUR = 30*60 # seconds
|
||||
else:
|
||||
TIMEOUT_DUR = 10*60 # seconds
|
||||
|
||||
# Scale the number of concurrent processes to the number of test cases, but
|
||||
# max out at a limited number of concurrent processes to not overwhelm the system
|
||||
with Pool(processes=min(len(configs),multiprocessing.cpu_count())) as pool:
|
||||
# right now fcov, ccov, nightly all use Imperas
|
||||
if (args.ccov or args.fcov or args.nightly):
|
||||
ImperasDVLicenseCount = 8 # limit number of concurrent processes to avoid overloading ImperasDV licenses
|
||||
else:
|
||||
ImperasDVLicenseCount = 10000 # effectively no license limit for non-lockstep tests
|
||||
with Pool(processes=min(len(configs),multiprocessing.cpu_count(), ImperasDVLicenseCount)) as pool:
|
||||
num_fail = 0
|
||||
results = {}
|
||||
for config in configs:
|
||||
@ -497,8 +531,10 @@ def main():
|
||||
print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (config.variant, config.name, TIMEOUT_DUR))
|
||||
|
||||
# Coverage report
|
||||
if ccov:
|
||||
if args.ccov:
|
||||
os.system('make QuestaCodeCoverage')
|
||||
if args.fcov:
|
||||
os.system('make QuestaFunctCoverage')
|
||||
# Count the number of failures
|
||||
if num_fail:
|
||||
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)
|
||||
|
6
bin/wsim
6
bin/wsim
@ -27,12 +27,13 @@ parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "verilat
|
||||
parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench")
|
||||
parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true")
|
||||
parser.add_argument("--ccov", "-c", help="Code Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", "-f", help="Functional Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", "-f", help="Functional Coverage, implies lockstep", action="store_true")
|
||||
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
|
||||
parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true")
|
||||
parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true")
|
||||
parser.add_argument("--locksteplog", "-b", help="Retired instruction number to be begin logging.", default=0)
|
||||
parser.add_argument("--covlog", "-d", help="Log coverage after n instructions.", default=0)
|
||||
parser.add_argument("--rvvi", "-r", help="Simulate rvvi hardware interface and ethernet.", action="store_true")
|
||||
args = parser.parse_args()
|
||||
print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'")
|
||||
ElfFile=""
|
||||
@ -64,6 +65,9 @@ if (args.gui or args.ccov or args.fcov or args.lockstep):
|
||||
if (args.vcd):
|
||||
args.args += " -DMAKEVCD=1"
|
||||
|
||||
if (args.rvvi):
|
||||
args.args += " -GRVVI_SYNTH_SUPPORTED=1"
|
||||
|
||||
# if lockstep is enabled, then we need to pass the Imperas lockstep arguments
|
||||
if(int(args.locksteplog) >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
|
@ -1657,15 +1657,24 @@ IDIV_ON_FPU 1
|
||||
|
||||
# imperas used for a smart memory
|
||||
# VCS doesn't like removing the bootrom, but make it tiny in a random unused location
|
||||
derive imperas rv64gc
|
||||
derive ImperasTG rv64gc
|
||||
ICACHE_SUPPORTED 0
|
||||
DCACHE_SUPPORTED 0
|
||||
VIRTMEM_SUPPORTED 0
|
||||
ZICCLSM_SUPPORTED 0
|
||||
ZAAMO_SUPPORTED 0
|
||||
ZALRSC_SUPPORTED 0
|
||||
ZICBOM_SUPPORTED 0
|
||||
ZICBOZ_SUPPORTED 0
|
||||
SVPBMT_SUPPORTED 0
|
||||
SVNAPOT_SUPPORTED 0
|
||||
BOOTROM_BASE 64'h700012340010
|
||||
BOOTROM_BASE 64'h700012340080
|
||||
BOOTROM_RANGE 64'h10
|
||||
CLINT_SUPPORTED 0
|
||||
GPIO_SUPPORTED 0
|
||||
UART_SUPPORTED 0
|
||||
PLIC_SUPPORTED 0
|
||||
SPI_SUPPORTED 0
|
||||
|
||||
|
||||
|
||||
|
@ -9,6 +9,32 @@
|
||||
set_property PACKAGE_PIN E3 [get_ports {default_100mhz_clk}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {default_100mhz_clk}]
|
||||
|
||||
##### RVVI Ethernet ####
|
||||
# taken from https://github.com/alexforencich/verilog-ethernet/blob/master/example/Arty/fpga/fpga.xdc
|
||||
set_property -dict {LOC F15 IOSTANDARD LVCMOS33} [get_ports phy_rx_clk]
|
||||
set_property -dict {LOC D18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[0]}]
|
||||
set_property -dict {LOC E17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[1]}]
|
||||
set_property -dict {LOC E18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[2]}]
|
||||
set_property -dict {LOC G17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[3]}]
|
||||
set_property -dict {LOC G16 IOSTANDARD LVCMOS33} [get_ports phy_rx_dv]
|
||||
set_property -dict {LOC C17 IOSTANDARD LVCMOS33} [get_ports phy_rx_er]
|
||||
set_property -dict {LOC H16 IOSTANDARD LVCMOS33} [get_ports phy_tx_clk]
|
||||
set_property -dict {LOC H14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[0]}]
|
||||
set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[1]}]
|
||||
set_property -dict {LOC J13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[2]}]
|
||||
set_property -dict {LOC H17 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[3]}]
|
||||
set_property -dict {LOC H15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports phy_tx_en]
|
||||
set_property -dict {LOC D17 IOSTANDARD LVCMOS33} [get_ports phy_col]
|
||||
set_property -dict {LOC G14 IOSTANDARD LVCMOS33} [get_ports phy_crs]
|
||||
set_property -dict {LOC G18 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_ref_clk]
|
||||
set_property -dict {LOC C16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_reset_n]
|
||||
|
||||
create_clock -period 40.000 -name phy_rx_clk [get_ports phy_rx_clk]
|
||||
create_clock -period 40.000 -name phy_tx_clk [get_ports phy_tx_clk]
|
||||
|
||||
set_false_path -to [get_ports {phy_ref_clk phy_reset_n}]
|
||||
set_output_delay 0 [get_ports {phy_ref_clk phy_reset_n}]
|
||||
|
||||
##### GPI ####
|
||||
set_property PACKAGE_PIN A8 [get_ports {GPI[0]}]
|
||||
set_property PACKAGE_PIN C9 [get_ports {GPI[1]}]
|
||||
|
@ -7,3 +7,4 @@ lsu/lsu.sv: logic PAdrM
|
||||
lsu/lsu.sv: logic ReadDataM
|
||||
lsu/lsu.sv: logic WriteDataM
|
||||
lsu/lsu.sv: logic MemRWM
|
||||
privileged/csrc.sv: logic HPMCOUNTER_REGW
|
||||
|
72
fpga/constraints/small-debug-rvvi.xdc
Normal file
72
fpga/constraints/small-debug-rvvi.xdc
Normal file
@ -0,0 +1,72 @@
|
||||
create_debug_core u_ila_0 ila
|
||||
set_property C_DATA_DEPTH 4096 [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGIN_EN true [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
|
||||
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
|
||||
set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ]
|
||||
set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ]
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
|
||||
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
|
||||
create_debug_port u_ila_0 trig_in
|
||||
create_debug_port u_ila_0 trig_in_ack
|
||||
#set_property port_width 1 [get_debug_ports u_ila_0/trig_in]
|
||||
#set_property port_width 1 [get_debug_ports u_ila_0/trig_in_ack]
|
||||
#set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/trig_in]
|
||||
connect_debug_port u_ila_0/trig_in [get_nets IlaTrigger]
|
||||
#connect_debug_port u_ila_0/trig_in_ack [get_nets IlaTriggerAck]
|
||||
connect_debug_port u_ila_0/clk [get_nets CPUCLK]
|
||||
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe0]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
|
||||
connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 1 [get_debug_ports u_ila_0/probe1]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1]
|
||||
connect_debug_port u_ila_0/probe1 [get_nets [list wallypipelinedsoc/core/TrapM ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 1 [get_debug_ports u_ila_0/probe2]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2]
|
||||
connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 32 [get_debug_ports u_ila_0/probe3]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3]
|
||||
connect_debug_port u_ila_0/probe3 [get_nets [list {wallypipelinedsoc/core/InstrM[0]} {wallypipelinedsoc/core/InstrM[1]} {wallypipelinedsoc/core/InstrM[2]} {wallypipelinedsoc/core/InstrM[3]} {wallypipelinedsoc/core/InstrM[4]} {wallypipelinedsoc/core/InstrM[5]} {wallypipelinedsoc/core/InstrM[6]} {wallypipelinedsoc/core/InstrM[7]} {wallypipelinedsoc/core/InstrM[8]} {wallypipelinedsoc/core/InstrM[9]} {wallypipelinedsoc/core/InstrM[10]} {wallypipelinedsoc/core/InstrM[11]} {wallypipelinedsoc/core/InstrM[12]} {wallypipelinedsoc/core/InstrM[13]} {wallypipelinedsoc/core/InstrM[14]} {wallypipelinedsoc/core/InstrM[15]} {wallypipelinedsoc/core/InstrM[16]} {wallypipelinedsoc/core/InstrM[17]} {wallypipelinedsoc/core/InstrM[18]} {wallypipelinedsoc/core/InstrM[19]} {wallypipelinedsoc/core/InstrM[20]} {wallypipelinedsoc/core/InstrM[21]} {wallypipelinedsoc/core/InstrM[22]} {wallypipelinedsoc/core/InstrM[23]} {wallypipelinedsoc/core/InstrM[24]} {wallypipelinedsoc/core/InstrM[25]} {wallypipelinedsoc/core/InstrM[26]} {wallypipelinedsoc/core/InstrM[27]} {wallypipelinedsoc/core/InstrM[28]} {wallypipelinedsoc/core/InstrM[29]} {wallypipelinedsoc/core/InstrM[30]} {wallypipelinedsoc/core/InstrM[31]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 2 [get_debug_ports u_ila_0/probe4]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4]
|
||||
connect_debug_port u_ila_0/probe4 [get_nets [list {wallypipelinedsoc/core/lsu/MemRWM[0]} {wallypipelinedsoc/core/lsu/MemRWM[1]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe5]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5]
|
||||
connect_debug_port u_ila_0/probe5 [get_nets [list {wallypipelinedsoc/core/lsu/IEUAdrM[0]} {wallypipelinedsoc/core/lsu/IEUAdrM[1]} {wallypipelinedsoc/core/lsu/IEUAdrM[2]} {wallypipelinedsoc/core/lsu/IEUAdrM[3]} {wallypipelinedsoc/core/lsu/IEUAdrM[4]} {wallypipelinedsoc/core/lsu/IEUAdrM[5]} {wallypipelinedsoc/core/lsu/IEUAdrM[6]} {wallypipelinedsoc/core/lsu/IEUAdrM[7]} {wallypipelinedsoc/core/lsu/IEUAdrM[8]} {wallypipelinedsoc/core/lsu/IEUAdrM[9]} {wallypipelinedsoc/core/lsu/IEUAdrM[10]} {wallypipelinedsoc/core/lsu/IEUAdrM[11]} {wallypipelinedsoc/core/lsu/IEUAdrM[12]} {wallypipelinedsoc/core/lsu/IEUAdrM[13]} {wallypipelinedsoc/core/lsu/IEUAdrM[14]} {wallypipelinedsoc/core/lsu/IEUAdrM[15]} {wallypipelinedsoc/core/lsu/IEUAdrM[16]} {wallypipelinedsoc/core/lsu/IEUAdrM[17]} {wallypipelinedsoc/core/lsu/IEUAdrM[18]} {wallypipelinedsoc/core/lsu/IEUAdrM[19]} {wallypipelinedsoc/core/lsu/IEUAdrM[20]} {wallypipelinedsoc/core/lsu/IEUAdrM[21]} {wallypipelinedsoc/core/lsu/IEUAdrM[22]} {wallypipelinedsoc/core/lsu/IEUAdrM[23]} {wallypipelinedsoc/core/lsu/IEUAdrM[24]} {wallypipelinedsoc/core/lsu/IEUAdrM[25]} {wallypipelinedsoc/core/lsu/IEUAdrM[26]} {wallypipelinedsoc/core/lsu/IEUAdrM[27]} {wallypipelinedsoc/core/lsu/IEUAdrM[28]} {wallypipelinedsoc/core/lsu/IEUAdrM[29]} {wallypipelinedsoc/core/lsu/IEUAdrM[30]} {wallypipelinedsoc/core/lsu/IEUAdrM[31]} {wallypipelinedsoc/core/lsu/IEUAdrM[32]} {wallypipelinedsoc/core/lsu/IEUAdrM[33]} {wallypipelinedsoc/core/lsu/IEUAdrM[34]} {wallypipelinedsoc/core/lsu/IEUAdrM[35]} {wallypipelinedsoc/core/lsu/IEUAdrM[36]} {wallypipelinedsoc/core/lsu/IEUAdrM[37]} {wallypipelinedsoc/core/lsu/IEUAdrM[38]} {wallypipelinedsoc/core/lsu/IEUAdrM[39]} {wallypipelinedsoc/core/lsu/IEUAdrM[40]} {wallypipelinedsoc/core/lsu/IEUAdrM[41]} {wallypipelinedsoc/core/lsu/IEUAdrM[42]} {wallypipelinedsoc/core/lsu/IEUAdrM[43]} {wallypipelinedsoc/core/lsu/IEUAdrM[44]} {wallypipelinedsoc/core/lsu/IEUAdrM[45]} {wallypipelinedsoc/core/lsu/IEUAdrM[46]} {wallypipelinedsoc/core/lsu/IEUAdrM[47]} {wallypipelinedsoc/core/lsu/IEUAdrM[48]} {wallypipelinedsoc/core/lsu/IEUAdrM[49]} {wallypipelinedsoc/core/lsu/IEUAdrM[50]} {wallypipelinedsoc/core/lsu/IEUAdrM[51]} {wallypipelinedsoc/core/lsu/IEUAdrM[52]} {wallypipelinedsoc/core/lsu/IEUAdrM[53]} {wallypipelinedsoc/core/lsu/IEUAdrM[54]} {wallypipelinedsoc/core/lsu/IEUAdrM[55]} {wallypipelinedsoc/core/lsu/IEUAdrM[56]} {wallypipelinedsoc/core/lsu/IEUAdrM[57]} {wallypipelinedsoc/core/lsu/IEUAdrM[58]} {wallypipelinedsoc/core/lsu/IEUAdrM[59]} {wallypipelinedsoc/core/lsu/IEUAdrM[60]} {wallypipelinedsoc/core/lsu/IEUAdrM[61]} {wallypipelinedsoc/core/lsu/IEUAdrM[62]} {wallypipelinedsoc/core/lsu/IEUAdrM[63]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe6]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6]
|
||||
connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/lsu/ReadDataM[0]} {wallypipelinedsoc/core/lsu/ReadDataM[1]} {wallypipelinedsoc/core/lsu/ReadDataM[2]} {wallypipelinedsoc/core/lsu/ReadDataM[3]} {wallypipelinedsoc/core/lsu/ReadDataM[4]} {wallypipelinedsoc/core/lsu/ReadDataM[5]} {wallypipelinedsoc/core/lsu/ReadDataM[6]} {wallypipelinedsoc/core/lsu/ReadDataM[7]} {wallypipelinedsoc/core/lsu/ReadDataM[8]} {wallypipelinedsoc/core/lsu/ReadDataM[9]} {wallypipelinedsoc/core/lsu/ReadDataM[10]} {wallypipelinedsoc/core/lsu/ReadDataM[11]} {wallypipelinedsoc/core/lsu/ReadDataM[12]} {wallypipelinedsoc/core/lsu/ReadDataM[13]} {wallypipelinedsoc/core/lsu/ReadDataM[14]} {wallypipelinedsoc/core/lsu/ReadDataM[15]} {wallypipelinedsoc/core/lsu/ReadDataM[16]} {wallypipelinedsoc/core/lsu/ReadDataM[17]} {wallypipelinedsoc/core/lsu/ReadDataM[18]} {wallypipelinedsoc/core/lsu/ReadDataM[19]} {wallypipelinedsoc/core/lsu/ReadDataM[20]} {wallypipelinedsoc/core/lsu/ReadDataM[21]} {wallypipelinedsoc/core/lsu/ReadDataM[22]} {wallypipelinedsoc/core/lsu/ReadDataM[23]} {wallypipelinedsoc/core/lsu/ReadDataM[24]} {wallypipelinedsoc/core/lsu/ReadDataM[25]} {wallypipelinedsoc/core/lsu/ReadDataM[26]} {wallypipelinedsoc/core/lsu/ReadDataM[27]} {wallypipelinedsoc/core/lsu/ReadDataM[28]} {wallypipelinedsoc/core/lsu/ReadDataM[29]} {wallypipelinedsoc/core/lsu/ReadDataM[30]} {wallypipelinedsoc/core/lsu/ReadDataM[31]} {wallypipelinedsoc/core/lsu/ReadDataM[32]} {wallypipelinedsoc/core/lsu/ReadDataM[33]} {wallypipelinedsoc/core/lsu/ReadDataM[34]} {wallypipelinedsoc/core/lsu/ReadDataM[35]} {wallypipelinedsoc/core/lsu/ReadDataM[36]} {wallypipelinedsoc/core/lsu/ReadDataM[37]} {wallypipelinedsoc/core/lsu/ReadDataM[38]} {wallypipelinedsoc/core/lsu/ReadDataM[39]} {wallypipelinedsoc/core/lsu/ReadDataM[40]} {wallypipelinedsoc/core/lsu/ReadDataM[41]} {wallypipelinedsoc/core/lsu/ReadDataM[42]} {wallypipelinedsoc/core/lsu/ReadDataM[43]} {wallypipelinedsoc/core/lsu/ReadDataM[44]} {wallypipelinedsoc/core/lsu/ReadDataM[45]} {wallypipelinedsoc/core/lsu/ReadDataM[46]} {wallypipelinedsoc/core/lsu/ReadDataM[47]} {wallypipelinedsoc/core/lsu/ReadDataM[48]} {wallypipelinedsoc/core/lsu/ReadDataM[49]} {wallypipelinedsoc/core/lsu/ReadDataM[50]} {wallypipelinedsoc/core/lsu/ReadDataM[51]} {wallypipelinedsoc/core/lsu/ReadDataM[52]} {wallypipelinedsoc/core/lsu/ReadDataM[53]} {wallypipelinedsoc/core/lsu/ReadDataM[54]} {wallypipelinedsoc/core/lsu/ReadDataM[55]} {wallypipelinedsoc/core/lsu/ReadDataM[56]} {wallypipelinedsoc/core/lsu/ReadDataM[57]} {wallypipelinedsoc/core/lsu/ReadDataM[58]} {wallypipelinedsoc/core/lsu/ReadDataM[59]} {wallypipelinedsoc/core/lsu/ReadDataM[60]} {wallypipelinedsoc/core/lsu/ReadDataM[61]} {wallypipelinedsoc/core/lsu/ReadDataM[62]} {wallypipelinedsoc/core/lsu/ReadDataM[63]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe7]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7]
|
||||
connect_debug_port u_ila_0/probe7 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 32 [get_debug_ports u_ila_0/probe8]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8]
|
||||
connect_debug_port u_ila_0/probe8 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 1 [get_debug_ports u_ila_0/probe9]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9]
|
||||
connect_debug_port u_ila_0/probe9 [get_nets [list {RVVIStall}]]
|
||||
|
||||
# the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock.
|
||||
#connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk]
|
||||
connect_debug_port dbg_hub/clk [get_nets CPUCLK]
|
||||
|
@ -51,6 +51,8 @@ PreProcessFiles:
|
||||
$(MAKE) -C ../../sim deriv
|
||||
rm -rf ../src/CopiedFiles_do_not_add_to_repo/
|
||||
cp -r ../../src/ ../src/CopiedFiles_do_not_add_to_repo/
|
||||
cp -r ../../addins/verilog-ethernet/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/rvvi
|
||||
cp -r ../../addins/verilog-ethernet/*/*/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/rvvi
|
||||
mkdir ../src/CopiedFiles_do_not_add_to_repo/config/
|
||||
cp ../../config/deriv/fpga/config.vh ../src/CopiedFiles_do_not_add_to_repo/config/
|
||||
./insert_debug_comment.sh
|
||||
|
@ -89,7 +89,8 @@ report_clock_interaction -file re
|
||||
write_verilog -force -mode funcsim sim/syn-funcsim.v
|
||||
|
||||
if {$board=="ArtyA7"} {
|
||||
source ../constraints/small-debug.xdc
|
||||
#source ../constraints/small-debug.xdc
|
||||
source ../constraints/small-debug-rvvi.xdc
|
||||
|
||||
} else {
|
||||
# source ../constraints/vcu-small-debug.xdc
|
||||
|
@ -12,10 +12,11 @@ set_property -dict [list CONFIG.PRIM_IN_FREQ {100.000} \
|
||||
CONFIG.NUM_OUT_CLKS {3} \
|
||||
CONFIG.CLKOUT2_USED {true} \
|
||||
CONFIG.CLKOUT3_USED {true} \
|
||||
CONFIG.CLKOUT4_USED {false} \
|
||||
CONFIG.CLKOUT4_USED {true} \
|
||||
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {166.66667} \
|
||||
CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {200} \
|
||||
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20} \
|
||||
CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {25} \
|
||||
CONFIG.CLKIN1_JITTER_PS {10.0} \
|
||||
] [get_ips $ipName]
|
||||
|
||||
|
10
fpga/rvvidaemon/Makefile
Normal file
10
fpga/rvvidaemon/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
all: rvvidaemon
|
||||
|
||||
rvvidaemon: rvvidaemon.o
|
||||
gcc $^ /opt/riscv/ImperasDV-OpenHW/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model.so -o rvvidaemon
|
||||
|
||||
%.o:%.c
|
||||
gcc -I/opt/riscv/ImperasDV-OpenHW/ImpProprietary/include/host -I/opt/riscv/ImperasDV-OpenHW/ImpPublic/include/host/rvvi/ -c $^ -o $@
|
||||
|
||||
clean:
|
||||
rm *.o rvvidaemon
|
500
fpga/rvvidaemon/rvvidaemon.c
Normal file
500
fpga/rvvidaemon/rvvidaemon.c
Normal file
@ -0,0 +1,500 @@
|
||||
///////////////////////////////////////////
|
||||
// rvvi daemon
|
||||
//
|
||||
// Written: Rose Thomposn ross1728@gmail.com
|
||||
// Created: 31 May 2024
|
||||
// Modified: 31 May 2024
|
||||
//
|
||||
// Purpose: Converts raw socket into rvvi interface to connect into ImperasDV
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/ether.h>
|
||||
#include "rvviApi.h" // *** bug fix me when this file gets included into the correct directory.
|
||||
#include "idv/idv.h"
|
||||
|
||||
|
||||
#define DEST_MAC0 0x43
|
||||
#define DEST_MAC1 0x68
|
||||
#define DEST_MAC2 0x11
|
||||
#define DEST_MAC3 0x11
|
||||
#define DEST_MAC4 0x02
|
||||
#define DEST_MAC5 0x45
|
||||
|
||||
#define SRC_MAC0 0x54
|
||||
#define SRC_MAC1 0x16
|
||||
#define SRC_MAC2 0x00
|
||||
#define SRC_MAC3 0x00
|
||||
#define SRC_MAC4 0x54
|
||||
#define SRC_MAC5 0x8F
|
||||
|
||||
#define BUF_SIZ 1024
|
||||
|
||||
//#define ETHER_TYPE 0x0801 // The type defined in packetizer.sv
|
||||
#define ETHER_TYPE 0x5c00 // The type defined in packetizer.sv
|
||||
//#define ETHER_TYPE 0x0000 // The type defined in packetizer.sv
|
||||
#define DEFAULT_IF "eno1"
|
||||
|
||||
struct sockaddr_ll socket_address;
|
||||
uint8_t sendbuf[BUF_SIZ];
|
||||
struct ether_header *sendeh = (struct ether_header *) sendbuf;
|
||||
int tx_len = 0;
|
||||
int sockfd;
|
||||
|
||||
typedef struct {
|
||||
uint64_t PC;
|
||||
uint32_t insn;
|
||||
uint64_t Mcycle;
|
||||
uint64_t Minstret;
|
||||
uint8_t Trap : 1;
|
||||
uint8_t PrivilegeMode : 2;
|
||||
uint8_t GPREn : 1;
|
||||
uint8_t FPREn : 1;
|
||||
uint16_t CSRCount : 12;
|
||||
uint8_t GPRReg : 5;
|
||||
uint64_t GPRValue;
|
||||
uint8_t FPRReg : 5;
|
||||
uint64_t FPRValue;
|
||||
uint8_t CSRWen[3];
|
||||
uint16_t CSRReg[3];
|
||||
uint64_t CSRValue[3];
|
||||
|
||||
} RequiredRVVI_t; // total size is 241 bits or 30.125 bytes
|
||||
|
||||
typedef struct {
|
||||
uint8_t RegAddress : 5;
|
||||
uint64_t RegValue;
|
||||
} Reg_t;
|
||||
|
||||
void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData);
|
||||
void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length);
|
||||
void PrintInstructionData(RequiredRVVI_t *InstructionData);
|
||||
int ProcessRvviAll(RequiredRVVI_t *InstructionData);
|
||||
void set_gpr(int hart, int reg, uint64_t value);
|
||||
void set_fpr(int hart, int reg, uint64_t value);
|
||||
int state_compare(int hart, uint64_t Minstret);
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
if(argc != 2){
|
||||
printf("Wrong number of arguments.\n");
|
||||
printf("rvvidaemon <ethernet device>\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t buf[BUF_SIZ];
|
||||
int sockopt;
|
||||
struct ifreq ifopts; /* set promiscuous mode */
|
||||
struct ether_header *eh = (struct ether_header *) buf;
|
||||
ssize_t headerbytes, numbytes, payloadbytes;
|
||||
|
||||
/* Open RAW socket to receive frames */
|
||||
if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
|
||||
perror("socket");
|
||||
}
|
||||
printf("Here 0\n");
|
||||
|
||||
/* Set interface to promiscuous mode - do we need to do this every time? */
|
||||
strncpy(ifopts.ifr_name, argv[1], IFNAMSIZ-1);
|
||||
ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
|
||||
printf("Here 1\n");
|
||||
ifopts.ifr_flags |= IFF_PROMISC;
|
||||
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
|
||||
printf("Here 2\n");
|
||||
if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0)
|
||||
perror("SIOCGIFINDEX");
|
||||
|
||||
/* Allow the socket to be reused - incase connection is closed prematurely */
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
|
||||
perror("setsockopt");
|
||||
close(sockfd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("Here 3\n");
|
||||
|
||||
/* Bind to device */
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, argv[1], IFNAMSIZ-1) == -1) {
|
||||
perror("SO_BINDTODEVICE");
|
||||
close(sockfd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("Here 4\n");
|
||||
|
||||
if(!rvviVersionCheck(RVVI_API_VERSION)){
|
||||
printf("Bad RVVI_API_VERSION\n");
|
||||
}
|
||||
|
||||
/* Construct the Ethernet header */
|
||||
memset(sendbuf, 0, BUF_SIZ);
|
||||
sendbuf[0] = DEST_MAC0;
|
||||
sendbuf[1] = DEST_MAC1;
|
||||
sendbuf[2] = DEST_MAC2;
|
||||
sendbuf[3] = DEST_MAC3;
|
||||
sendbuf[4] = DEST_MAC4;
|
||||
sendbuf[5] = DEST_MAC5;
|
||||
sendbuf[6] = SRC_MAC0;
|
||||
sendbuf[7] = SRC_MAC1;
|
||||
sendbuf[8] = SRC_MAC2;
|
||||
sendbuf[9] = SRC_MAC3;
|
||||
sendbuf[10] = SRC_MAC4;
|
||||
sendbuf[11] = SRC_MAC5;
|
||||
|
||||
sendeh->ether_type = htons(ETHER_TYPE);
|
||||
tx_len += sizeof(struct ether_header);
|
||||
/* Packet data */
|
||||
sendbuf[tx_len++] = 't';
|
||||
sendbuf[tx_len++] = 'r';
|
||||
sendbuf[tx_len++] = 'i';
|
||||
sendbuf[tx_len++] = 'g';
|
||||
sendbuf[tx_len++] = 'i';
|
||||
sendbuf[tx_len++] = 'n';
|
||||
|
||||
rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org");
|
||||
rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME,"riscv");
|
||||
rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC");
|
||||
rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56);
|
||||
rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6);
|
||||
|
||||
/* Index of the network device */
|
||||
socket_address.sll_ifindex = ifopts.ifr_ifindex;
|
||||
/* Address length*/
|
||||
socket_address.sll_halen = ETH_ALEN;
|
||||
/* Destination MAC */
|
||||
socket_address.sll_addr[0] = DEST_MAC0;
|
||||
socket_address.sll_addr[1] = DEST_MAC1;
|
||||
socket_address.sll_addr[2] = DEST_MAC2;
|
||||
socket_address.sll_addr[3] = DEST_MAC3;
|
||||
socket_address.sll_addr[4] = DEST_MAC4;
|
||||
socket_address.sll_addr[5] = DEST_MAC5;
|
||||
|
||||
int i;
|
||||
printf("buffer: ");
|
||||
for(i=0;i<tx_len;i++){
|
||||
printf("%02hhx ", sendbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("sockfd %x\n", sockfd);
|
||||
|
||||
// eventually we want to put the elffiles here
|
||||
rvviRefInit(NULL);
|
||||
rvviRefPcSet(0, 0x1000);
|
||||
|
||||
// Volatile CSRs
|
||||
rvviRefCsrSetVolatile(0, 0xC00); // CYCLE
|
||||
rvviRefCsrSetVolatile(0, 0xB00); // MCYCLE
|
||||
rvviRefCsrSetVolatile(0, 0xC02); // INSTRET
|
||||
rvviRefCsrSetVolatile(0, 0xB02); // MINSTRET
|
||||
rvviRefCsrSetVolatile(0, 0xC01); // TIME
|
||||
|
||||
int iter;
|
||||
for (iter = 0xC03; iter <= 0xC1F; iter++) {
|
||||
rvviRefCsrSetVolatile(0, iter); // HPMCOUNTERx
|
||||
}
|
||||
// Machine MHPMCOUNTER3 - MHPMCOUNTER31
|
||||
for (iter = 0xB03; iter <= 0xB1F; iter++) {
|
||||
rvviRefCsrSetVolatile(0, iter); // MHPMCOUNTERx
|
||||
}
|
||||
// cannot predict this register due to latency between
|
||||
// pending and taken
|
||||
rvviRefCsrSetVolatile(0, 0x344); // MIP
|
||||
rvviRefCsrSetVolatile(0, 0x144); // SIP
|
||||
|
||||
// set bootrom and bootram as volatile memory
|
||||
rvviRefMemorySetVolatile(0x1000, 0x1FFF);
|
||||
rvviRefMemorySetVolatile(0x2000, 0x2FFF);
|
||||
|
||||
// Privileges for PMA are set in the imperas.ic
|
||||
// volatile (IO) regions are defined here
|
||||
// only real ROM/RAM areas are BOOTROM and UNCORE_RAM
|
||||
rvviRefMemorySetVolatile(0x2000000, 0x2000000 + 0xFFFF);
|
||||
rvviRefMemorySetVolatile(0x10060000, 0x10060000 + 0xFF);
|
||||
rvviRefMemorySetVolatile(0x10000000, 0x10000000 + 0x7);
|
||||
rvviRefMemorySetVolatile(0x0C000000, 0x0C000000 + 0x03FFFFFF);
|
||||
rvviRefMemorySetVolatile(0x00013000, 0x00013000 + 0x7F);
|
||||
rvviRefMemorySetVolatile(0x10040000, 0x10040000 + 0xFFF);
|
||||
|
||||
while(1) {
|
||||
//printf("listener: Waiting to recvfrom...\n");
|
||||
numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
|
||||
headerbytes = (sizeof(struct ether_header));
|
||||
payloadbytes = numbytes - headerbytes;
|
||||
int result;
|
||||
//printf("listener: got frame %lu bytes\n", numbytes);
|
||||
//printf("payload size: %lu bytes\n", payloadbytes);
|
||||
if (eh->ether_dhost[0] == DEST_MAC0 &&
|
||||
eh->ether_dhost[1] == DEST_MAC1 &&
|
||||
eh->ether_dhost[2] == DEST_MAC2 &&
|
||||
eh->ether_dhost[3] == DEST_MAC3 &&
|
||||
eh->ether_dhost[4] == DEST_MAC4 &&
|
||||
eh->ether_dhost[5] == DEST_MAC5) {
|
||||
//printf("Correct destination MAC address\n");
|
||||
uint64_t PC;
|
||||
uint32_t insn;
|
||||
RequiredRVVI_t InstructionData;
|
||||
DecodeRVVI(buf + headerbytes, payloadbytes, &InstructionData);
|
||||
// now let's drive IDV
|
||||
// start simple just drive and compare PC.
|
||||
PrintInstructionData(&InstructionData);
|
||||
result = ProcessRvviAll(&InstructionData);
|
||||
if(result == -1) break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Simulation halted due to mismatch\n");
|
||||
|
||||
close(sockfd);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ProcessRvviAll(RequiredRVVI_t *InstructionData){
|
||||
long int found;
|
||||
uint64_t time = InstructionData->Mcycle;
|
||||
uint8_t trap = InstructionData->Trap;
|
||||
uint64_t order = InstructionData->Minstret;
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
if(InstructionData->GPREn) set_gpr(0, InstructionData->GPRReg, InstructionData->GPRValue);
|
||||
if(InstructionData->FPREn) set_fpr(0, InstructionData->FPRReg, InstructionData->FPRValue);
|
||||
|
||||
if (trap) {
|
||||
rvviDutTrap(0, InstructionData->PC, InstructionData->insn);
|
||||
} else {
|
||||
rvviDutRetire(0, InstructionData->PC, InstructionData->insn, 0);
|
||||
}
|
||||
|
||||
if(!trap) result = state_compare(0, InstructionData->Minstret);
|
||||
// *** set is for nets like interrupts come back to this.
|
||||
//found = rvviRefNetIndexGet("pc_rdata");
|
||||
//rvviRefNetSet(found, InstructionData->PC, time);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
int state_compare(int hart, uint64_t Minstret){
|
||||
uint8_t result = 1;
|
||||
uint8_t stepOk = 0;
|
||||
char buf[80];
|
||||
rvviDutCycleCountSet(Minstret);
|
||||
if(rvviRefEventStep(hart) != 0) {
|
||||
stepOk = 1;
|
||||
result &= rvviRefPcCompare(hart);
|
||||
result &= rvviRefInsBinCompare(hart);
|
||||
result &= rvviRefGprsCompare(hart);
|
||||
result &= rvviRefFprsCompare(hart);
|
||||
result &= rvviRefCsrsCompare(hart);
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
/* Send packet */
|
||||
if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0){
|
||||
printf("Send failed\n");
|
||||
}else {
|
||||
printf("send success!\n");
|
||||
}
|
||||
|
||||
sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret);
|
||||
idvMsgError(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void set_gpr(int hart, int reg, uint64_t value){
|
||||
rvviDutGprSet(hart, reg, value);
|
||||
}
|
||||
|
||||
void set_fpr(int hart, int reg, uint64_t value){
|
||||
rvviDutFprSet(hart, reg, value);
|
||||
}
|
||||
|
||||
void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData){
|
||||
// you know this actually easiser in assembly. :(
|
||||
uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ];
|
||||
uint8_t * buf2ptr, *buf3ptr;
|
||||
buf2ptr = buf2;
|
||||
buf3ptr = buf3;
|
||||
//int PayloadSize = sizeof(RequiredRVVI_t) - 1;
|
||||
int PayloadSize = 30;
|
||||
int Buf2Size = BUF_SIZ - PayloadSize;
|
||||
uint64_t Mcycle, Minstret;
|
||||
uint64_t PC;
|
||||
uint32_t insn;
|
||||
// unforunately the struct appoarch does not work?!?
|
||||
PC = * (uint64_t *) payload;
|
||||
payload += 8;
|
||||
insn = * (uint32_t *) payload;
|
||||
payload += 4;
|
||||
Mcycle = * (uint64_t *) payload;
|
||||
payload += 8;
|
||||
Minstret = * (uint64_t *) payload;
|
||||
payload += 8;
|
||||
// the next 4 bytes contain CSRCount (12), FPRWen(1), GPRWen(1), PrivilegeMode(2), Trap(1)
|
||||
uint32_t RequiredFlags;
|
||||
RequiredFlags = * (uint32_t *) payload;
|
||||
uint8_t Trap, PrivilegeMode, GPRWen, FPRWen;
|
||||
uint16_t CSRCount = 0;
|
||||
uint8_t GPRReg = 0;
|
||||
uint64_t GPRData = 0;
|
||||
uint8_t FPRReg = 0;
|
||||
uint64_t FPRData = 0;
|
||||
uint8_t CSRWen[3] = {0, 0, 0};
|
||||
uint16_t CSRReg[3];
|
||||
uint64_t CSRValue[3];
|
||||
int CSRIndex;
|
||||
|
||||
Trap = RequiredFlags & 0x1;
|
||||
PrivilegeMode = (RequiredFlags >> 1) & 0x3;
|
||||
GPRWen = (RequiredFlags >> 3) & 0x1;
|
||||
FPRWen = (RequiredFlags >> 4) & 0x1;
|
||||
CSRCount = (RequiredFlags >> 5) & 0xFFF;
|
||||
payload += 2;
|
||||
|
||||
if(GPRWen || FPRWen || (CSRCount != 0)){
|
||||
// the first bit of payload is the last bit of CSRCount.
|
||||
ssize_t newPayloadSize = payloadsize - 30;
|
||||
BitShiftArray(buf2, payload, 1, newPayloadSize);
|
||||
int index;
|
||||
if(GPRWen){
|
||||
GPRReg = * (uint8_t *) buf2ptr;
|
||||
GPRReg = GPRReg & 0x1F;
|
||||
BitShiftArray(buf3, buf2ptr, 5, newPayloadSize);
|
||||
GPRData = * (uint64_t *) buf3;
|
||||
if(FPRWen){
|
||||
buf3ptr += 8;
|
||||
FPRReg = * (uint8_t *) buf3ptr;
|
||||
BitShiftArray(buf2, buf3ptr, 5, newPayloadSize - 8);
|
||||
FPRReg = FPRReg & 0x1F;
|
||||
FPRData = * (uint64_t *) buf2;
|
||||
}
|
||||
}else if(FPRWen){
|
||||
FPRReg = * (uint8_t *) buf2;
|
||||
FPRReg = FPRReg & 0x1F;
|
||||
BitShiftArray(buf3, buf2, 5, newPayloadSize);
|
||||
FPRData = * (uint64_t *) buf3;
|
||||
}
|
||||
if(GPRWen ^ FPRWen){
|
||||
payload += 8;
|
||||
Buf2Size = payloadsize - 38;
|
||||
BitShiftArray(buf2, payload, 6, Buf2Size);
|
||||
}else if(GPRWen & FPRWen){
|
||||
payload += 17;
|
||||
Buf2Size = payloadsize - 47;
|
||||
BitShiftArray(buf2, payload, 3, Buf2Size);
|
||||
}else{
|
||||
Buf2Size = payloadsize - 30;
|
||||
BitShiftArray(buf2, payload, 1, Buf2Size);
|
||||
}
|
||||
buf2ptr = buf2;
|
||||
for(CSRIndex = 0; CSRIndex < CSRCount; CSRIndex++){
|
||||
CSRReg[CSRIndex] = (*(uint16_t *) buf2ptr) & 0xFFF;
|
||||
Buf2Size -= 1;
|
||||
BitShiftArray(buf3, buf2ptr + 1, 4, Buf2Size);
|
||||
CSRValue[CSRIndex] = (*(uint64_t *) buf3);
|
||||
CSRWen[CSRIndex] = 1;
|
||||
buf2ptr = buf3;
|
||||
}
|
||||
}
|
||||
InstructionData->PC = PC;
|
||||
InstructionData->insn = insn;
|
||||
InstructionData->Mcycle = Mcycle;
|
||||
InstructionData->Minstret = Minstret;
|
||||
InstructionData->Trap = Trap;
|
||||
InstructionData->PrivilegeMode = PrivilegeMode;
|
||||
InstructionData->GPREn = GPRWen;
|
||||
InstructionData->FPREn = FPRWen;
|
||||
InstructionData->CSRCount = CSRCount;
|
||||
InstructionData->GPRReg = GPRReg;
|
||||
InstructionData->GPRValue = GPRData;
|
||||
InstructionData->FPRReg = FPRReg;
|
||||
InstructionData->FPRValue = FPRData;
|
||||
for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){
|
||||
InstructionData->CSRWen[CSRIndex] = CSRWen[CSRIndex];
|
||||
InstructionData->CSRReg[CSRIndex] = CSRReg[CSRIndex];
|
||||
InstructionData->CSRValue[CSRIndex] = CSRValue[CSRIndex];
|
||||
}
|
||||
}
|
||||
|
||||
void PrintInstructionData(RequiredRVVI_t *InstructionData){
|
||||
int CSRIndex;
|
||||
printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx",
|
||||
InstructionData->PC, InstructionData->insn, InstructionData->Mcycle, InstructionData->Minstret, InstructionData->Trap, InstructionData->PrivilegeMode);
|
||||
if(InstructionData->GPREn){
|
||||
printf(", GPR[%d] = %lx", InstructionData->GPRReg, InstructionData->GPRValue);
|
||||
}
|
||||
if(InstructionData->FPREn){
|
||||
printf(", FPR[%d] = %lx", InstructionData->FPRReg, InstructionData->FPRValue);
|
||||
}
|
||||
for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){
|
||||
if(InstructionData->CSRWen[CSRIndex]){
|
||||
printf(", CSR[%x] = %lx", InstructionData->CSRReg[CSRIndex], InstructionData->CSRValue[CSRIndex]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){
|
||||
// always shift right by ShiftAmount (0 to 7 bit positions).
|
||||
// *** this implemenation is very inefficient. improve later.
|
||||
if(ShiftAmount < 0 || ShiftAmount > 7) return;
|
||||
/* Read the first source byte
|
||||
Read the second source byte
|
||||
Right Shift byte 1 by ShiftAmount
|
||||
Right Rotate byte 2 by ShiftAmount
|
||||
Mask byte 2 by ~(2^ShiftAmount -1)
|
||||
OR together the two bytes to form the final next byte
|
||||
|
||||
repeat this for each byte
|
||||
On the last byte we don't do the last steps
|
||||
*/
|
||||
int Index;
|
||||
for(Index = 0; Index < Length - 1; Index++){
|
||||
uint8_t byte1 = src[Index];
|
||||
uint8_t byte2 = src[Index+1];
|
||||
byte1 = byte1 >> ShiftAmount;
|
||||
uint8_t byte2rot = (byte2 << (unsigned) (8 - ShiftAmount)) & 0xff;
|
||||
uint8_t byte1final = byte2rot | byte1;
|
||||
dst[Index] = byte1final;
|
||||
}
|
||||
// fence post
|
||||
// For last one there is only one source byte
|
||||
uint8_t byte1 = src[Length-1];
|
||||
byte1 = byte1 >> ShiftAmount;
|
||||
dst[Length-1] = byte1;
|
||||
}
|
@ -28,7 +28,7 @@
|
||||
|
||||
import cvw::*;
|
||||
|
||||
module fpgaTop
|
||||
module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
(input default_100mhz_clk,
|
||||
(* mark_debug = "true" *) input resetn,
|
||||
input south_reset,
|
||||
@ -44,6 +44,21 @@ module fpgaTop
|
||||
inout SDCCmd,
|
||||
input SDCCD,
|
||||
|
||||
/*
|
||||
* Ethernet: 100BASE-T MII
|
||||
*/
|
||||
output phy_ref_clk,
|
||||
input phy_rx_clk,
|
||||
input [3:0] phy_rxd,
|
||||
input phy_rx_dv,
|
||||
input phy_rx_er,
|
||||
input phy_tx_clk,
|
||||
output [3:0] phy_txd,
|
||||
output phy_tx_en,
|
||||
input phy_col, // nc
|
||||
input phy_crs, // nc
|
||||
output phy_reset_n,
|
||||
|
||||
inout [15:0] ddr3_dq,
|
||||
inout [1:0] ddr3_dqs_n,
|
||||
inout [1:0] ddr3_dqs_p,
|
||||
@ -428,7 +443,8 @@ module fpgaTop
|
||||
wire mmcm_locked;
|
||||
wire [11:0] device_temp;
|
||||
wire mmcm1_locked;
|
||||
|
||||
|
||||
(* mark_debug = "true" *) logic RVVIStall;
|
||||
|
||||
assign GPIOIN = {28'b0, GPI};
|
||||
assign GPO = GPIOOUT[4:0];
|
||||
@ -446,6 +462,7 @@ module fpgaTop
|
||||
xlnx_mmcm xln_mmcm(.clk_out1(clk167),
|
||||
.clk_out2(clk200),
|
||||
.clk_out3(CPUCLK),
|
||||
.clk_out4(phy_ref_clk),
|
||||
.reset(1'b0),
|
||||
.locked(mmcm1_locked),
|
||||
.clk_in1(default_100mhz_clk));
|
||||
@ -496,7 +513,7 @@ module fpgaTop
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0),
|
||||
.GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr);
|
||||
.UARTSin, .UARTSout, .SDCIntr, .ExternalStall(RVVIStall));
|
||||
|
||||
|
||||
// ahb lite to axi bridge
|
||||
@ -1096,7 +1113,146 @@ module fpgaTop
|
||||
|
||||
.init_calib_complete(c0_init_calib_complete),
|
||||
.device_temp(device_temp));
|
||||
|
||||
|
||||
(* mark_debug = "true" *) logic IlaTrigger;
|
||||
|
||||
|
||||
if(RVVI_SYNTH_SUPPORTED) begin : rvvi_synth
|
||||
localparam MAX_CSRS = 3;
|
||||
localparam TOTAL_CSRS = 36;
|
||||
localparam [31:0] RVVI_INIT_TIME_OUT = 32'd100000000;
|
||||
localparam [31:0] RVVI_PACKET_DELAY = 32'd400;
|
||||
|
||||
// pipeline controlls
|
||||
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
logic InstrValidM;
|
||||
logic [31:0] InstrRawD;
|
||||
logic [63:0] Mcycle, Minstret;
|
||||
logic TrapM;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
// registers gpr and fpr
|
||||
logic GPRWen, FPRWen;
|
||||
logic [4:0] GPRAddr, FPRAddr;
|
||||
logic [P.XLEN-1:0] GPRValue, FPRValue;
|
||||
logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0];
|
||||
|
||||
logic valid;
|
||||
logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi;
|
||||
|
||||
assign StallE = fpgaTop.wallypipelinedsoc.core.StallE;
|
||||
assign StallM = fpgaTop.wallypipelinedsoc.core.StallM;
|
||||
assign StallW = fpgaTop.wallypipelinedsoc.core.StallW;
|
||||
assign FlushE = fpgaTop.wallypipelinedsoc.core.FlushE;
|
||||
assign FlushM = fpgaTop.wallypipelinedsoc.core.FlushM;
|
||||
assign FlushW = fpgaTop.wallypipelinedsoc.core.FlushW;
|
||||
assign InstrValidM = fpgaTop.wallypipelinedsoc.core.ieu.InstrValidM;
|
||||
assign InstrRawD = fpgaTop.wallypipelinedsoc.core.ifu.InstrRawD;
|
||||
assign PCM = fpgaTop.wallypipelinedsoc.core.ifu.PCM;
|
||||
assign Mcycle = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0];
|
||||
assign Minstret = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2];
|
||||
assign TrapM = fpgaTop.wallypipelinedsoc.core.TrapM;
|
||||
assign PrivilegeModeW = fpgaTop.wallypipelinedsoc.core.priv.priv.privmode.PrivilegeModeW;
|
||||
assign GPRAddr = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.a3;
|
||||
assign GPRWen = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.we3;
|
||||
assign GPRValue = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.wd3;
|
||||
assign FPRAddr = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.a4;
|
||||
assign FPRWen = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.we4;
|
||||
assign FPRValue = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.wd4;
|
||||
|
||||
assign CSRArray[0] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300
|
||||
assign CSRArray[1] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310
|
||||
assign CSRArray[2] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305
|
||||
assign CSRArray[3] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341
|
||||
assign CSRArray[4] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306
|
||||
assign CSRArray[5] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320
|
||||
assign CSRArray[6] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302
|
||||
assign CSRArray[7] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303
|
||||
assign CSRArray[8] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344
|
||||
assign CSRArray[9] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304
|
||||
assign CSRArray[10] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301
|
||||
assign CSRArray[11] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A
|
||||
assign CSRArray[12] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14
|
||||
assign CSRArray[13] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340
|
||||
assign CSRArray[14] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342
|
||||
assign CSRArray[15] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343
|
||||
assign CSRArray[16] = 0; // 12'hF11
|
||||
assign CSRArray[17] = 0; // 12'hF12
|
||||
assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13
|
||||
assign CSRArray[19] = 0; // 12'hF15
|
||||
assign CSRArray[20] = 0; // 12'h34A
|
||||
// supervisor CSRs
|
||||
assign CSRArray[21] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100
|
||||
assign CSRArray[22] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104
|
||||
assign CSRArray[23] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105
|
||||
assign CSRArray[24] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141
|
||||
assign CSRArray[25] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106
|
||||
assign CSRArray[26] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A
|
||||
assign CSRArray[27] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180
|
||||
assign CSRArray[28] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140
|
||||
assign CSRArray[29] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143
|
||||
assign CSRArray[30] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142
|
||||
assign CSRArray[31] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144
|
||||
assign CSRArray[32] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D
|
||||
// user CSRs
|
||||
assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001
|
||||
assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002
|
||||
assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003
|
||||
|
||||
rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW,
|
||||
.PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM,
|
||||
.PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray,
|
||||
.valid, .rvvi);
|
||||
|
||||
// axi 4 write data channel
|
||||
logic [31:0] RvviAxiWdata;
|
||||
logic [3:0] RvviAxiWstrb;
|
||||
logic RvviAxiWlast;
|
||||
logic RvviAxiWvalid;
|
||||
logic RvviAxiWready;
|
||||
|
||||
logic [31:0] RvviAxiRdata;
|
||||
logic [3:0] RvviAxiRstrb;
|
||||
logic RvviAxiRlast;
|
||||
logic RvviAxiRvalid;
|
||||
|
||||
logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame;
|
||||
logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame;
|
||||
|
||||
packetizer #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall,
|
||||
.RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready);
|
||||
|
||||
eth_mac_mii_fifo #(.TARGET("XILINX"), .CLOCK_INPUT_STYLE("BUFG"), .AXIS_DATA_WIDTH(32), .TX_FIFO_DEPTH(1024)) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset),
|
||||
.tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready),
|
||||
.tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(RvviAxiRdata),
|
||||
.rx_axis_tkeep(RvviAxiRstrb), .rx_axis_tvalid(RvviAxiRvalid), .rx_axis_tready(1'b1),
|
||||
.rx_axis_tlast(RvviAxiRlast), .rx_axis_tuser(),
|
||||
|
||||
.mii_rx_clk(phy_rx_clk),
|
||||
.mii_rxd(phy_rxd),
|
||||
.mii_rx_dv(phy_rx_dv),
|
||||
.mii_rx_er(phy_rx_er),
|
||||
.mii_tx_clk(phy_tx_clk),
|
||||
.mii_txd(phy_txd),
|
||||
.mii_tx_en(phy_tx_en),
|
||||
.mii_tx_er(),
|
||||
|
||||
// status
|
||||
.tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame,
|
||||
.rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame,
|
||||
.cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1)
|
||||
);
|
||||
|
||||
triggergen triggergen(.clk(CPUCLK), .reset(bus_struct_reset), .RvviAxiRdata,
|
||||
.RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger);
|
||||
end else begin // if (P.RVVI_SYNTH_SUPPORTED)
|
||||
assign IlaTrigger = '0;
|
||||
assign RVVIStall = '0;
|
||||
end
|
||||
|
||||
//assign phy_reset_n = ~bus_struct_reset;
|
||||
assign phy_reset_n = ~1'b0;
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -30,6 +30,13 @@ QuestaCodeCoverage: questa/ucdb/rv64gc_arch64i.ucdb
|
||||
# vcover report -recursive questa/ucdb/cov.ucdb > questa/cov/rv64gc_recursive.rpt
|
||||
vcover report -details -threshH 100 -html questa/ucdb/cov.ucdb
|
||||
|
||||
QuestaFunctCoverage: ${SIM}/questa/fcov_ucdb/rv64gc_WALLY-COV-add.elf.ucdb
|
||||
vcover merge -out ${SIM}/questa/fcov_ucdb/fcov.ucdb ${SIM}/questa/fcov_ucdb/rv64gc_WALLY-COV-add.elf.ucdb ${SIM}/questa/fcov_ucdb/rv64gc_WALLY*.ucdb -logfile ${SIM}/questa/fcov_logs/log
|
||||
vcover report -details -html ${SIM}/questa/fcov_ucdb/fcov.ucdb
|
||||
vcover report ${SIM}/questa/fcov_ucdb/fcov.ucdb -details -cvg > ${SIM}/questa/fcov/fcov.log
|
||||
vcover report ${SIM}/questa/fcov_ucdb/fcov.ucdb -testdetails -cvg > ${SIM}/questa/fcov/fcov.testdetails.log
|
||||
vcover report ${SIM}/questa/fcov_ucdb/fcov.ucdb -details -cvg | egrep "Coverpoint|Covergroup|Cross|TYPE" > ${SIM}/questa/fcov/fcov.summary.log
|
||||
grep "TOTAL COVERGROUP COVERAGE" ${SIM}/questa/fcov/fcov.log
|
||||
|
||||
imperasdv_cov:
|
||||
touch ${SIM}/seed0.txt
|
||||
@ -91,6 +98,7 @@ combine_functcov:
|
||||
cd ${SIM}/questa/fcov && rm -rf *
|
||||
cd ${SIM}/questa/fcov_ucdb && rm -rf *
|
||||
wsim rv64gc ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf --fcov > ${SIM}/questa/fcov_logs/add.log 2>&1
|
||||
wsim rv64gc ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf --fcov > ${SIM}/questa/fcov_logs/and.log 2>&1
|
||||
|
||||
#run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/fcov/add.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-add.elf >> ${SIM}/questa/fcov_logs/add.log 2>&1
|
||||
#run-elf-cov.bash --seed ${SIM}/questa/seed0.txt --verbose --coverdb ${SIM}/questa/fcov/and.ucdb --elf ${WALLY}/tests/functcov/rv64/I/WALLY-COV-and.elf >> ${SIM}/questa/fcov_logs/add.log 2>&1
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#export RISCV=/scratch/moore/RISCV
|
||||
|
||||
export IMPERAS_TOOLS=$(pwd)/imperas.ic
|
||||
export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=100"
|
||||
#export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000"
|
||||
#export OTHERFLAGS=""
|
||||
|
||||
vsim -do "do wally.do buildroot buildroot testbench --lockstep +acc -GDEBUG=1"
|
@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
###########################################
|
||||
## imperas-one-time.sh
|
||||
##
|
||||
## Written: Ross Thompson (ross1728@gmail.com) and Lee Moore (moore@imperas.com)
|
||||
## Created: 31 January 2023
|
||||
## Modified: 31 January 2023
|
||||
##
|
||||
## Purpose: Run wally with imperas
|
||||
##
|
||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
## https://github.com/openhwgroup/cvw
|
||||
##
|
||||
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
##
|
||||
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
## may obtain a copy of the License at
|
||||
##
|
||||
## https://solderpad.org/licenses/SHL-2.1/
|
||||
##
|
||||
## Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
## either express or implied. See the License for the specific language governing permissions
|
||||
## and limitations under the License.
|
||||
################################################################################################
|
||||
IMPERAS_TOOLS=$(pwd)/imperas.ic \
|
||||
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
|
||||
TESTDIR=${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege/src/Lee.S/ \
|
||||
vsim -do "do wally-imperas.do rv64gc"
|
@ -1,79 +0,0 @@
|
||||
# wally.do
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
|
||||
vlog +incdir+$env(WALLY)/config/$1 \
|
||||
+incdir+$env(WALLY)/config/deriv/$1 \
|
||||
+incdir+$env(WALLY)/config/shared \
|
||||
+define+USE_IMPERAS_DV \
|
||||
+define+IDV_INCLUDE_TRACE2COV \
|
||||
+define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT \
|
||||
+define+COVER_RV64I \
|
||||
+define+COVER_RV64M \
|
||||
+define+COVER_RV64A \
|
||||
+define+COVER_RV64F \
|
||||
+define+COVER_RV64D \
|
||||
+define+COVER_RV64ZICSR \
|
||||
+define+COVER_RV64C \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
|
||||
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \
|
||||
\
|
||||
+incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
|
||||
\
|
||||
$env(WALLY)/src/cvw.sv \
|
||||
$env(WALLY)/testbench/testbench.sv \
|
||||
$env(WALLY)/testbench/common/*.sv \
|
||||
$env(WALLY)/src/*/*.sv \
|
||||
$env(WALLY)/src/*/*/*.sv \
|
||||
-suppress 2583 \
|
||||
-suppress 7063 \
|
||||
+acc
|
||||
vopt +acc work.testbench -G DEBUG=1 -o workopt
|
||||
eval vsim workopt +nowarn3829 -fatal 7 \
|
||||
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
|
||||
+ElfFile=$env(TESTDIR)/ref/ref.elf $env(OTHERFLAGS) +TRACE2COV_ENABLE=1
|
||||
|
||||
coverage save -onexit $env(WALLY)/sim/questa/riscv.ucdb
|
||||
|
||||
|
||||
view wave
|
||||
#-- display input and output signals as hexidecimal values
|
||||
# add log -recursive /*
|
||||
# do wave.do
|
||||
|
||||
run -all
|
||||
|
||||
noview $env(WALLY)/testbench/testbench-imperas.sv
|
||||
view wave
|
||||
|
||||
#quit -f
|
@ -1,48 +0,0 @@
|
||||
# wally.do
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
|
||||
vlog +incdir+../config/$1 \
|
||||
+incdir+../config/shared \
|
||||
../../external/ImperasDV-HMC/Imperas/ImpPublic/source/host/rvvi/rvviTrace.sv \
|
||||
../src/cvw.sv \
|
||||
../testbench/testbench_imperas.sv \
|
||||
../testbench/common/*.sv \
|
||||
../src/*/*.sv \
|
||||
../src/*/*/*.sv \
|
||||
-suppress 2583 \
|
||||
-suppress 7063
|
||||
vopt +acc work.testbench -G DEBUG=1 -o workopt
|
||||
eval vsim workopt +nowarn3829 -fatal 7 \
|
||||
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
|
||||
view wave
|
||||
#-- display input and output signals as hexidecimal values
|
||||
add log -recursive /*
|
||||
do wave.do
|
||||
|
||||
run -all
|
||||
|
||||
noview ../testbench/testbench_imperas.sv
|
||||
view wave
|
@ -1,64 +0,0 @@
|
||||
# wally.do
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
|
||||
|
||||
vlog +incdir+../config/$1 \
|
||||
+incdir+../config/shared \
|
||||
+define+USE_IMPERAS_DV \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
|
||||
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
|
||||
../src/cvw.sv \
|
||||
../testbench/testbench-imperas.sv \
|
||||
../testbench/common/*.sv \
|
||||
../src/*/*.sv \
|
||||
../src/*/*/*.sv \
|
||||
-suppress 2583 \
|
||||
-suppress 7063
|
||||
|
||||
vopt +acc work.testbench -G DEBUG=1 -o workopt
|
||||
eval vsim workopt +nowarn3829 -fatal 7 \
|
||||
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
|
||||
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
|
||||
view wave
|
||||
#-- display input and output signals as hexidecimal values
|
||||
add log -recursive /*
|
||||
do wave.do
|
||||
|
||||
run -all
|
||||
|
||||
noview ../testbench/testbench_imperas.sv
|
||||
view wave
|
||||
|
||||
#quit -f
|
@ -122,13 +122,14 @@ if {$FunctCoverageIndex >= 0} {
|
||||
set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV"
|
||||
set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I"
|
||||
set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT"
|
||||
# Uncomment various cover statements below to control which extensions get functional coverage
|
||||
set FCdefineCOVER_RV64I "+define+COVER_RV64I"
|
||||
set FCdefineCOVER_RV64M "+define+COVER_RV64M"
|
||||
set FCdefineCOVER_RV64A "+define+COVER_RV64A"
|
||||
set FCdefineCOVER_RV64F "+define+COVER_RV64F"
|
||||
set FCdefineCOVER_RV64D "+define+COVER_RV64D"
|
||||
set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR"
|
||||
set FCdefineCOVER_RV64C "+define+COVER_RV64C"
|
||||
#set FCdefineCOVER_RV64M "+define+COVER_RV64M"
|
||||
#set FCdefineCOVER_RV64A "+define+COVER_RV64A"
|
||||
#set FCdefineCOVER_RV64F "+define+COVER_RV64F"
|
||||
#set FCdefineCOVER_RV64D "+define+COVER_RV64D"
|
||||
#set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR"
|
||||
#set FCdefineCOVER_RV64C "+define+COVER_RV64C"
|
||||
set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV"
|
||||
set FCTRACE2COV "+TRACE2COV_ENABLE=1"
|
||||
set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1"
|
||||
@ -196,7 +197,7 @@ set temp3 [lindex $PlusArgs 3]
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${idvFiles} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
|
||||
vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${idvFiles} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
|
@ -657,9 +657,25 @@ add wave -noupdate -group wfi /testbench/dut/core/priv/priv/pmd/WFITimeoutM
|
||||
add wave -noupdate -expand -group testbench /testbench/DCacheFlushStart
|
||||
add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFault
|
||||
add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFaultDelay
|
||||
add wave -noupdate -expand -group rvvi /testbench/rvvi_synth/rvvisynth/clk
|
||||
add wave -noupdate -expand -group rvvi /testbench/rvvi_synth/rvvisynth/rvvi
|
||||
add wave -noupdate -expand -group rvvi /testbench/rvvi_synth/rvvisynth/valid
|
||||
add wave -noupdate -group packetizer -color Gold /testbench/rvvi_synth/packetizer/CurrState
|
||||
add wave -noupdate -group packetizer -radix unsigned /testbench/rvvi_synth/packetizer/WordCount
|
||||
add wave -noupdate -group packetizer /testbench/rvvi_synth/packetizer/RVVIStall
|
||||
add wave -noupdate -group packetizer /testbench/rvvi_synth/packetizer/rvviDelay
|
||||
add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWdata
|
||||
add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWlast
|
||||
add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWstrb
|
||||
add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWvalid
|
||||
add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWready
|
||||
add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_clk
|
||||
add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_txd
|
||||
add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_en
|
||||
add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_er
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 4} {6586 ns} 1} {{Cursor 4} {2112952 ns} 0} {{Cursor 3} {403021 ns} 1}
|
||||
quietly wave cursor active 2
|
||||
WaveRestoreCursors {{Cursor 4} {640 ns} 1} {{Cursor 4} {2400 ns} 1} {{Cursor 3} {554 ns} 0} {{Cursor 4} {120089 ns} 0}
|
||||
quietly wave cursor active 4
|
||||
configure wave -namecolwidth 250
|
||||
configure wave -valuecolwidth 194
|
||||
configure wave -justifyvalue left
|
||||
@ -674,4 +690,4 @@ configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {2039338 ns} {2323972 ns}
|
||||
WaveRestoreZoom {0 ns} {1033211 ns}
|
||||
|
@ -25,7 +25,7 @@ TARGET=$(WORKING_DIR)/target
|
||||
# INCLUDE_PATH are pathes that Verilator should search for files it needs
|
||||
INCLUDE_PATH="-I${WALLY}/config/shared" "-I${WALLY}/config/$(WALLYCONF)" "-I${WALLY}/config/deriv/$(WALLYCONF)"
|
||||
# SOURCES are source files
|
||||
SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv
|
||||
SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv
|
||||
# DEPENDENCIES are configuration files and source files, which leads to recompilation of executables
|
||||
DEPENDENCIES=${WALLY}/config/shared/*.vh $(SOURCES)
|
||||
|
||||
|
@ -296,7 +296,6 @@ typedef struct packed {
|
||||
int DIVBLEN ;
|
||||
// integer division/remainder constants
|
||||
int INTDIVb ;
|
||||
|
||||
} cvw_t;
|
||||
|
||||
endpackage
|
||||
|
@ -81,6 +81,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
logic [1:0] Fmt, Fmt2; // format - before possible reduction
|
||||
logic SupportedFmt; // is the format supported
|
||||
logic SupportedFmt2; // is the source format supported for fp -> fp
|
||||
logic SupportedRM; // is the rounding mode supported
|
||||
logic FCvtIntD, FCvtIntM; // convert to integer operation
|
||||
logic ZfaD; // Zfa variants of instructions
|
||||
logic ZfaFRoundNXD; // Zfa froundnx instruction
|
||||
@ -93,14 +94,19 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
(Fmt == 2'b10 & P.ZFH_SUPPORTED) | (Fmt == 2'b11 & P.Q_SUPPORTED));
|
||||
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) |
|
||||
(Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED));
|
||||
|
||||
// rounding modes 5 and 6 are reserved. Rounding mode 7 is dynamic, and is reserved if FRM is 5, 6, or 7
|
||||
assign SupportedRM = ~(Funct3D == 3'b101 | Funct3D == 3'b110 | (Funct3D == 3'b111 & (FRM_REGW == 3'b101 | FRM_REGW == 3'b110 | FRM_REGW == 3'b111))) |
|
||||
(OpD == 7'b1010011 & Funct3D == 3'b101 & Funct7D[6:2] == 5'b10100 & P.ZFA_SUPPORTED); // Zfa fltq has a funny rounding mode
|
||||
/*assign SupportedRM = ~(Funct3D == 3'b101 | Funct3D == 3'b110 | (Funct3D == 3'b111 & (FRM_REGW == 3'b101 | FRM_REGW == 3'b110 | FRM_REGW == 3'b111))) |
|
||||
(OpD == 7'b1010011 & P.ZFA_SUPPORTED);
|
||||
*/
|
||||
// decode the instruction
|
||||
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt_Zfa_FroundNX
|
||||
always_comb
|
||||
if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled
|
||||
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0;
|
||||
else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt)
|
||||
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; // for anything other than loads and stores, check for supported format
|
||||
else if (OpD != 7'b0000111 & OpD != 7'b0100111 & (~SupportedFmt | ~SupportedRM))
|
||||
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; // for anything other than loads and stores, check for supported format and rounding mode
|
||||
else begin
|
||||
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; // default: non-implemented instruction
|
||||
/* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed
|
||||
|
@ -31,7 +31,7 @@ module hazard import cvw::*; #(parameter cvw_t P) (
|
||||
input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
|
||||
input logic StructuralStallD,
|
||||
input logic LSUStallM, IFUStallF,
|
||||
input logic FPUStallD,
|
||||
input logic FPUStallD, ExternalStall,
|
||||
input logic DivBusyE, FDivBusyE,
|
||||
input logic wfiM, IntPendingM,
|
||||
// Stall & flush outputs
|
||||
@ -89,7 +89,7 @@ module hazard import cvw::*; #(parameter cvw_t P) (
|
||||
// Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1.
|
||||
// assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause;
|
||||
// Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out.
|
||||
assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause);
|
||||
assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause) | ExternalStall;
|
||||
|
||||
// Stall each stage for cause or if the next stage is stalled
|
||||
// coverage off: StallFCause is always 0
|
||||
|
@ -238,7 +238,7 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
if ((P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED) & P.XLEN == 64) begin // ZKND and ZKNE shared instructions
|
||||
casez({OpD, Funct7D, Funct3D})
|
||||
17'b0010011_0011000_001: if (Rs2D[4] == 1'b1)
|
||||
17'b0010011_0011000_001: if (Rs2D[4] == 1'b1 & $unsigned(Rs2D[3:0]) <= 10)
|
||||
BMUControlsD = `BMUCTRLW'b000_0111_0010_1_0_0_0_1_0_0_0_0_0; // aes64ks1i - key schedule istr1
|
||||
17'b0110011_0111111_000: BMUControlsD = `BMUCTRLW'b000_0111_0011_1_0_0_0_1_0_0_0_0_0; // aes64ks2 - key schedule istr2
|
||||
endcase
|
||||
|
@ -32,13 +32,15 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
||||
output logic [31:0] InstrD, // Decompressed instruction
|
||||
output logic IllegalCompInstrD // Invalid decompressed instruction
|
||||
);
|
||||
|
||||
|
||||
logic [32:0] LInstrD; // decompressed instruction with illegal flag in [32]
|
||||
logic [15:0] instr16;
|
||||
logic [4:0] rds1, rs2, rs1p, rs2p, rds1p, rdp;
|
||||
logic [11:0] immCILSP, immCILSPD, immCSS, immCSSD, immCL, immCLD, immCI, immCS, immCSD, immCB, immCIASP, immCIW;
|
||||
logic [19:0] immCJ, immCILUI;
|
||||
logic [5:0] immSH;
|
||||
logic [1:0] op;
|
||||
logic LegalCompInstrD;
|
||||
|
||||
// Extract op and register source/destination fields
|
||||
assign instr16 = InstrRawD[15:0]; // instruction is already aligned
|
||||
@ -62,10 +64,10 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
||||
assign immCJ = {instr16[12], instr16[8], instr16[10:9], instr16[6], instr16[7], instr16[2], instr16[11], instr16[5:3], {9{instr16[12]}}};
|
||||
assign immCB = {{4{instr16[12]}}, instr16[6:5], instr16[2], instr16[11:10], instr16[4:3], instr16[12]};
|
||||
assign immCI = {{7{instr16[12]}}, instr16[6:2]};
|
||||
assign immCILUI = {{15{instr16[12]}}, instr16[6:2]};
|
||||
assign immCIASP = {{3{instr16[12]}}, instr16[4:3], instr16[5], instr16[2], instr16[6], 4'b0000};
|
||||
assign immCILUI = {{15{instr16[12]}}, instr16[6:2]}; // c.lui
|
||||
assign immCIASP = {{3{instr16[12]}}, instr16[4:3], instr16[5], instr16[2], instr16[6], 4'b0000}; // c.addi16sp
|
||||
assign immCIW = {2'b00, instr16[10:7], instr16[12:11], instr16[5], instr16[6], 2'b00};
|
||||
assign immSH = {instr16[12], instr16[6:2]};
|
||||
assign immSH = {instr16[12], instr16[6:2]}; // c. shift instructions: c.srli, c.srai, c.slli
|
||||
|
||||
// only for RV128
|
||||
// assign immCILSPQ = {2{instr16[5]}, instr16[5:2], instr16[12], instr16[6], 4'b0000};
|
||||
@ -75,173 +77,110 @@ module decompress import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
always_comb
|
||||
if (op == 2'b11) begin // noncompressed instruction
|
||||
InstrD = InstrRawD;
|
||||
IllegalCompInstrD = '0;
|
||||
LInstrD = {1'b1, InstrRawD};
|
||||
end else begin // convert compressed instruction into uncompressed
|
||||
IllegalCompInstrD = '0;
|
||||
LInstrD = {1'b0, 16'b0, instr16}; // if a legal instruction is not decoded, default to illegal and preserve 16-bit value for mtval
|
||||
case ({op, instr16[15:13]})
|
||||
5'b00000: if (immCIW != 0) InstrD = {immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn
|
||||
else begin // illegal instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00001: if (P.ZCD_SUPPORTED)
|
||||
InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00010: InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw
|
||||
5'b00011: if (P.XLEN==32)
|
||||
if (P.ZCF_SUPPORTED)
|
||||
InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw
|
||||
else begin
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld;
|
||||
5'b00000: if (immCIW != 0) LInstrD = {1'b1, immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn
|
||||
5'b00001: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld
|
||||
5'b00010: LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw
|
||||
5'b00011: if (P.XLEN==32) begin
|
||||
if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw
|
||||
end else LInstrD = {1'b1, immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld
|
||||
5'b00100: if (P.ZCB_SUPPORTED)
|
||||
if (instr16[12:10] == 3'b000)
|
||||
InstrD = {10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu
|
||||
if (instr16[12:10] == 3'b000) LInstrD = {1'b1, 10'b0, instr16[5], instr16[6], rs1p, 3'b100, rdp, 7'b0000011}; // c.lbu
|
||||
else if (instr16[12:10] == 3'b001) begin
|
||||
if (instr16[6])
|
||||
InstrD = {10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh
|
||||
else
|
||||
InstrD = {10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu
|
||||
if (instr16[6]) LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b001, rdp, 7'b0000011}; // c.lh
|
||||
else LInstrD = {1'b1, 10'b0, instr16[5], 1'b0, rs1p, 3'b101, rdp, 7'b0000011}; // c.lhu
|
||||
end else if (instr16[12:10] == 3'b010)
|
||||
InstrD = {7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb
|
||||
LInstrD = {1'b1, 7'b0, rs2p, rs1p, 3'b000, 3'b000, instr16[5], instr16[6], 7'b0100011}; // c.sb
|
||||
else if (instr16[12:10] == 3'b011 & instr16[6] == 1'b0)
|
||||
InstrD = {7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh
|
||||
else begin
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else begin
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00101: if (P.ZCD_SUPPORTED)
|
||||
InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00110: InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw
|
||||
5'b00111: if (P.XLEN==32)
|
||||
if (P.ZCF_SUPPORTED)
|
||||
InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw
|
||||
else begin
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd
|
||||
5'b01000: InstrD = {immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi
|
||||
5'b01001: if (P.XLEN==32)
|
||||
InstrD = {immCJ, 5'b00001, 7'b1101111}; // c.jal
|
||||
else
|
||||
InstrD = {immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw
|
||||
5'b01010: InstrD = {immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li
|
||||
5'b01011: if (rds1 != 5'b00010)
|
||||
InstrD = {immCILUI, rds1, 7'b0110111}; // c.lui
|
||||
else
|
||||
InstrD = {immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp
|
||||
5'b01100: if (instr16[11:10] == 2'b00)
|
||||
InstrD = {6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli
|
||||
else if (instr16[11:10] == 2'b01)
|
||||
InstrD = {6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai
|
||||
else if (instr16[11:10] == 2'b10)
|
||||
InstrD = {immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi
|
||||
else if (instr16[12:10] == 3'b011)
|
||||
if (instr16[6:5] == 2'b00)
|
||||
InstrD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub
|
||||
else if (instr16[6:5] == 2'b01)
|
||||
InstrD = {7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor
|
||||
else if (instr16[6:5] == 2'b10)
|
||||
InstrD = {7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or
|
||||
else // if (instr16[6:5] == 2'b11)
|
||||
InstrD = {7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and
|
||||
else begin // (instr16[12:10] == 3'b111)
|
||||
LInstrD = {1'b1, 7'b0, rs2p, rs1p, 3'b001, 3'b000, instr16[5], 1'b0, 7'b0100011}; // c.sh
|
||||
5'b00101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd
|
||||
5'b00110: LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw
|
||||
5'b00111: if (P.XLEN==32) begin
|
||||
if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw
|
||||
end else LInstrD = {1'b1, immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; // c.sd
|
||||
5'b01000: if (rds1 != 5'b0)
|
||||
if (immCI[5:0] != 0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi
|
||||
else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.addi with imm = 0 is a HINT, treated as nop
|
||||
else if (immCI[5:0] == 6'b0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop = addi x0, x0, 0
|
||||
else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.nop with imm != 0 is a HINT, treated as nop
|
||||
5'b01001: if (P.XLEN==32) LInstrD = {1'b1, immCJ, 5'b00001, 7'b1101111}; // c.jal
|
||||
else if (rds1 != 5'b0) LInstrD = {1'b1, immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw
|
||||
5'b01010: if (rds1 != 5'b0) LInstrD = {1'b1, immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li
|
||||
else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.li with rd = 0 is a HINT, treated as nop
|
||||
5'b01011: if (rds1 == 5'b00010) begin
|
||||
if (immCIASP[9:4] != 6'b0) LInstrD = {1'b1, immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp
|
||||
end else if (immCILUI[5:0] != 0)
|
||||
if (rds1 != 5'b0) LInstrD = {1'b1, immCILUI, rds1, 7'b0110111}; // c.lui
|
||||
else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.lui with rd = 0, imm!=0 is a HINT, treated as nop
|
||||
5'b01100: if (instr16[11:10] == 2'b00) begin
|
||||
if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli; shamt[5] must be 0 in RV32C
|
||||
end else if (instr16[11:10] == 2'b01) begin
|
||||
if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai; shamt[5] must be 0 in RV32C
|
||||
end else if (instr16[11:10] == 2'b10) LInstrD = {1'b1, immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi
|
||||
else if (instr16[12:10] == 3'b011) begin
|
||||
if (instr16[6:5] == 2'b00) LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub
|
||||
else if (instr16[6:5] == 2'b01) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor
|
||||
else if (instr16[6:5] == 2'b10) LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or
|
||||
else LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and
|
||||
end else begin // (instr16[12:10] == 3'b111)
|
||||
if (instr16[6:5] == 2'b00 & P.XLEN > 32)
|
||||
InstrD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw
|
||||
LInstrD = {1'b1, 7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw
|
||||
else if (instr16[6:5] == 2'b01 & P.XLEN > 32)
|
||||
InstrD = {7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw
|
||||
LInstrD = {1'b1, 7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw
|
||||
else if (instr16[6:2] == 5'b11000 & P.ZCB_SUPPORTED)
|
||||
InstrD = {12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255
|
||||
LInstrD = {1'b1, 12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255
|
||||
else if (instr16[6:2] == 5'b11001 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED)
|
||||
InstrD = {12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b
|
||||
LInstrD = {1'b1, 12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b
|
||||
else if (instr16[6:2] == 5'b11010 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED)
|
||||
InstrD = {7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h
|
||||
LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h
|
||||
else if (instr16[6:2] == 5'b11011 & P.ZCB_SUPPORTED & P.ZBB_SUPPORTED)
|
||||
InstrD = {12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h
|
||||
LInstrD = {1'b1, 12'b011000000101, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.h
|
||||
else if (instr16[6:2] == 5'b11101 & P.ZCB_SUPPORTED)
|
||||
InstrD = {12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori
|
||||
LInstrD = {1'b1, 12'b111111111111, rds1p, 3'b100, rds1p, 7'b0010011}; // c.not = xori
|
||||
else if (instr16[6:2] == 5'b11100 & P.ZCB_SUPPORTED & P.ZBA_SUPPORTED & P.XLEN > 32)
|
||||
InstrD = {7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0
|
||||
LInstrD = {1'b1, 7'b0000100, 5'b00000, rds1p, 3'b000, rds1p, 7'b0111011}; // c.zext.w = add.uw rd, rs1, 0
|
||||
else if (instr16[6:5] == 2'b10 & P.ZCB_SUPPORTED & P.ZMMUL_SUPPORTED)
|
||||
InstrD = {7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul
|
||||
else begin // reserved
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
/** end else begin // illegal instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap **/
|
||||
LInstrD = {1'b1, 7'b0000001, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.mul
|
||||
end
|
||||
5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j
|
||||
5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz
|
||||
5'b01111: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez
|
||||
5'b10000: InstrD = {6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli
|
||||
5'b01101: LInstrD = {1'b1, immCJ, 5'b00000, 7'b1101111}; // c.j
|
||||
5'b01110: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz
|
||||
5'b01111: LInstrD = {1'b1, immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez
|
||||
5'b10000: if (rds1 != 5'b0) begin
|
||||
if (P.XLEN > 32 | ~immSH[5]) LInstrD = {1'b1, 6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli; shamt[5] must be 0 in RV32C
|
||||
end else if (immSH != 0) LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.slli with rd = 0, immm != 0 is a HINT, treated as nop
|
||||
5'b10001: if (P.ZCD_SUPPORTED)
|
||||
InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b10010: InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp
|
||||
5'b10011: if (P.XLEN == 32)
|
||||
if (P.ZCF_SUPPORTED)
|
||||
InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp
|
||||
else begin
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp
|
||||
if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp
|
||||
5'b10010: if (rds1 != 5'b0) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp
|
||||
5'b10011: if (P.XLEN == 32) begin
|
||||
if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp
|
||||
end else if (rds1 != 5'b0) LInstrD = {1'b1, immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp
|
||||
5'b10100: if (instr16[12] == 0)
|
||||
if (instr16[6:2] == 5'b00000)
|
||||
InstrD = {7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr
|
||||
else
|
||||
InstrD = {7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv
|
||||
if (rs2 == 5'b00000) begin
|
||||
if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, 5'b00000, rds1, 3'b000, 5'b00000, 7'b1100111}; // c.jr
|
||||
end else
|
||||
if (rds1 != 5'b0) LInstrD = {1'b1, 7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv
|
||||
else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.mv with rd = 0 is a HINT, treated as nop
|
||||
else
|
||||
if (rs2 == 5'b00000)
|
||||
if (rds1 == 5'b00000)
|
||||
InstrD = {12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak
|
||||
else
|
||||
InstrD = {12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr
|
||||
else
|
||||
InstrD = {7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add
|
||||
5'b10101: if (P.ZCD_SUPPORTED)
|
||||
InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp
|
||||
else begin // unsupported instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b10110: InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp
|
||||
5'b10111: if (P.XLEN==32)
|
||||
if (P.ZCF_SUPPORTED)
|
||||
InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp
|
||||
else begin
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else
|
||||
InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp
|
||||
default: begin // illegal instruction
|
||||
IllegalCompInstrD = 1'b1;
|
||||
InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
if (rs2 == 5'b00000) begin
|
||||
if (rds1 == 5'b00000) LInstrD = {1'b1, 12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak
|
||||
else if (rds1 != 5'b0) LInstrD = {1'b1, 12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr
|
||||
end else
|
||||
if (rds1 != 0) LInstrD = {1'b1, 7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add
|
||||
else LInstrD = {1'b1, 25'b0, 7'b0010011}; // c.add with rd = 0 is a HINT, treated as nop, even if it is a C.NTL
|
||||
5'b10101: if (P.ZCD_SUPPORTED) LInstrD = {1'b1, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp
|
||||
5'b10110: LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp
|
||||
5'b10111: if (P.XLEN==32) begin
|
||||
if (P.ZCF_SUPPORTED) LInstrD = {1'b1, immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp
|
||||
end else LInstrD = {1'b1, immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp
|
||||
default: ; // illegal instruction
|
||||
endcase
|
||||
end
|
||||
|
||||
// extract instruction and illegal from LInstrD
|
||||
assign {LegalCompInstrD, InstrD} = LInstrD;
|
||||
assign IllegalCompInstrD = ~LegalCompInstrD;
|
||||
|
||||
endmodule
|
||||
|
@ -57,6 +57,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
||||
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
|
||||
logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
|
||||
logic [P.XLEN-1:0] MENVCFGH_REGW;
|
||||
logic [P.XLEN-1:0] TVECWriteValM;
|
||||
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
||||
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
||||
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
||||
@ -105,7 +106,10 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
||||
genvar i;
|
||||
if (P.PMP_ENTRIES > 0) begin:pmp
|
||||
logic [P.PMP_ENTRIES-1:0] WritePMPCFGM;
|
||||
logic [P.PMP_ENTRIES-1:0] WritePMPADDRM ;
|
||||
logic [P.PMP_ENTRIES-1:0] WritePMPADDRM;
|
||||
logic [7:0] CSRPMPWriteValM[P.PMP_ENTRIES-1:0];
|
||||
logic [7:0] CSRPMPLegalizedWriteValM[P.PMP_ENTRIES-1:0];
|
||||
logic [1:0] CSRPMPWRLegalizedWriteValM[P.PMP_ENTRIES-1:0];
|
||||
logic [P.PMP_ENTRIES-1:0] ADDRLocked, CFGLocked;
|
||||
for(i=0; i<P.PMP_ENTRIES; i++) begin
|
||||
// when the lock bit is set, don't allow writes to the PMPCFG or PMPADDR
|
||||
@ -120,11 +124,15 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
||||
flopenr #(P.PA_BITS-2) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM[P.PA_BITS-3:0], PMPADDR_ARRAY_REGW[i]);
|
||||
if (P.XLEN==64) begin
|
||||
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~CFGLocked[i];
|
||||
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%8)*8+7:(i%8)*8], PMPCFG_ARRAY_REGW[i]);
|
||||
assign CSRPMPWriteValM[i] = CSRWriteValM[(i%8)*8+7:(i%8)*8];
|
||||
end else begin
|
||||
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~CFGLocked[i];
|
||||
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%4)*8+7:(i%4)*8], PMPCFG_ARRAY_REGW[i]);
|
||||
assign CSRPMPWriteValM[i] = CSRWriteValM[(i%4)*8+7:(i%4)*8];
|
||||
end
|
||||
|
||||
assign CSRPMPWRLegalizedWriteValM[i] = {(CSRPMPWriteValM[i][1] & CSRPMPWriteValM[i][0]), CSRPMPWriteValM[i][0]}; // legalize WR fields (reserved 10 written as 00)
|
||||
assign CSRPMPLegalizedWriteValM[i] = {CSRPMPWriteValM[i][7], 2'b00, CSRPMPWriteValM[i][4:2], CSRPMPWRLegalizedWriteValM[i]};
|
||||
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRPMPWriteValM[i], PMPCFG_ARRAY_REGW[i]);
|
||||
end
|
||||
end
|
||||
|
||||
@ -152,7 +160,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
||||
assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR);
|
||||
|
||||
// CSRs
|
||||
flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);
|
||||
assign TVECWriteValM = CSRWriteValM[0] ? {CSRWriteValM[P.XLEN-1:6], 6'b000001} : {CSRWriteValM[P.XLEN-1:2], 2'b00};
|
||||
flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, TVECWriteValM, MTVEC_REGW);
|
||||
if (P.S_SUPPORTED) begin:deleg // DELEG registers should exist
|
||||
flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW);
|
||||
flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW);
|
||||
|
@ -78,6 +78,7 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW;
|
||||
logic [P.XLEN-1:0] SENVCFG_WriteValM;
|
||||
logic [P.XLEN-1:0] TVECWriteValM;
|
||||
|
||||
logic [63:0] STIMECMP_REGW;
|
||||
|
||||
@ -100,7 +101,8 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
||||
assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & STCE & (P.XLEN == 32);
|
||||
|
||||
// CSRs
|
||||
flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
|
||||
assign TVECWriteValM = CSRWriteValM[0] ? {CSRWriteValM[P.XLEN-1:6], 6'b000001} : {CSRWriteValM[P.XLEN-1:2], 2'b00}; // could share this with MTVEC, but reduces to 4-bit AND to mask bits [5:2]
|
||||
flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, TVECWriteValM, STVEC_REGW);
|
||||
flopenr #(P.XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
|
||||
flopenr #(P.XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
|
||||
flopenr #(P.XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, {NextCauseM[4], {(P.XLEN-5){1'b0}}, NextCauseM[3:0]}, SCAUSE_REGW);
|
||||
|
77
src/rvvi/csrindextoaddr.sv
Normal file
77
src/rvvi/csrindextoaddr.sv
Normal file
@ -0,0 +1,77 @@
|
||||
///////////////////////////////////////////
|
||||
// csrindextoaddr.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: 24 January 2024
|
||||
// Modified: 24 January 2024
|
||||
//
|
||||
// Purpose: Converts the rvvi CSR index into the CSR address
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module csrindextoaddr #(parameter TOTAL_CSRS = 36) (
|
||||
input logic [TOTAL_CSRS-1:0] CSRWen,
|
||||
output logic [11:0] CSRAddr);
|
||||
|
||||
always_comb begin
|
||||
case(CSRWen)
|
||||
36'h0_0000_0000: CSRAddr = 12'h000;
|
||||
36'h0_0000_0001: CSRAddr = 12'h300;
|
||||
36'h0_0000_0002: CSRAddr = 12'h310;
|
||||
36'h0_0000_0004: CSRAddr = 12'h305;
|
||||
36'h0_0000_0008: CSRAddr = 12'h341;
|
||||
36'h0_0000_0010: CSRAddr = 12'h306;
|
||||
36'h0_0000_0020: CSRAddr = 12'h320;
|
||||
36'h0_0000_0040: CSRAddr = 12'h302;
|
||||
36'h0_0000_0080: CSRAddr = 12'h303;
|
||||
36'h0_0000_0100: CSRAddr = 12'h344;
|
||||
36'h0_0000_0200: CSRAddr = 12'h304;
|
||||
36'h0_0000_0400: CSRAddr = 12'h301;
|
||||
36'h0_0000_0800: CSRAddr = 12'h30A;
|
||||
36'h0_0000_1000: CSRAddr = 12'hF14;
|
||||
36'h0_0000_2000: CSRAddr = 12'h340;
|
||||
36'h0_0000_4000: CSRAddr = 12'h342;
|
||||
36'h0_0000_8000: CSRAddr = 12'h343;
|
||||
36'h0_0001_0000: CSRAddr = 12'hF11;
|
||||
36'h0_0002_0000: CSRAddr = 12'hF12;
|
||||
36'h0_0004_0000: CSRAddr = 12'hF13;
|
||||
36'h0_0008_0000: CSRAddr = 12'hF15;
|
||||
36'h0_0010_0000: CSRAddr = 12'h34A;
|
||||
36'h0_0020_0000: CSRAddr = 12'h100;
|
||||
36'h0_0040_0000: CSRAddr = 12'h104;
|
||||
36'h0_0080_0000: CSRAddr = 12'h105;
|
||||
36'h0_0100_0000: CSRAddr = 12'h141;
|
||||
36'h0_0200_0000: CSRAddr = 12'h106;
|
||||
36'h0_0400_0000: CSRAddr = 12'h10A;
|
||||
36'h0_0800_0000: CSRAddr = 12'h180;
|
||||
36'h0_1000_0000: CSRAddr = 12'h140;
|
||||
36'h0_2000_0000: CSRAddr = 12'h143;
|
||||
36'h0_4000_0000: CSRAddr = 12'h142;
|
||||
36'h0_8000_0000: CSRAddr = 12'h144;
|
||||
36'h1_0000_0000: CSRAddr = 12'h14D;
|
||||
36'h2_0000_0000: CSRAddr = 12'h001;
|
||||
36'h4_0000_0000: CSRAddr = 12'h002;
|
||||
36'h8_0000_0000: CSRAddr = 12'h003;
|
||||
default : CSRAddr = 12'h000;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
141
src/rvvi/packetizer.sv
Normal file
141
src/rvvi/packetizer.sv
Normal file
@ -0,0 +1,141 @@
|
||||
///////////////////////////////////////////
|
||||
// packetizer.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: 21 May 2024
|
||||
// Modified: 21 May 2024
|
||||
//
|
||||
// Purpose: Converts the compressed RVVI format into AXI 4 burst write transactions.
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module packetizer import cvw::*; #(parameter cvw_t P,
|
||||
parameter integer MAX_CSRS,
|
||||
parameter logic [31:0] RVVI_INIT_TIME_OUT = 32'd4,
|
||||
parameter logic [31:0] RVVI_PACKET_DELAY = 32'd2
|
||||
)(
|
||||
input logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi,
|
||||
input logic valid,
|
||||
input logic m_axi_aclk, m_axi_aresetn,
|
||||
output logic RVVIStall,
|
||||
// axi 4 write address channel
|
||||
// axi 4 write data channel
|
||||
output logic [31:0] RvviAxiWdata,
|
||||
output logic [3:0] RvviAxiWstrb,
|
||||
output logic RvviAxiWlast,
|
||||
output logic RvviAxiWvalid,
|
||||
input logic RvviAxiWready
|
||||
);
|
||||
|
||||
localparam TotalFrameLengthBits = 2*48+17+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12);
|
||||
localparam TotalFrameLengthBytes = TotalFrameLengthBits / 8;
|
||||
|
||||
logic [9:0] WordCount;
|
||||
logic [11:0] BytesInFrame;
|
||||
logic TransReady;
|
||||
logic BurstDone;
|
||||
logic WordCountReset;
|
||||
logic WordCountEnable;
|
||||
logic [47:0] SrcMac, DstMac;
|
||||
logic [15:0] EthType, Length;
|
||||
logic [31:0] Tag;
|
||||
logic [TotalFrameLengthBits-1:0] TotalFrame;
|
||||
logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0];
|
||||
|
||||
logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvviDelay;
|
||||
|
||||
typedef enum {STATE_RST, STATE_COUNT, STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_INSERT_DELAY} statetype;
|
||||
(* mark_debug = "true" *) statetype CurrState, NextState;
|
||||
|
||||
logic [31:0] RstCount;
|
||||
(* mark_debug = "true" *) logic [31:0] FrameCount;
|
||||
logic RstCountRst, RstCountEn, CountFlag, DelayFlag;
|
||||
|
||||
|
||||
always_ff @(posedge m_axi_aclk) begin
|
||||
if(~m_axi_aresetn) CurrState <= STATE_RST;
|
||||
else CurrState <= NextState;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
STATE_RST: NextState = STATE_COUNT;
|
||||
STATE_COUNT: if (CountFlag) NextState = STATE_RDY;
|
||||
else NextState = STATE_COUNT;
|
||||
STATE_RDY: if (TransReady & valid) NextState = STATE_TRANS;
|
||||
else if(~TransReady & valid) NextState = STATE_WAIT;
|
||||
else NextState = STATE_RDY;
|
||||
STATE_WAIT: if(TransReady) NextState = STATE_TRANS;
|
||||
else NextState = STATE_WAIT;
|
||||
STATE_TRANS: if(BurstDone & TransReady) NextState = STATE_TRANS_INSERT_DELAY;
|
||||
else NextState = STATE_TRANS;
|
||||
STATE_TRANS_INSERT_DELAY: if(DelayFlag) NextState = STATE_RDY;
|
||||
else NextState = STATE_TRANS_INSERT_DELAY;
|
||||
default: NextState = STATE_RDY;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign RVVIStall = CurrState != STATE_RDY;
|
||||
assign TransReady = RvviAxiWready;
|
||||
assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady);
|
||||
assign WordCountReset = CurrState == STATE_RDY;
|
||||
assign RstCountEn = CurrState == STATE_COUNT | CurrState == STATE_TRANS_INSERT_DELAY;
|
||||
assign RstCountRst = CurrState == STATE_RST | CurrState == STATE_TRANS;
|
||||
|
||||
// have to count at least 250 ms after reset pulled to wait for the phy to actually be ready
|
||||
// at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000.
|
||||
counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount);
|
||||
assign CountFlag = RstCount == RVVI_INIT_TIME_OUT;
|
||||
assign DelayFlag = RstCount == RVVI_PACKET_DELAY;
|
||||
|
||||
counter #(32) framecounter(m_axi_aclk, ~m_axi_aresetn, (RvviAxiWready & RvviAxiWlast), FrameCount);
|
||||
|
||||
|
||||
flopenr #(187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)) rvvireg(m_axi_aclk, ~m_axi_aresetn, valid, rvvi, rvviDelay);
|
||||
|
||||
|
||||
counter #(10) WordCounter(m_axi_aclk, WordCountReset, WordCountEnable, WordCount);
|
||||
// *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame
|
||||
// for now this will be exactly 608 bits (76 bytes, 19 words) + the ethernet frame overhead and 2-byte padding = 92-bytes
|
||||
assign BytesInFrame = 12'd2 + 12'd76 + 12'd6 + 12'd6 + 12'd2;
|
||||
assign BurstDone = WordCount == (BytesInFrame[11:2] - 1'b1);
|
||||
|
||||
genvar index;
|
||||
for (index = 0; index < TotalFrameLengthBytes/4; index++) begin
|
||||
assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)];
|
||||
end
|
||||
|
||||
assign Length = {4'b0, BytesInFrame};
|
||||
assign TotalFrame = {17'b0, rvviDelay, EthType, DstMac, SrcMac};
|
||||
|
||||
// *** fix me later
|
||||
assign DstMac = 48'h8F54_0000_1654; // made something up
|
||||
assign SrcMac = 48'h4502_1111_6843;
|
||||
assign Tag = 32'b0;
|
||||
assign EthType = 16'h005c;
|
||||
|
||||
assign RvviAxiWdata = TotalFrameWords[WordCount[4:0]];
|
||||
assign RvviAxiWstrb = '1;
|
||||
assign RvviAxiWlast = BurstDone & (CurrState == STATE_TRANS);
|
||||
assign RvviAxiWvalid = (CurrState == STATE_TRANS);
|
||||
|
||||
endmodule
|
||||
|
46
src/rvvi/priorityaomux.sv
Normal file
46
src/rvvi/priorityaomux.sv
Normal file
@ -0,0 +1,46 @@
|
||||
///////////////////////////////////////////
|
||||
// priorityaomux.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: 24 January 2024
|
||||
// Modified: 24 January 2024
|
||||
//
|
||||
// Purpose: priority AND-OR MUX.
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module priorityaomux #(parameter ROWS = 8, COLS = 64) (
|
||||
input logic [ROWS-1:0] Sel,
|
||||
input var logic [COLS-1:0] A [ROWS-1:0],
|
||||
output logic [COLS-1:0] Y,
|
||||
output logic [ROWS-1:0] SelPriority);
|
||||
|
||||
logic [COLS-1:0] AMasked [ROWS-1:0];
|
||||
genvar index;
|
||||
|
||||
priorityonehot #(ROWS) priorityonehot(Sel, SelPriority);
|
||||
for(index = 0; index < ROWS; index = index + 1) begin
|
||||
assign AMasked[index] = SelPriority[index] ? A[index] : '0;
|
||||
end
|
||||
or_rows #(ROWS, COLS) or_rows(AMasked, Y);
|
||||
|
||||
endmodule
|
||||
|
41
src/rvvi/regchangedetect.sv
Normal file
41
src/rvvi/regchangedetect.sv
Normal file
@ -0,0 +1,41 @@
|
||||
///////////////////////////////////////////
|
||||
// regchangedetect.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: 24 January 2024
|
||||
// Modified: 24 January 2024
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module regchangedetect #(parameter XLEN = 64) (
|
||||
input clk, reset,
|
||||
input logic [XLEN-1:0] Value,
|
||||
output logic Change);
|
||||
|
||||
logic [XLEN-1:0] ValueD;
|
||||
|
||||
flopr #(XLEN) register(clk, reset, Value, ValueD);
|
||||
assign Change = |(Value ^ ValueD);
|
||||
|
||||
endmodule
|
||||
|
138
src/rvvi/rvvisynth.sv
Normal file
138
src/rvvi/rvvisynth.sv
Normal file
@ -0,0 +1,138 @@
|
||||
///////////////////////////////////////////
|
||||
// rvvisynth.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: 23 January 2024
|
||||
// Modified: 23 January 2024
|
||||
//
|
||||
// Purpose: Synthesizable rvvi bridge from Wally to generic compressed format.
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module rvvisynth import cvw::*; #(parameter cvw_t P,
|
||||
parameter integer MAX_CSRS = 5,
|
||||
parameter integer TOTAL_CSRS = 36)(
|
||||
input logic clk, reset,
|
||||
input logic StallE, StallM, StallW, FlushE, FlushM, FlushW,
|
||||
// required
|
||||
input logic [P.XLEN-1:0] PCM,
|
||||
input logic InstrValidM,
|
||||
input logic [31:0] InstrRawD,
|
||||
input logic [63:0] Mcycle, Minstret,
|
||||
input logic TrapM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
// registers gpr and fpr
|
||||
input logic GPRWen, FPRWen,
|
||||
input logic [4:0] GPRAddr, FPRAddr,
|
||||
input logic [P.XLEN-1:0] GPRValue, FPRValue,
|
||||
input var logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0],
|
||||
output logic valid,
|
||||
output logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi
|
||||
);
|
||||
|
||||
// pipeline controlls
|
||||
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCW;
|
||||
logic InstrValidW;
|
||||
logic [31:0] InstrRawE, InstrRawM, InstrRawW;
|
||||
logic TrapW;
|
||||
|
||||
// registers gpr and fpr
|
||||
logic [P.XLEN-1:0] XLENZeros;
|
||||
logic [TOTAL_CSRS-1:0] CSRArrayWen;
|
||||
logic [P.XLEN-1:0] CSRValue [MAX_CSRS-1:0];
|
||||
logic [TOTAL_CSRS-1:0] CSRWen [MAX_CSRS-1:0];
|
||||
logic [11:0] CSRAddr [MAX_CSRS-1:0];
|
||||
logic [MAX_CSRS-1:0] EnabledCSRs;
|
||||
logic [MAX_CSRS-1:0] CSRCountShort;
|
||||
logic [11:0] CSRCount;
|
||||
logic [177+P.XLEN-1:0] Required;
|
||||
logic [10+2*P.XLEN-1:0] Registers;
|
||||
logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs;
|
||||
|
||||
assign XLENZeros = '0;
|
||||
|
||||
// start out easy and just populate Required
|
||||
// PC, inst, mcycle, minstret, trap, mode
|
||||
|
||||
flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW);
|
||||
flopenrc #(P.XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW);
|
||||
flopenrc #(32) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE);
|
||||
flopenrc #(32) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
|
||||
flopenrc #(32) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW);
|
||||
flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW);
|
||||
|
||||
assign valid = InstrValidW & ~StallW;
|
||||
assign Required = {CSRCount, FPRWen, GPRWen, PrivilegeModeW, TrapW, Minstret, Mcycle, InstrRawW, PCW};
|
||||
assign Registers = {FPRWen, GPRWen} == 2'b11 ? {FPRValue, FPRAddr, GPRValue, GPRAddr} :
|
||||
{FPRWen, GPRWen} == 2'b01 ? {XLENZeros, 5'b0, GPRValue, GPRAddr} :
|
||||
{FPRWen, GPRWen} == 2'b10 ? {XLENZeros, 5'b0, FPRValue, FPRAddr} :
|
||||
'0;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
// For some reason verilator complains about CSRWenFilterMatrix being in a circular loop when it is not.
|
||||
|
||||
// the CSRs are complex
|
||||
// 1. we need to get the CSR values
|
||||
// 2. we check if the CSR value changes by registering the value then XORing with the old value.
|
||||
// 3. Then use priorityaomux to collect CSR values and addresses for compating into the compressed rvvi format
|
||||
|
||||
// step 2
|
||||
genvar index;
|
||||
for (index = 0; index < TOTAL_CSRS; index = index + 1) begin
|
||||
regchangedetect #(P.XLEN) changedetect(clk, reset, CSRArray[index], CSRArrayWen[index]);
|
||||
end
|
||||
|
||||
// step 3a
|
||||
logic [TOTAL_CSRS-1:0] CSRWenPriorityMatrix [MAX_CSRS-1:0];
|
||||
logic [TOTAL_CSRS-1:0] CSRWenFilterMatrix [MAX_CSRS-1:0];
|
||||
|
||||
priorityaomux #(TOTAL_CSRS, P.XLEN) firstpriorityaomux(CSRArrayWen, CSRArray, CSRValue[0], CSRWenPriorityMatrix[0]);
|
||||
assign CSRWenFilterMatrix[0] = CSRArrayWen;
|
||||
|
||||
for(index = 1; index < MAX_CSRS; index = index + 1) begin
|
||||
priorityaomux #(TOTAL_CSRS, P.XLEN) priorityaomux(CSRWenFilterMatrix[index], CSRArray, CSRValue[index], CSRWenPriorityMatrix[index]);
|
||||
assign CSRWenFilterMatrix[index] = CSRWenFilterMatrix[index-1] & ~CSRWenPriorityMatrix[index-1];
|
||||
end
|
||||
for(index = 0; index < MAX_CSRS; index = index + 1) begin
|
||||
// step 3b
|
||||
csrindextoaddr #(TOTAL_CSRS) csrindextoaddr(CSRWenPriorityMatrix[index], CSRAddr[index]);
|
||||
assign CSRs[(index+1) * (P.XLEN + 12)- 1: index * (P.XLEN + 12)] = {CSRValue[index], CSRAddr[index]};
|
||||
assign EnabledCSRs[index] = |CSRWenPriorityMatrix[index];
|
||||
end
|
||||
|
||||
integer index2;
|
||||
always_comb begin
|
||||
CSRCountShort = '0;
|
||||
for(index2 = 0; index2 < MAX_CSRS; index2++) begin
|
||||
/* verilator lint_off WIDTHEXPAND */
|
||||
CSRCountShort += EnabledCSRs[index2];
|
||||
/* verilator lint_on WIDTHEXPAND */
|
||||
end
|
||||
end
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
assign CSRCount = {{{12-MAX_CSRS}{1'b0}}, CSRCountShort};
|
||||
assign rvvi = {CSRs, Registers, Required};
|
||||
|
||||
endmodule
|
||||
|
110
src/rvvi/triggergen.sv
Normal file
110
src/rvvi/triggergen.sv
Normal file
@ -0,0 +1,110 @@
|
||||
///////////////////////////////////////////
|
||||
// triggergen.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: June 26, 2024
|
||||
// Modified: June 26, 2024
|
||||
//
|
||||
// Purpose: Scans for specific ethernet frame to generate an ila trigger.
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module triggergen import cvw::*; (
|
||||
input logic clk, reset,
|
||||
input logic [31:0] RvviAxiRdata,
|
||||
input logic [3:0] RvviAxiRstrb,
|
||||
input logic RvviAxiRlast,
|
||||
input logic RvviAxiRvalid,
|
||||
output logic IlaTrigger);
|
||||
|
||||
typedef enum {STATE_RST, STATE_COMPARE, STATE_MISMATCH, STATE_TRIGGER, STATE_TRIGGER_DONE} statetype;
|
||||
(* mark_debug = "true" *) statetype CurrState, NextState;
|
||||
|
||||
logic [31:0] mem [4:0];
|
||||
logic [2:0] Counter;
|
||||
logic CounterEn, CounterRst;
|
||||
logic [31:0] RvviAxiRdataDelay;
|
||||
logic [3:0] RvviAxiRstrbDelay;
|
||||
logic RvviAxiRvalidDelay;
|
||||
logic Match, Overflow, Mismatch, Threshold;
|
||||
logic IlaTriggerOneCycle;
|
||||
|
||||
assign mem[0] = 32'h1111_6843; // dst mac [31:0]
|
||||
assign mem[1] = 32'h1654_4502; // src mac [15:0], dst mac [47:32]
|
||||
assign mem[2] = 32'h8f54_0000; // src mac [47:16]
|
||||
assign mem[3] = 32'h7274_005c; // "rt", ether type 005c
|
||||
assign mem[4] = 32'h6e69_6769; // "igin" (trigin)
|
||||
|
||||
flopenr #(32) rvviaxirdatareg(clk, reset, RvviAxiRvalid, RvviAxiRdata, RvviAxiRdataDelay);
|
||||
flopenr #(4) rvviaxirstrbreg(clk, reset, RvviAxiRvalid, RvviAxiRstrb, RvviAxiRstrbDelay);
|
||||
flopr #(1) rvviaxirvalidreg(clk, reset, RvviAxiRvalid, RvviAxiRvalidDelay);
|
||||
|
||||
counter #(3) counter(clk, CounterRst, CounterEn, Counter);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if(reset) CurrState <= STATE_RST;
|
||||
else CurrState <= NextState;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
STATE_RST: if(RvviAxiRvalid) NextState = STATE_COMPARE;
|
||||
else NextState = STATE_RST;
|
||||
STATE_COMPARE: if(RvviAxiRlast) NextState = STATE_RST;
|
||||
else if(Mismatch | Overflow) NextState = STATE_MISMATCH;
|
||||
else if(Threshold & Match) NextState = STATE_TRIGGER;
|
||||
else NextState = STATE_COMPARE;
|
||||
STATE_MISMATCH: if(RvviAxiRlast) NextState = STATE_RST;
|
||||
else NextState = STATE_MISMATCH;
|
||||
STATE_TRIGGER: if(RvviAxiRlast) NextState = STATE_RST;
|
||||
else NextState = STATE_TRIGGER_DONE;
|
||||
STATE_TRIGGER_DONE: if(RvviAxiRlast) NextState = STATE_RST;
|
||||
else NextState = STATE_TRIGGER_DONE;
|
||||
default: NextState = STATE_RST;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign Match = (mem[Counter] == RvviAxiRdataDelay) & (CurrState == STATE_COMPARE) & RvviAxiRvalidDelay;
|
||||
assign Overflow = Counter > 4'd4;
|
||||
assign Threshold = Counter >= 4'd4;
|
||||
assign Mismatch = (mem[Counter] != RvviAxiRdataDelay) & (CurrState == STATE_COMPARE) & RvviAxiRvalidDelay;
|
||||
assign IlaTriggerOneCycle = CurrState == STATE_TRIGGER;
|
||||
assign CounterRst = CurrState == STATE_RST;
|
||||
assign CounterEn = RvviAxiRvalid;
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
always_ff @(posedge clk) begin
|
||||
if(reset) IlaTrigger <= '0;
|
||||
else if (IlaTriggerOneCycle) IlaTrigger <= '1;
|
||||
else if (IlaTriggerAck) IlaTrigger <= '0;
|
||||
else IlaTrigger <= IlaTrigger;
|
||||
end
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
// this is a bit hacky, but it works!
|
||||
logic [3:0] TriggerCount;
|
||||
logic TriggerReset, TriggerEn;
|
||||
counter #(4) triggercounter(clk, reset | TriggerReset, TriggerEn, TriggerCount);
|
||||
assign TriggerReset = TriggerCount == 4'd10;
|
||||
assign TriggerEn = IlaTriggerOneCycle | (TriggerCount != 4'd0 & TriggerCount < 4'd10);
|
||||
assign IlaTrigger = TriggerEn;
|
||||
|
||||
endmodule
|
@ -44,7 +44,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
output logic [2:0] HBURST,
|
||||
output logic [3:0] HPROT,
|
||||
output logic [1:0] HTRANS,
|
||||
output logic HMASTLOCK
|
||||
output logic HMASTLOCK,
|
||||
input logic ExternalStall
|
||||
);
|
||||
|
||||
logic StallF, StallD, StallE, StallM, StallW;
|
||||
@ -274,7 +275,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.BPWrongE, .CSRWriteFenceM, .RetM, .TrapM,
|
||||
.StructuralStallD,
|
||||
.LSUStallM, .IFUStallF,
|
||||
.FPUStallD,
|
||||
.FPUStallD, .ExternalStall,
|
||||
.DivBusyE, .FDivBusyE,
|
||||
.wfiM, .IntPendingM,
|
||||
// Stall & flush outputs
|
||||
|
@ -32,10 +32,12 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic reset_ext, // external asynchronous reset pin
|
||||
output logic reset, // reset synchronized to clk to prevent races on release
|
||||
// AHB Interface
|
||||
input logic [P.AHBW-1:0] HRDATAEXT,
|
||||
input logic [P.AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic HSELEXT,
|
||||
output logic HSELEXTSDC,
|
||||
// fpga debug signals
|
||||
input logic ExternalStall,
|
||||
// outputs to external memory, shared with uncore memory
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [P.PA_BITS-1:0] HADDR,
|
||||
@ -75,7 +77,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
wallypipelinedcore #(P) core(.clk, .reset,
|
||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT,
|
||||
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB,
|
||||
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK
|
||||
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .ExternalStall
|
||||
);
|
||||
|
||||
// instantiate uncore if a bus interface exists
|
||||
@ -90,4 +92,5 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
MTIME_CLINT, GPIOOUT, GPIOEN, UARTSout, SPIOut, SPICS} = '0;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -66,6 +66,7 @@ module riscvassertions import cvw::*; #(parameter cvw_t P);
|
||||
assert ((P.ZCF_SUPPORTED == 0) | ((P.F_SUPPORTED == 1) & (P.XLEN == 32))) else $fatal(1, "ZCF requires F and XLEN == 32");
|
||||
assert ((P.ZCD_SUPPORTED == 0) | (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D");
|
||||
assert ((P.LLEN == P.XLEN) | (P.DCACHE_SUPPORTED & P.DTIM_SUPPORTED == 0)) else $fatal(1, "LLEN > XLEN (D on RV32 or Q on RV64) requires data cache");
|
||||
assert ((P.ZICCLSM_SUPPORTED == 0) | (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "ZICCLSM requires DCACHE_SUPPORTED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
170
testbench/common/rvvitbwrapper.sv
Normal file
170
testbench/common/rvvitbwrapper.sv
Normal file
@ -0,0 +1,170 @@
|
||||
///////////////////////////////////////////
|
||||
// loggers.sv
|
||||
//
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Modified: 24 July 2024
|
||||
//
|
||||
// Purpose: Wraps all the synthesizable rvvi hardware into a single module for the testbench.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module rvvitbwrapper import cvw::*; #(parameter cvw_t P,
|
||||
parameter MAX_CSRS = 5,
|
||||
parameter logic [31:0] RVVI_INIT_TIME_OUT = 32'd4,
|
||||
parameter logic [31:0] RVVI_PACKET_DELAY = 32'd2)(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
output logic RVVIStall,
|
||||
input logic mii_tx_clk,
|
||||
output logic [3:0] mii_txd,
|
||||
output logic mii_tx_en, mii_tx_er,
|
||||
input logic mii_rx_clk,
|
||||
input logic [3:0] mii_rxd,
|
||||
input logic mii_rx_dv,
|
||||
input logic mii_rx_er
|
||||
);
|
||||
|
||||
logic valid;
|
||||
logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi;
|
||||
|
||||
localparam TOTAL_CSRS = 36;
|
||||
|
||||
// pipeline controlls
|
||||
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
logic InstrValidM;
|
||||
logic [31:0] InstrRawD;
|
||||
logic [63:0] Mcycle, Minstret;
|
||||
logic TrapM;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
// registers gpr and fpr
|
||||
logic GPRWen, FPRWen;
|
||||
logic [4:0] GPRAddr, FPRAddr;
|
||||
logic [P.XLEN-1:0] GPRValue, FPRValue;
|
||||
logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0];
|
||||
|
||||
// axi 4 write data channel
|
||||
logic [31:0] RvviAxiWdata;
|
||||
logic [3:0] RvviAxiWstrb;
|
||||
logic RvviAxiWlast;
|
||||
logic RvviAxiWvalid;
|
||||
logic RvviAxiWready;
|
||||
|
||||
logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame;
|
||||
logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame;
|
||||
|
||||
logic MiiTxEnDelay;
|
||||
logic EthernetTXCounterEn;
|
||||
logic [31:0] EthernetTXCount;
|
||||
|
||||
assign StallE = dut.core.StallE;
|
||||
assign StallM = dut.core.StallM;
|
||||
assign StallW = dut.core.StallW;
|
||||
assign FlushE = dut.core.FlushE;
|
||||
assign FlushM = dut.core.FlushM;
|
||||
assign FlushW = dut.core.FlushW;
|
||||
assign InstrValidM = dut.core.ieu.InstrValidM;
|
||||
assign InstrRawD = dut.core.ifu.InstrRawD;
|
||||
assign PCM = dut.core.ifu.PCM;
|
||||
assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0];
|
||||
assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2];
|
||||
assign TrapM = dut.core.TrapM;
|
||||
assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW;
|
||||
assign GPRAddr = dut.core.ieu.dp.regf.a3;
|
||||
assign GPRWen = dut.core.ieu.dp.regf.we3;
|
||||
assign GPRValue = dut.core.ieu.dp.regf.wd3;
|
||||
assign FPRAddr = dut.core.fpu.fpu.fregfile.a4;
|
||||
assign FPRWen = dut.core.fpu.fpu.fregfile.we4;
|
||||
assign FPRValue = dut.core.fpu.fpu.fregfile.wd4;
|
||||
|
||||
assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300
|
||||
assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310
|
||||
assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305
|
||||
assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341
|
||||
assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306
|
||||
assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320
|
||||
assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302
|
||||
assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303
|
||||
assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344
|
||||
assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304
|
||||
assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301
|
||||
assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A
|
||||
assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14
|
||||
assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340
|
||||
assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342
|
||||
assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343
|
||||
assign CSRArray[16] = 0; // 12'hF11
|
||||
assign CSRArray[17] = 0; // 12'hF12
|
||||
assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13
|
||||
assign CSRArray[19] = 0; // 12'hF15
|
||||
assign CSRArray[20] = 0; // 12'h34A
|
||||
// supervisor CSRs
|
||||
assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100
|
||||
assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104
|
||||
assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105
|
||||
assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141
|
||||
assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106
|
||||
assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A
|
||||
assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180
|
||||
assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140
|
||||
assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143
|
||||
assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142
|
||||
assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144
|
||||
assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D
|
||||
// user CSRs
|
||||
assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001
|
||||
assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002
|
||||
assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003
|
||||
|
||||
rvvisynth #(P, MAX_CSRS, TOTAL_CSRS) rvvisynth(.clk, .reset, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW,
|
||||
.PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM,
|
||||
.PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray,
|
||||
.valid, .rvvi);
|
||||
|
||||
packetizer #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall,
|
||||
.RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready);
|
||||
|
||||
eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset),
|
||||
.tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready),
|
||||
.tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1),
|
||||
.rx_axis_tlast(), .rx_axis_tuser(),
|
||||
|
||||
.mii_rx_clk(clk),
|
||||
.mii_rxd('0),
|
||||
.mii_rx_dv('0),
|
||||
.mii_rx_er('0),
|
||||
.mii_tx_clk(clk),
|
||||
.mii_txd,
|
||||
.mii_tx_en,
|
||||
.mii_tx_er,
|
||||
|
||||
// status
|
||||
.tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame,
|
||||
.rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame,
|
||||
.cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1));
|
||||
|
||||
flopr #(1) txedgereg(clk, reset, mii_tx_en, MiiTxEnDelay);
|
||||
assign EthernetTXCounterEn = ~mii_tx_en & MiiTxEnDelay;
|
||||
counter #(32) ethernexttxcounter(clk, reset, EthernetTXCounterEn, EthernetTXCount);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
@ -274,7 +274,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
// Initially connecting the writeback stage signals, but may need to use M stage
|
||||
// and gate on ~FlushW.
|
||||
|
||||
assign valid = InstrValidW & ~StallW;
|
||||
assign valid = InstrValidW & ~StallW & ~reset;
|
||||
assign rvvi.clk = clk;
|
||||
assign rvvi.valid[0][0] = valid;
|
||||
assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order
|
||||
|
@ -33,7 +33,6 @@
|
||||
`include "idv/idv.svh"
|
||||
`endif
|
||||
|
||||
|
||||
import cvw::*;
|
||||
|
||||
module testbench;
|
||||
@ -44,6 +43,7 @@ module testbench;
|
||||
parameter BPRED_LOGGER=0;
|
||||
parameter I_CACHE_ADDR_LOGGER=0;
|
||||
parameter D_CACHE_ADDR_LOGGER=0;
|
||||
parameter RVVI_SYNTH_SUPPORTED=0;
|
||||
|
||||
`ifdef USE_IMPERAS_DV
|
||||
import idvPkg::*;
|
||||
@ -114,6 +114,7 @@ module testbench;
|
||||
logic SelectTest;
|
||||
logic TestComplete;
|
||||
logic PrevPCZero;
|
||||
logic RVVIStall;
|
||||
|
||||
initial begin
|
||||
// look for arguments passed to simulation, or use defaults
|
||||
@ -589,7 +590,8 @@ module testbench;
|
||||
assign SDCIntr = 1'b0;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall(RVVIStall),
|
||||
.HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPIIn, .SPIOut, .SPICS);
|
||||
@ -599,6 +601,22 @@ module testbench;
|
||||
clk = 1'b1; # 5; clk = 1'b0; # 5;
|
||||
end
|
||||
|
||||
if(RVVI_SYNTH_SUPPORTED) begin : rvvi_synth
|
||||
localparam MAX_CSRS = 5;
|
||||
localparam logic [31:0] RVVI_INIT_TIME_OUT = 32'd4;
|
||||
localparam logic [31:0] RVVI_PACKET_DELAY = 32'd2;
|
||||
|
||||
logic [3:0] mii_txd;
|
||||
logic mii_tx_en, mii_tx_er;
|
||||
|
||||
rvvitbwrapper #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY)
|
||||
rvvitbwrapper(.clk, .reset, .RVVIStall, .mii_tx_clk(clk), .mii_txd, .mii_tx_en, .mii_tx_er,
|
||||
.mii_rx_clk(clk), .mii_rxd('0), .mii_rx_dv('0), .mii_rx_er('0));
|
||||
end else begin
|
||||
assign RVVIStall = '0;
|
||||
end
|
||||
|
||||
|
||||
/*
|
||||
// Print key info each cycle for debugging
|
||||
always @(posedge clk) begin
|
||||
|
@ -60,7 +60,7 @@ module wallywrapper import cvw::*;(
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
logic HSELEXTSDC;
|
||||
|
||||
logic ExternalStall;
|
||||
|
||||
// instantiate device to be tested
|
||||
assign GPIOIN = 0;
|
||||
@ -70,8 +70,9 @@ module wallywrapper import cvw::*;(
|
||||
assign HRESPEXT = 0;
|
||||
assign HRDATAEXT = 0;
|
||||
|
||||
assign ExternalStall = '0;
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC,
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SPIIn, .SPIOut, .SPICS, .SDCIntr);
|
||||
|
@ -31,54 +31,89 @@ def signedImm12(imm):
|
||||
imm = imm - 0x1000
|
||||
return str(imm)
|
||||
|
||||
def signedImm20(imm):
|
||||
def unsignedImm20(imm):
|
||||
imm = imm % pow(2, 20)
|
||||
if (imm & 0x80000):
|
||||
imm = imm - 0x100000
|
||||
return str(imm)
|
||||
|
||||
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen):
|
||||
def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen):
|
||||
lines = "\n# Testcase " + str(desc) + "\n"
|
||||
if (rs1val < 0):
|
||||
rs1val = rs1val + 2**xlen
|
||||
if (rs2val < 0):
|
||||
rs2val = rs2val + 2**xlen
|
||||
lines = lines + "li x" + str(rd) + ", " + formatstr.format(rdval) + " # initialize rd to a random value that should get changed\n"
|
||||
lines = lines + "li x" + str(rd) + ", " + formatstr.format(rdval) + " # initialize rd to a random value that should get changed; helps covering rd_toggle\n"
|
||||
if (test in rtype):
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n"
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value\n"
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\n"
|
||||
elif (test in shiftitype):
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n"
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n"
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
|
||||
if (test in shiftiwtype):
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, 32) + " # perform operation\n"
|
||||
else:
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n"
|
||||
elif (test in itype):
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n"
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
|
||||
lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n"
|
||||
elif (test in loaditype):#["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
|
||||
lines = lines + "auipc x" + str(rs1) + ", 0x20" + " # add upper immediate value to pc \n"
|
||||
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # add immediate to lower part of rs1 \n"
|
||||
lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n"
|
||||
elif (test in stypes):#["sb", "sh", "sw", "sd"]
|
||||
#lines = lines + test + " x" + str(rs2) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n"
|
||||
#lines = lines + test + " x" + str(rs2) + ", " "0(x" + str(rs1) + ") # perform operation \n"
|
||||
print("Error: %s type not implemented yet" % test)
|
||||
elif (test in btypes):#["beq", "bne", "blt", "bge", "bltu", "bgeu"]
|
||||
if (randint(1,100) > 50):
|
||||
rs1val = rs2val
|
||||
lines = lines + "# same values in both registers\n"
|
||||
if (rs1 != 0):
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
|
||||
lines = lines + "la x" + str(rs1) + ", scratch" + " # base address \n"
|
||||
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # sub immediate from rs1 to counter offset\n"
|
||||
if (xlen == 32):
|
||||
storeop = "sw"
|
||||
else:
|
||||
storeop = "sd"
|
||||
lines = lines + storeop + " x" + str(rs2) + ", " + signedImm12(immval) +" (x" + str(rs1) + ") # store value to put someting in memory\n"
|
||||
lines = lines + test + " x" + str(rd) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation\n"
|
||||
# lines = lines + test + " x" + str(rd) + ", 0(x" + str(rs1) + ") # perform operation\n"
|
||||
elif (test in stype):#["sb", "sh", "sw", "sd"]
|
||||
if (rs1 != 0):
|
||||
if (rs2 == rs1): # make sure registers are different so they don't conflict
|
||||
rs2 = (rs1 + 1) % 32
|
||||
if (rs2 == 0):
|
||||
rs2 = 1
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
|
||||
lines = lines + "la x" + str(rs1) + ", scratch" + " # base address \n"
|
||||
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # sub immediate from rs1 to counter offset\n"
|
||||
lines = lines + test + " x" + str(rs2) + ", " + signedImm12(immval) + "(x" + str(rs1) + ") # perform operation \n"
|
||||
elif (test in btype):#["beq", "bne", "blt", "bge", "bltu", "bgeu"]
|
||||
for same in range(2):
|
||||
if (same):
|
||||
rs1val = rs2val
|
||||
lines = lines + "# same values in both registers\n"
|
||||
lines = lines + "nop\n"
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1\n"
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2\n"
|
||||
lines = lines + test + " x" + str(rs1) + ", x" + str(rs2) + ", some_label_for_btype_" + str(immval) + str(same) + " # perform operation \n"
|
||||
lines = lines + "addi x0, x1, 1\n"
|
||||
lines = lines + "some_label_for_btype_" + str(immval)+ str(same) + ":\n"
|
||||
lines = lines + "addi x0, x2, 2\n"
|
||||
lines = lines + "nop\nnop\nnop\nnop\nnop\n"
|
||||
elif (test in jtype):#["jal"]
|
||||
lines = lines + "jal x" + str(rd) + ", 1f # perform operation\n"
|
||||
lines = lines + "nop\n"
|
||||
lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value that should get changed\n"
|
||||
lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value that should get changed\n"
|
||||
lines = lines + test + " x" + str(rs1) + ", x" + str(rs2) + ", some_label_for_sb_types_" + str(immval) + "+4" + " # perform operation \n"
|
||||
lines = lines + "addi x0, x1, 1\n"
|
||||
lines = lines + "some_label_for_sb_types_" + str(immval) + ":\n"
|
||||
lines = lines + "addi x0, x2, 2\n"
|
||||
lines = lines + "nop\nnop\nnop\nnop\nnop\n"
|
||||
lines = lines + "1:\n"
|
||||
elif (test in jalrtype):#["jalr"]
|
||||
lines = lines + "la x" + str(rs1) + ", 1f\n"
|
||||
lines = lines + "addi x" + str(rs1) + ", x" + str(rs1) + ", " + signedImm12(-immval) + " # add immediate to lower part of rs1\n"
|
||||
lines = lines + "jalr x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n"
|
||||
lines = lines + "nop\n"
|
||||
lines = lines + "1:\n"
|
||||
elif (test in utype):#["lui", "auipc"]
|
||||
lines = lines + test + " x" + str(rd) + ", " + unsignedImm20(immval) + " # perform operation\n"
|
||||
else:
|
||||
pass
|
||||
#print("Error: %s type not implemented yet" % test)
|
||||
f.write(lines)
|
||||
|
||||
def writeHazardVector(desc, rs1a, rs2a, rda, rs1b, rs2b, rdb, test):
|
||||
# consecutive R-type instructions to trigger hazards
|
||||
lines = "\n# Testcase " + str(desc) + "\n"
|
||||
lines = lines + test + " x" + str(rda) + ", x" + str(rs1a) + ", x" + str(rs2a) + " # perform first operation\n"
|
||||
lines = lines + test + " x" + str(rdb) + ", x" + str(rs1b) + ", x" + str(rs2b) + " # perform second operation\n"
|
||||
f.write(lines)
|
||||
|
||||
def randomize():
|
||||
rs1 = randint(1, 31)
|
||||
rs2 = randint(1, 31)
|
||||
@ -93,177 +128,257 @@ def randomize():
|
||||
rdval = randint(0, 2**xlen-1)
|
||||
return [rs1, rs2, rd, rs1val, rs2val, immval, rdval]
|
||||
|
||||
def make_rd(test, storecmd, xlen):
|
||||
def make_rd(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rd (Test destination rd = x" + str(r) + ")"
|
||||
writeCovVector(desc, rs1, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1(test, storecmd, xlen):
|
||||
def make_rs1(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs1 (Test source rs1 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, r, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs2(test, storecmd, xlen):
|
||||
def make_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs2 (Test source rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, rs1, r, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, r, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs1(test, storecmd, xlen):
|
||||
def make_rd_rs1(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs1 (Test rd = rs1 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs2(test, storecmd, xlen):
|
||||
def make_rd_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs2 (Test rd = rs1 = x" + str(r) + ")"
|
||||
writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs1_rs2(test, storecmd, xlen):
|
||||
def make_rd_rs1_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs1_rs2 (Test rd = rs1 = rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1_rs2(test, storecmd, xlen):
|
||||
def make_rs1_rs2(test, xlen):
|
||||
for r in range(32):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs1_rs2 (Test rs1 = rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, r, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
desc = "cmp_rs1_rs2 (Test rs1 = rs2 = x" + str(r) + ")"
|
||||
writeCovVector(desc, r, r, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1_maxvals(test, storecmd, xlen):
|
||||
def make_rs1_maxvals(test, xlen):
|
||||
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs1_maxvals (Test source rs1 value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, v, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, rd, v, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs2_maxvals(test, storecmd, xlen):
|
||||
def make_rs2_maxvals(test, xlen):
|
||||
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rs2_maxvals (Test source rs2 value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, v, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, v, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_maxvals(test, storecmd, xlen):
|
||||
def make_rd_maxvals(test, xlen):
|
||||
for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]:
|
||||
# rs1 = 0, rs2 = v, others are random
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, 0, rd, v, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, 0, rd, v, rs2val, 0, rdval, test, xlen)
|
||||
# rs1, rs2 = v, others are random
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, v, v, v, rdval, test, xlen)
|
||||
# rs1 = all 1s, rs2 = v, others are random
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_rd_maxvals (Test rd value = " + hex(v) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, v, -1, -1, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs1_eqval(test, storecmd, xlen):
|
||||
def make_rd_rs1_eqval(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rdm_rs1_eqval (Test rs1 = rd = " + hex(rs1val) + ")"
|
||||
writeCovVector(desc, rs1, 0, rd, rdval, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, 0, rd, rdval, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rd_rs2_eqval(test, storecmd, xlen):
|
||||
def make_rd_rs2_eqval(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rd_rs2_eqval (Test rs2 = rd = " + hex(rs2val) + ")"
|
||||
writeCovVector(desc, 0, rs2, rd, rs1val, rdval, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, 0, rs2, rd, rs1val, rdval, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs1_rs2_eqval(test, storecmd, xlen):
|
||||
def make_rs1_rs2_eqval(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cmp_rs1_rs2_eqval (Test rs1 = rs2 = " + hex(rs1val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs1val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs1val, immval, rdval, test, xlen)
|
||||
|
||||
#def make_cp_gpr_hazard(test, storecmd, xlen):
|
||||
# pass # *** to be implemented ***
|
||||
def make_cp_gpr_hazard(test, xlen):
|
||||
for haz in ["raw", "waw", "war"]:
|
||||
for src in range(2):
|
||||
[rs1a, rs2a, rda, rs1vala, rs2vala, immvala, rdvala] = randomize()
|
||||
[rs1b, rs2b, rdb, rs1valb, rs2valb, immvalb, rdvalb] = randomize()
|
||||
# set up hazard
|
||||
if (haz == "raw"):
|
||||
if (src):
|
||||
rs2b = rda
|
||||
else:
|
||||
rs1b = rda
|
||||
elif (haz == "waw"):
|
||||
rdb = rda
|
||||
elif (haz == "war"):
|
||||
if (src):
|
||||
rdb = rs2a
|
||||
else:
|
||||
rdb = rs1a
|
||||
desc = "cmp_gpr_hazard " + haz + " test"
|
||||
writeHazardVector(desc, rs1a, rs2a, rda, rs1b, rs2b, rdb, test)
|
||||
|
||||
def make_rs1_sign(test, storecmd, xlen):
|
||||
def make_rs1_sign(test, xlen):
|
||||
for v in [1, -1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
rs1val = abs(rs1val % 2**(xlen-1)) * v;
|
||||
desc = "cp_rs1_sign (Test source rs1 value = " + hex(rs1val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_rs2_sign(test, storecmd, xlen):
|
||||
def make_rs2_sign(test, xlen):
|
||||
for v in [1, -1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
rs2val = abs(rs2val % 2**(xlen-1)) * v;
|
||||
desc = "cp_rs2_sign (Test source rs2 value = " + hex(rs2val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def make_cr_rs1_rs2_sign(test, storecmd, xlen):
|
||||
def make_cr_rs1_rs2_sign(test, xlen):
|
||||
for v1 in [1, -1]:
|
||||
for v2 in [1, -1]:
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
rs1val = abs(rs1val % 2**(xlen-1)) * v1;
|
||||
rs2val = abs(rs2val % 2**(xlen-1)) * v2;
|
||||
desc = "cr_rs1_rs2 (Test source rs1 = " + hex(rs1val) + " rs2 = " + hex(rs2val) + ")"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, xlen)
|
||||
|
||||
def write_tests(coverpoints, test, storecmd, xlen):
|
||||
def make_imm_zero(test, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
desc = "cp_imm_zero"
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, 0, rdval, test, xlen)
|
||||
|
||||
def make_j_imm_ones_zeros(test, xlen):
|
||||
for align in range(2,19):
|
||||
lines = "\n# Testcase cp_imm_ones_zeros " + str(align) + "\n"
|
||||
lines = lines + "li x1, " + formatstr.format(randint(0, 2**xlen-1)) + "\n"
|
||||
lines = lines + "jal x20, 1f # jump to aligned address to stress immediate\n"
|
||||
lines = lines + ".align " + str(align) + "\n"
|
||||
lines = lines + "1:\n"
|
||||
f.write(lines)
|
||||
|
||||
def make_offset(test, xlen):
|
||||
if (test in btype):
|
||||
lines = "\n# Testcase cp_offset\n"
|
||||
lines = lines + "j 2f # jump past backward branch target\n"
|
||||
lines = lines + "1: j 3f # backward branch target: jump past backward branch\n"
|
||||
lines = lines + "2: " + test + " x0, x0, 1b # backward branch\n"
|
||||
lines = lines + "3: nop # done with sequence\n"
|
||||
f.write(lines)
|
||||
|
||||
def make_mem_hazard(test, xlen):
|
||||
lines = "\n# Testcase mem_hazard (no dependency)\n"
|
||||
lines = lines + "la x1, scratch\n"
|
||||
lines = lines + test + " x2, 0(x1)\n"
|
||||
f.write(lines)
|
||||
|
||||
def make_cr_rs1_imm(test, xlen):
|
||||
desc = "cp_cr_rs1_imm"
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
for s1 in range(2):
|
||||
for s2 in range(3):
|
||||
if (s1):
|
||||
rs1v = -abs(rs1val)
|
||||
else:
|
||||
rs1v = abs(rs1val)
|
||||
if (s2 == 0):
|
||||
immv = 0
|
||||
elif (s2 == 1):
|
||||
immv = abs(immval)
|
||||
else:
|
||||
immv = -abs(immval)
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1v, rs2val, immv, rdval, test, xlen)
|
||||
|
||||
def make_imm_shift(test, xlen):
|
||||
desc = "cp_imm_shift"
|
||||
for shift in range(0, xlen):
|
||||
[rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize()
|
||||
writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, shift, rdval, test, xlen)
|
||||
|
||||
def write_tests(coverpoints, test, xlen):
|
||||
for coverpoint in coverpoints:
|
||||
if (coverpoint == "cp_asm_count"):
|
||||
pass
|
||||
elif (coverpoint == "cp_rd"):
|
||||
make_rd(test, storecmd, xlen)
|
||||
make_rd(test, xlen)
|
||||
elif (coverpoint == "cp_rs1"):
|
||||
make_rs1(test, storecmd, xlen)
|
||||
make_rs1(test, xlen)
|
||||
elif (coverpoint == "cp_rs2"):
|
||||
make_rs2(test, storecmd, xlen)
|
||||
make_rs2(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1"):
|
||||
make_rd_rs1(test, storecmd, xlen)
|
||||
make_rd_rs1(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs2"):
|
||||
make_rd_rs2(test, storecmd, xlen)
|
||||
make_rd_rs2(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1_rs2"):
|
||||
make_rd_rs1_rs2(test, storecmd, xlen)
|
||||
make_rd_rs1_rs2(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1_eq"):
|
||||
pass # duplicate of cmp_rd_rs1
|
||||
elif (coverpoint == "cmp_rd_rs2_eq"):
|
||||
pass # duplicate of cmp_rd_rs2
|
||||
elif (coverpoint == "cmp_rs1_rs2_eq"):
|
||||
make_rs1_rs2(test, storecmd, xlen)
|
||||
make_rs1_rs2(test, xlen)
|
||||
elif (coverpoint == "cp_rs1_maxvals"):
|
||||
make_rs1_maxvals(test, storecmd, xlen)
|
||||
make_rs1_maxvals(test, xlen)
|
||||
elif (coverpoint == "cp_rs2_maxvals"):
|
||||
make_rs2_maxvals(test, storecmd, xlen)
|
||||
make_rs2_maxvals(test, xlen)
|
||||
elif (coverpoint == "cp_rd_maxvals"):
|
||||
make_rd_maxvals(test, storecmd, xlen)
|
||||
make_rd_maxvals(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs1_eqval"):
|
||||
make_rd_rs1_eqval(test, storecmd, xlen)
|
||||
make_rd_rs1_eqval(test, xlen)
|
||||
elif (coverpoint == "cmp_rd_rs2_eqval"):
|
||||
make_rd_rs2_eqval(test, storecmd, xlen)
|
||||
make_rd_rs2_eqval(test, xlen)
|
||||
elif (coverpoint == "cmp_rs1_rs2_eqval"):
|
||||
make_rs1_rs2_eqval(test, storecmd, xlen)
|
||||
make_rs1_rs2_eqval(test, xlen)
|
||||
elif (coverpoint == "cp_rs1_sign"):
|
||||
make_rs1_sign(test, storecmd, xlen)
|
||||
make_rs1_sign(test, xlen)
|
||||
elif (coverpoint == "cp_rs2_sign"):
|
||||
make_rs2_sign(test, storecmd, xlen)
|
||||
make_rs2_sign(test, xlen)
|
||||
elif (coverpoint == "cp_rd_sign"):
|
||||
pass #TODO hope already covered by rd_maxvals
|
||||
elif (coverpoint == "cr_rs1_rs2"):
|
||||
make_cr_rs1_rs2_sign(test, storecmd, xlen)
|
||||
make_cr_rs1_rs2_sign(test, xlen)
|
||||
elif (coverpoint == "cp_gpr_hazard"):
|
||||
make_cp_gpr_hazard(test, xlen)
|
||||
elif (coverpoint == "cp_rs1_toggle"):
|
||||
pass #TODO toggle not needed and seems to be covered by other things
|
||||
elif (coverpoint == "cp_rs2_toggle"):
|
||||
pass #TODO toggle not needed and seems to be covered by other things
|
||||
elif (coverpoint == "cp_rd_toggle"):
|
||||
pass #TODO toggle not needed and seems to be covered by other things
|
||||
elif (coverpoint == "cp_gpr_hazard"):
|
||||
pass #TODO not yet implemented
|
||||
elif (coverpoint == "cp_imm_sign"):
|
||||
pass #TODO
|
||||
make_imm_zero(test, xlen)
|
||||
elif (coverpoint == "cr_rs1_imm"):
|
||||
pass #TODO (not if crosses are not needed)
|
||||
make_cr_rs1_imm(test, xlen)
|
||||
elif (coverpoint == "cp_imm_ones_zeros"):
|
||||
pass #TODO
|
||||
if (test in jtype):
|
||||
make_j_imm_ones_zeros(test, xlen)
|
||||
elif (coverpoint == "cp_mem_hazard"):
|
||||
pass #TODO
|
||||
make_mem_hazard(test, xlen)
|
||||
elif (coverpoint == "cp_imm_zero"):
|
||||
pass #TODO
|
||||
make_imm_zero(test, xlen)
|
||||
elif (coverpoint == "cp_mem_unaligned"):
|
||||
pass #TODO
|
||||
pass # seems this should be part of privileged tests
|
||||
elif (coverpoint == "cp_offset"):
|
||||
pass #TODO
|
||||
make_offset(test, xlen)
|
||||
elif (coverpoint == "cr_nord_rs1_rs2"):
|
||||
pass #TODO (not if crosses are not needed)
|
||||
elif (coverpoint == "cp_imm_shift"):
|
||||
pass #TODO
|
||||
make_imm_shift(test, xlen)
|
||||
elif (coverpoint == "cp_rd_boolean"):
|
||||
pass #TODO
|
||||
pass # covered by other generators
|
||||
else:
|
||||
print("Warning: " + coverpoint + " not implemented yet for " + test)
|
||||
|
||||
@ -301,10 +416,14 @@ rtype = ["add", "sub", "sll", "slt", "sltu", "xor", "srl", "sra", "or", "and",
|
||||
"mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu",
|
||||
"mulw", "divw", "divuw", "remw", "remuw"]
|
||||
loaditype = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]
|
||||
shiftitype = ["slli", "srli", "srai"]
|
||||
itype = ["addi", "slti", "sltiu", "xori", "ori", "andi"]
|
||||
stypes = ["sb", "sh", "sw", "sd"]
|
||||
btypes = ["beq", "bne", "blt", "bge", "bltu", "bgeu"]
|
||||
shiftitype = ["slli", "srli", "srai", "slliw", "srliw", "sraiw"]
|
||||
shiftiwtype = ["slliw", "srliw", "sraiw"]
|
||||
itype = ["addi", "slti", "sltiu", "xori", "ori", "andi", "addiw"]
|
||||
stype = ["sb", "sh", "sw", "sd"]
|
||||
btype = ["beq", "bne", "blt", "bge", "bltu", "bgeu"]
|
||||
jtype = ["jal"]
|
||||
jalrtype = ["jalr"]
|
||||
utype = ["lui", "auipc"]
|
||||
# TODO: auipc missing, check whatelse is missing in ^these^ types
|
||||
|
||||
coverpoints = getcovergroups(coverdefdir, coverfiles)
|
||||
@ -327,12 +446,11 @@ for xlen in xlens:
|
||||
else:
|
||||
storecmd = "sd"
|
||||
wordsize = 8
|
||||
WALLY = os.environ.get('WALLY')
|
||||
pathname = WALLY+"/tests/functcov/rv" + str(xlen) + "/I/"
|
||||
cmd = "mkdir -p " + pathname + " ; rm -f " + pathname + "/*" # make directory and remove old tests in dir
|
||||
os.system(cmd)
|
||||
for test in coverpoints.keys():
|
||||
# pathname = "../wally-riscv-arch-test/riscv-test-suite/rv" + str(xlen) + "i_m/I/"
|
||||
WALLY = os.environ.get('WALLY')
|
||||
pathname = WALLY+"/tests/functcov/rv" + str(xlen) + "/I/"
|
||||
cmd = "mkdir -p " + pathname
|
||||
os.system(cmd)
|
||||
basename = "WALLY-COV-" + test
|
||||
fname = pathname + "/" + basename + ".S"
|
||||
|
||||
@ -340,9 +458,9 @@ for xlen in xlens:
|
||||
f = open(fname, "w")
|
||||
line = "///////////////////////////////////////////\n"
|
||||
f.write(line)
|
||||
lines="// "+fname+ "\n// " + author + "\n"
|
||||
f.write(lines)
|
||||
line ="// Created " + str(datetime.now())
|
||||
line="// "+fname+ "\n// " + author + "\n"
|
||||
f.write(line)
|
||||
line ="// Created " + str(datetime.now()) + "\n"
|
||||
f.write(line)
|
||||
|
||||
# insert generic header
|
||||
@ -355,8 +473,8 @@ for xlen in xlens:
|
||||
#if (test not in rtests):
|
||||
# exit("Error: %s not implemented yet" % test)
|
||||
#else:
|
||||
# write_rtype_arith_vectors(test, storecmd, xlen)
|
||||
write_tests(coverpoints[test], test, storecmd, xlen)
|
||||
# write_rtype_arith_vectors(test, xlen)
|
||||
write_tests(coverpoints[test], test, xlen)
|
||||
|
||||
# print footer
|
||||
line = "\n.EQU NUMTESTS," + str(1) + "\n\n"
|
||||
@ -366,9 +484,6 @@ for xlen in xlens:
|
||||
f.write(line)
|
||||
|
||||
# Finish
|
||||
# lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
|
||||
# lines = lines + "\nRV_COMPLIANCE_DATA_END\n"
|
||||
f.write(lines)
|
||||
f.close()
|
||||
|
||||
|
||||
|
@ -2,4 +2,10 @@
|
||||
self_loop:
|
||||
j self_loop
|
||||
|
||||
.data
|
||||
|
||||
.align 4
|
||||
scratch:
|
||||
.bss 8
|
||||
|
||||
.end
|
||||
|
Loading…
Reference in New Issue
Block a user