mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:ross144/cvw
This commit is contained in:
commit
869860bc55
1
.gitignore
vendored
1
.gitignore
vendored
@ -101,6 +101,7 @@ sim/localhistory_m6k10_results_april24.txt
|
||||
sim/cfi/*
|
||||
sim/branch/*
|
||||
sim/covhtmlreport/
|
||||
sim/*/*Cache.log
|
||||
|
||||
# Questa
|
||||
sim/questa/logs
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -31,3 +31,6 @@
|
||||
[submodule "cvw-arch-verif"]
|
||||
path = addins/cvw-arch-verif
|
||||
url = https://github.com/openhwgroup/cvw-arch-verif
|
||||
[submodule "addins/riscvISACOV"]
|
||||
path = addins/riscvISACOV
|
||||
url = https://github.com/riscv-verification/riscvISACOV.git
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9d54f3f8e902bb85db74305993d2fc03796b57bc
|
||||
Subproject commit 189974e497d7b8d2c08bb1d151b1ccdeaf3a64c9
|
1
addins/riscvISACOV
Submodule
1
addins/riscvISACOV
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ac9fa2d386c0cb2f44e1e1e83a555d585034dfa3
|
@ -41,7 +41,6 @@
|
||||
# Add -d or --dist to report the distribution of loads, stores, and atomic ops.
|
||||
# These distributions may not add up to 100; this is because of flushes or invalidations.
|
||||
|
||||
import sys
|
||||
import math
|
||||
import argparse
|
||||
import os
|
||||
@ -193,7 +192,7 @@ class Cache:
|
||||
return self.__str__()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Simulates a L1 cache.")
|
||||
parser.add_argument('numlines', type=int, help="The number of lines per way (a power of 2)", metavar="L")
|
||||
parser.add_argument('numways', type=int, help="The number of ways (a power of 2)", metavar='W')
|
||||
@ -207,7 +206,7 @@ if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
cache = Cache(args.numlines, args.numways, args.addrlen, args.taglen)
|
||||
extfile = os.path.expanduser(args.file)
|
||||
nofails = True
|
||||
mismatches = 0
|
||||
|
||||
if args.perf:
|
||||
hits = 0
|
||||
@ -269,7 +268,7 @@ if __name__ == "__main__":
|
||||
|
||||
if not result == lninfo[2]:
|
||||
print("Result mismatch at address", lninfo[0]+ ". Wally:", lninfo[2]+", Sim:", result)
|
||||
nofails = False
|
||||
mismatches += 1
|
||||
if args.dist:
|
||||
percent_loads = str(round(100*loads/totalops))
|
||||
percent_stores = str(round(100*stores/totalops))
|
||||
@ -280,5 +279,9 @@ if __name__ == "__main__":
|
||||
ratio = round(hits/misses,3)
|
||||
print("There were", hits, "hits and", misses, "misses. The hit/miss ratio was", str(ratio)+".")
|
||||
|
||||
if nofails:
|
||||
print("SUCCESS! There were no mismatches between Wally and the sim.")
|
||||
if mismatches == 0:
|
||||
print("SUCCESS! There were no mismatches between Wally and the sim.")
|
||||
return mismatches
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
@ -517,6 +517,8 @@ def main():
|
||||
TIMEOUT_DUR = 60*1440 # 1 day
|
||||
elif args.testfloat:
|
||||
TIMEOUT_DUR = 30*60 # seconds
|
||||
elif args.nightly:
|
||||
TIMEOUT_DUR = 30*60 # seconds
|
||||
else:
|
||||
TIMEOUT_DUR = 10*60 # seconds
|
||||
|
||||
|
62
bin/wsim
62
bin/wsim
@ -28,8 +28,10 @@ parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testb
|
||||
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, implies lockstep", action="store_true")
|
||||
parser.add_argument("--fcov2", "-f2", help="Functional Coverage, implies lockstep", action="store_true")
|
||||
parser.add_argument("--fcovrvvi", "-fr", help="Functional Coverage RVVI", action="store_true")
|
||||
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
|
||||
parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", 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)
|
||||
@ -66,7 +68,7 @@ if(args.testsuite.endswith('.elf') and args.elf == ""): # No --elf argument; che
|
||||
|
||||
|
||||
# Validate arguments
|
||||
if (args.gui or args.ccov or args.fcov or args.fcovrvvi or args.lockstep):
|
||||
if (args.gui or args.ccov or args.fcov or args.fcov2 or args.fcovrvvi or args.lockstep):
|
||||
if args.sim not in ["questa", "vcs"]:
|
||||
print("Option only supported for Questa and VCS")
|
||||
exit(1)
|
||||
@ -75,16 +77,30 @@ if (args.vcd):
|
||||
args.args += " -DMAKEVCD=1"
|
||||
|
||||
if (args.rvvi):
|
||||
args.args += " -GRVVI_SYNTH_SUPPORTED=1"
|
||||
args.params += " RVVI_SYNTH_SUPPORTED=1 "
|
||||
|
||||
if (args.tb == "testbench_fp"):
|
||||
args.params += " TEST=\"" + args.testsuite + "\" "
|
||||
|
||||
# if lockstep is enabled, then we need to pass the Imperas lockstep arguments
|
||||
if(int(args.locksteplog) >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
if((args.lockstep or args.fcov or args.fcov2) and args.sim == "questa"):
|
||||
prefix = "IMPERAS_TOOLS=" + WALLY + "/config/"+args.config+"/imperas.ic"
|
||||
prefix = "MTI_VCO_MODE=64 " + prefix
|
||||
else:
|
||||
prefix = ""
|
||||
|
||||
if (args.lockstep):
|
||||
prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic"
|
||||
if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog)
|
||||
else: ImperasPlusArgs = ""
|
||||
if(args.fcov):
|
||||
CovEnableStr = "1" if int(args.covlog) > 0 else "0"
|
||||
if(args.covlog >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr
|
||||
suffix = ""
|
||||
if(args.fcov2):
|
||||
CovEnableStr = "1" if int(args.covlog) > 0 else "0";
|
||||
if(args.covlog >= 1): EnableLog = 1
|
||||
else: EnableLog = 0
|
||||
@ -94,16 +110,19 @@ if (args.lockstep):
|
||||
CovEnableStr = ""
|
||||
suffix = "--lockstep"
|
||||
else:
|
||||
prefix = ""
|
||||
ImperasPlusArgs = ""
|
||||
suffix = ""
|
||||
flags = suffix + " " + ImperasPlusArgs
|
||||
flags = suffix
|
||||
args.args += ImperasPlusArgs
|
||||
|
||||
|
||||
# other flags
|
||||
if (args.ccov):
|
||||
flags += " --ccov"
|
||||
if (args.fcov):
|
||||
flags += " --fcov"
|
||||
if (args.fcov2):
|
||||
flags += " --fcov2"
|
||||
if (args.fcovrvvi):
|
||||
flags += "--fcovrvvi"
|
||||
|
||||
@ -119,15 +138,18 @@ cd = "cd $WALLY/sim/" +args.sim
|
||||
|
||||
# per-simulator launch
|
||||
if (args.sim == "questa"):
|
||||
if (args.gui) and (args.tb == "testbench"):
|
||||
args.params += "DEBUG=1"
|
||||
if (ElfFile != ""):
|
||||
args.args += " " + ElfFile
|
||||
if (args.args != ""):
|
||||
args.args = " --args \\\"" + args.args + "\\\""
|
||||
if (args.params != ""):
|
||||
args.params = " --params \\\"" + args.params + "\\\""
|
||||
# Questa cannot accept more than 9 arguments. fcov implies lockstep
|
||||
if (args.tb == "testbench_fp"):
|
||||
args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args
|
||||
cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + flags
|
||||
cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + args.params + " " + flags
|
||||
if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible
|
||||
if(args.tb == "testbench"):
|
||||
cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\""
|
||||
elif(args.tb == "testbench_fp"):
|
||||
cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\""
|
||||
cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\""
|
||||
else: # launch Questa in batch mode
|
||||
cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\""
|
||||
print("Running Questa with command: " + cmd)
|
||||
@ -135,17 +157,23 @@ if (args.sim == "questa"):
|
||||
elif (args.sim == "verilator"):
|
||||
# PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i
|
||||
print(f"Running Verilator on {args.config} {args.testsuite}")
|
||||
os.system(f"/usr/bin/make -C {regressionDir}/verilator WALLYCONF={args.config} TEST={args.testsuite} TESTBENCH={args.tb} EXTRA_ARGS='{args.args}'")
|
||||
os.system(f"/usr/bin/make -C {regressionDir}/verilator WALLYCONF={args.config} TEST={args.testsuite} TESTBENCH={args.tb} PLUS_ARGS=\"{args.args}\" PARAM_ARGS=\"{args.params}\"")
|
||||
elif (args.sim == "vcs"):
|
||||
print("wsim params: " + args.params)
|
||||
print(f"Running VCS on " + args.config + " " + args.testsuite)
|
||||
if (args.gui):
|
||||
args.args += "gui"
|
||||
# if (args.gui):
|
||||
# flags += " --gui"
|
||||
if (args.args == ""):
|
||||
vcsargs = ""
|
||||
else:
|
||||
vcsargs = " --args " + args.args
|
||||
vcsargs = " --args \"" + args.args + "\" "
|
||||
if (args.params == ""):
|
||||
vcsparams = ""
|
||||
else:
|
||||
vcsparams = " --params \"" + args.params + "\" "
|
||||
print("VCS params: " + vcsparams)
|
||||
if (ElfFile != ""):
|
||||
ElfFile = " --elffile " + ElfFile
|
||||
cmd = cd + "; " + prefix + " ./run_vcs " + args.config + " " + args.testsuite + vcsargs + ElfFile + " " + flags
|
||||
cmd = cd + "; " + prefix + " ./run_vcs " + args.config + " " + args.testsuite + " " + " --tb " + args.tb + " " + vcsargs + vcsparams + ElfFile + " " + flags
|
||||
print(cmd)
|
||||
os.system(cmd)
|
||||
|
119
config/rv32gc/imperas.ic
Normal file
119
config/rv32gc/imperas.ic
Normal file
@ -0,0 +1,119 @@
|
||||
# imperas.ic
|
||||
# Initialization file for ImperasDV lock step simulation
|
||||
# David_Harris@hmc.edu 15 August 2024
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
|
||||
#--mpdconsole
|
||||
#--gdbconsole
|
||||
#--showoverrides
|
||||
#--showcommands
|
||||
|
||||
# Core settings
|
||||
--variant RV32GC # for RV32GC
|
||||
--override cpu/priv_version=1.12
|
||||
--override cpu/user_version=20191213
|
||||
# arch
|
||||
--override cpu/mimpid=0x100
|
||||
--override cpu/mvendorid=0x602
|
||||
--override cpu/marchid=0x24
|
||||
--override refRoot/cpu/tvec_align=64
|
||||
--override refRoot/cpu/envcfg_mask=1 # dh 1/26/24 this should be deleted when ImperasDV is updated to allow envcfg.FIOM to be written
|
||||
|
||||
# bit manipulation
|
||||
--override cpu/add_Extensions=B
|
||||
--override cpu/bitmanip_version=1.0.0
|
||||
--override cpu/misa_B_Zba_Zbb_Zbs=T
|
||||
|
||||
# More extensions
|
||||
--override cpu/Zcb=T
|
||||
--override cpu/Zicond=T
|
||||
--override cpu/Zfh=T
|
||||
--override cpu/Zfa=T
|
||||
|
||||
# Cache block operations
|
||||
--override cpu/Zicbom=T
|
||||
--override cpu/Zicbop=T
|
||||
--override cpu/Zicboz=T
|
||||
--override cmomp_bytes=64 # Zic64b
|
||||
--override cmoz_bytes=64 # Zic64b
|
||||
--override lr_sc_grain=8 # Za64rs requires <=64; we use native word size
|
||||
|
||||
# 64 KiB continuous huge pages supported
|
||||
#--override cpu/Svpbmt=F
|
||||
#--override cpu/Svnapot_page_mask=65536
|
||||
|
||||
# SV32 supported
|
||||
--override cpu/Sv_modes=3
|
||||
#--showoverrides
|
||||
|
||||
--override cpu/Svinval=T
|
||||
|
||||
|
||||
# clarify
|
||||
#--override refRoot/cpu/mtvec_sext=F
|
||||
|
||||
--override cpu/tval_ii_code=T
|
||||
|
||||
#--override cpu/time_undefined=T
|
||||
#--override cpu/cycle_undefined=T
|
||||
#--override cpu/instret_undefined=T
|
||||
#--override cpu/hpmcounter_undefined=T
|
||||
|
||||
--override cpu/reset_address=0x80000000
|
||||
|
||||
--override cpu/unaligned=F # Zicclsm (should be true)
|
||||
--override cpu/ignore_non_leaf_DAU=1
|
||||
--override cpu/wfi_is_nop=T
|
||||
--override cpu/misa_Extensions_mask=0x0 # MISA not writable
|
||||
--override cpu/Sstc=T
|
||||
|
||||
# Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1
|
||||
--override cpu/Svadu=T
|
||||
#--override cpu/updatePTEA=F
|
||||
#--override cpu/updatePTED=F
|
||||
|
||||
--override cpu/PMP_registers=16
|
||||
--override cpu/PMP_undefined=T
|
||||
|
||||
# mstatus.FS is set dirty on any write to a FPR, or when a fp operation signals an exception
|
||||
--override cpu/mstatus_fs_mode=write_1
|
||||
|
||||
# PMA Settings
|
||||
# 'r': read access allowed
|
||||
# 'w': write access allowed
|
||||
# 'x': execute access allowed
|
||||
# 'a': aligned access required
|
||||
# 'A': atomic instructions NOT allowed (actually USER1 privilege needed)
|
||||
# 'P': push/pop instructions NOT allowed (actually USER2 privilege needed)
|
||||
# '1': 1-byte accesses allowed
|
||||
# '2': 2-byte accesses allowed
|
||||
# '4': 4-byte accesses allowed
|
||||
# '8': 8-byte accesses allowed
|
||||
# '-', space: ignored (use for input string formatting).
|
||||
#
|
||||
# SVxx Memory 0x0000000000 0x7FFFFFFFFF
|
||||
#
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0xFFFFFFFFFFFFFFFFFF -attributes " ---a-- ---- " # All memory inaccessible unless defined otherwise
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ---a-- ---- " # INITIAL
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 " # BOOTROM
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw-aA- --48 " # SDC
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw-aA- 1248 " # CLINT
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw-aA- --4- " # PLIC
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
|
||||
|
||||
# Enable the Imperas instruction coverage
|
||||
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
|
||||
#-override refRoot/cpu/cv/cover=basic
|
||||
#-override refRoot/cpu/cv/extensions=RV32I
|
||||
|
||||
# Add Imperas simulator application instruction tracing
|
||||
# uncomment these to provide tracing
|
||||
--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||
--override cpu/debugflags=6 --override cpu/verbose=1
|
||||
--override cpu/show_c_prefix=T
|
||||
|
||||
# Store simulator output to logfile
|
||||
--output imperas.log
|
@ -109,9 +109,9 @@
|
||||
|
||||
# Add Imperas simulator application instruction tracing
|
||||
# uncomment these to provide tracing
|
||||
--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||
--override cpu/debugflags=6 --override cpu/verbose=1
|
||||
--override cpu/show_c_prefix=T
|
||||
#--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||
#--override cpu/debugflags=6 --override cpu/verbose=1
|
||||
#--override cpu/show_c_prefix=T
|
||||
|
||||
# Store simulator output to logfile
|
||||
--output imperas.log
|
@ -4,7 +4,7 @@
|
||||
# This clock is not used by wally or the AHB Bus. However it is used by the AXI BUS on the DD3 IP.
|
||||
|
||||
#create_generated_clock -name CLKDiv64_Gen -source [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/I0] -multiply_by 1 -divide_by 1 [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/O]
|
||||
create_generated_clock -name SPISDCClock -source [get_pins clk_out3_xlnx_mmcm] -multiply_by 1 -divide_by 1 [get_pins wallypipelinedsoc/uncore.uncore/sdc.sdc/SPICLK]
|
||||
create_generated_clock -name SPISDCClock -source [get_pins mmcm/clk_out3] -multiply_by 1 -divide_by 1 [get_pins wallypipelinedsoc/uncoregen.uncore/sdc.sdc/SPICLK]
|
||||
|
||||
##### clock #####
|
||||
set_property PACKAGE_PIN E3 [get_ports default_100mhz_clk]
|
||||
@ -45,8 +45,8 @@ set_property IOSTANDARD LVCMOS33 [get_ports {GPI[3]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[2]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[0]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 0.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -min -add_delay 0.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 0.000 [get_ports {GPI[*]}]
|
||||
set_max_delay -from [get_ports {GPI[*]}] 20.000
|
||||
|
||||
##### GPO ####
|
||||
@ -62,8 +62,8 @@ set_property IOSTANDARD LVCMOS33 [get_ports {GPO[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {GPO[0]}]
|
||||
set_max_delay -to [get_ports {GPO[*]}] 20.000
|
||||
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks clk_out3_mmcm] -min -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
|
||||
|
||||
##### UART #####
|
||||
@ -75,24 +75,24 @@ set_max_delay -to [get_ports UARTSout] 20.000
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports UARTSin]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports UARTSout]
|
||||
set_property DRIVE 4 [get_ports UARTSout]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 0.000 [get_ports UARTSin]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [get_ports UARTSin]
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 0.000 [get_ports UARTSout]
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [get_ports UARTSout]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -min -add_delay 0.000 [get_ports UARTSin]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 0.000 [get_ports UARTSin]
|
||||
set_output_delay -clock [get_clocks clk_out3_mmcm] -min -add_delay 0.000 [get_ports UARTSout]
|
||||
set_output_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 0.000 [get_ports UARTSout]
|
||||
|
||||
|
||||
##### reset #####
|
||||
#************** reset is inverted
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.000 [get_ports resetn]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 2.000 [get_ports resetn]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -min -add_delay 2.000 [get_ports resetn]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 2.000 [get_ports resetn]
|
||||
set_max_delay -from [get_ports resetn] 20.000
|
||||
set_false_path -from [get_ports resetn]
|
||||
set_property PACKAGE_PIN C2 [get_ports resetn]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports resetn]
|
||||
|
||||
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.000 [get_ports south_reset]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 2.000 [get_ports south_reset]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -min -add_delay 2.000 [get_ports south_reset]
|
||||
set_input_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 2.000 [get_ports south_reset]
|
||||
set_max_delay -from [get_ports south_reset] 20.000
|
||||
set_false_path -from [get_ports south_reset]
|
||||
set_property PACKAGE_PIN D9 [get_ports south_reset]
|
||||
@ -220,77 +220,77 @@ set_property IOSTANDARD SSTL135 [get_ports {ddr3_odt[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_cs_n[0]}]
|
||||
|
||||
|
||||
set_properity PACKAGE_PIN K5 [get_ports ddr3_dq[0]]
|
||||
set_properity PACKAGE_PIN L3 [get_ports ddr3_dq[1]]
|
||||
set_properity PACKAGE_PIN K3 [get_ports ddr3_dq[2]]
|
||||
set_properity PACKAGE_PIN L6 [get_ports ddr3_dq[3]]
|
||||
set_properity PACKAGE_PIN M3 [get_ports ddr3_dq[4]]
|
||||
set_properity PACKAGE_PIN M1 [get_ports ddr3_dq[5]]
|
||||
set_properity PACKAGE_PIN L4 [get_ports ddr3_dq[6]]
|
||||
set_properity PACKAGE_PIN M2 [get_ports ddr3_dq[7]]
|
||||
set_properity PACKAGE_PIN V4 [get_ports ddr3_dq[8]]
|
||||
set_properity PACKAGE_PIN T5 [get_ports ddr3_dq[9]]
|
||||
set_properity PACKAGE_PIN U4 [get_ports ddr3_dq[10]]
|
||||
set_properity PACKAGE_PIN V5 [get_ports ddr3_dq[11]]
|
||||
set_properity PACKAGE_PIN V1 [get_ports ddr3_dq[12]]
|
||||
set_properity PACKAGE_PIN T3 [get_ports ddr3_dq[13]]
|
||||
set_properity PACKAGE_PIN U3 [get_ports ddr3_dq[14]]
|
||||
set_properity PACKAGE_PIN R3 [get_ports ddr3_dq[15]]
|
||||
set_properity PACKAGE_PIN L1 [get_ports ddr3_dm[0]]
|
||||
set_properity PACKAGE_PIN U1 [get_ports ddr3_dm[1]]
|
||||
set_properity PACKAGE_PIN N2 [get_ports ddr3_dqs_p[0]]
|
||||
set_properity PACKAGE_PIN N1 [get_ports ddr3_dqs_n[0]]
|
||||
set_properity PACKAGE_PIN U2 [get_ports ddr3_dqs_p[1]]
|
||||
set_properity PACKAGE_PIN V2 [get_ports ddr3_dqs_n[1]]
|
||||
set_properity PACKAGE_PIN T8 [get_ports ddr3_addr[13]]
|
||||
set_properity PACKAGE_PIN T6 [get_ports ddr3_addr[12]]
|
||||
set_properity PACKAGE_PIN U6 [get_ports ddr3_addr[11]]
|
||||
set_properity PACKAGE_PIN R6 [get_ports ddr3_addr[10]]
|
||||
set_properity PACKAGE_PIN V7 [get_ports ddr3_addr[9]]
|
||||
set_properity PACKAGE_PIN R8 [get_ports ddr3_addr[8]]
|
||||
set_properity PACKAGE_PIN U7 [get_ports ddr3_addr[7]]
|
||||
set_properity PACKAGE_PIN V6 [get_ports ddr3_addr[6]]
|
||||
set_properity PACKAGE_PIN R7 [get_ports ddr3_addr[5]]
|
||||
set_properity PACKAGE_PIN N6 [get_ports ddr3_addr[4]]
|
||||
set_properity PACKAGE_PIN T1 [get_ports ddr3_addr[3]]
|
||||
set_properity PACKAGE_PIN N4 [get_ports ddr3_addr[2]]
|
||||
set_properity PACKAGE_PIN M6 [get_ports ddr3_addr[1]]
|
||||
set_properity PACKAGE_PIN R2 [get_ports ddr3_addr[0]]
|
||||
set_properity PACKAGE_PIN P2 [get_ports ddr3_ba[2]]
|
||||
set_properity PACKAGE_PIN P4 [get_ports ddr3_ba[1]]
|
||||
set_properity PACKAGE_PIN R1 [get_ports ddr3_ba[0]]
|
||||
set_properity PACKAGE_PIN U9 [get_ports ddr3_ck_p[0]]
|
||||
set_properity PACKAGE_PIN V9 [get_ports ddr3_ck_n[0]]
|
||||
set_properity PACKAGE_PIN P3 [get_ports ddr3_ras_n]
|
||||
set_properity PACKAGE_PIN M4 [get_ports ddr3_cas_n]
|
||||
set_properity PACKAGE_PIN P5 [get_ports ddr3_we_n]
|
||||
set_properity PACKAGE_PIN K6 [get_ports ddr3_reset_n]
|
||||
set_properity PACKAGE_PIN N5 [get_ports ddr3_cke[0]]
|
||||
set_properity PACKAGE_PIN R5 [get_ports ddr3_odt[0]]
|
||||
set_properity PACKAGE_PIN U8 [get_ports ddr3_cs_n[0]]
|
||||
set_property PACKAGE_PIN K5 [get_ports ddr3_dq[0]]
|
||||
set_property PACKAGE_PIN L3 [get_ports ddr3_dq[1]]
|
||||
set_property PACKAGE_PIN K3 [get_ports ddr3_dq[2]]
|
||||
set_property PACKAGE_PIN L6 [get_ports ddr3_dq[3]]
|
||||
set_property PACKAGE_PIN M3 [get_ports ddr3_dq[4]]
|
||||
set_property PACKAGE_PIN M1 [get_ports ddr3_dq[5]]
|
||||
set_property PACKAGE_PIN L4 [get_ports ddr3_dq[6]]
|
||||
set_property PACKAGE_PIN M2 [get_ports ddr3_dq[7]]
|
||||
set_property PACKAGE_PIN V4 [get_ports ddr3_dq[8]]
|
||||
set_property PACKAGE_PIN T5 [get_ports ddr3_dq[9]]
|
||||
set_property PACKAGE_PIN U4 [get_ports ddr3_dq[10]]
|
||||
set_property PACKAGE_PIN V5 [get_ports ddr3_dq[11]]
|
||||
set_property PACKAGE_PIN V1 [get_ports ddr3_dq[12]]
|
||||
set_property PACKAGE_PIN T3 [get_ports ddr3_dq[13]]
|
||||
set_property PACKAGE_PIN U3 [get_ports ddr3_dq[14]]
|
||||
set_property PACKAGE_PIN R3 [get_ports ddr3_dq[15]]
|
||||
set_property PACKAGE_PIN L1 [get_ports ddr3_dm[0]]
|
||||
set_property PACKAGE_PIN U1 [get_ports ddr3_dm[1]]
|
||||
set_property PACKAGE_PIN N2 [get_ports ddr3_dqs_p[0]]
|
||||
set_property PACKAGE_PIN N1 [get_ports ddr3_dqs_n[0]]
|
||||
set_property PACKAGE_PIN U2 [get_ports ddr3_dqs_p[1]]
|
||||
set_property PACKAGE_PIN V2 [get_ports ddr3_dqs_n[1]]
|
||||
set_property PACKAGE_PIN T8 [get_ports ddr3_addr[13]]
|
||||
set_property PACKAGE_PIN T6 [get_ports ddr3_addr[12]]
|
||||
set_property PACKAGE_PIN U6 [get_ports ddr3_addr[11]]
|
||||
set_property PACKAGE_PIN R6 [get_ports ddr3_addr[10]]
|
||||
set_property PACKAGE_PIN V7 [get_ports ddr3_addr[9]]
|
||||
set_property PACKAGE_PIN R8 [get_ports ddr3_addr[8]]
|
||||
set_property PACKAGE_PIN U7 [get_ports ddr3_addr[7]]
|
||||
set_property PACKAGE_PIN V6 [get_ports ddr3_addr[6]]
|
||||
set_property PACKAGE_PIN R7 [get_ports ddr3_addr[5]]
|
||||
set_property PACKAGE_PIN N6 [get_ports ddr3_addr[4]]
|
||||
set_property PACKAGE_PIN T1 [get_ports ddr3_addr[3]]
|
||||
set_property PACKAGE_PIN N4 [get_ports ddr3_addr[2]]
|
||||
set_property PACKAGE_PIN M6 [get_ports ddr3_addr[1]]
|
||||
set_property PACKAGE_PIN R2 [get_ports ddr3_addr[0]]
|
||||
set_property PACKAGE_PIN P2 [get_ports ddr3_ba[2]]
|
||||
set_property PACKAGE_PIN P4 [get_ports ddr3_ba[1]]
|
||||
set_property PACKAGE_PIN R1 [get_ports ddr3_ba[0]]
|
||||
set_property PACKAGE_PIN U9 [get_ports ddr3_ck_p[0]]
|
||||
set_property PACKAGE_PIN V9 [get_ports ddr3_ck_n[0]]
|
||||
set_property PACKAGE_PIN P3 [get_ports ddr3_ras_n]
|
||||
set_property PACKAGE_PIN M4 [get_ports ddr3_cas_n]
|
||||
set_property PACKAGE_PIN P5 [get_ports ddr3_we_n]
|
||||
set_property PACKAGE_PIN K6 [get_ports ddr3_reset_n]
|
||||
set_property PACKAGE_PIN N5 [get_ports ddr3_cke[0]]
|
||||
set_property PACKAGE_PIN R5 [get_ports ddr3_odt[0]]
|
||||
set_property PACKAGE_PIN U8 [get_ports ddr3_cs_n[0]]
|
||||
|
||||
|
||||
create_clock -period 40.000 -name VIRTUAL_clk_out3_mmcm -waveform {0.000 20.000}
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports SDCCD]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCCD]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports SDCIn]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCIn]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports SDCWP]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCWP]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports UARTSin]
|
||||
set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports UARTSin]
|
||||
create_clock -period 12.000 -name VIRTUAL_clk_pll_i -waveform {0.000 6.000}
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports SDCCLK]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 0.000 [get_ports SDCCLK]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports SDCCS]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCCS]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports SDCCmd]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCCmd]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports UARTSout]
|
||||
set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports UARTSout]
|
||||
#create_clock -period 50.000 -name VIRTUAL_clk_out3_mmcm -waveform {0.000 25.000}
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports {GPI[*]}]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports {GPI[*]}]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports SDCCD]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCCD]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports SDCIn]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCIn]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports SDCWP]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCWP]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 10.000 [get_ports UARTSin]
|
||||
#set_input_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports UARTSin]
|
||||
#create_clock -period 12.000 -name VIRTUAL_clk_pll_i -waveform {0.000 6.000}
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports {GPO[*]}]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports SDCCLK]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 0.000 [get_ports SDCCLK]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports SDCCS]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCCS]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports SDCCmd]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports SDCCmd]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -min -add_delay 0.000 [get_ports UARTSout]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_out3_mmcm] -max -add_delay 10.000 [get_ports UARTSout]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_pll_i] -min -add_delay 0.000 [get_ports ddr3_reset_n]
|
||||
#set_output_delay -clock [get_clocks VIRTUAL_clk_pll_i] -max -add_delay 80.000 [get_ports ddr3_reset_n]
|
||||
|
@ -1,3 +1,32 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spi.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Header file for interfaceing with the SPI peripheral
|
||||
//
|
||||
//
|
||||
//
|
||||
// A component of the 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.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#ifndef SPI_HEADER
|
||||
#define SPI_HEADER
|
||||
|
@ -1,33 +1,46 @@
|
||||
# wally-batch.do
|
||||
# wally.do
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
# Usage: do wally-batch.do <config> <testcases> <testbench> [--ccov] [--fcov] [+acc] [any number of +value] [any number of -G VAR=VAL]
|
||||
# Example: do wally-batch.do rv64gc arch64i testbench
|
||||
# Usage: do wally.do <config> <testcases> <testbench> [--ccov] [--fcov] [+acc] [--args "any number of +value"] [--params "any number of VAR=VAL parameter overrides"]
|
||||
# Example: do wally.do rv64gc arch64i testbench
|
||||
|
||||
# Use this wally-batch.do file to run this example.
|
||||
# Use this wally.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-batch.do
|
||||
# do wally.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-batch.do -c
|
||||
# vsim -do wally.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
set DEBUG 1
|
||||
# lcheck - return 1 if value is in list and remove it from list
|
||||
proc lcheck {listVariable value} {
|
||||
upvar 1 $listVariable list
|
||||
set index [lsearch -exact $list $value]
|
||||
if {$index >= 0} {
|
||||
set list [lreplace $list $index $index]
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
set DEBUG 1
|
||||
onbreak {resume}
|
||||
onerror {quit -f}
|
||||
|
||||
# Initialize variables
|
||||
set CFG ${1}
|
||||
set TESTSUITE ${2}
|
||||
set TESTBENCH ${3}
|
||||
set WKDIR wkdir/${CFG}_${TESTSUITE}
|
||||
set WALLY $::env(WALLY)
|
||||
set IMPERAS_HOME $::env(IMPERAS_HOME)
|
||||
set CONFIG ${WALLY}/config
|
||||
set SRC ${WALLY}/src
|
||||
set TB ${WALLY}/testbench
|
||||
@ -38,10 +51,12 @@ if [file exists ${WKDIR}] {
|
||||
vdel -lib ${WKDIR} -all
|
||||
}
|
||||
vlib ${WKDIR}
|
||||
# Create directory for coverage data
|
||||
mkdir -p cov
|
||||
# Create directory for functional coverage data
|
||||
mkdir -p ${WALLY}/addins/cvw-arch-verif/work
|
||||
mkdir -p ${FCRVVI}
|
||||
|
||||
set PlusArgs ""
|
||||
set ParamArgs ""
|
||||
set ExpandedParamArgs {}
|
||||
|
||||
set ccov 0
|
||||
set CoverageVoptArg ""
|
||||
@ -51,47 +66,26 @@ set FuncCovRVVI 0
|
||||
set FCdefineRVVI_COVERAGE ""
|
||||
|
||||
set FunctCoverage 0
|
||||
set riscvISACOVsrc ""
|
||||
set FCdefineINCLUDE_TRACE2COV ""
|
||||
set FCdefineCOVER_BASE_RV64I ""
|
||||
set FCdefineCOVER_LEVEL_DV_PR_EXT ""
|
||||
set FCdefineCOVER_RV64I ""
|
||||
set FCdefineCOVER_RV64M ""
|
||||
set FCdefineCOVER_RV64A ""
|
||||
set FCdefineCOVER_RV64F ""
|
||||
set FCdefineCOVER_RV64D ""
|
||||
set FCdefineCOVER_RV64ZICSR ""
|
||||
set FCdefineCOVER_RV64C ""
|
||||
set FCdefineIDV_INCLUDE_TRACE2COV ""
|
||||
set FCTRACE2COV ""
|
||||
set FCdefineIDV_TRACE2COV ""
|
||||
set FCvlog ""
|
||||
set FCvopt ""
|
||||
set FCdefineCOVER_EXTS {}
|
||||
|
||||
set lockstep 0
|
||||
# ok this is annoying. vlog, vopt, and vsim are very picky about how arguments are passed.
|
||||
# unforunately it won't allow these to be grouped as one argument per command so they are broken
|
||||
# apart.
|
||||
set lockstepvoptstring ""
|
||||
set lockstepvlog ""
|
||||
set SVLib ""
|
||||
set SVLibPath ""
|
||||
set OtherFlags ""
|
||||
set ImperasPubInc ""
|
||||
set ImperasPrivInc ""
|
||||
set rvviFiles ""
|
||||
set idvFiles ""
|
||||
|
||||
set GUI 0
|
||||
set accFlag ""
|
||||
|
||||
# Need to be able to pass arguments to vopt. Unforunately argv does not work because
|
||||
# it takes on different values if vsim and the do file are called from the command line or
|
||||
# if the do file isd called from questa sim directly. This chunk of code uses the $4 through $n
|
||||
# if the do file is called from questa sim directly. This chunk of code uses the $4 through $n
|
||||
# variables and compacts into a single list for passing to vopt.
|
||||
set tbArgs ""
|
||||
set from 4
|
||||
set step 1
|
||||
set lst {}
|
||||
|
||||
set PlusArgs {}
|
||||
set ParamArgs {}
|
||||
for {set i 0} true {incr i} {
|
||||
set x [expr {$i*$step + $from}]
|
||||
if {$x > $argc} break
|
||||
@ -103,84 +97,96 @@ echo "number of args = $argc"
|
||||
echo "lst = $lst"
|
||||
|
||||
# if +acc found set flag and remove from list
|
||||
set AccIndex [lsearch -exact $lst "+acc"]
|
||||
if {$AccIndex >= 0} {
|
||||
if {[lcheck lst "+acc"]} {
|
||||
set GUI 1
|
||||
set accFlag "+acc"
|
||||
set lst [lreplace $lst $AccIndex $AccIndex]
|
||||
}
|
||||
|
||||
# if +coverage found set flag and remove from list
|
||||
set CoverageIndex [lsearch -exact $lst "--ccov"]
|
||||
if {$CoverageIndex >= 0} {
|
||||
# if --ccov found set flag and remove from list
|
||||
if {[lcheck lst "--ccov"]} {
|
||||
set ccov 1
|
||||
set CoverageVoptArg "+cover=sbecf"
|
||||
set CoverageVsimArg "-coverage"
|
||||
set lst [lreplace $lst $CoverageIndex $CoverageIndex]
|
||||
}
|
||||
|
||||
set FCoverageIndexRVVI [lsearch -exact $lst "--fcovrvvi"]
|
||||
if {$FCoverageIndexRVVI >= 0} {
|
||||
# if --fcovrvvi found set flag and remove from list
|
||||
if {[lcheck lst "--fcovrvvi"]} {
|
||||
set FuncCovRVVI 1
|
||||
set FCdefineRVVI_COVERAGE "+define+RVVI_COVERAGE"
|
||||
set lst [lreplace $lst $FCoverageIndexRVVI $FCoverageIndexRVVI]
|
||||
}
|
||||
|
||||
# if +coverage found set flag and remove from list
|
||||
set FunctCoverageIndex [lsearch -exact $lst "--fcov"]
|
||||
if {$FunctCoverageIndex >= 0} {
|
||||
# if --fcov found set flag and remove from list
|
||||
if {[lcheck lst "--fcov"]} {
|
||||
set FunctCoverage 1
|
||||
set riscvISACOVsrc +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source
|
||||
|
||||
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"
|
||||
set FCvlog "+define+INCLUDE_TRACE2COV \
|
||||
+define+IDV_INCLUDE_TRACE2COV \
|
||||
+define+COVER_BASE_RV64I \
|
||||
+define+COVER_LEVEL_DV_PR_EXT \
|
||||
+incdir+${IMPERAS_HOME}/ImpProprietary/source/host/riscvISACOV/source"
|
||||
set FCvopt "+TRACE2COV_ENABLE=1 +IDV_TRACE2COV=1"
|
||||
# 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 FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV"
|
||||
set FCTRACE2COV "+TRACE2COV_ENABLE=1"
|
||||
set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1"
|
||||
set lst [lreplace $lst $FunctCoverageIndex $FunctCoverageIndex]
|
||||
}\
|
||||
|
||||
set LockStepIndex [lsearch -exact $lst "--lockstep"]
|
||||
# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running
|
||||
# functional coverage and imply it.
|
||||
if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0} {
|
||||
lappend FCdefineCOVER_EXTS "+define+COVER_RV64I"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64M"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64A"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64F"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64D"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64ZICSR"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64C"
|
||||
|
||||
}
|
||||
|
||||
# if --fcov2 found set flag and remove from list
|
||||
if {[lcheck lst "--fcov2"]} {
|
||||
set FunctCoverage 1
|
||||
set FCvlog "+define+INCLUDE_TRACE2COV \
|
||||
+define+IDV_INCLUDE_TRACE2COV \
|
||||
+define+COVER_BASE_RV32I \
|
||||
+define+COVER_LEVEL_DV_PR_EXT \
|
||||
+incdir+$env(WALLY)/addins/riscvISACOV/source \
|
||||
+incdir+$env(WALLY)/addins/cvw-arch-verif/fcov/RV32"
|
||||
set FCvopt "+TRACE2COV_ENABLE=1 +IDV_TRACE2COV=1"
|
||||
# Uncomment various cover statements below to control which extensions get functional coverage
|
||||
lappend FCdefineCOVER_EXTS "+define+COVER_RV32I"
|
||||
lappend FCdefineCOVER_EXTS "+define+COVER_RV32M"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64M"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64A"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64F"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64D"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64ZICSR"
|
||||
#lappend FCdefineCOVER_EXTS "+define+COVER_RV64C"
|
||||
}
|
||||
|
||||
# if --lockstep or --fcov found set flag and remove from list
|
||||
if {[lcheck lst "--lockstep"] || $FunctCoverage == 1} {
|
||||
set lockstep 1
|
||||
|
||||
# ideally this would all be one or two variables, but questa is having a real hard time
|
||||
# with this. For now they have to be separate.
|
||||
set lockstepvoptstring "+define+USE_IMPERAS_DV"
|
||||
set ImperasPubInc +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host
|
||||
set ImperasPrivInc +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host
|
||||
set rvviFiles $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/*.sv
|
||||
set idvFiles $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/*.sv
|
||||
set SVLib "-sv_lib"
|
||||
set SVLibPath $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model
|
||||
set lockstepvlog "+define+USE_IMPERAS_DV \
|
||||
+incdir+${IMPERAS_HOME}/ImpPublic/include/host \
|
||||
+incdir+${IMPERAS_HOME}/ImpProprietary/include/host \
|
||||
${IMPERAS_HOME}/ImpPublic/source/host/rvvi/*.sv \
|
||||
${IMPERAS_HOME}/ImpProprietary/source/host/idv/*.sv"
|
||||
set SVLib "-sv_lib ${IMPERAS_HOME}/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model"
|
||||
#set OtherFlags $::env(OTHERFLAGS) # not working 7/15/24 dh; this should be the way to pass things like --verbose (Issue 871)
|
||||
|
||||
if {$LockStepIndex >= 0} {
|
||||
set lst [lreplace $lst $LockStepIndex $LockStepIndex]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# separate the +args from the -G parameters
|
||||
foreach otherArg $lst {
|
||||
if {[string index $otherArg 0] eq "+"} {
|
||||
lappend PlusArgs $otherArg
|
||||
} else {
|
||||
lappend ParamArgs $otherArg
|
||||
}
|
||||
# Set PlusArgs passed using the --args flag
|
||||
set PlusArgsIndex [lsearch -exact $lst "--args"]
|
||||
if {$PlusArgsIndex >= 0} {
|
||||
set PlusArgs [lindex $lst [expr {$PlusArgsIndex + 1}]]
|
||||
set lst [lreplace $lst $PlusArgsIndex [expr {$PlusArgsIndex + 1}]]
|
||||
}
|
||||
|
||||
# Set ParamArgs passed using the --params flag and expand into a list of -G<param> arguments
|
||||
set ParamArgsIndex [lsearch -exact $lst "--params"]
|
||||
if {$ParamArgsIndex >= 0} {
|
||||
set ParamArgs [lindex $lst [expr {$ParamArgsIndex + 1}]]
|
||||
set ParamArgs [regexp -all -inline {\S+} $ParamArgs]
|
||||
foreach param $ParamArgs {
|
||||
lappend ExpandedParamArgs -G$param
|
||||
}
|
||||
set lst [lreplace $lst $ParamArgsIndex [expr {$ParamArgsIndex + 1}]]
|
||||
}
|
||||
|
||||
# Debug print statements
|
||||
if {$DEBUG > 0} {
|
||||
echo "GUI = $GUI"
|
||||
echo "ccov = $ccov"
|
||||
@ -189,41 +195,27 @@ if {$DEBUG > 0} {
|
||||
echo "FunctCoverage = $FunctCoverage"
|
||||
echo "remaining list = $lst"
|
||||
echo "Extra +args = $PlusArgs"
|
||||
echo "Extra -args = $ParamArgs"
|
||||
echo "Extra -args = $ExpandedParamArgs"
|
||||
}
|
||||
|
||||
foreach x $PlusArgs {
|
||||
echo "Element is $x"
|
||||
}
|
||||
|
||||
# need a better solution this is really ugly
|
||||
# Questa really don't like passing $PlusArgs on the command line to vsim. It treats the whole things
|
||||
# as one string rather than mutliple separate +args. Is there an automated way to pass these?
|
||||
set temp0 [lindex $PlusArgs 0]
|
||||
set temp1 [lindex $PlusArgs 1]
|
||||
set temp2 [lindex $PlusArgs 2]
|
||||
set temp3 [lindex $PlusArgs 3]
|
||||
|
||||
#quit
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
vlog -lint +nowarnRDGN -suppress 2244 -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} ${FCdefineRVVI_COVERAGE} ${idvFiles} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv +incdir+${FCRVVI}/common +incdir+${FCRVVI} ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv -suppress 2244 -suppress 2282 -suppress 2583 -suppress 7063,2596,13286
|
||||
set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI}/common +incdir+${FCRVVI}"
|
||||
set SOURCES "${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv"
|
||||
vlog -lint +nowarnRDGN -work ${WKDIR} {*}${INC_DIRS} {*}${FCvlog} {*}${FCdefineCOVER_EXTS} {*}${lockstepvlog} ${FCdefineRVVI_COVERAGE} {*}${SOURCES} -suppress 2244 -suppress 2282 -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
|
||||
vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} ${ParamArgs} -o testbenchopt ${CoverageVoptArg}
|
||||
vopt $accFlag wkdir/${CFG}_${TESTSUITE}.${TESTBENCH} -work ${WKDIR} {*}${ExpandedParamArgs} -o testbenchopt ${CoverageVoptArg}
|
||||
|
||||
#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg}
|
||||
#vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} ${PlusArgs} -fatal 7 ${SVLib} ${SVLibPath} +IDV_TRACE2COV=1 +TRACE2COV_ENABLE=1 -suppress 3829 ${CoverageVsimArg}
|
||||
vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} $temp0 $temp1 $temp2 $temp3 -fatal 7 ${SVLib} ${SVLibPath} ${OtherFlags} ${FCTRACE2COV} ${FCdefineIDV_TRACE2COV} -suppress 3829 ${CoverageVsimArg}
|
||||
vsim -lib ${WKDIR} testbenchopt +TEST=${TESTSUITE} {*}${PlusArgs} -fatal 7 {*}${SVLib} ${OtherFlags} {*}${FCvopt} -suppress 3829 ${CoverageVsimArg}
|
||||
|
||||
# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
|
||||
# power add generates the logging necessary for saif generation.
|
||||
# power add -r /dut/core/*
|
||||
|
||||
# add waveforms if GUI is enabled
|
||||
if { ${GUI} } {
|
||||
add log -recursive /*
|
||||
if { ${TESTBENCH} eq "testbench_fp" } {
|
||||
@ -265,4 +257,3 @@ if {$ccov} {
|
||||
if { ${GUI} == 0} {
|
||||
quit
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,9 @@
|
||||
## Written: lserafini@hmc.edu
|
||||
## Created: 11 April 2023
|
||||
## Modified: 12 April 2023
|
||||
## Modified: 10 August 2023, jcarlin@hmc.edu
|
||||
##
|
||||
## Purpose: Run the cache simulator on each rv64gc test suite in turn.
|
||||
## Purpose: Run the cache simulator on each rv64gc test suite in turn.
|
||||
##
|
||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
## https://github.com/openhwgroup/cvw
|
||||
@ -16,24 +17,24 @@
|
||||
##
|
||||
## 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
|
||||
## 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
|
||||
## 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.
|
||||
################################################################################################
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
# NOTE: make sure testbench.sv has the ICache and DCache loggers enabled!
|
||||
# This does not check the test output for correctness, run regression for that.
|
||||
# Add -p or --perf to report the hit/miss ratio.
|
||||
# Add -p or --perf to report the hit/miss ratio.
|
||||
# Add -d or --dist to report the distribution of loads, stores, and atomic ops.
|
||||
# These distributions may not add up to 100; this is because of flushes or invalidations.
|
||||
|
||||
@ -48,36 +49,46 @@ class bcolors:
|
||||
BOLD = '\033[1m'
|
||||
UNDERLINE = '\033[4m'
|
||||
|
||||
# tests64gc = ["coverage64gc", "arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m",
|
||||
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
|
||||
"arch64zi", "wally64a", "wally64periph", "wally64priv",
|
||||
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
|
||||
"imperas64f", "imperas64d", "imperas64c", "imperas64i"]
|
||||
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zcb",
|
||||
"arch64zifencei", "arch64zicond", "arch64a_amo", "wally64a_lrsc", "wally64periph", "wally64priv",
|
||||
"arch64zbkb", "arch64zbkc", "arch64zbkx", "arch64zknd", "arch64zkne", "arch64zknh",
|
||||
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"]
|
||||
# arch64i is the most interesting case. Uncomment line below to run just that case
|
||||
tests64gc = ["arch64i"]
|
||||
# tests64gc = ["arch64i"]
|
||||
|
||||
cachetypes = ["ICache", "DCache"]
|
||||
simdir = os.path.expanduser("~/cvw/sim")
|
||||
simdir = os.path.expandvars("$WALLY/sim")
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Runs the cache simulator on all rv64gc test suites")
|
||||
parser.add_argument('-p', "--perf", action='store_true', help="Report hit/miss ratio")
|
||||
parser.add_argument('-d', "--dist", action='store_true', help="Report distribution of operations")
|
||||
|
||||
parser.add_argument('-s', "--sim", help="Simulator", choices=["questa", "verilator", "vcs"], default="verilator")
|
||||
args = parser.parse_args()
|
||||
|
||||
testcmd = "vsim -do \"do wally-batch.do rv64gc {}\" -c > /dev/null"
|
||||
simargs = "I_CACHE_ADDR_LOGGER=1\\\'b1 D_CACHE_ADDR_LOGGER=1\\\'b1"
|
||||
testcmd = "wsim --sim " + args.sim + " rv64gc {} --params \"" + simargs + "\" > /dev/null"
|
||||
cachecmd = "CacheSim.py 64 4 56 44 -f {}"
|
||||
|
||||
mismatches = 0
|
||||
|
||||
if args.perf:
|
||||
cachecmd += " -p"
|
||||
if args.dist:
|
||||
cachecmd += " -d"
|
||||
|
||||
|
||||
for test in tests64gc:
|
||||
print(f"{bcolors.HEADER}Commencing test", test+f":{bcolors.ENDC}")
|
||||
# remove wkdir to force recompile with logging enabled
|
||||
os.system("rm -rf " + simdir + "/" + args.sim + "/wkdir/rv64gc_" + test)
|
||||
os.system("rm -rf " + simdir + "/" + args.sim + "/*Cache.log")
|
||||
print(testcmd.format(test))
|
||||
os.system(testcmd.format(test))
|
||||
for cache in cachetypes:
|
||||
print(f"{bcolors.OKCYAN}Running the", cache, f"simulator.{bcolors.ENDC}")
|
||||
os.system(cachecmd.format(cache+".log"))
|
||||
result = subprocess.run(cachecmd.format(args.sim+"/"+cache+".log"), shell=True)
|
||||
mismatches += result.returncode
|
||||
print()
|
||||
return mismatches
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
||||
|
@ -23,10 +23,12 @@ def runfindcmd(cmd):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("config", help="Configuration file")
|
||||
parser.add_argument("testsuite", help="Test suite (or none, when running a single ELF file) ")
|
||||
parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testbench_fp"], default="testbench")
|
||||
parser.add_argument("--elffile", "-e", help="ELF file name", default="")
|
||||
parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true")
|
||||
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
|
||||
parser.add_argument("--params", "-p", help="Optional top-level parameter overrides of the form param=value", default="")
|
||||
parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true")
|
||||
# GUI not yet implemented
|
||||
#parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true")
|
||||
@ -49,7 +51,8 @@ rtlsrc_cmd = "find " + srcdir + ' -name "*.sv" ! -path "' + srcdir + '/generic/m
|
||||
rtlsrc_files = runfindcmd(rtlsrc_cmd)
|
||||
tbcommon_cmd = 'find ' + tbdir+'/common -name "*.sv" ! -path "' + tbdir+'/common/wallyTracer.sv"'
|
||||
tbcommon_files = runfindcmd(tbcommon_cmd)
|
||||
RTL_FILES = tbdir+'/testbench.sv ' + str(rtlsrc_files) + ' ' + str(tbcommon_files)
|
||||
tb_file = tbdir + "/" + args.tb + ".sv"
|
||||
RTL_FILES = tb_file + ' ' + str(rtlsrc_files) + ' ' + str(tbcommon_files)
|
||||
|
||||
# Include directories
|
||||
INCLUDE_PATH="+incdir+" + cfgdir + "/" + args.config + " +incdir+" + cfgdir + "/deriv/" + args.config + " +incdir+" + cfgdir + "/shared +incdir+$WALLY/tests +incdir+" + tbdir + " +incdir+" + srcdir
|
||||
@ -68,10 +71,23 @@ if (args.coverage):
|
||||
else:
|
||||
COV_OPTIONS = ""
|
||||
|
||||
# Write parameter overrides to a file
|
||||
f = open(os.path.expandvars(wkdir) + "/param_overrides.txt", "w")
|
||||
for param in args.params.split():
|
||||
[param, value] = param.split("=")
|
||||
if "\\'" in value: # for bit values
|
||||
value = value.replace("\\'", "'")
|
||||
else: # for strings
|
||||
value = "\"" + value + "\""
|
||||
# print("param=" + param + " value=" + value)
|
||||
f.write("assign " + value + " " + args.tb + "/" + param + "\n")
|
||||
f.close()
|
||||
PARAM_OVERRIDES=" -parameters " + wkdir + "/param_overrides.txt "
|
||||
|
||||
# Simulation commands
|
||||
OUTPUT="sim_out"
|
||||
VCS_CMD="vcs +lint=all,noGCWM,noUI,noSVA-UA,noIDTS,noNS,noULCO,noCAWM-L,noWMIA-L,noSV-PIU,noSTASKW_CO,noSTASKW_CO1,noSTASKW_RMCOF -suppress +warn -sverilog +vc -Mupdate -line -full64 -lca -ntb_opts sensitive_dyn " + INCLUDE_PATH # Disabled Debug flags; add them back for a GUI mode -debug_access+all+reverse -kdb +vcs+vcdpluson
|
||||
VCS = VCS_CMD + " -Mdir=" + wkdir + " " + srcdir + "/cvw.sv " + LOCKSTEP_OPTIONS + " " + COV_OPTIONS + " " + RTL_FILES + " -o " + wkdir + "/" + OUTPUT + " -work " + wkdir + " -Mlib " + wkdir + " -l " + logdir + "/" + args.config + "_" + args.testsuite + ".log"
|
||||
VCS_CMD="vcs +lint=all,noGCWM,noUI,noSVA-UA,noIDTS,noNS,noULCO,noCAWM-L,noWMIA-L,noSV-PIU,noSTASKW_CO,noSTASKW_CO1,noSTASKW_RMCOF -suppress +warn -sverilog +vc -Mupdate -line -full64 -lca -ntb_opts sensitive_dyn " + "-top " + args.tb + PARAM_OVERRIDES + INCLUDE_PATH # Disabled Debug flags; add them back for a GUI mode -debug_access+all+reverse -kdb +vcs+vcdpluson
|
||||
VCS = VCS_CMD + " -Mdir=" + wkdir + " " + srcdir + "/cvw.sv " + LOCKSTEP_OPTIONS + " " + COV_OPTIONS + " " + RTL_FILES + " -o " + wkdir + "/" + OUTPUT + " -work " + wkdir + " -Mlib=" + wkdir + " -l " + logdir + "/" + args.config + "_" + args.testsuite + ".log"
|
||||
SIMV_CMD= wkdir + "/" + OUTPUT + " +TEST=" + args.testsuite + " " + args.elffile + " " + args.args + " -no_save " + LOCKSTEP_SIMV
|
||||
|
||||
# Run simulation
|
||||
@ -81,4 +97,3 @@ subprocess.run(SIMV_CMD, shell=True)
|
||||
if (args.coverage):
|
||||
COV_RUN = "urg -dir " + wkdir + "/coverage.vdb -format text -report IndividualCovReport/" + args.config + "_" + args.testsuite
|
||||
subprocess.run(COV_RUN, shell=True)
|
||||
|
||||
|
@ -7,12 +7,13 @@ SHELL := /bin/bash
|
||||
|
||||
# verilator configurations
|
||||
OPT=
|
||||
PARAMS?=-DVERILATOR=1 --no-trace-top
|
||||
PARAMS?=--no-trace-top
|
||||
NONPROF?=--stats
|
||||
VERILATOR_DIR=${WALLY}/sim/verilator
|
||||
SOURCE=${WALLY}/config/shared/*.vh ${WALLY}/config/${WALLYCONF} ${WALLY}/config/deriv/${WALLYCONF} ${WALLY}/src/cvw.sv ${WALLY}/testbench/*.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv
|
||||
EXTRA_ARGS=
|
||||
|
||||
PLUS_ARGS=
|
||||
PARAM_ARGS=
|
||||
EXPANDED_PARAM_ARGS:=$(patsubst %,-G%,$(PARAM_ARGS))
|
||||
|
||||
WALLYCONF?=rv64gc
|
||||
TEST?=arch64i
|
||||
@ -32,11 +33,9 @@ DEPENDENCIES=${WALLY}/config/shared/*.vh $(SOURCES)
|
||||
# regular testbench requires a wrapper defining getenvval
|
||||
ifeq ($(TESTBENCH), testbench)
|
||||
WRAPPER=${WALLY}/sim/verilator/wrapper.c
|
||||
GTEST=
|
||||
ARGTEST=+TEST=$(TEST)
|
||||
else
|
||||
WRAPPER=
|
||||
GTEST=-GTEST="\"${TEST}\""
|
||||
ARGTEST=
|
||||
endif
|
||||
|
||||
@ -44,7 +43,7 @@ default: run
|
||||
|
||||
run: wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH}
|
||||
mkdir -p $(VERILATOR_DIR)/logs
|
||||
wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} ${ARGTEST} $(EXTRA_ARGS)
|
||||
wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} ${ARGTEST} $(PLUS_ARGS)
|
||||
|
||||
profile: obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF)
|
||||
$(VERILATOR_DIR)/obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) ${ARGTEST}
|
||||
@ -64,7 +63,7 @@ wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH}: $(DEPENDENCIES)
|
||||
--top-module ${TESTBENCH} --relative-includes \
|
||||
$(INCLUDE_PATH) \
|
||||
${WRAPPER} \
|
||||
${GTEST} \
|
||||
${EXPANDED_PARAM_ARGS} \
|
||||
$(SOURCES)
|
||||
|
||||
obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES)
|
||||
@ -76,7 +75,7 @@ obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES)
|
||||
--top-module ${TESTBENCH} --relative-includes \
|
||||
$(INCLUDE_PATH) \
|
||||
${WRAPPER} \
|
||||
${GTEST} \
|
||||
${EXPANDED_PARAM_ARGS} \
|
||||
$(SOURCES)
|
||||
|
||||
clean:
|
||||
|
@ -169,12 +169,17 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
|
||||
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
|
||||
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
||||
CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW;
|
||||
CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[P.XLEN-1:0];
|
||||
// user CSRs
|
||||
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
|
||||
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
|
||||
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
|
||||
|
||||
if (P.XLEN == 32) begin
|
||||
CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrsr.MSTATUSH_REGW;
|
||||
CSRArray[12'h31A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFGH_REGW;
|
||||
CSRArray[12'h15D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[63:32];
|
||||
end
|
||||
end else begin // hold the old value if the pipeline is stalled.
|
||||
|
||||
// PMP CFG 3A0 to 3AF
|
||||
|
@ -762,7 +762,7 @@ end
|
||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
|
||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
|
||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GCK"));
|
||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56));
|
||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, XLEN==64 ? 56 : 34));
|
||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
|
||||
|
||||
if(elffilename == "buildroot") filename = "";
|
||||
@ -824,15 +824,25 @@ end
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
|
||||
|
||||
if (P.XLEN == 32) begin
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC81)); // TIMEH
|
||||
end
|
||||
// User HPMCOUNTER3 - HPMCOUNTER31
|
||||
for (iter='hC03; iter<='hC1F; iter++) begin
|
||||
void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx
|
||||
if (P.XLEN == 32)
|
||||
void'(rvviRefCsrSetVolatile(0, iter+128)); // HPMCOUNTERxH
|
||||
end
|
||||
|
||||
// Machine MHPMCOUNTER3 - MHPMCOUNTER31
|
||||
for (iter='hB03; iter<='hB1F; iter++) begin
|
||||
void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx
|
||||
if (P.XLEN == 32)
|
||||
void'(rvviRefCsrSetVolatile(0, iter+128)); // MHPMCOUNTERxH
|
||||
end
|
||||
|
||||
// cannot predict this register due to latency between
|
||||
|
@ -637,7 +637,11 @@ module testbench_fp;
|
||||
// check if nothing is being tested
|
||||
if (Tests.size() == 0) begin
|
||||
$display("TEST %s not supported in this configuration", TEST);
|
||||
$stop;
|
||||
`ifdef QUESTA
|
||||
$stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug
|
||||
`else
|
||||
$finish;
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
||||
@ -987,7 +991,11 @@ module testbench_fp;
|
||||
X[P.FLEN-1:0], Y[P.FLEN-1:0], Z[P.FLEN-1:0], SrcA, Res[P.FLEN-1:0], ResFlg, Ans[P.FLEN-1:0], AnsFlg);
|
||||
//$display(" fma.Xs %h Xe %h Xm %h Ys %h Ye %h Ym %h Ss %h Se %h Sm %h", fma.Xs, fma.Xe, fma.Xm, fma.Ys, fma.Ye, fma.Ym, fma.Ss, fma.Se, fma.Sm);
|
||||
//$display(" readvectors.unpack.X %h Xs %h Xe %h Xm %h", readvectors.unpack.X, readvectors.unpack.Xs, readvectors.unpack.Xe, readvectors.unpack.Xm);
|
||||
$stop;
|
||||
`ifdef QUESTA
|
||||
$stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug
|
||||
`else
|
||||
$finish;
|
||||
`endif
|
||||
end
|
||||
|
||||
if (TestVectors[VectorNum] == '1 & Tests[TestNum] !== "") begin // if reached the eof
|
||||
@ -1013,7 +1021,11 @@ module testbench_fp;
|
||||
// if no more Tests - finish
|
||||
if (Tests[TestNum] === "") begin
|
||||
$display("\nAll Tests completed with %d errors\n", errors);
|
||||
$stop;
|
||||
`ifdef QUESTA
|
||||
$stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug
|
||||
`else
|
||||
$finish;
|
||||
`endif
|
||||
end
|
||||
$display("Running %s vectors", Tests[TestNum]);
|
||||
end
|
||||
|
112
tests/custom/spitest/Makefile
Normal file
112
tests/custom/spitest/Makefile
Normal file
@ -0,0 +1,112 @@
|
||||
CEXT := c
|
||||
CPPEXT := cpp
|
||||
AEXT := s
|
||||
SEXT := S
|
||||
SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\)
|
||||
OBJEXT := o
|
||||
DEPEXT := d
|
||||
SRCDIR := .
|
||||
BUILDDIR := OBJ
|
||||
|
||||
SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort)
|
||||
OBJECTS := $(SOURCES:.$(CEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(OBJECTS:.$(AEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(OBJECTS:.$(SEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS))
|
||||
|
||||
TARGETDIR := bin
|
||||
TARGET := $(TARGETDIR)/spitest.elf
|
||||
ROOT := ..
|
||||
LIBRARY_DIRS :=
|
||||
LIBRARY_FILES :=
|
||||
|
||||
MARCH :=-march=rv64imfdc
|
||||
MABI :=-mabi=lp64d
|
||||
LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles
|
||||
LINKER :=$(ROOT)/linker8000-0000.x
|
||||
|
||||
|
||||
AFLAGS =$(MARCH) $(MABI) -W
|
||||
CFLAGS =$(MARCH) $(MABI) -mcmodel=medany -O2
|
||||
AS=riscv64-unknown-elf-as
|
||||
CC=riscv64-unknown-elf-gcc
|
||||
AR=riscv64-unknown-elf-ar
|
||||
|
||||
|
||||
#Default Make
|
||||
all: directories $(TARGET).memfile
|
||||
|
||||
#Remake
|
||||
remake: clean all
|
||||
|
||||
#Make the Directories
|
||||
directories:
|
||||
@mkdir -p $(TARGETDIR)
|
||||
@mkdir -p $(BUILDDIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump
|
||||
|
||||
|
||||
#Needed for building additional library projects
|
||||
ifdef LIBRARY_DIRS
|
||||
LIBS+=${LIBRARY_DIRS:%=-L%} ${LIBRARY_FILES:%=-l%}
|
||||
INC+=${LIBRARY_DIRS:%=-I%}
|
||||
|
||||
${LIBRARY_DIRS}:
|
||||
make -C $@ -j 1
|
||||
|
||||
.PHONY: $(LIBRARY_DIRS) $(TARGET)
|
||||
endif
|
||||
|
||||
|
||||
#Pull in dependency info for *existing* .o files
|
||||
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
|
||||
|
||||
#Link
|
||||
$(TARGET): $(OBJECTS) $(LIBRARY_DIRS)
|
||||
$(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER}
|
||||
|
||||
|
||||
#Compile
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
|
||||
# gcc won't output dependencies for assembly files for some reason
|
||||
# most asm files don't have dependencies so the echo will work for now.
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
|
||||
# C++
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
|
||||
# convert to hex
|
||||
$(TARGET).memfile: $(TARGET)
|
||||
@echo 'Making object dump file.'
|
||||
@riscv64-unknown-elf-objdump -D $< > $<.objdump
|
||||
@echo 'Making memory file'
|
||||
riscv64-unknown-elf-elf2hex --bit-width 64 --input $^ --output $@
|
||||
extractFunctionRadix.sh $<.objdump
|
||||
mkdir -p ../work/
|
||||
cp -f $(TARGETDIR)/* ../work/
|
116
tests/custom/spitest/spi.h
Normal file
116
tests/custom/spitest/spi.h
Normal file
@ -0,0 +1,116 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spi.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Header file for interfaceing with the SPI peripheral
|
||||
//
|
||||
//
|
||||
//
|
||||
// A component of the 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.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#ifndef SPI_HEADER
|
||||
#define SPI_HEADER
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SPI_BASE 0x13000 /* Base address of SPI device used for SDC */
|
||||
|
||||
/* register offsets */
|
||||
#define SPI_SCKDIV SPI_BASE + 0x00 /* Serial clock divisor */
|
||||
#define SPI_SCKMODE SPI_BASE + 0x04 /* Serial clock mode */
|
||||
#define SPI_CSID SPI_BASE + 0x10 /* Chip select ID */
|
||||
#define SPI_CSDEF SPI_BASE + 0x14 /* Chip select default */
|
||||
#define SPI_CSMODE SPI_BASE + 0x18 /* Chip select mode */
|
||||
#define SPI_DELAY0 SPI_BASE + 0x28 /* Delay control 0 */
|
||||
#define SPI_DELAY1 SPI_BASE + 0x2c /* Delay control 1 */
|
||||
#define SPI_FMT SPI_BASE + 0x40 /* Frame format */
|
||||
#define SPI_TXDATA SPI_BASE + 0x48 /* Tx FIFO data */
|
||||
#define SPI_RXDATA SPI_BASE + 0x4c /* Rx FIFO data */
|
||||
#define SPI_TXMARK SPI_BASE + 0x50 /* Tx FIFO [<35;39;29Mwatermark */
|
||||
#define SPI_RXMARK SPI_BASE + 0x54 /* Rx FIFO watermark */
|
||||
|
||||
/* Non-implemented
|
||||
#define SPI_FCTRL SPI_BASE + 0x60 // SPI flash interface control
|
||||
#define SPI_FFMT SPI_BASE + 0x64 // SPI flash instruction format
|
||||
*/
|
||||
#define SPI_IE SPI_BASE + 0x70 /* Interrupt Enable Register */
|
||||
#define SPI_IP SPI_BASE + 0x74 /* Interrupt Pendings Register */
|
||||
|
||||
/* delay0 bits */
|
||||
#define SIFIVE_SPI_DELAY0_CSSCK(x) ((uint32_t)(x))
|
||||
#define SIFIVE_SPI_DELAY0_CSSCK_MASK 0xffU
|
||||
#define SIFIVE_SPI_DELAY0_SCKCS(x) ((uint32_t)(x) << 16)
|
||||
#define SIFIVE_SPI_DELAY0_SCKCS_MASK (0xffU << 16)
|
||||
|
||||
/* delay1 bits */
|
||||
#define SIFIVE_SPI_DELAY1_INTERCS(x) ((uint32_t)(x))
|
||||
#define SIFIVE_SPI_DELAY1_INTERCS_MASK 0xffU
|
||||
#define SIFIVE_SPI_DELAY1_INTERXFR(x) ((uint32_t)(x) << 16)
|
||||
#define SIFIVE_SPI_DELAY1_INTERXFR_MASK (0xffU << 16)
|
||||
|
||||
/* csmode bits */
|
||||
#define SIFIVE_SPI_CSMODE_MODE_AUTO 0U
|
||||
#define SIFIVE_SPI_CSMODE_MODE_HOLD 2U
|
||||
#define SIFIVE_SPI_CSMODE_MODE_OFF 3U
|
||||
|
||||
// inline void write_reg(uintptr_t addr, uint32_t value);
|
||||
//inline uint32_t read_reg(uintptr_t addr);
|
||||
//inline void spi_sendbyte(uint8_t byte);
|
||||
//inline void waittx();
|
||||
//inline void waitrx();
|
||||
uint8_t spi_txrx(uint8_t byte);
|
||||
uint8_t spi_dummy();
|
||||
//inline uint8_t spi_readbyte();
|
||||
//uint64_t spi_read64();
|
||||
void spi_init();
|
||||
void spi_set_clock(uint32_t clkin, uint32_t clkout);
|
||||
|
||||
static inline void write_reg(uintptr_t addr, uint32_t value) {
|
||||
volatile uint32_t * loc = (volatile uint32_t *) addr;
|
||||
*loc = value;
|
||||
}
|
||||
|
||||
// Read a register
|
||||
static inline uint32_t read_reg(uintptr_t addr) {
|
||||
return *(volatile uint32_t *) addr;
|
||||
}
|
||||
|
||||
// Queues a single byte in the transfer fifo
|
||||
static inline void spi_sendbyte(uint8_t byte) {
|
||||
// Write byte to transfer fifo
|
||||
write_reg(SPI_TXDATA, byte);
|
||||
}
|
||||
|
||||
static inline void waittx() {
|
||||
while(!(read_reg(SPI_IP) & 1)) {}
|
||||
}
|
||||
|
||||
static inline void waitrx() {
|
||||
while(read_reg(SPI_IP) & 2) {}
|
||||
}
|
||||
|
||||
static inline uint8_t spi_readbyte() {
|
||||
return read_reg(SPI_RXDATA);
|
||||
}
|
||||
|
||||
#endif
|
107
tests/custom/spitest/spitest.c
Normal file
107
tests/custom/spitest/spitest.c
Normal file
@ -0,0 +1,107 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spi.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 8/27/2024
|
||||
//
|
||||
// Purpose: C code to test SPI bugs
|
||||
//
|
||||
//
|
||||
//
|
||||
// A component of the 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.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "spi.h"
|
||||
|
||||
// Testing SPI peripheral in loopback mode
|
||||
// TODO: Need to make sure the configuration I'm using uses loopback
|
||||
// mode. This can be specified in derivlists.txt
|
||||
// TODO:
|
||||
|
||||
uint8_t spi_txrx(uint8_t byte) {
|
||||
spi_sendbyte(byte);
|
||||
waittx();
|
||||
return spi_readbyte();
|
||||
}
|
||||
|
||||
uint8_t spi_dummy() {
|
||||
return spi_txrx(0xff);
|
||||
}
|
||||
|
||||
void spi_set_clock(uint32_t clkin, uint32_t clkout) {
|
||||
uint32_t div = (clkin/(2*clkout)) - 1;
|
||||
write_reg(SPI_SCKDIV, div);
|
||||
}
|
||||
|
||||
// Initialize Sifive FU540 based SPI Controller
|
||||
void spi_init(uint32_t clkin) {
|
||||
// Enable interrupts
|
||||
write_reg(SPI_IE, 0x3);
|
||||
|
||||
// Set TXMARK to 1. If the number of entries is < 1
|
||||
// IP's txwm field will go high.
|
||||
// Set RXMARK to 0. If the number of entries is > 0
|
||||
// IP's rwxm field will go high.
|
||||
write_reg(SPI_TXMARK, 1);
|
||||
write_reg(SPI_RXMARK, 0);
|
||||
|
||||
// Set Delay 0 to default
|
||||
write_reg(SPI_DELAY0,
|
||||
SIFIVE_SPI_DELAY0_CSSCK(1) |
|
||||
SIFIVE_SPI_DELAY0_SCKCS(1));
|
||||
|
||||
// Set Delay 1 to default
|
||||
write_reg(SPI_DELAY1,
|
||||
SIFIVE_SPI_DELAY1_INTERCS(1) |
|
||||
SIFIVE_SPI_DELAY1_INTERXFR(0));
|
||||
|
||||
// Initialize the SPI controller clock to
|
||||
// div = (20MHz/(2*400kHz)) - 1 = 24 = 0x18
|
||||
write_reg(SPI_SCKDIV, 0x18);
|
||||
}
|
||||
|
||||
void main() {
|
||||
spi_init(100000000);
|
||||
|
||||
spi_set_clock(100000000,50000000);
|
||||
|
||||
volatile uint8_t *p = (uint8_t *)(0x8F000000);
|
||||
int j;
|
||||
uint64_t n = 0;
|
||||
|
||||
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_HOLD);
|
||||
//n = 512/8;
|
||||
|
||||
n = 4;
|
||||
do {
|
||||
// Send 8 dummy bytes (fifo should be empty)
|
||||
for (j = 0; j < 8; j++) {
|
||||
spi_sendbyte(0xaa + j);
|
||||
}
|
||||
|
||||
// Reset counter. Process bytes AS THEY COME IN.
|
||||
for (j = 0; j < 8; j++) {
|
||||
while (!(read_reg(SPI_IP) & 2)) {}
|
||||
uint8_t x = spi_readbyte();
|
||||
*p++ = x;
|
||||
}
|
||||
} while(--n > 0);
|
||||
|
||||
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
|
||||
}
|
59
tests/custom/spitest/start.s
Normal file
59
tests/custom/spitest/start.s
Normal file
@ -0,0 +1,59 @@
|
||||
.section .init
|
||||
.global _start
|
||||
.type _start, @function
|
||||
|
||||
_start:
|
||||
# Initialize global pointer
|
||||
.option push
|
||||
.option norelax
|
||||
1:auipc gp, %pcrel_hi(__global_pointer$)
|
||||
addi gp, gp, %pcrel_lo(1b)
|
||||
.option pop
|
||||
|
||||
li x1, 0
|
||||
li x2, 0
|
||||
li x4, 0
|
||||
li x5, 0
|
||||
li x6, 0
|
||||
li x7, 0
|
||||
li x8, 0
|
||||
li x9, 0
|
||||
li x10, 0
|
||||
li x11, 0
|
||||
li x12, 0
|
||||
li x13, 0
|
||||
li x14, 0
|
||||
li x15, 0
|
||||
li x16, 0
|
||||
li x17, 0
|
||||
li x18, 0
|
||||
li x19, 0
|
||||
li x20, 0
|
||||
li x21, 0
|
||||
li x22, 0
|
||||
li x23, 0
|
||||
li x24, 0
|
||||
li x25, 0
|
||||
li x26, 0
|
||||
li x27, 0
|
||||
li x28, 0
|
||||
li x29, 0
|
||||
li x30, 0
|
||||
li x31, 0
|
||||
|
||||
|
||||
|
||||
# set the stack pointer to the top of memory - 8 bytes (pointer size)
|
||||
li sp, 0x87FFFFF8
|
||||
|
||||
jal ra, main
|
||||
jal ra, _halt
|
||||
|
||||
.section .text
|
||||
.global _halt
|
||||
.type _halt, @function
|
||||
_halt:
|
||||
li gp, 1
|
||||
li a0, 0
|
||||
ecall
|
||||
j _halt
|
Loading…
Reference in New Issue
Block a user