Merge branch 'main' of github.com:ross144/cvw

This commit is contained in:
Rose Thompson 2024-09-02 14:08:48 -07:00
commit 869860bc55
22 changed files with 892 additions and 269 deletions

1
.gitignore vendored
View File

@ -101,6 +101,7 @@ sim/localhistory_m6k10_results_april24.txt
sim/cfi/* sim/cfi/*
sim/branch/* sim/branch/*
sim/covhtmlreport/ sim/covhtmlreport/
sim/*/*Cache.log
# Questa # Questa
sim/questa/logs sim/questa/logs

3
.gitmodules vendored
View File

@ -31,3 +31,6 @@
[submodule "cvw-arch-verif"] [submodule "cvw-arch-verif"]
path = addins/cvw-arch-verif path = addins/cvw-arch-verif
url = https://github.com/openhwgroup/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

@ -0,0 +1 @@
Subproject commit ac9fa2d386c0cb2f44e1e1e83a555d585034dfa3

View File

@ -41,7 +41,6 @@
# Add -d or --dist to report the distribution of loads, stores, and atomic ops. # 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. # These distributions may not add up to 100; this is because of flushes or invalidations.
import sys
import math import math
import argparse import argparse
import os import os
@ -193,7 +192,7 @@ class Cache:
return self.__str__() return self.__str__()
if __name__ == "__main__": def main():
parser = argparse.ArgumentParser(description="Simulates a L1 cache.") 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('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') 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() args = parser.parse_args()
cache = Cache(args.numlines, args.numways, args.addrlen, args.taglen) cache = Cache(args.numlines, args.numways, args.addrlen, args.taglen)
extfile = os.path.expanduser(args.file) extfile = os.path.expanduser(args.file)
nofails = True mismatches = 0
if args.perf: if args.perf:
hits = 0 hits = 0
@ -269,7 +268,7 @@ if __name__ == "__main__":
if not result == lninfo[2]: if not result == lninfo[2]:
print("Result mismatch at address", lninfo[0]+ ". Wally:", lninfo[2]+", Sim:", result) print("Result mismatch at address", lninfo[0]+ ". Wally:", lninfo[2]+", Sim:", result)
nofails = False mismatches += 1
if args.dist: if args.dist:
percent_loads = str(round(100*loads/totalops)) percent_loads = str(round(100*loads/totalops))
percent_stores = str(round(100*stores/totalops)) percent_stores = str(round(100*stores/totalops))
@ -280,5 +279,9 @@ if __name__ == "__main__":
ratio = round(hits/misses,3) ratio = round(hits/misses,3)
print("There were", hits, "hits and", misses, "misses. The hit/miss ratio was", str(ratio)+".") print("There were", hits, "hits and", misses, "misses. The hit/miss ratio was", str(ratio)+".")
if nofails: if mismatches == 0:
print("SUCCESS! There were no mismatches between Wally and the sim.") print("SUCCESS! There were no mismatches between Wally and the sim.")
return mismatches
if __name__ == '__main__':
exit(main())

View File

@ -517,6 +517,8 @@ def main():
TIMEOUT_DUR = 60*1440 # 1 day TIMEOUT_DUR = 60*1440 # 1 day
elif args.testfloat: elif args.testfloat:
TIMEOUT_DUR = 30*60 # seconds TIMEOUT_DUR = 30*60 # seconds
elif args.nightly:
TIMEOUT_DUR = 30*60 # seconds
else: else:
TIMEOUT_DUR = 10*60 # seconds TIMEOUT_DUR = 10*60 # seconds

View File

