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/branch/*
sim/covhtmlreport/
sim/*/*Cache.log
# Questa
sim/questa/logs

3
.gitmodules vendored
View File

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

@ -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.
# 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())

View File

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

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("--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
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
# 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

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.
#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]

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
#ifndef 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
#
# 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
}

View File

@ -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())

View File

@ -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)

View File

@ -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:

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

View File

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

View File

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

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