@ -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("--gui", "-g", help="Simulate with GUI", action="store_true")
parser.add_argument("--ccov", "-c", help="Code Coverage", 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("--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("--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("--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("--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("--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("--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 # 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"]: if args.sim not in ["questa", "vcs"]:
print("Option only supported for Questa and VCS") print("Option only supported for Questa and VCS")
exit(1) exit(1)
@ -75,16 +77,30 @@ if (args.vcd):
args.args += " -DMAKEVCD=1" args.args += " -DMAKEVCD=1"
if (args.rvvi): 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 lockstep is enabled, then we need to pass the Imperas lockstep arguments
if(int(args.locksteplog) >= 1): EnableLog = 1 if(int(args.locksteplog) >= 1): EnableLog = 1
else: EnableLog = 0 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): 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) if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog)
else: ImperasPlusArgs = "" else: ImperasPlusArgs = ""
if(args.fcov): 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"; CovEnableStr = "1" if int(args.covlog) > 0 else "0";
if(args.covlog >= 1): EnableLog = 1 if(args.covlog >= 1): EnableLog = 1
else: EnableLog = 0 else: EnableLog = 0
@ -94,16 +110,19 @@ if (args.lockstep):
CovEnableStr = "" CovEnableStr = ""
suffix = "--lockstep" suffix = "--lockstep"
else: else:
prefix = ""
ImperasPlusArgs = "" ImperasPlusArgs = ""
suffix = "" suffix = ""
flags = suffix + " " + ImperasPlusArgs flags = suffix
args.args += ImperasPlusArgs
# other flags # other flags
if (args.ccov): if (args.ccov):
flags += " --ccov" flags += " --ccov"
if (args.fcov): if (args.fcov):
flags += " --fcov" flags += " --fcov"
if (args.fcov2):
flags += " --fcov2"
if (args.fcovrvvi): if (args.fcovrvvi):
flags += "--fcovrvvi" flags += "--fcovrvvi"
@ -119,15 +138,18 @@ cd = "cd $WALLY/sim/" +args.sim
# per-simulator launch # per-simulator launch
if (args.sim == "questa"): 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 # Questa cannot accept more than 9 arguments. fcov implies lockstep
if (args.tb == "testbench_fp"): cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + args.params + " " + flags
args.args = " -GTEST=\"" + args.testsuite + "\" " + args.args
cmd = "do wally.do " + args.config + " " + args.testsuite + " " + args.tb + " " + args.args + " " + ElfFile + " " + flags
if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible if (args.gui): # launch Questa with GUI; add +acc to keep variables accessible
if(args.tb == "testbench"): cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\""
cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc -GDEBUG=1\""
elif(args.tb == "testbench_fp"):
cmd = cd + "; " + prefix + " vsim -do \"" + cmd + " +acc\""
else: # launch Questa in batch mode else: # launch Questa in batch mode
cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\"" cmd = cd + "; " + prefix + " vsim -c -do \"" + cmd + "\""
print("Running Questa with command: " + cmd) print("Running Questa with command: " + cmd)
@ -135,17 +157,23 @@ if (args.sim == "questa"):
elif (args.sim == "verilator"): elif (args.sim == "verilator"):
# PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i # PWD=${WALLY}/sim CONFIG=rv64gc TESTSUITE=arch64i
print(f"Running Verilator on {args.config} {args.testsuite}") 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"): elif (args.sim == "vcs"):
print("wsim params: " + args.params)
print(f"Running VCS on " + args.config + " " + args.testsuite) print(f"Running VCS on " + args.config + " " + args.testsuite)
if (args.gui): # if (args.gui):
args.args += "gui" # flags += " --gui"
if (args.args == ""): if (args.args == ""):
vcsargs = "" vcsargs = ""
else: else:
vcsargs = " --args " + args.args vcsargs = " --args \"" + args.args + "\" "
if (args.params == ""):
vcsparams = ""
else:
vcsparams = " --params \"" + args.params + "\" "
print("VCS params: " + vcsparams)
if (ElfFile != ""): if (ElfFile != ""):
ElfFile = " --elffile " + 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) print(cmd)
os.system(cmd) os.system(cmd)

119
config/rv32gc/imperas.ic Normal file
View 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

View File

@ -109,9 +109,9 @@
# Add Imperas simulator application instruction tracing # Add Imperas simulator application instruction tracing
# uncomment these to provide tracing # uncomment these to provide tracing
--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000 #--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
--override cpu/debugflags=6 --override cpu/verbose=1 #--override cpu/debugflags=6 --override cpu/verbose=1
--override cpu/show_c_prefix=T #--override cpu/show_c_prefix=T
# Store simulator output to logfile # Store simulator output to logfile
--output imperas.log --output imperas.log

View File

@ -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. # 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 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 ##### ##### clock #####
set_property PACKAGE_PIN E3 [get_ports default_100mhz_clk] 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[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPI[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[0]}] 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_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] -max -add_delay 0.000 [get_ports {GPI[*]}]
set_max_delay -from [get_ports {GPI[*]}] 20.000 set_max_delay -from [get_ports {GPI[*]}] 20.000
##### GPO #### ##### GPO ####
@ -62,8 +62,8 @@ set_property IOSTANDARD LVCMOS33 [get_ports {GPO[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPO[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPO[0]}]
set_max_delay -to [get_ports {GPO[*]}] 20.000 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_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] -max -add_delay 0.000 [get_ports {GPO[*]}]
##### UART ##### ##### 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 UARTSin]
set_property IOSTANDARD LVCMOS33 [get_ports UARTSout] set_property IOSTANDARD LVCMOS33 [get_ports UARTSout]
set_property DRIVE 4 [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_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_input_delay -clock [get_clocks clk_out3_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_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_output_delay -clock [get_clocks clk_out3_mmcm] -max -add_delay 0.000 [get_ports UARTSout]
##### reset ##### ##### reset #####
#************** reset is inverted #************** 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_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] -max -add_delay 2.000 [get_ports resetn]
set_max_delay -from [get_ports resetn] 20.000 set_max_delay -from [get_ports resetn] 20.000
set_false_path -from [get_ports resetn] set_false_path -from [get_ports resetn]
set_property PACKAGE_PIN C2 [get_ports resetn] set_property PACKAGE_PIN C2 [get_ports resetn]
set_property IOSTANDARD LVCMOS33 [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_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] -max -add_delay 2.000 [get_ports south_reset]
set_max_delay -from [get_ports south_reset] 20.000 set_max_delay -from [get_ports south_reset] 20.000
set_false_path -from [get_ports south_reset] set_false_path -from [get_ports south_reset]
set_property PACKAGE_PIN D9 [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_property IOSTANDARD SSTL135 [get_ports {ddr3_cs_n[0]}]
set_properity PACKAGE_PIN K5 [get_ports ddr3_dq[0]] set_property PACKAGE_PIN K5 [get_ports ddr3_dq[0]]
set_properity PACKAGE_PIN L3 [get_ports ddr3_dq[1]] set_property PACKAGE_PIN L3 [get_ports ddr3_dq[1]]
set_properity PACKAGE_PIN K3 [get_ports ddr3_dq[2]] set_property PACKAGE_PIN K3 [get_ports ddr3_dq[2]]
set_properity PACKAGE_PIN L6 [get_ports ddr3_dq[3]] set_property PACKAGE_PIN L6 [get_ports ddr3_dq[3]]
set_properity PACKAGE_PIN M3 [get_ports ddr3_dq[4]] set_property PACKAGE_PIN M3 [get_ports ddr3_dq[4]]
set_properity PACKAGE_PIN M1 [get_ports ddr3_dq[5]] set_property PACKAGE_PIN M1 [get_ports ddr3_dq[5]]
set_properity PACKAGE_PIN L4 [get_ports ddr3_dq[6]] set_property PACKAGE_PIN L4 [get_ports ddr3_dq[6]]
set_properity PACKAGE_PIN M2 [get_ports ddr3_dq[7]] set_property PACKAGE_PIN M2 [get_ports ddr3_dq[7]]
set_properity PACKAGE_PIN V4 [get_ports ddr3_dq[8]] set_property PACKAGE_PIN V4 [get_ports ddr3_dq[8]]
set_properity PACKAGE_PIN T5 [get_ports ddr3_dq[9]] set_property PACKAGE_PIN T5 [get_ports ddr3_dq[9]]
set_properity PACKAGE_PIN U4 [get_ports ddr3_dq[10]] set_property PACKAGE_PIN U4 [get_ports ddr3_dq[10]]
set_properity PACKAGE_PIN V5 [get_ports ddr3_dq[11]] set_property PACKAGE_PIN V5 [get_ports ddr3_dq[11]]
set_properity PACKAGE_PIN V1 [get_ports ddr3_dq[12]] set_property PACKAGE_PIN V1 [get_ports ddr3_dq[12]]
set_properity PACKAGE_PIN T3 [get_ports ddr3_dq[13]] set_property PACKAGE_PIN T3 [get_ports ddr3_dq[13]]
set_properity PACKAGE_PIN U3 [get_ports ddr3_dq[14]] set_property PACKAGE_PIN U3 [get_ports ddr3_dq[14]]
set_properity PACKAGE_PIN R3 [get_ports ddr3_dq[15]] set_property PACKAGE_PIN R3 [get_ports ddr3_dq[15]]
set_properity PACKAGE_PIN L1 [get_ports ddr3_dm[0]] set_property PACKAGE_PIN L1 [get_ports ddr3_dm[0]]
set_properity PACKAGE_PIN U1 [get_ports ddr3_dm[1]] set_property PACKAGE_PIN U1 [get_ports ddr3_dm[1]]
set_properity PACKAGE_PIN N2 [get_ports ddr3_dqs_p[0]] set_property PACKAGE_PIN N2 [get_ports ddr3_dqs_p[0]]
set_properity PACKAGE_PIN N1 [get_ports ddr3_dqs_n[0]] set_property PACKAGE_PIN N1 [get_ports ddr3_dqs_n[0]]
set_properity PACKAGE_PIN U2 [get_ports ddr3_dqs_p[1]] set_property PACKAGE_PIN U2 [get_ports ddr3_dqs_p[1]]
set_properity PACKAGE_PIN V2 [get_ports ddr3_dqs_n[1]] set_property PACKAGE_PIN V2 [get_ports ddr3_dqs_n[1]]
set_properity PACKAGE_PIN T8 [get_ports ddr3_addr[13]] set_property PACKAGE_PIN T8 [get_ports ddr3_addr[13]]
set_properity PACKAGE_PIN T6 [get_ports ddr3_addr[12]] set_property PACKAGE_PIN T6 [get_ports ddr3_addr[12]]
set_properity PACKAGE_PIN U6 [get_ports ddr3_addr[11]] set_property PACKAGE_PIN U6 [get_ports ddr3_addr[11]]
set_properity PACKAGE_PIN R6 [get_ports ddr3_addr[10]] set_property PACKAGE_PIN R6 [get_ports ddr3_addr[10]]
set_properity PACKAGE_PIN V7 [get_ports ddr3_addr[9]] set_property PACKAGE_PIN V7 [get_ports ddr3_addr[9]]
set_properity PACKAGE_PIN R8 [get_ports ddr3_addr[8]] set_property PACKAGE_PIN R8 [get_ports ddr3_addr[8]]
set_properity PACKAGE_PIN U7 [get_ports ddr3_addr[7]] set_property PACKAGE_PIN U7 [get_ports ddr3_addr[7]]
set_properity PACKAGE_PIN V6 [get_ports ddr3_addr[6]] set_property PACKAGE_PIN V6 [get_ports ddr3_addr[6]]
set_properity PACKAGE_PIN R7 [get_ports ddr3_addr[5]] set_property PACKAGE_PIN R7 [get_ports ddr3_addr[5]]
set_properity PACKAGE_PIN N6 [get_ports ddr3_addr[4]] set_property PACKAGE_PIN N6 [get_ports ddr3_addr[4]]
set_properity PACKAGE_PIN T1 [get_ports ddr3_addr[3]] set_property PACKAGE_PIN T1 [get_ports ddr3_addr[3]]
set_properity PACKAGE_PIN N4 [get_ports ddr3_addr[2]] set_property PACKAGE_PIN N4 [get_ports ddr3_addr[2]]
set_properity PACKAGE_PIN M6 [get_ports ddr3_addr[1]] set_property PACKAGE_PIN M6 [get_ports ddr3_addr[1]]
set_properity PACKAGE_PIN R2 [get_ports ddr3_addr[0]] set_property PACKAGE_PIN R2 [get_ports ddr3_addr[0]]
set_properity PACKAGE_PIN P2 [get_ports ddr3_ba[2]] set_property PACKAGE_PIN P2 [get_ports ddr3_ba[2]]
set_properity PACKAGE_PIN P4 [get_ports ddr3_ba[1]] set_property PACKAGE_PIN P4 [get_ports ddr3_ba[1]]
set_properity PACKAGE_PIN R1 [get_ports ddr3_ba[0]] set_property PACKAGE_PIN R1 [get_ports ddr3_ba[0]]
set_properity PACKAGE_PIN U9 [get_ports ddr3_ck_p[0]] set_property PACKAGE_PIN U9 [get_ports ddr3_ck_p[0]]
set_properity PACKAGE_PIN V9 [get_ports ddr3_ck_n[0]] set_property PACKAGE_PIN V9 [get_ports ddr3_ck_n[0]]
set_properity PACKAGE_PIN P3 [get_ports ddr3_ras_n] set_property PACKAGE_PIN P3 [get_ports ddr3_ras_n]
set_properity PACKAGE_PIN M4 [get_ports ddr3_cas_n] set_property PACKAGE_PIN M4 [get_ports ddr3_cas_n]
set_properity PACKAGE_PIN P5 [get_ports ddr3_we_n] set_property PACKAGE_PIN P5 [get_ports ddr3_we_n]
set_properity PACKAGE_PIN K6 [get_ports ddr3_reset_n] set_property PACKAGE_PIN K6 [get_ports ddr3_reset_n]
set_properity PACKAGE_PIN N5 [get_ports ddr3_cke[0]] set_property PACKAGE_PIN N5 [get_ports ddr3_cke[0]]
set_properity PACKAGE_PIN R5 [get_ports ddr3_odt[0]] set_property PACKAGE_PIN R5 [get_ports ddr3_odt[0]]
set_properity PACKAGE_PIN U8 [get_ports ddr3_cs_n[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} #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] -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] -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] -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] -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] -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] -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] -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] -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] -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] #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} #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] -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] -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] -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] -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] -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] -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] -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] -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] -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_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] -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] #set_output_delay -clock [get_clocks VIRTUAL_clk_pll_i] -max -add_delay 80.000 [get_ports ddr3_reset_n]

View File

@ -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 #pragma once
#ifndef SPI_HEADER #ifndef SPI_HEADER
#define SPI_HEADER #define SPI_HEADER

View File

@ -1,33 +1,46 @@
# wally-batch.do # wally.do
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
# #
# Modification by Oklahoma State University & Harvey Mudd College # Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench # Use with Testbench
# James Stine, 2008; David Harris 2021 # James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!! # Go Cowboys!!!!!!
# #
# Takes 1:10 to run RV64IC tests using gui # 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] # 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-batch.do rv64gc arch64i testbench # 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: # 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: # 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) # (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} onbreak {resume}
onerror {quit -f} onerror {quit -f}
# Initialize variables
set CFG ${1} set CFG ${1}
set TESTSUITE ${2} set TESTSUITE ${2}
set TESTBENCH ${3} set TESTBENCH ${3}
set WKDIR wkdir/${CFG}_${TESTSUITE} set WKDIR wkdir/${CFG}_${TESTSUITE}
set WALLY $::env(WALLY) set WALLY $::env(WALLY)
set IMPERAS_HOME $::env(IMPERAS_HOME)
set CONFIG ${WALLY}/config set CONFIG ${WALLY}/config
set SRC ${WALLY}/src set SRC ${WALLY}/src
set TB ${WALLY}/testbench set TB ${WALLY}/testbench
@ -38,10 +51,12 @@ if [file exists ${WKDIR}] {
vdel -lib ${WKDIR} -all vdel -lib ${WKDIR} -all
} }
vlib ${WKDIR} vlib ${WKDIR}
# Create directory for coverage data
mkdir -p cov
# Create directory for functional coverage data # 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 ccov 0
set CoverageVoptArg "" set CoverageVoptArg ""
@ -51,47 +66,26 @@ set FuncCovRVVI 0
set FCdefineRVVI_COVERAGE "" set FCdefineRVVI_COVERAGE ""
set FunctCoverage 0 set FunctCoverage 0
set riscvISACOVsrc "" set FCvlog ""
set FCdefineINCLUDE_TRACE2COV "" set FCvopt ""
set FCdefineCOVER_BASE_RV64I "" set FCdefineCOVER_EXTS {}
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 lockstep 0 set lockstep 0
# ok this is annoying. vlog, vopt, and vsim are very picky about how arguments are passed. set lockstepvlog ""
# unforunately it won't allow these to be grouped as one argument per command so they are broken
# apart.
set lockstepvoptstring ""
set SVLib "" set SVLib ""
set SVLibPath ""
set OtherFlags "" set OtherFlags ""
set ImperasPubInc ""
set ImperasPrivInc ""
set rvviFiles ""
set idvFiles ""
set GUI 0 set GUI 0
set accFlag "" set accFlag ""
# Need to be able to pass arguments to vopt. Unforunately argv does not work because # 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 # 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. # variables and compacts into a single list for passing to vopt.
set tbArgs ""
set from 4 set from 4
set step 1 set step 1
set lst {} set lst {}
set PlusArgs {}
set ParamArgs {}
for {set i 0} true {incr i} { for {set i 0} true {incr i} {
set x [expr {$i*$step + $from}] set x [expr {$i*$step + $from}]
if {$x > $argc} break if {$x > $argc} break
@ -103,84 +97,96 @@ echo "number of args = $argc"
echo "lst = $lst" echo "lst = $lst"
# if +acc found set flag and remove from list # if +acc found set flag and remove from list
set AccIndex [lsearch -exact $lst "+acc"] if {[lcheck lst "+acc"]} {
if {$AccIndex >= 0} {
set GUI 1 set GUI 1
set accFlag "+acc" set accFlag "+acc"
set lst [lreplace $lst $AccIndex $AccIndex]
} }
# if +coverage found set flag and remove from list # if --ccov found set flag and remove from list
set CoverageIndex [lsearch -exact $lst "--ccov"] if {[lcheck lst "--ccov"]} {
if {$CoverageIndex >= 0} {
set ccov 1 set ccov 1
set CoverageVoptArg "+cover=sbecf" set CoverageVoptArg "+cover=sbecf"
set CoverageVsimArg "-coverage" set CoverageVsimArg "-coverage"
set lst [lreplace $lst $CoverageIndex $CoverageIndex]
} }
set FCoverageIndexRVVI [lsearch -exact $lst "--fcovrvvi"] # if --fcovrvvi found set flag and remove from list
if {$FCoverageIndexRVVI >= 0} { if {[lcheck lst "--fcovrvvi"]} {
set FuncCovRVVI 1 set FuncCovRVVI 1
set FCdefineRVVI_COVERAGE "+define+RVVI_COVERAGE" set FCdefineRVVI_COVERAGE "+define+RVVI_COVERAGE"
set lst [lreplace $lst $FCoverageIndexRVVI $FCoverageIndexRVVI]
} }
# if +coverage found set flag and remove from list # if --fcov found set flag and remove from list
set FunctCoverageIndex [lsearch -exact $lst "--fcov"] if {[lcheck lst "--fcov"]} {
if {$FunctCoverageIndex >= 0} {
set FunctCoverage 1 set FunctCoverage 1
set riscvISACOVsrc +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source set FCvlog "+define+INCLUDE_TRACE2COV \
+define+IDV_INCLUDE_TRACE2COV \
set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV" +define+COVER_BASE_RV64I \
set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I" +define+COVER_LEVEL_DV_PR_EXT \
set FCdefineCOVER_LEVEL_DV_PR_EXT "+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 # Uncomment various cover statements below to control which extensions get functional coverage
set FCdefineCOVER_RV64I "+define+COVER_RV64I" lappend FCdefineCOVER_EXTS "+define+COVER_RV64I"
#set FCdefineCOVER_RV64M "+define+COVER_RV64M" #lappend FCdefineCOVER_EXTS "+define+COVER_RV64M"
#set FCdefineCOVER_RV64A "+define+COVER_RV64A" #lappend FCdefineCOVER_EXTS "+define+COVER_RV64A"
#set FCdefineCOVER_RV64F "+define+COVER_RV64F" #lappend FCdefineCOVER_EXTS "+define+COVER_RV64F"
#set FCdefineCOVER_RV64D "+define+COVER_RV64D" #lappend FCdefineCOVER_EXTS "+define+COVER_RV64D"
#set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR" #lappend FCdefineCOVER_EXTS "+define+COVER_RV64ZICSR"
#set FCdefineCOVER_RV64C "+define+COVER_RV64C" #lappend FCdefineCOVER_EXTS "+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] # if --fcov2 found set flag and remove from list
}\ if {[lcheck lst "--fcov2"]} {
set FunctCoverage 1
set LockStepIndex [lsearch -exact $lst "--lockstep"] set FCvlog "+define+INCLUDE_TRACE2COV \
# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running +define+IDV_INCLUDE_TRACE2COV \
# functional coverage and imply it. +define+COVER_BASE_RV32I \
if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0} { +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 set lockstep 1
set lockstepvlog "+define+USE_IMPERAS_DV \
# ideally this would all be one or two variables, but questa is having a real hard time +incdir+${IMPERAS_HOME}/ImpPublic/include/host \
# with this. For now they have to be separate. +incdir+${IMPERAS_HOME}/ImpProprietary/include/host \
set lockstepvoptstring "+define+USE_IMPERAS_DV" ${IMPERAS_HOME}/ImpPublic/source/host/rvvi/*.sv \
set ImperasPubInc +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host ${IMPERAS_HOME}/ImpProprietary/source/host/idv/*.sv"
set ImperasPrivInc +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host set SVLib "-sv_lib ${IMPERAS_HOME}/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model"
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 OtherFlags $::env(OTHERFLAGS) # not working 7/15/24 dh; this should be the way to pass things like --verbose (Issue 871) #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]
}
} }
# Set PlusArgs passed using the --args flag
# separate the +args from the -G parameters set PlusArgsIndex [lsearch -exact $lst "--args"]
foreach otherArg $lst { if {$PlusArgsIndex >= 0} {
if {[string index $otherArg 0] eq "+"} { set PlusArgs [lindex $lst [expr {$PlusArgsIndex + 1}]]
lappend PlusArgs $otherArg set lst [lreplace $lst $PlusArgsIndex [expr {$PlusArgsIndex + 1}]]
} else {
lappend ParamArgs $otherArg
}
} }
# 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} { if {$DEBUG > 0} {
echo "GUI = $GUI" echo "GUI = $GUI"
echo "ccov = $ccov" echo "ccov = $ccov"
@ -189,41 +195,27 @@ if {$DEBUG > 0} {
echo "FunctCoverage = $FunctCoverage" echo "FunctCoverage = $FunctCoverage"
echo "remaining list = $lst" echo "remaining list = $lst"
echo "Extra +args = $PlusArgs" 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 # compile source files
# suppress spurious warnngs about # suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time" # "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt # because vsim will run vopt
set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI}/common +incdir+${FCRVVI}"
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 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 # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # 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} ${OtherFlags} {*}${FCvopt} -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/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
# power add generates the logging necessary for saif generation. # power add generates the logging necessary for saif generation.
# power add -r /dut/core/* # power add -r /dut/core/*
# add waveforms if GUI is enabled
if { ${GUI} } { if { ${GUI} } {
add log -recursive /* add log -recursive /*
if { ${TESTBENCH} eq "testbench_fp" } { if { ${TESTBENCH} eq "testbench_fp" } {
@ -265,4 +257,3 @@ if {$ccov} {
if { ${GUI} == 0} { if { ${GUI} == 0} {
quit quit
} }

View File

@ -6,8 +6,9 @@
## Written: lserafini@hmc.edu ## Written: lserafini@hmc.edu
## Created: 11 April 2023 ## Created: 11 April 2023
## Modified: 12 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. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw ## https://github.com/openhwgroup/cvw
@ -16,24 +17,24 @@
## ##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 ## 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 ## 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 ## 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 ## may obtain a copy of the License at
## ##
## https:##solderpad.org/licenses/SHL-2.1/ ## https:##solderpad.org/licenses/SHL-2.1/
## ##
## Unless required by applicable law or agreed to in writing, any work distributed under the ## 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, ## 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 ## either express or implied. See the License for the specific language governing permissions
## and limitations under the License. ## and limitations under the License.
################################################################################################ ################################################################################################
import sys
import os import os
import argparse import argparse
import subprocess
# NOTE: make sure testbench.sv has the ICache and DCache loggers enabled! # 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. # 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. # 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. # These distributions may not add up to 100; this is because of flushes or invalidations.
@ -48,36 +49,46 @@ class bcolors:
BOLD = '\033[1m' BOLD = '\033[1m'
UNDERLINE = '\033[4m' UNDERLINE = '\033[4m'
# tests64gc = ["coverage64gc", "arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zcb",
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zifencei", "arch64zicond", "arch64a_amo", "wally64a_lrsc", "wally64periph", "wally64priv",
"arch64zi", "wally64a", "wally64periph", "wally64priv", "arch64zbkb", "arch64zbkc", "arch64zbkx", "arch64zknd", "arch64zkne", "arch64zknh",
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"]
"imperas64f", "imperas64d", "imperas64c", "imperas64i"]
# arch64i is the most interesting case. Uncomment line below to run just that case # arch64i is the most interesting case. Uncomment line below to run just that case
tests64gc = ["arch64i"] # tests64gc = ["arch64i"]
cachetypes = ["ICache", "DCache"] 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 = 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('-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('-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() args = parser.parse_args()
simargs = "I_CACHE_ADDR_LOGGER=1\\\'b1 D_CACHE_ADDR_LOGGER=1\\\'b1"
testcmd = "vsim -do \"do wally-batch.do rv64gc {}\" -c > /dev/null" testcmd = "wsim --sim " + args.sim + " rv64gc {} --params \"" + simargs + "\" > /dev/null"
cachecmd = "CacheSim.py 64 4 56 44 -f {}" cachecmd = "CacheSim.py 64 4 56 44 -f {}"
mismatches = 0
if args.perf: if args.perf:
cachecmd += " -p" cachecmd += " -p"
if args.dist: if args.dist:
cachecmd += " -d" cachecmd += " -d"
for test in tests64gc: for test in tests64gc:
print(f"{bcolors.HEADER}Commencing test", test+f":{bcolors.ENDC}") 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)) os.system(testcmd.format(test))
for cache in cachetypes: for cache in cachetypes:
print(f"{bcolors.OKCYAN}Running the", cache, f"simulator.{bcolors.ENDC}") 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() print()
return mismatches
if __name__ == '__main__':
exit(main())

View File

@ -23,10 +23,12 @@ def runfindcmd(cmd):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("config", help="Configuration file") 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("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("--elffile", "-e", help="ELF file name", default="")
parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true") 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("--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("--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") parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true")
# GUI not yet implemented # GUI not yet implemented
#parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true") #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) rtlsrc_files = runfindcmd(rtlsrc_cmd)
tbcommon_cmd = 'find ' + tbdir+'/common -name "*.sv" ! -path "' + tbdir+'/common/wallyTracer.sv"' tbcommon_cmd = 'find ' + tbdir+'/common -name "*.sv" ! -path "' + tbdir+'/common/wallyTracer.sv"'
tbcommon_files = runfindcmd(tbcommon_cmd) 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 directories
INCLUDE_PATH="+incdir+" + cfgdir + "/" + args.config + " +incdir+" + cfgdir + "/deriv/" + args.config + " +incdir+" + cfgdir + "/shared +incdir+$WALLY/tests +incdir+" + tbdir + " +incdir+" + srcdir 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: else:
COV_OPTIONS = "" 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 # Simulation commands
OUTPUT="sim_out" 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_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" 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 SIMV_CMD= wkdir + "/" + OUTPUT + " +TEST=" + args.testsuite + " " + args.elffile + " " + args.args + " -no_save " + LOCKSTEP_SIMV
# Run simulation # Run simulation
@ -81,4 +97,3 @@ subprocess.run(SIMV_CMD, shell=True)
if (args.coverage): if (args.coverage):
COV_RUN = "urg -dir " + wkdir + "/coverage.vdb -format text -report IndividualCovReport/" + args.config + "_" + args.testsuite COV_RUN = "urg -dir " + wkdir + "/coverage.vdb -format text -report IndividualCovReport/" + args.config + "_" + args.testsuite
subprocess.run(COV_RUN, shell=True) subprocess.run(COV_RUN, shell=True)

View File

@ -7,12 +7,13 @@ SHELL := /bin/bash
# verilator configurations # verilator configurations
OPT= OPT=
PARAMS?=-DVERILATOR=1 --no-trace-top PARAMS?=--no-trace-top
NONPROF?=--stats NONPROF?=--stats
VERILATOR_DIR=${WALLY}/sim/verilator 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 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 WALLYCONF?=rv64gc
TEST?=arch64i TEST?=arch64i
@ -32,11 +33,9 @@ DEPENDENCIES=${WALLY}/config/shared/*.vh $(SOURCES)
# regular testbench requires a wrapper defining getenvval # regular testbench requires a wrapper defining getenvval
ifeq ($(TESTBENCH), testbench) ifeq ($(TESTBENCH), testbench)
WRAPPER=${WALLY}/sim/verilator/wrapper.c WRAPPER=${WALLY}/sim/verilator/wrapper.c
GTEST=
ARGTEST=+TEST=$(TEST) ARGTEST=+TEST=$(TEST)
else else
WRAPPER= WRAPPER=
GTEST=-GTEST="\"${TEST}\""
ARGTEST= ARGTEST=
endif endif
@ -44,7 +43,7 @@ default: run
run: wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} run: wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH}
mkdir -p $(VERILATOR_DIR)/logs 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) profile: obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF)
$(VERILATOR_DIR)/obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) ${ARGTEST} $(VERILATOR_DIR)/obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) ${ARGTEST}
@ -64,7 +63,7 @@ wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH}: $(DEPENDENCIES)
--top-module ${TESTBENCH} --relative-includes \ --top-module ${TESTBENCH} --relative-includes \
$(INCLUDE_PATH) \ $(INCLUDE_PATH) \
${WRAPPER} \ ${WRAPPER} \
${GTEST} \ ${EXPANDED_PARAM_ARGS} \
$(SOURCES) $(SOURCES)
obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES) obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES)
@ -76,7 +75,7 @@ obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES)
--top-module ${TESTBENCH} --relative-includes \ --top-module ${TESTBENCH} --relative-includes \
$(INCLUDE_PATH) \ $(INCLUDE_PATH) \
${WRAPPER} \ ${WRAPPER} \
${GTEST} \ ${EXPANDED_PARAM_ARGS} \
$(SOURCES) $(SOURCES)
clean: clean:

View File

@ -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'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'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'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 // user CSRs
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; 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'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}; 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. end else begin // hold the old value if the pipeline is stalled.
// PMP CFG 3A0 to 3AF // PMP CFG 3A0 to 3AF

View File

@ -762,7 +762,7 @@ end
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org")); void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv")); void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GCK")); 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)); void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
if(elffilename == "buildroot") filename = ""; if(elffilename == "buildroot") filename = "";
@ -824,15 +824,25 @@ end
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME 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 // User HPMCOUNTER3 - HPMCOUNTER31
for (iter='hC03; iter<='hC1F; iter++) begin for (iter='hC03; iter<='hC1F; iter++) begin
void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx
if (P.XLEN == 32)
void'(rvviRefCsrSetVolatile(0, iter+128)); // HPMCOUNTERxH
end end
// Machine MHPMCOUNTER3 - MHPMCOUNTER31 // Machine MHPMCOUNTER3 - MHPMCOUNTER31
for (iter='hB03; iter<='hB1F; iter++) begin for (iter='hB03; iter<='hB1F; iter++) begin
void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx
if (P.XLEN == 32)
void'(rvviRefCsrSetVolatile(0, iter+128)); // MHPMCOUNTERxH
end end
// cannot predict this register due to latency between // cannot predict this register due to latency between

View File

@ -637,7 +637,11 @@ module testbench_fp;
// check if nothing is being tested // check if nothing is being tested
if (Tests.size() == 0) begin if (Tests.size() == 0) begin
$display("TEST %s not supported in this configuration", TEST); $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
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); 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(" 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); //$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 end
if (TestVectors[VectorNum] == '1 & Tests[TestNum] !== "") begin // if reached the eof if (TestVectors[VectorNum] == '1 & Tests[TestNum] !== "") begin // if reached the eof
@ -1013,7 +1021,11 @@ module testbench_fp;
// if no more Tests - finish // if no more Tests - finish
if (Tests[TestNum] === "") begin if (Tests[TestNum] === "") begin
$display("\nAll Tests completed with %d errors\n", errors); $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 end
$display("Running %s vectors", Tests[TestNum]); $display("Running %s vectors", Tests[TestNum]);
end end

View 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
View 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

View 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);
}

View 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