mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-02 09:45:18 +00:00
Merge branch 'main' of https://github.com/openhwgroup/cvw into installation
This commit is contained in:
commit
76eef03fe4
3
.gitignore
vendored
3
.gitignore
vendored
@ -193,6 +193,9 @@ config/deriv
|
||||
docs/docker/buildroot-config-src
|
||||
docs/docker/testvector-generation
|
||||
sim/questa/cov
|
||||
sim/questa/fcovrvvi
|
||||
sim/questa/fcovrvvi_logs
|
||||
sim/questa/fcovrvvi_ucdb
|
||||
sim/covhtmlreport/
|
||||
sim/questa/logs
|
||||
sim/questa/wkdir
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -28,3 +28,6 @@
|
||||
sparseCheckout = true
|
||||
path = addins/verilog-ethernet
|
||||
url = https://github.com/ross144/verilog-ethernet.git
|
||||
[submodule "cvw-arch-verif"]
|
||||
path = cvw-arch-verif
|
||||
url = https://github.com/openhwgroup/cvw-arch-verif
|
||||
|
@ -340,6 +340,7 @@ defaultsim = "verilator" # Default simulator for all other tests
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--ccov", help="Code Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", help="Functional Coverage", action="store_true")
|
||||
parser.add_argument("--fcovrvvi", help="Functional Coverage RVVI", action="store_true")
|
||||
parser.add_argument("--nightly", help="Run large nightly regression", action="store_true")
|
||||
parser.add_argument("--buildroot", help="Include Buildroot Linux boot test (takes many hours, done along with --nightly)", action="store_true")
|
||||
parser.add_argument("--testfloat", help="Include Testfloat floating-point unit tests", action="store_true")
|
||||
@ -357,6 +358,8 @@ if (args.ccov): # only run RV64GC tests in coverage mode
|
||||
coverStr = '--ccov'
|
||||
elif (args.fcov): # only run RV64GC tests in lockstep in coverage mode
|
||||
coverStr = '--fcov'
|
||||
elif (args.fcovrvvi): # only run RV64GC tests in rvvi coverage mode
|
||||
coverStr = '--fcovrvvi'
|
||||
else:
|
||||
coverStr = ''
|
||||
|
||||
@ -392,6 +395,10 @@ elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional c
|
||||
# grepstr="SUCCESS! All tests ran without failures",
|
||||
# grepfile = sim_log)
|
||||
#configs.append(tc)
|
||||
elif (args.fcovrvvi): # only run RV64GC tests on Questa in rvvi coverage mode
|
||||
addTests(tests64gc_nofp, coveragesim)
|
||||
if (args.fp):
|
||||
addTests(tests64gc_fp, coveragesim)
|
||||
else:
|
||||
for sim in sims:
|
||||
if (not (args.buildroot and sim == defaultsim)): # skip short buildroot sim if running long one
|
||||
@ -501,6 +508,9 @@ def main():
|
||||
if args.ccov:
|
||||
TIMEOUT_DUR = 20*60 # seconds
|
||||
os.system('rm -f questa/cov/*.ucdb')
|
||||
elif args.fcovrvvi:
|
||||
TIMEOUT_DUR = 20*60
|
||||
os.system('rm -f questa/fcovrvvi_ucdb/* questa/fcovrvvi_logs/* questa/fcovrvvi/*')
|
||||
elif args.fcov:
|
||||
TIMEOUT_DUR = 1*60
|
||||
os.system('rm -f questa/fcov_ucdb/* questa/fcov_logs/* questa/fcov/*')
|
||||
@ -535,6 +545,8 @@ def main():
|
||||
os.system('make QuestaCodeCoverage')
|
||||
if args.fcov:
|
||||
os.system('make QuestaFunctCoverage')
|
||||
if args.fcovrvvi:
|
||||
os.system('make QuestaFunctCoverageRvvi')
|
||||
# Count the number of failures
|
||||
if num_fail:
|
||||
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)
|
||||
|
7
bin/wsim
7
bin/wsim
@ -28,6 +28,7 @@ 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("--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("--vcd", "-v", help="Generate testbench.vcd", action="store_true")
|
||||
parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true")
|
||||
@ -57,7 +58,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.lockstep):
|
||||
if (args.gui or args.ccov or args.fcov or args.fcovrvvi or args.lockstep):
|
||||
if args.sim not in ["questa", "vcs"]:
|
||||
print("Option only supported for Questa and VCS")
|
||||
exit(1)
|
||||
@ -95,10 +96,12 @@ if (args.ccov):
|
||||
flags += " --ccov"
|
||||
if (args.fcov):
|
||||
flags += " --fcov"
|
||||
if (args.fcovrvvi):
|
||||
flags += "--fcovrvvi"
|
||||
|
||||
# create the output sub-directories.
|
||||
regressionDir = WALLY + '/sim/'
|
||||
for d in ["logs", "wkdir", "cov", "ucdb", "fcov", "fcov_ucdb"]:
|
||||
for d in ["logs", "wkdir", "cov", "ucdb", "fcov", "fcov_ucdb", "fcovrvvi", "fcovrvvi_ucdb"]:
|
||||
try:
|
||||
os.mkdir(regressionDir+args.sim+"/"+d)
|
||||
except:
|
||||
|
@ -50,7 +50,8 @@ PLIC_NUM_SRC 32'd53
|
||||
deriv fpga buildroot
|
||||
BOOTROM_PRELOAD 1
|
||||
UNCORE_RAM_BASE 64'h2000
|
||||
UNCORE_RAM_RANGE 64'hFFF
|
||||
UNCORE_RAM_RANGE 64'h1FFF
|
||||
BOOTROM_RANGE 64'hFFF
|
||||
EXT_MEM_SUPPORTED 1
|
||||
EXT_MEM_BASE 64'h80000000
|
||||
EXT_MEM_RANGE 64'h0FFFFFFF
|
||||
|
1
cvw-arch-verif
Submodule
1
cvw-arch-verif
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 2a4f56ec97db7cdd6fd13fb928122d408fefbf1e
|
@ -4,6 +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]
|
||||
|
||||
##### clock #####
|
||||
set_property PACKAGE_PIN E3 [get_ports {default_100mhz_clk}]
|
||||
@ -60,6 +61,7 @@ set_property IOSTANDARD LVCMOS33 [get_ports {GPO[2]}]
|
||||
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[*]}]
|
||||
|
||||
@ -100,42 +102,52 @@ set_property IOSTANDARD LVCMOS33 [get_ports {south_reset}]
|
||||
|
||||
##### SD Card I/O #####
|
||||
#***** may have to switch to Pmod JB or JC.
|
||||
set_property PACKAGE_PIN D4 [get_ports {SDCDat[3]}]
|
||||
set_property PACKAGE_PIN D2 [get_ports {SDCDat[2]}]
|
||||
set_property PACKAGE_PIN E2 [get_ports {SDCDat[1]}]
|
||||
set_property PACKAGE_PIN F4 [get_ports {SDCDat[0]}]
|
||||
set_property PACKAGE_PIN F3 [get_ports SDCCLK]
|
||||
set_property PACKAGE_PIN D3 [get_ports {SDCCmd}]
|
||||
set_property PACKAGE_PIN H2 [get_ports {SDCCD}]
|
||||
#set_property PACKAGE_PIN D4 [get_ports {SDCDat[3]}]
|
||||
#set_property PACKAGE_PIN D2 [get_ports {SDCDat[2]}]
|
||||
#set_property PACKAGE_PIN E2 [get_ports {SDCDat[1]}]
|
||||
#set_property PACKAGE_PIN F4 [get_ports {SDCDat[0]}]
|
||||
#set_property PACKAGE_PIN F3 [get_ports SDCCLK]
|
||||
#set_property PACKAGE_PIN D3 [get_ports {SDCCmd}]
|
||||
#set_property PACKAGE_PIN H2 [get_ports {SDCCD}]
|
||||
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[3]}]
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[2]}]
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[1]}]
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[0]}]
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports SDCCLK]
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports {SDCCmd}]
|
||||
#set_property IOSTANDARD LVCMOS33 [get_ports {SDCCD}]
|
||||
#set_property PULLUP true [get_ports {SDCDat[3]}]
|
||||
#set_property PULLUP true [get_ports {SDCDat[2]}]
|
||||
#set_property PULLUP true [get_ports {SDCDat[1]}]
|
||||
#set_property PULLUP true [get_ports {SDCDat[0]}]
|
||||
#set_property PULLUP true [get_ports {SDCCmd}]
|
||||
#set_property PULLUP true [get_ports {SDCCD}]
|
||||
|
||||
# SDCDat[3]
|
||||
set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCCS}]
|
||||
# set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCDat[2]}]
|
||||
# set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCDat[1]}]
|
||||
# SDCDat[0]
|
||||
set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCIn}]
|
||||
set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCCLK}]
|
||||
set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCCmd}]
|
||||
set_property -dict {PACKAGE_PIN H2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCCD}]
|
||||
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCWP}]
|
||||
|
||||
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[3]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[2]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[0]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports SDCCLK]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {SDCCmd}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {SDCCD}]
|
||||
set_property PULLUP true [get_ports {SDCDat[3]}]
|
||||
set_property PULLUP true [get_ports {SDCDat[2]}]
|
||||
set_property PULLUP true [get_ports {SDCDat[1]}]
|
||||
set_property PULLUP true [get_ports {SDCDat[0]}]
|
||||
set_property PULLUP true [get_ports {SDCCmd}]
|
||||
set_property PULLUP true [get_ports {SDCCD}]
|
||||
set_input_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.500 [get_ports {SDCCS}]
|
||||
set_input_delay -clock [get_clocks SPISDCClock] -max -add_delay 10.000 [get_ports {SDCCS}]
|
||||
|
||||
set_input_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.500 [get_ports {SDCIn}]
|
||||
set_input_delay -clock [get_clocks SPISDCClock] -max -add_delay 10.000 [get_ports {SDCIn}]
|
||||
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.500 [get_ports {SDCDat[*]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 21.000 [get_ports {SDCDat[*]}]
|
||||
set_output_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.000 [get_ports {SDCCmd}]
|
||||
set_output_delay -clock [get_clocks SPISDCClock] -max -add_delay 6.000 [get_ports {SDCCmd}]
|
||||
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.500 [get_ports {SDCCmd}]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 14.000 [get_ports {SDCCmd}]
|
||||
set_output_delay -clock [get_clocks SPISDCClock] 0.000 [get_ports SDCCLK]
|
||||
|
||||
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.000 [get_ports {SDCCmd}]
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 6.000 [get_ports {SDCCmd}]
|
||||
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] 0.000 [get_ports SDCCLK]
|
||||
|
||||
#set_multicycle_path -from [get_pins xlnx_ddr3_c0/u_xlnx_ddr3_mig/u_memc_ui_top_axi/mem_intfc0/ddr_phy_top0/u_ddr_calib_top/init_calib_complete_reg/C] -to [get_pins xlnx_proc_sys_reset_0/U0/EXT_LPF/lpf_int_reg/D] 10
|
||||
|
||||
set_max_delay -datapath_only -from [get_pins xlnx_ddr3_c0/u_xlnx_ddr3_mig/u_memc_ui_top_axi/mem_intfc0/ddr_phy_top0/u_ddr_calib_top/init_calib_complete_reg/C] -to [get_pins xlnx_proc_sys_reset_0/U0/EXT_LPF/lpf_int_reg/D] 20.000
|
||||
|
@ -1,14 +1,14 @@
|
||||
dst := IP
|
||||
|
||||
# vcu118
|
||||
#export XILINX_PART := xcvu9p-flga2104-2L-e
|
||||
#export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
|
||||
#export board := vcu118
|
||||
# export XILINX_PART := xcvu9p-flga2104-2L-e
|
||||
# export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
|
||||
# export board := vcu118
|
||||
|
||||
# vcu108
|
||||
#export XILINX_PART := xcvu095-ffva2104-2-e
|
||||
#export XILINX_BOARD := xilinx.com:vcu108:part0:1.2
|
||||
#export board := vcu108
|
||||
# export XILINX_PART := xcvu095-ffva2104-2-e
|
||||
# export XILINX_BOARD := xilinx.com:vcu108:part0:1.7
|
||||
# export board := vcu108
|
||||
|
||||
# Arty A7
|
||||
export XILINX_PART := xc7a100tcsg324-1
|
||||
@ -40,11 +40,11 @@ IP_Arty: $(dst)/xlnx_proc_sys_reset.log \
|
||||
$(dst)/xlnx_ddr3-$(board).log \
|
||||
$(dst)/xlnx_mmcm.log \
|
||||
$(dst)/xlnx_axi_clock_converter.log \
|
||||
$(dst)/xlnx_ahblite_axi_bridge.log \
|
||||
$(dst)/xlnx_axi_crossbar.log \
|
||||
$(dst)/xlnx_axi_dwidth_conv_32to64.log \
|
||||
$(dst)/xlnx_axi_dwidth_conv_64to32.log \
|
||||
$(dst)/xlnx_axi_prtcl_conv.log
|
||||
$(dst)/xlnx_ahblite_axi_bridge.log
|
||||
#$(dst)/xlnx_axi_crossbar.log \
|
||||
#$(dst)/xlnx_axi_dwidth_conv_32to64.log \
|
||||
#$(dst)/xlnx_axi_dwidth_conv_64to32.log \
|
||||
#$(dst)/xlnx_axi_prtcl_conv.log
|
||||
|
||||
|
||||
PreProcessFiles:
|
||||
@ -61,6 +61,7 @@ PreProcessFiles:
|
||||
# This line allows the Bootloader to be loaded in a Block RAM on the FPGA
|
||||
sed -i "s/bit \[DATA_WIDTH-1:0\].*ROM.*/(\* rom_style=\"block\" \*) &/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv
|
||||
sed -i 's/$$WALLY/\.\.\/\.\.\/\.\.\//g' ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv
|
||||
sed -i 's/$$WALLY/\.\.\/\.\.\/\.\.\//g' ../src/CopiedFiles_do_not_add_to_repo/generic/mem/ram1p1rwbe.sv
|
||||
|
||||
$(dst)/%.log: %.tcl
|
||||
mkdir -p IP
|
||||
|
@ -27,10 +27,10 @@ read_ip IP/xlnx_proc_sys_reset.srcs/sources_1/ip/xlnx_proc_sys_reset/xlnx_proc_s
|
||||
read_ip IP/xlnx_ahblite_axi_bridge.srcs/sources_1/ip/xlnx_ahblite_axi_bridge/xlnx_ahblite_axi_bridge.xci
|
||||
read_ip IP/xlnx_axi_clock_converter.srcs/sources_1/ip/xlnx_axi_clock_converter/xlnx_axi_clock_converter.xci
|
||||
# Added crossbar - Jacob Pease <2023-01-12 Thu>
|
||||
read_ip IP/xlnx_axi_crossbar.srcs/sources_1/ip/xlnx_axi_crossbar/xlnx_axi_crossbar.xci
|
||||
read_ip IP/xlnx_axi_dwidth_conv_32to64.srcs/sources_1/ip/xlnx_axi_dwidth_conv_32to64/xlnx_axi_dwidth_conv_32to64.xci
|
||||
read_ip IP/xlnx_axi_dwidth_conv_64to32.srcs/sources_1/ip/xlnx_axi_dwidth_conv_64to32/xlnx_axi_dwidth_conv_64to32.xci
|
||||
read_ip IP/xlnx_axi_prtcl_conv.srcs/sources_1/ip/xlnx_axi_prtcl_conv/xlnx_axi_prtcl_conv.xci
|
||||
#read_ip IP/xlnx_axi_crossbar.srcs/sources_1/ip/xlnx_axi_crossbar/xlnx_axi_crossbar.xci
|
||||
#read_ip IP/xlnx_axi_dwidth_conv_32to64.srcs/sources_1/ip/xlnx_axi_dwidth_conv_32to64/xlnx_axi_dwidth_conv_32to64.xci
|
||||
#read_ip IP/xlnx_axi_dwidth_conv_64to32.srcs/sources_1/ip/xlnx_axi_dwidth_conv_64to32/xlnx_axi_dwidth_conv_64to32.xci
|
||||
#read_ip IP/xlnx_axi_prtcl_conv.srcs/sources_1/ip/xlnx_axi_prtcl_conv/xlnx_axi_prtcl_conv.xci
|
||||
|
||||
if {$board=="ArtyA7"} {
|
||||
read_ip IP/xlnx_ddr3.srcs/sources_1/ip/xlnx_ddr3/xlnx_ddr3.xci
|
||||
@ -91,10 +91,8 @@ write_verilog -force -mode funcsim sim/syn-funcsim.v
|
||||
if {$board=="ArtyA7"} {
|
||||
#source ../constraints/small-debug.xdc
|
||||
source ../constraints/small-debug-rvvi.xdc
|
||||
|
||||
} else {
|
||||
# source ../constraints/vcu-small-debug.xdc
|
||||
source ../constraints/debug6.xdc
|
||||
source ../constraints/vcu-small-debug.xdc
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,17 +33,21 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
(* mark_debug = "true" *) input resetn,
|
||||
input south_reset,
|
||||
|
||||
input [3:0] GPI,
|
||||
output [4:0] GPO,
|
||||
// GPIO signals
|
||||
input [3:0] GPI,
|
||||
output [4:0] GPO,
|
||||
|
||||
input UARTSin,
|
||||
output UARTSout,
|
||||
|
||||
inout [3:0] SDCDat,
|
||||
output SDCCLK,
|
||||
inout SDCCmd,
|
||||
input SDCCD,
|
||||
// UART Signals
|
||||
input UARTSin,
|
||||
output UARTSout,
|
||||
|
||||
// SDC Signals connecting to an SPI peripheral
|
||||
input SDCIn,
|
||||
output SDCCLK,
|
||||
output SDCCmd,
|
||||
output SDCCS,
|
||||
input SDCCD,
|
||||
input SDCWP,
|
||||
/*
|
||||
* Ethernet: 100BASE-T MII
|
||||
*/
|
||||
@ -76,6 +80,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
output [0:0] ddr3_odt
|
||||
);
|
||||
|
||||
// MMCM Signals
|
||||
wire CPUCLK;
|
||||
wire c0_ddr4_ui_clk_sync_rst;
|
||||
wire bus_struct_reset;
|
||||
@ -84,12 +89,12 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
wire peripheral_aresetn;
|
||||
wire mb_reset;
|
||||
|
||||
// AHB Signals from Wally
|
||||
wire HCLKOpen;
|
||||
wire HRESETnOpen;
|
||||
wire [63:0] HRDATAEXT;
|
||||
wire HREADYEXT;
|
||||
wire HRESPEXT;
|
||||
wire HSELEXTSDC; // TEMP BOOT SIGNAL - JACOB
|
||||
wire HSELEXT;
|
||||
wire [55:0] HADDR;
|
||||
wire [63:0] HWDATA;
|
||||
@ -102,12 +107,10 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
wire [3:0] HPROT;
|
||||
wire HMASTLOCK;
|
||||
|
||||
// GPIO Signals
|
||||
wire [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
|
||||
wire SDCCmdIn;
|
||||
wire SDCCmdOE;
|
||||
wire SDCCmdOut;
|
||||
|
||||
// AHB to AXI Bridge Signals
|
||||
wire [3:0] m_axi_awid;
|
||||
wire [7:0] m_axi_awlen;
|
||||
wire [2:0] m_axi_awsize;
|
||||
@ -115,40 +118,40 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
wire [3:0] m_axi_awcache;
|
||||
wire [31:0] m_axi_awaddr;
|
||||
wire [2:0] m_axi_awprot;
|
||||
wire m_axi_awvalid;
|
||||
wire m_axi_awready;
|
||||
wire m_axi_awlock;
|
||||
wire m_axi_awvalid;
|
||||
wire m_axi_awready;
|
||||
wire m_axi_awlock;
|
||||
wire [63:0] m_axi_wdata;
|
||||
wire [7:0] m_axi_wstrb;
|
||||
wire m_axi_wlast;
|
||||
wire m_axi_wvalid;
|
||||
wire m_axi_wready;
|
||||
wire m_axi_wlast;
|
||||
wire m_axi_wvalid;
|
||||
wire m_axi_wready;
|
||||
wire [3:0] m_axi_bid;
|
||||
wire [1:0] m_axi_bresp;
|
||||
wire m_axi_bvalid;
|
||||
wire m_axi_bready;
|
||||
wire m_axi_bvalid;
|
||||
wire m_axi_bready;
|
||||
wire [3:0] m_axi_arid;
|
||||
wire [7:0] m_axi_arlen;
|
||||
wire [2:0] m_axi_arsize;
|
||||
wire [1:0] m_axi_arburst;
|
||||
wire [2:0] m_axi_arprot;
|
||||
wire [3:0] m_axi_arcache;
|
||||
wire m_axi_arvalid;
|
||||
wire m_axi_arvalid;
|
||||
wire [31:0] m_axi_araddr;
|
||||
wire m_axi_arlock;
|
||||
wire m_axi_arready;
|
||||
wire m_axi_arready;
|
||||
wire [3:0] m_axi_rid;
|
||||
wire [63:0] m_axi_rdata;
|
||||
wire [1:0] m_axi_rresp;
|
||||
wire m_axi_rvalid;
|
||||
wire m_axi_rlast;
|
||||
wire m_axi_rready;
|
||||
wire m_axi_rvalid;
|
||||
wire m_axi_rlast;
|
||||
wire m_axi_rready;
|
||||
|
||||
// AXI Signals going out of Clock Converter
|
||||
wire [3:0] BUS_axi_arregion;
|
||||
wire [3:0] BUS_axi_arqos;
|
||||
wire [3:0] BUS_axi_awregion;
|
||||
wire [3:0] BUS_axi_awqos;
|
||||
|
||||
wire [3:0] BUS_axi_awid;
|
||||
wire [7:0] BUS_axi_awlen;
|
||||
wire [2:0] BUS_axi_awsize;
|
||||
@ -188,250 +191,10 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
wire BUSCLK;
|
||||
wire sdio_reset_open;
|
||||
|
||||
// Crossbar to Bus ------------------------------------------------
|
||||
|
||||
wire s00_axi_aclk;
|
||||
wire s00_axi_aresetn;
|
||||
wire [3:0] s00_axi_awid;
|
||||
wire [31:0]s00_axi_awaddr;
|
||||
wire [7:0]s00_axi_awlen;
|
||||
wire [2:0]s00_axi_awsize;
|
||||
wire [1:0]s00_axi_awburst;
|
||||
wire [0:0]s00_axi_awlock;
|
||||
wire [3:0]s00_axi_awcache;
|
||||
wire [2:0]s00_axi_awprot;
|
||||
wire [3:0]s00_axi_awregion;
|
||||
wire [3:0]s00_axi_awqos;
|
||||
wire s00_axi_awvalid;
|
||||
wire s00_axi_awready;
|
||||
wire [63:0]s00_axi_wdata;
|
||||
wire [7:0]s00_axi_wstrb;
|
||||
wire s00_axi_wlast;
|
||||
wire s00_axi_wvalid;
|
||||
wire s00_axi_wready;
|
||||
wire [1:0]s00_axi_bresp;
|
||||
wire s00_axi_bvalid;
|
||||
wire s00_axi_bready;
|
||||
wire [3:0] s00_axi_arid;
|
||||
wire [31:0]s00_axi_araddr;
|
||||
wire [7:0]s00_axi_arlen;
|
||||
wire [2:0]s00_axi_arsize;
|
||||
wire [1:0]s00_axi_arburst;
|
||||
wire [0:0]s00_axi_arlock;
|
||||
wire [3:0]s00_axi_arcache;
|
||||
wire [2:0]s00_axi_arprot;
|
||||
wire [3:0]s00_axi_arregion;
|
||||
wire [3:0]s00_axi_arqos;
|
||||
wire s00_axi_arvalid;
|
||||
wire s00_axi_arready;
|
||||
wire [63:0]s00_axi_rdata;
|
||||
wire [1:0]s00_axi_rresp;
|
||||
wire s00_axi_rlast;
|
||||
wire s00_axi_rvalid;
|
||||
wire s00_axi_rready;
|
||||
|
||||
wire [3:0] s00_axi_bid;
|
||||
wire [3:0] s00_axi_rid;
|
||||
|
||||
// 64to32 dwidth converter input interface-------------------------
|
||||
wire s01_axi_aclk;
|
||||
wire s01_axi_aresetn;
|
||||
wire [3:0]s01_axi_awid;
|
||||
wire [31:0]s01_axi_awaddr;
|
||||
wire [7:0]s01_axi_awlen;
|
||||
wire [2:0]s01_axi_awsize;
|
||||
wire [1:0]s01_axi_awburst;
|
||||
wire [0:0]s01_axi_awlock;
|
||||
wire [3:0]s01_axi_awcache;
|
||||
wire [2:0]s01_axi_awprot;
|
||||
wire [3:0]s01_axi_awregion;
|
||||
wire [3:0]s01_axi_awqos; // qos signals need to be 0 for SDC
|
||||
wire s01_axi_awvalid;
|
||||
wire s01_axi_awready;
|
||||
wire [63:0]s01_axi_wdata;
|
||||
wire [7:0]s01_axi_wstrb;
|
||||
wire s01_axi_wlast;
|
||||
wire s01_axi_wvalid;
|
||||
wire s01_axi_wready;
|
||||
wire [1:0]s01_axi_bresp;
|
||||
wire s01_axi_bvalid;
|
||||
wire s01_axi_bready;
|
||||
wire [31:0]s01_axi_araddr;
|
||||
wire [7:0]s01_axi_arlen;
|
||||
wire [3:0] s01_axi_arid;
|
||||
wire [2:0]s01_axi_arsize;
|
||||
wire [1:0]s01_axi_arburst;
|
||||
wire [0:0]s01_axi_arlock;
|
||||
wire [3:0]s01_axi_arcache;
|
||||
wire [2:0]s01_axi_arprot;
|
||||
wire [3:0]s01_axi_arregion;
|
||||
wire [3:0]s01_axi_arqos; //
|
||||
wire s01_axi_arvalid;
|
||||
wire s01_axi_arready;
|
||||
wire [63:0]s01_axi_rdata;
|
||||
wire [1:0]s01_axi_rresp;
|
||||
wire s01_axi_rlast;
|
||||
wire s01_axi_rvalid;
|
||||
wire s01_axi_rready;
|
||||
|
||||
// Output Interface
|
||||
wire [31:0]axi4in_axi_awaddr;
|
||||
wire [7:0]axi4in_axi_awlen;
|
||||
wire [2:0]axi4in_axi_awsize;
|
||||
wire [1:0]axi4in_axi_awburst;
|
||||
wire [0:0]axi4in_axi_awlock;
|
||||
wire [3:0]axi4in_axi_awcache;
|
||||
wire [2:0]axi4in_axi_awprot;
|
||||
wire [3:0]axi4in_axi_awregion;
|
||||
wire [3:0]axi4in_axi_awqos;
|
||||
wire axi4in_axi_awvalid;
|
||||
wire axi4in_axi_awready;
|
||||
wire [31:0]axi4in_axi_wdata;
|
||||
wire [3:0]axi4in_axi_wstrb;
|
||||
wire axi4in_axi_wlast;
|
||||
wire axi4in_axi_wvalid;
|
||||
wire axi4in_axi_wready;
|
||||
wire [1:0]axi4in_axi_bresp;
|
||||
wire axi4in_axi_bvalid;
|
||||
wire axi4in_axi_bready;
|
||||
wire [31:0]axi4in_axi_araddr;
|
||||
wire [7:0]axi4in_axi_arlen;
|
||||
wire [2:0]axi4in_axi_arsize;
|
||||
wire [1:0]axi4in_axi_arburst;
|
||||
wire [0:0]axi4in_axi_arlock;
|
||||
wire [3:0]axi4in_axi_arcache;
|
||||
wire [2:0]axi4in_axi_arprot;
|
||||
wire [3:0]axi4in_axi_arregion;
|
||||
wire [3:0]axi4in_axi_arqos;
|
||||
wire axi4in_axi_arvalid;
|
||||
wire axi4in_axi_arready;
|
||||
wire [31:0]axi4in_axi_rdata;
|
||||
wire [1:0]axi4in_axi_rresp;
|
||||
wire axi4in_axi_rlast;
|
||||
wire axi4in_axi_rvalid;
|
||||
wire axi4in_axi_rready;
|
||||
|
||||
// AXI4 to AXI4-Lite Protocol converter output
|
||||
wire [31:0]SDCin_axi_awaddr;
|
||||
wire [2:0]SDCin_axi_awprot;
|
||||
wire SDCin_axi_awvalid;
|
||||
wire SDCin_axi_awready;
|
||||
wire [31:0]SDCin_axi_wdata;
|
||||
wire [3:0]SDCin_axi_wstrb;
|
||||
wire SDCin_axi_wvalid;
|
||||
wire SDCin_axi_wready;
|
||||
wire [1:0]SDCin_axi_bresp;
|
||||
wire SDCin_axi_bvalid;
|
||||
wire SDCin_axi_bready;
|
||||
wire [31:0]SDCin_axi_araddr;
|
||||
wire [2:0]SDCin_axi_arprot;
|
||||
wire SDCin_axi_arvalid;
|
||||
wire SDCin_axi_arready;
|
||||
wire [31:0]SDCin_axi_rdata;
|
||||
wire [1:0]SDCin_axi_rresp;
|
||||
wire SDCin_axi_rvalid;
|
||||
wire SDCin_axi_rready;
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// 32to64 dwidth converter input interface -----------------------
|
||||
wire [31:0]SDCout_axi_awaddr;
|
||||
wire [7:0]SDCout_axi_awlen;
|
||||
wire [2:0]SDCout_axi_awsize;
|
||||
wire [1:0]SDCout_axi_awburst;
|
||||
wire [0:0]SDCout_axi_awlock;
|
||||
wire [3:0]SDCout_axi_awcache;
|
||||
wire [2:0]SDCout_axi_awprot;
|
||||
wire [3:0]SDCout_axi_awregion;
|
||||
wire [3:0]SDCout_axi_awqos;
|
||||
wire SDCout_axi_awvalid;
|
||||
wire SDCout_axi_awready;
|
||||
wire [31:0]SDCout_axi_wdata;
|
||||
wire [3:0]SDCout_axi_wstrb;
|
||||
wire SDCout_axi_wlast;
|
||||
wire SDCout_axi_wvalid;
|
||||
wire SDCout_axi_wready;
|
||||
wire [1:0]SDCout_axi_bresp;
|
||||
wire SDCout_axi_bvalid;
|
||||
wire SDCout_axi_bready;
|
||||
wire [31:0]SDCout_axi_araddr;
|
||||
wire [7:0]SDCout_axi_arlen;
|
||||
wire [2:0]SDCout_axi_arsize;
|
||||
wire [1:0]SDCout_axi_arburst;
|
||||
wire [0:0]SDCout_axi_arlock;
|
||||
wire [3:0]SDCout_axi_arcache;
|
||||
wire [2:0]SDCout_axi_arprot;
|
||||
wire [3:0]SDCout_axi_arregion;
|
||||
wire [3:0]SDCout_axi_arqos;
|
||||
wire SDCout_axi_arvalid;
|
||||
wire SDCout_axi_arready;
|
||||
wire [31:0]SDCout_axi_rdata;
|
||||
wire [1:0]SDCout_axi_rresp;
|
||||
wire SDCout_axi_rlast;
|
||||
wire SDCout_axi_rvalid;
|
||||
wire SDCout_axi_rready;
|
||||
|
||||
// Output Interface
|
||||
wire [3:0]m01_axi_awid;
|
||||
wire [31:0]m01_axi_awaddr;
|
||||
wire [7:0]m01_axi_awlen;
|
||||
wire [2:0]m01_axi_awsize;
|
||||
wire [1:0]m01_axi_awburst;
|
||||
wire [0:0]m01_axi_awlock;
|
||||
wire [3:0]m01_axi_awcache;
|
||||
wire [2:0]m01_axi_awprot;
|
||||
wire [3:0]m01_axi_awregion;
|
||||
wire [3:0]m01_axi_awqos;
|
||||
wire m01_axi_awvalid;
|
||||
wire m01_axi_awready;
|
||||
wire [63:0]m01_axi_wdata;
|
||||
wire [7:0]m01_axi_wstrb;
|
||||
wire m01_axi_wlast;
|
||||
wire m01_axi_wvalid;
|
||||
wire m01_axi_wready;
|
||||
wire [3:0] m01_axi_bid;
|
||||
wire [1:0]m01_axi_bresp;
|
||||
wire m01_axi_bvalid;
|
||||
wire m01_axi_bready;
|
||||
wire [3:0] m01_axi_arid;
|
||||
wire [31:0]m01_axi_araddr;
|
||||
wire [7:0]m01_axi_arlen;
|
||||
wire [2:0]m01_axi_arsize;
|
||||
wire [1:0]m01_axi_arburst;
|
||||
wire [0:0]m01_axi_arlock;
|
||||
wire [3:0]m01_axi_arcache;
|
||||
wire [2:0]m01_axi_arprot;
|
||||
wire [3:0]m01_axi_arregion;
|
||||
wire [3:0]m01_axi_arqos;
|
||||
wire m01_axi_arvalid;
|
||||
wire m01_axi_arready;
|
||||
wire [3:0] m01_axi_rid;
|
||||
wire [63:0]m01_axi_rdata;
|
||||
wire [1:0]m01_axi_rresp;
|
||||
wire m01_axi_rlast;
|
||||
wire m01_axi_rvalid;
|
||||
wire m01_axi_rready;
|
||||
|
||||
// Old SDC input
|
||||
// wire [3:0] SDCDatIn;
|
||||
|
||||
// New SDC Command IOBUF connections
|
||||
wire sd_cmd_i;
|
||||
wire sd_cmd_reg_o;
|
||||
wire sd_cmd_reg_t;
|
||||
|
||||
// SD Card Interrupt signal
|
||||
wire SDCIntr;
|
||||
|
||||
// New SDC Data IOBUF connections
|
||||
wire [3:0] sd_dat_i;
|
||||
wire [3:0] sd_dat_reg_o;
|
||||
wire sd_dat_reg_t;
|
||||
|
||||
|
||||
wire c0_init_calib_complete;
|
||||
wire c0_init_calib_complete;
|
||||
wire dbg_clk;
|
||||
wire [511 : 0] dbg_bus;
|
||||
wire ui_clk_sync_rst;
|
||||
wire ui_clk_sync_rst;
|
||||
|
||||
wire CLK208;
|
||||
wire clk167;
|
||||
@ -440,18 +203,21 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
wire app_sr_active;
|
||||
wire app_ref_ack;
|
||||
wire app_zq_ack;
|
||||
wire mmcm_locked;
|
||||
wire mmcm_locked;
|
||||
wire [11:0] device_temp;
|
||||
wire mmcm1_locked;
|
||||
wire mmcm1_locked;
|
||||
|
||||
(* mark_debug = "true" *) logic RVVIStall;
|
||||
|
||||
assign GPIOIN = {28'b0, GPI};
|
||||
assign GPIOIN = {25'b0, SDCCD, SDCWP, 1'b0, GPI};
|
||||
assign GPO = GPIOOUT[4:0];
|
||||
assign ahblite_resetn = peripheral_aresetn;
|
||||
assign cpu_reset = bus_struct_reset;
|
||||
assign calib = c0_init_calib_complete;
|
||||
|
||||
logic [3:0] SDCCSin;
|
||||
assign SDCCS = SDCCSin[0];
|
||||
|
||||
// mmcm
|
||||
|
||||
// the ddr3 mig7 requires 2 input clocks
|
||||
@ -466,26 +232,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
.reset(1'b0),
|
||||
.locked(mmcm1_locked),
|
||||
.clk_in1(default_100mhz_clk));
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
// SD Card Tristate
|
||||
IOBUF iobufSDCMD(.T(~SDCCmdOE), // iobuf's T is active low
|
||||
.I(SDCCmdOut),
|
||||
.O(SDCCmdIn),
|
||||
.IO(SDCCmd));
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
// IOBUFS for new SDC peripheral
|
||||
IOBUF IOBUF_cmd (.O(sd_cmd_i), .IO(SDCCmd), .I(sd_cmd_reg_o), .T(sd_cmd_reg_t));
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 4; i = i + 1) begin
|
||||
IOBUF iobufSDCDat(.T(sd_dat_reg_t),
|
||||
.I(sd_dat_reg_o[i]),
|
||||
.O(sd_dat_i[i]),
|
||||
.IO(SDCDat[i]) );
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// reset controller XILINX IP
|
||||
@ -501,26 +248,24 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
.interconnect_aresetn(interconnect_aresetn), //open
|
||||
.peripheral_aresetn(peripheral_aresetn));
|
||||
|
||||
// wally
|
||||
// RT and JP: FIXME add sdc interrupt and HSELEXTSDC, remove old sdc after the new sdc ahb version is implemented
|
||||
|
||||
`include "parameter-defs.vh"
|
||||
|
||||
|
||||
// Wally
|
||||
wallypipelinedsoc #(P)
|
||||
wallypipelinedsoc(.clk(CPUCLK), .reset_ext(bus_struct_reset), .reset(),
|
||||
.HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT,
|
||||
.HSELEXTSDC, .HCLK(HCLKOpen), .HRESETn(HRESETnOpen),
|
||||
.HCLK(HCLKOpen), .HRESETn(HRESETnOpen),
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0),
|
||||
.GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .ExternalStall(RVVIStall));
|
||||
.UARTSin, .UARTSout, .SDCIn, .SDCCmd, .SDCCS(SDCCSin), .SDCCLK, .ExternalStall(RVVIStall));
|
||||
|
||||
|
||||
// ahb lite to axi bridge
|
||||
xlnx_ahblite_axi_bridge xlnx_ahblite_axi_bridge_0
|
||||
(.s_ahb_hclk(CPUCLK),
|
||||
.s_ahb_hresetn(peripheral_aresetn),
|
||||
.s_ahb_hsel(HSELEXT | HSELEXTSDC),
|
||||
.s_ahb_hsel(HSELEXT),
|
||||
.s_ahb_haddr(HADDR[31:0]),
|
||||
.s_ahb_hprot(HPROT),
|
||||
.s_ahb_htrans(HTRANS),
|
||||
@ -568,432 +313,49 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
.m_axi_rlast(m_axi_rlast),
|
||||
.m_axi_rready(m_axi_rready));
|
||||
|
||||
// AXI Crossbar for arbitrating the SDC and CPU --------------
|
||||
xlnx_axi_crossbar xlnx_axi_crossbar_0
|
||||
(.aclk(CPUCLK),
|
||||
.aresetn(peripheral_aresetn),
|
||||
|
||||
// Connect Masters
|
||||
.s_axi_awid({4'b1000, m_axi_awid}),
|
||||
.s_axi_awaddr({m01_axi_awaddr, m_axi_awaddr}),
|
||||
.s_axi_awlen({m01_axi_awlen, m_axi_awlen}),
|
||||
.s_axi_awsize({m01_axi_awsize, m_axi_awsize}),
|
||||
.s_axi_awburst({m01_axi_awburst, m_axi_awburst}),
|
||||
.s_axi_awlock({m01_axi_awlock, m_axi_awlock}),
|
||||
.s_axi_awcache({m01_axi_awcache, m_axi_awcache}),
|
||||
.s_axi_awprot({m01_axi_awprot, m_axi_awprot}),
|
||||
.s_axi_awqos(8'b0),
|
||||
.s_axi_awvalid({m01_axi_awvalid, m_axi_awvalid}),
|
||||
.s_axi_awready({m01_axi_awready, m_axi_awready}),
|
||||
.s_axi_wdata({m01_axi_wdata, m_axi_wdata}),
|
||||
.s_axi_wstrb({m01_axi_wstrb, m_axi_wstrb}),
|
||||
.s_axi_wlast({m01_axi_wlast, m_axi_wlast}),
|
||||
.s_axi_wvalid({m01_axi_wvalid, m_axi_wvalid}),
|
||||
.s_axi_wready({m01_axi_wready, m_axi_wready}),
|
||||
.s_axi_bid({m01_axi_bid, m_axi_bid}),
|
||||
.s_axi_bresp({m01_axi_bresp, m_axi_bresp}),
|
||||
.s_axi_bvalid({m01_axi_bvalid, m_axi_bvalid}),
|
||||
.s_axi_bready({m01_axi_bready, m_axi_bready}),
|
||||
.s_axi_arid({4'b1000, m_axi_arid}),
|
||||
.s_axi_araddr({m01_axi_araddr, m_axi_araddr}),
|
||||
.s_axi_arlen({m01_axi_arlen, m_axi_arlen}),
|
||||
.s_axi_arsize({m01_axi_arsize, m_axi_arsize}),
|
||||
.s_axi_arburst({m01_axi_arburst, m_axi_arburst}),
|
||||
.s_axi_arlock({m01_axi_arlock, m_axi_arlock}),
|
||||
.s_axi_arcache({m01_axi_arcache, m_axi_arcache}),
|
||||
.s_axi_arprot({m01_axi_arprot, m_axi_arprot}),
|
||||
.s_axi_arqos(8'b0),
|
||||
.s_axi_arvalid({m01_axi_arvalid, m_axi_arvalid}),
|
||||
.s_axi_arready({m01_axi_arready, m_axi_arready}),
|
||||
.s_axi_rid({m01_axi_rid, m_axi_rid}),
|
||||
.s_axi_rdata({m01_axi_rdata, m_axi_rdata}),
|
||||
.s_axi_rresp({m01_axi_rresp, m_axi_rresp}),
|
||||
.s_axi_rlast({m01_axi_rlast, m_axi_rlast}),
|
||||
.s_axi_rvalid({m01_axi_rvalid, m_axi_rvalid}),
|
||||
.s_axi_rready({m01_axi_rready, m_axi_rready}),
|
||||
|
||||
// Connect Slaves
|
||||
.m_axi_awid({s01_axi_awid, s00_axi_awid}),
|
||||
.m_axi_awlen({s01_axi_awlen, s00_axi_awlen}),
|
||||
.m_axi_awsize({s01_axi_awsize, s00_axi_awsize}),
|
||||
.m_axi_awburst({s01_axi_awburst, s00_axi_awburst}),
|
||||
.m_axi_awcache({s01_axi_awcache, s00_axi_awcache}),
|
||||
.m_axi_awaddr({s01_axi_awaddr, s00_axi_awaddr}),
|
||||
.m_axi_awprot({s01_axi_awprot, s00_axi_awprot}),
|
||||
.m_axi_awregion({s01_axi_awregion, s00_axi_awregion}),
|
||||
.m_axi_awqos({s01_axi_awqos, s00_axi_awqos}),
|
||||
.m_axi_awvalid({s01_axi_awvalid, s00_axi_awvalid}),
|
||||
.m_axi_awready({s01_axi_awready, s00_axi_awready}),
|
||||
.m_axi_awlock({s01_axi_awlock, s00_axi_awlock}),
|
||||
.m_axi_wdata({s01_axi_wdata, s00_axi_wdata}),
|
||||
.m_axi_wstrb({s01_axi_wstrb, s00_axi_wstrb}),
|
||||
.m_axi_wlast({s01_axi_wlast, s00_axi_wlast}),
|
||||
.m_axi_wvalid({s01_axi_wvalid, s00_axi_wvalid}),
|
||||
.m_axi_wready({s01_axi_wready, s00_axi_wready}),
|
||||
.m_axi_bid({4'b1000, s00_axi_bid}),
|
||||
.m_axi_bresp({s01_axi_bresp, s00_axi_bresp}),
|
||||
.m_axi_bvalid({s01_axi_bvalid, s00_axi_bvalid}),
|
||||
.m_axi_bready({s01_axi_bready, s00_axi_bready}),
|
||||
.m_axi_arid({s01_axi_arid, s00_axi_arid}),
|
||||
.m_axi_arlen({s01_axi_arlen, s00_axi_arlen}),
|
||||
.m_axi_arsize({s01_axi_arsize, s00_axi_arsize}),
|
||||
.m_axi_arburst({s01_axi_arburst, s00_axi_arburst}),
|
||||
.m_axi_arprot({s01_axi_arprot, s00_axi_arprot}),
|
||||
.m_axi_arregion({s01_axi_arregion, s00_axi_arregion}),
|
||||
.m_axi_arqos({s01_axi_arqos, s00_axi_arqos}),
|
||||
.m_axi_arcache({s01_axi_arcache, s00_axi_arcache}),
|
||||
.m_axi_arvalid({s01_axi_arvalid, s00_axi_arvalid}),
|
||||
.m_axi_araddr({s01_axi_araddr, s00_axi_araddr}),
|
||||
.m_axi_arlock({s01_axi_arlock, s00_axi_arlock}),
|
||||
.m_axi_arready({s01_axi_arready, s00_axi_arready}),
|
||||
.m_axi_rid({4'b1000, s00_axi_rid}),
|
||||
.m_axi_rdata({s01_axi_rdata, s00_axi_rdata}),
|
||||
.m_axi_rresp({s01_axi_rresp, s00_axi_rresp}),
|
||||
.m_axi_rvalid({s01_axi_rvalid, s00_axi_rvalid}),
|
||||
.m_axi_rlast({s01_axi_rlast, s00_axi_rlast}),
|
||||
.m_axi_rready({s01_axi_rready, s00_axi_rready})
|
||||
);
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
// SDC Implementation ----------------------------------
|
||||
//
|
||||
// The SDC peripheral from Eugene Tarassov takes in an AXI4Lite
|
||||
// interface and outputs an AXI4 interface. In order to convert from
|
||||
// one to the other, we use these dwidth converters to make sure the
|
||||
// bit widths match the rest of the bus.
|
||||
|
||||
xlnx_axi_dwidth_conv_64to32 axi_conv_down
|
||||
(.s_axi_aclk(CPUCLK),
|
||||
.s_axi_aresetn(peripheral_aresetn),
|
||||
|
||||
// Slave interface
|
||||
.s_axi_awaddr(s01_axi_awaddr),
|
||||
.s_axi_awlen(s01_axi_awlen),
|
||||
.s_axi_awsize(s01_axi_awsize),
|
||||
.s_axi_awburst(s01_axi_awburst),
|
||||
.s_axi_awlock(s01_axi_awlock),
|
||||
.s_axi_awcache(s01_axi_awcache),
|
||||
.s_axi_awprot(s01_axi_awprot),
|
||||
.s_axi_awregion(s01_axi_awregion),
|
||||
.s_axi_awqos(4'b0),
|
||||
.s_axi_awvalid(s01_axi_awvalid),
|
||||
.s_axi_awready(s01_axi_awready),
|
||||
.s_axi_wdata(s01_axi_wdata),
|
||||
.s_axi_wstrb(s01_axi_wstrb),
|
||||
.s_axi_wlast(s01_axi_wlast),
|
||||
.s_axi_wvalid(s01_axi_wvalid),
|
||||
.s_axi_wready(s01_axi_wready),
|
||||
.s_axi_bresp(s01_axi_bresp),
|
||||
.s_axi_bvalid(s01_axi_bvalid),
|
||||
.s_axi_bready(s01_axi_bready),
|
||||
.s_axi_araddr(s01_axi_araddr),
|
||||
.s_axi_arlen(s01_axi_arlen),
|
||||
.s_axi_arsize(s01_axi_arsize),
|
||||
.s_axi_arburst(s01_axi_arburst),
|
||||
.s_axi_arlock(s01_axi_arlock),
|
||||
.s_axi_arcache(s01_axi_arcache),
|
||||
.s_axi_arprot(s01_axi_arprot),
|
||||
.s_axi_arregion(s01_axi_arregion),
|
||||
.s_axi_arqos(4'b0),
|
||||
.s_axi_arvalid(s01_axi_arvalid),
|
||||
.s_axi_arready(s01_axi_arready),
|
||||
.s_axi_rdata(s01_axi_rdata),
|
||||
.s_axi_rresp(s01_axi_rresp),
|
||||
.s_axi_rlast(s01_axi_rlast),
|
||||
.s_axi_rvalid(s01_axi_rvalid),
|
||||
.s_axi_rready(s01_axi_rready),
|
||||
|
||||
// Master interface
|
||||
.m_axi_awaddr(axi4in_axi_awaddr),
|
||||
.m_axi_awlen(axi4in_axi_awlen),
|
||||
.m_axi_awsize(axi4in_axi_awsize),
|
||||
.m_axi_awburst(axi4in_axi_awburst),
|
||||
.m_axi_awlock(axi4in_axi_awlock),
|
||||
.m_axi_awcache(axi4in_axi_awcache),
|
||||
.m_axi_awprot(axi4in_axi_awprot),
|
||||
.m_axi_awregion(axi4in_axi_awregion),
|
||||
.m_axi_awqos(axi4in_axi_awqos),
|
||||
.m_axi_awvalid(axi4in_axi_awvalid),
|
||||
.m_axi_awready(axi4in_axi_awready),
|
||||
.m_axi_wdata(axi4in_axi_wdata),
|
||||
.m_axi_wstrb(axi4in_axi_wstrb),
|
||||
.m_axi_wlast(axi4in_axi_wlast),
|
||||
.m_axi_wvalid(axi4in_axi_wvalid),
|
||||
.m_axi_wready(axi4in_axi_wready),
|
||||
.m_axi_bresp(axi4in_axi_bresp),
|
||||
.m_axi_bvalid(axi4in_axi_bvalid),
|
||||
.m_axi_bready(axi4in_axi_bready),
|
||||
.m_axi_araddr(axi4in_axi_araddr),
|
||||
.m_axi_arlen(axi4in_axi_arlen),
|
||||
.m_axi_arsize(axi4in_axi_arsize),
|
||||
.m_axi_arburst(axi4in_axi_arburst),
|
||||
.m_axi_arlock(axi4in_axi_arlock),
|
||||
.m_axi_arcache(axi4in_axi_arcache),
|
||||
.m_axi_arprot(axi4in_axi_arprot),
|
||||
.m_axi_arregion(axi4in_axi_arregion),
|
||||
.m_axi_arqos(axi4in_axi_arqos),
|
||||
.m_axi_arvalid(axi4in_axi_arvalid),
|
||||
.m_axi_arready(axi4in_axi_arready),
|
||||
.m_axi_rdata(axi4in_axi_rdata),
|
||||
.m_axi_rresp(axi4in_axi_rresp),
|
||||
.m_axi_rlast(axi4in_axi_rlast),
|
||||
.m_axi_rvalid(axi4in_axi_rvalid),
|
||||
.m_axi_rready(axi4in_axi_rready)
|
||||
);
|
||||
|
||||
xlnx_axi_prtcl_conv axi4tolite
|
||||
(.aclk(CPUCLK),
|
||||
.aresetn(peripheral_aresetn),
|
||||
|
||||
// AXI4 In
|
||||
.s_axi_awaddr(axi4in_axi_awaddr),
|
||||
.s_axi_awlen(axi4in_axi_awlen),
|
||||
.s_axi_awsize(axi4in_axi_awsize),
|
||||
.s_axi_awburst(axi4in_axi_awburst),
|
||||
.s_axi_awlock(axi4in_axi_awlock),
|
||||
.s_axi_awcache(axi4in_axi_awcache),
|
||||
.s_axi_awprot(axi4in_axi_awprot),
|
||||
.s_axi_awregion(axi4in_axi_awregion),
|
||||
.s_axi_awqos(axi4in_axi_awqos),
|
||||
.s_axi_awvalid(axi4in_axi_awvalid),
|
||||
.s_axi_awready(axi4in_axi_awready),
|
||||
.s_axi_wdata(axi4in_axi_wdata),
|
||||
.s_axi_wstrb(axi4in_axi_wstrb),
|
||||
.s_axi_wlast(axi4in_axi_wlast),
|
||||
.s_axi_wvalid(axi4in_axi_wvalid),
|
||||
.s_axi_wready(axi4in_axi_wready),
|
||||
.s_axi_bresp(axi4in_axi_bresp),
|
||||
.s_axi_bvalid(axi4in_axi_bvalid),
|
||||
.s_axi_bready(axi4in_axi_bready),
|
||||
.s_axi_araddr(axi4in_axi_araddr),
|
||||
.s_axi_arlen(axi4in_axi_arlen),
|
||||
.s_axi_arsize(axi4in_axi_arsize),
|
||||
.s_axi_arburst(axi4in_axi_arburst),
|
||||
.s_axi_arlock(axi4in_axi_arlock),
|
||||
.s_axi_arcache(axi4in_axi_arcache),
|
||||
.s_axi_arprot(axi4in_axi_arprot),
|
||||
.s_axi_arregion(axi4in_axi_arregion),
|
||||
.s_axi_arqos(axi4in_axi_arqos),
|
||||
.s_axi_arvalid(axi4in_axi_arvalid),
|
||||
.s_axi_arready(axi4in_axi_arready),
|
||||
.s_axi_rdata(axi4in_axi_rdata),
|
||||
.s_axi_rresp(axi4in_axi_rresp),
|
||||
.s_axi_rlast(axi4in_axi_rlast),
|
||||
.s_axi_rvalid(axi4in_axi_rvalid),
|
||||
.s_axi_rready(axi4in_axi_rready),
|
||||
|
||||
// AXI4Lite Out
|
||||
.m_axi_awaddr(SDCin_axi_awaddr),
|
||||
.m_axi_awprot(SDCin_axi_awprot),
|
||||
.m_axi_awvalid(SDCin_axi_awvalid),
|
||||
.m_axi_awready(SDCin_axi_awready),
|
||||
.m_axi_wdata(SDCin_axi_wdata),
|
||||
.m_axi_wstrb(SDCin_axi_wstrb),
|
||||
.m_axi_wvalid(SDCin_axi_wvalid),
|
||||
.m_axi_wready(SDCin_axi_wready),
|
||||
.m_axi_bresp(SDCin_axi_bresp),
|
||||
.m_axi_bvalid(SDCin_axi_bvalid),
|
||||
.m_axi_bready(SDCin_axi_bready),
|
||||
.m_axi_araddr(SDCin_axi_araddr),
|
||||
.m_axi_arprot(SDCin_axi_arprot),
|
||||
.m_axi_arvalid(SDCin_axi_arvalid),
|
||||
.m_axi_arready(SDCin_axi_arready),
|
||||
.m_axi_rdata(SDCin_axi_rdata),
|
||||
.m_axi_rresp(SDCin_axi_rresp),
|
||||
.m_axi_rvalid(SDCin_axi_rvalid),
|
||||
.m_axi_rready(SDCin_axi_rready)
|
||||
|
||||
);
|
||||
|
||||
|
||||
sdc_controller axiSDC
|
||||
(.clock(CPUCLK),
|
||||
.async_resetn(peripheral_aresetn),
|
||||
|
||||
// Slave Interface
|
||||
.s_axi_awaddr({8'b0, SDCin_axi_awaddr[7:0]}),
|
||||
.s_axi_awvalid(SDCin_axi_awvalid),
|
||||
.s_axi_awready(SDCin_axi_awready),
|
||||
.s_axi_wdata(SDCin_axi_wdata),
|
||||
.s_axi_wvalid(SDCin_axi_wvalid),
|
||||
.s_axi_wready(SDCin_axi_wready),
|
||||
.s_axi_bresp(SDCin_axi_bresp),
|
||||
.s_axi_bvalid(SDCin_axi_bvalid),
|
||||
.s_axi_bready(SDCin_axi_bready),
|
||||
.s_axi_araddr({8'b0, SDCin_axi_araddr[7:0]}),
|
||||
.s_axi_arvalid(SDCin_axi_arvalid),
|
||||
.s_axi_arready(SDCin_axi_arready),
|
||||
.s_axi_rdata(SDCin_axi_rdata),
|
||||
.s_axi_rresp(SDCin_axi_rresp),
|
||||
.s_axi_rvalid(SDCin_axi_rvalid),
|
||||
.s_axi_rready(SDCin_axi_rready),
|
||||
.sdio_reset(sdio_reset_open),
|
||||
|
||||
// Master Interface
|
||||
.m_axi_awaddr(SDCout_axi_awaddr),
|
||||
.m_axi_awlen(SDCout_axi_awlen),
|
||||
.m_axi_awvalid(SDCout_axi_awvalid),
|
||||
.m_axi_awready(SDCout_axi_awready),
|
||||
.m_axi_wdata(SDCout_axi_wdata),
|
||||
.m_axi_wlast(SDCout_axi_wlast),
|
||||
.m_axi_wvalid(SDCout_axi_wvalid),
|
||||
.m_axi_wready(SDCout_axi_wready),
|
||||
.m_axi_bresp(SDCout_axi_bresp),
|
||||
.m_axi_bvalid(SDCout_axi_bvalid),
|
||||
.m_axi_bready(SDCout_axi_bready),
|
||||
.m_axi_araddr(SDCout_axi_araddr),
|
||||
.m_axi_arlen(SDCout_axi_arlen),
|
||||
.m_axi_arvalid(SDCout_axi_arvalid),
|
||||
.m_axi_arready(SDCout_axi_arready),
|
||||
.m_axi_rdata(SDCout_axi_rdata),
|
||||
.m_axi_rlast(SDCout_axi_rlast),
|
||||
.m_axi_rresp(SDCout_axi_rresp),
|
||||
.m_axi_rvalid(SDCout_axi_rvalid),
|
||||
.m_axi_rready(SDCout_axi_rready),
|
||||
|
||||
// SDC interface
|
||||
//.sdio_cmd(1'b0),
|
||||
//.sdio_dat(4'b0),
|
||||
//.sdio_cd(1'b0)
|
||||
|
||||
.sd_dat_reg_t(sd_dat_reg_t),
|
||||
.sd_dat_reg_o(sd_dat_reg_o),
|
||||
.sd_dat_i(sd_dat_i),
|
||||
|
||||
.sd_cmd_reg_t(sd_cmd_reg_t),
|
||||
.sd_cmd_reg_o(sd_cmd_reg_o),
|
||||
.sd_cmd_i(sd_cmd_i),
|
||||
|
||||
.sdio_clk(SDCCLK),
|
||||
.sdio_cd(SDCCD),
|
||||
|
||||
.interrupt(SDCIntr)
|
||||
);
|
||||
|
||||
xlnx_axi_dwidth_conv_32to64 axi_conv_up
|
||||
(.s_axi_aclk(CPUCLK),
|
||||
.s_axi_aresetn(peripheral_aresetn),
|
||||
|
||||
// Slave interface
|
||||
.s_axi_awaddr(SDCout_axi_awaddr),
|
||||
.s_axi_awlen(SDCout_axi_awlen),
|
||||
.s_axi_awsize(3'b010),
|
||||
.s_axi_awburst(2'b01),
|
||||
.s_axi_awlock(1'b0),
|
||||
.s_axi_awcache(4'b0),
|
||||
.s_axi_awprot(3'b0),
|
||||
.s_axi_awregion(4'b0),
|
||||
.s_axi_awqos(4'b0),
|
||||
.s_axi_awvalid(SDCout_axi_awvalid),
|
||||
.s_axi_awready(SDCout_axi_awready),
|
||||
.s_axi_wdata(SDCout_axi_wdata),
|
||||
.s_axi_wstrb(8'b11111111),
|
||||
.s_axi_wlast(SDCout_axi_wlast),
|
||||
.s_axi_wvalid(SDCout_axi_wvalid),
|
||||
.s_axi_wready(SDCout_axi_wready),
|
||||
.s_axi_bresp(SDCout_axi_bresp),
|
||||
.s_axi_bvalid(SDCout_axi_bvalid),
|
||||
.s_axi_bready(SDCout_axi_bready),
|
||||
.s_axi_araddr(SDCout_axi_araddr),
|
||||
.s_axi_arlen(SDCout_axi_arlen),
|
||||
.s_axi_arsize(3'b010),
|
||||
.s_axi_arburst(2'b01),
|
||||
.s_axi_arlock(1'b0),
|
||||
.s_axi_arcache(4'b0),
|
||||
.s_axi_arprot(3'b0),
|
||||
.s_axi_arregion(4'b0),
|
||||
.s_axi_arqos(4'b0),
|
||||
.s_axi_arvalid(SDCout_axi_arvalid),
|
||||
.s_axi_arready(SDCout_axi_arready),
|
||||
.s_axi_rdata(SDCout_axi_rdata),
|
||||
.s_axi_rresp(SDCout_axi_rresp),
|
||||
.s_axi_rlast(SDCout_axi_rlast),
|
||||
.s_axi_rvalid(SDCout_axi_rvalid),
|
||||
.s_axi_rready(SDCout_axi_rready),
|
||||
|
||||
// Master interface
|
||||
.m_axi_awaddr(m01_axi_awaddr),
|
||||
.m_axi_awlen(m01_axi_awlen),
|
||||
.m_axi_awsize(m01_axi_awsize),
|
||||
.m_axi_awburst(m01_axi_awburst),
|
||||
.m_axi_awlock(m01_axi_awlock),
|
||||
.m_axi_awcache(m01_axi_awcache),
|
||||
.m_axi_awprot(m01_axi_awprot),
|
||||
.m_axi_awregion(m01_axi_awregion),
|
||||
.m_axi_awqos(m01_axi_awqos),
|
||||
.m_axi_awvalid(m01_axi_awvalid),
|
||||
.m_axi_awready(m01_axi_awready),
|
||||
.m_axi_wdata(m01_axi_wdata),
|
||||
.m_axi_wstrb(m01_axi_wstrb),
|
||||
.m_axi_wlast(m01_axi_wlast),
|
||||
.m_axi_wvalid(m01_axi_wvalid),
|
||||
.m_axi_wready(m01_axi_wready),
|
||||
.m_axi_bresp(m01_axi_bresp),
|
||||
.m_axi_bvalid(m01_axi_bvalid),
|
||||
.m_axi_bready(m01_axi_bready),
|
||||
.m_axi_araddr(m01_axi_araddr),
|
||||
.m_axi_arlen(m01_axi_arlen),
|
||||
.m_axi_arsize(m01_axi_arsize),
|
||||
.m_axi_arburst(m01_axi_arburst),
|
||||
.m_axi_arlock(m01_axi_arlock),
|
||||
.m_axi_arcache(m01_axi_arcache),
|
||||
.m_axi_arprot(m01_axi_arprot),
|
||||
.m_axi_arregion(m01_axi_arregion),
|
||||
.m_axi_arqos(m01_axi_arqos),
|
||||
.m_axi_arvalid(m01_axi_arvalid),
|
||||
.m_axi_arready(m01_axi_arready),
|
||||
.m_axi_rdata(m01_axi_rdata),
|
||||
.m_axi_rresp(m01_axi_rresp),
|
||||
.m_axi_rlast(m01_axi_rlast),
|
||||
.m_axi_rvalid(m01_axi_rvalid),
|
||||
.m_axi_rready(m01_axi_rready)
|
||||
);
|
||||
|
||||
// End SDC signals --------------------------------------------
|
||||
|
||||
// AXI Clock Converter
|
||||
xlnx_axi_clock_converter xlnx_axi_clock_converter_0
|
||||
(.s_axi_aclk(CPUCLK),
|
||||
.s_axi_aresetn(peripheral_aresetn),
|
||||
.s_axi_awid(s00_axi_awid),
|
||||
.s_axi_awlen(s00_axi_awlen),
|
||||
.s_axi_awsize(s00_axi_awsize),
|
||||
.s_axi_awburst(s00_axi_awburst),
|
||||
.s_axi_awcache(s00_axi_awcache),
|
||||
.s_axi_awaddr(s00_axi_awaddr[30:0] ),
|
||||
.s_axi_awprot(s00_axi_awprot),
|
||||
.s_axi_awid(m_axi_awid),
|
||||
.s_axi_awlen(m_axi_awlen),
|
||||
.s_axi_awsize(m_axi_awsize),
|
||||
.s_axi_awburst(m_axi_awburst),
|
||||
.s_axi_awcache(m_axi_awcache),
|
||||
.s_axi_awaddr(m_axi_awaddr[30:0] ),
|
||||
.s_axi_awprot(m_axi_awprot),
|
||||
.s_axi_awregion(4'b0), // this could be a bug. bridge does not have these outputs
|
||||
.s_axi_awqos(4'b0), // this could be a bug. bridge does not have these outputs
|
||||
.s_axi_awvalid(s00_axi_awvalid),
|
||||
.s_axi_awready(s00_axi_awready),
|
||||
.s_axi_awlock(s00_axi_awlock),
|
||||
.s_axi_wdata(s00_axi_wdata),
|
||||
.s_axi_wstrb(s00_axi_wstrb),
|
||||
.s_axi_wlast(s00_axi_wlast),
|
||||
.s_axi_wvalid(s00_axi_wvalid),
|
||||
.s_axi_wready(s00_axi_wready),
|
||||
.s_axi_bid(s00_axi_bid),
|
||||
.s_axi_bresp(s00_axi_bresp),
|
||||
.s_axi_bvalid(s00_axi_bvalid),
|
||||
.s_axi_bready(s00_axi_bready),
|
||||
.s_axi_arid(s00_axi_arid),
|
||||
.s_axi_arlen(s00_axi_arlen),
|
||||
.s_axi_arsize(s00_axi_arsize),
|
||||
.s_axi_arburst(s00_axi_arburst),
|
||||
.s_axi_arprot(s00_axi_arprot),
|
||||
.s_axi_awvalid(m_axi_awvalid),
|
||||
.s_axi_awready(m_axi_awready),
|
||||
.s_axi_awlock(m_axi_awlock),
|
||||
.s_axi_wdata(m_axi_wdata),
|
||||
.s_axi_wstrb(m_axi_wstrb),
|
||||
.s_axi_wlast(m_axi_wlast),
|
||||
.s_axi_wvalid(m_axi_wvalid),
|
||||
.s_axi_wready(m_axi_wready),
|
||||
.s_axi_bid(m_axi_bid),
|
||||
.s_axi_bresp(m_axi_bresp),
|
||||
.s_axi_bvalid(m_axi_bvalid),
|
||||
.s_axi_bready(m_axi_bready),
|
||||
.s_axi_arid(m_axi_arid),
|
||||
.s_axi_arlen(m_axi_arlen),
|
||||
.s_axi_arsize(m_axi_arsize),
|
||||
.s_axi_arburst(m_axi_arburst),
|
||||
.s_axi_arprot(m_axi_arprot),
|
||||
.s_axi_arregion(4'b0), // this could be a bug. bridge does not have these outputs
|
||||
.s_axi_arqos(4'b0), // this could be a bug. bridge does not have these outputs
|
||||
.s_axi_arcache(s00_axi_arcache),
|
||||
.s_axi_arvalid(s00_axi_arvalid),
|
||||
.s_axi_araddr(s00_axi_araddr[30:0]),
|
||||
.s_axi_arlock(s00_axi_arlock),
|
||||
.s_axi_arready(s00_axi_arready),
|
||||
.s_axi_rid(s00_axi_rid),
|
||||
.s_axi_rdata(s00_axi_rdata),
|
||||
.s_axi_rresp(s00_axi_rresp),
|
||||
.s_axi_rvalid(s00_axi_rvalid),
|
||||
.s_axi_rlast(s00_axi_rlast),
|
||||
.s_axi_rready(s00_axi_rready),
|
||||
.s_axi_arcache(m_axi_arcache),
|
||||
.s_axi_arvalid(m_axi_arvalid),
|
||||
.s_axi_araddr(m_axi_araddr[30:0]),
|
||||
.s_axi_arlock(m_axi_arlock),
|
||||
.s_axi_arready(m_axi_arready),
|
||||
.s_axi_rid(m_axi_rid),
|
||||
.s_axi_rdata(m_axi_rdata),
|
||||
.s_axi_rresp(m_axi_rresp),
|
||||
.s_axi_rvalid(m_axi_rvalid),
|
||||
.s_axi_rlast(m_axi_rlast),
|
||||
.s_axi_rready(m_axi_rready),
|
||||
|
||||
.m_axi_aclk(BUSCLK),
|
||||
.m_axi_aresetn(resetn),
|
||||
@ -1037,6 +399,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1)
|
||||
.m_axi_rlast(BUS_axi_rlast),
|
||||
.m_axi_rready(BUS_axi_rready));
|
||||
|
||||
// DDR3 Controller
|
||||
xlnx_ddr3 xlnx_ddr3_c0
|
||||
(
|
||||
// ddr3 I/O
|
||||
|
@ -17,6 +17,7 @@ OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS))
|
||||
|
||||
TARGETDIR := bin
|
||||
TARGET := $(TARGETDIR)/boot
|
||||
MEMFILES := $(TARGETDIR/boot.mem $(TARGETDIR)/data.mem
|
||||
ROOT := ..
|
||||
LIBRARY_DIRS :=
|
||||
LIBRARY_FILES :=
|
||||
@ -37,7 +38,7 @@ AR=riscv64-unknown-elf-ar
|
||||
|
||||
|
||||
#Default Make
|
||||
all: directories $(TARGET).memfile
|
||||
all: directories $(TARGET).memfile
|
||||
|
||||
#Remake
|
||||
remake: clean all
|
||||
@ -48,7 +49,7 @@ directories:
|
||||
@mkdir -p $(BUILDDIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump
|
||||
rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump boot.mem data.mem
|
||||
|
||||
|
||||
#Needed for building additional library projects
|
||||
@ -112,3 +113,7 @@ $(TARGET).memfile: $(TARGET)
|
||||
extractFunctionRadix.sh $<.objdump
|
||||
mkdir -p ../../imperas-riscv-tests/work/rv64BP/
|
||||
cp -f $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/
|
||||
@echo 'Splitting memfile.'
|
||||
./splitfile.sh $@
|
||||
mv boot.mem ../src/boot.mem
|
||||
mv data.mem ../src/data.mem
|
||||
|
532
fpga/zsbl/boot.c
532
fpga/zsbl/boot.c
@ -1,422 +1,146 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// boot.c
|
||||
//
|
||||
// Written: Jacob Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Main bootloader entry point
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 <stddef.h>
|
||||
#include "boot.h"
|
||||
#include "gpt.h"
|
||||
#include "uart.h"
|
||||
#include "spi.h"
|
||||
#include "sd.h"
|
||||
#include "time.h"
|
||||
#include "riscv.h"
|
||||
#include "fail.h"
|
||||
|
||||
/* Card type flags (card_type) */
|
||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
||||
#define CT_SD1 0x02 /* SD ver 1 */
|
||||
#define CT_SD2 0x04 /* SD ver 2 */
|
||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
||||
#define CT_BLOCK 0x08 /* Block addressing */
|
||||
int disk_read(BYTE * buf, LBA_t sector, UINT count) {
|
||||
uint64_t r;
|
||||
UINT i;
|
||||
volatile uint8_t *p = buf;
|
||||
|
||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (1) /* SEND_OP_COND */
|
||||
#define CMD2 (2) /* SEND_CID */
|
||||
#define CMD3 (3) /* RELATIVE_ADDR */
|
||||
#define CMD4 (4)
|
||||
#define CMD5 (5) /* SLEEP_WAKE (SDC) */
|
||||
#define CMD6 (6) /* SWITCH_FUNC */
|
||||
#define CMD7 (7) /* SELECT */
|
||||
#define CMD8 (8) /* SEND_IF_COND */
|
||||
#define CMD9 (9) /* SEND_CSD */
|
||||
#define CMD10 (10) /* SEND_CID */
|
||||
#define CMD11 (11)
|
||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
||||
#define CMD13 (13)
|
||||
#define CMD15 (15)
|
||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD19 (19)
|
||||
#define CMD20 (20)
|
||||
#define CMD23 (23)
|
||||
#define CMD24 (24)
|
||||
#define CMD25 (25)
|
||||
#define CMD27 (27)
|
||||
#define CMD28 (28)
|
||||
#define CMD29 (29)
|
||||
#define CMD30 (30)
|
||||
#define CMD32 (32)
|
||||
#define CMD33 (33)
|
||||
#define CMD38 (38)
|
||||
#define CMD42 (42)
|
||||
#define CMD55 (55) /* APP_CMD */
|
||||
#define CMD56 (56)
|
||||
#define ACMD6 (0x80+6) /* define the data bus width */
|
||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (ACMD) */
|
||||
UINT modulus = count/50;
|
||||
|
||||
// Capability bits
|
||||
#define SDC_CAPABILITY_SD_4BIT 0x0001
|
||||
#define SDC_CAPABILITY_SD_RESET 0x0002
|
||||
#define SDC_CAPABILITY_ADDR 0xff00
|
||||
|
||||
// Control bits
|
||||
#define SDC_CONTROL_SD_4BIT 0x0001
|
||||
#define SDC_CONTROL_SD_RESET 0x0002
|
||||
|
||||
// Card detect bits
|
||||
#define SDC_CARD_INSERT_INT_EN 0x0001
|
||||
#define SDC_CARD_INSERT_INT_REQ 0x0002
|
||||
#define SDC_CARD_REMOVE_INT_EN 0x0004
|
||||
#define SDC_CARD_REMOVE_INT_REQ 0x0008
|
||||
|
||||
// Command status bits
|
||||
#define SDC_CMD_INT_STATUS_CC 0x0001 // Command complete
|
||||
#define SDC_CMD_INT_STATUS_EI 0x0002 // Any error
|
||||
#define SDC_CMD_INT_STATUS_CTE 0x0004 // Timeout
|
||||
#define SDC_CMD_INT_STATUS_CCRC 0x0008 // CRC error
|
||||
#define SDC_CMD_INT_STATUS_CIE 0x0010 // Command code check error
|
||||
|
||||
// Data status bits
|
||||
#define SDC_DAT_INT_STATUS_TRS 0x0001 // Transfer complete
|
||||
#define SDC_DAT_INT_STATUS_ERR 0x0002 // Any error
|
||||
#define SDC_DAT_INT_STATUS_CTE 0x0004 // Timeout
|
||||
#define SDC_DAT_INT_STATUS_CRC 0x0008 // CRC error
|
||||
#define SDC_DAT_INT_STATUS_CFE 0x0010 // Data FIFO underrun or overrun
|
||||
|
||||
|
||||
#define ERR_EOF 30
|
||||
#define ERR_NOT_ELF 31
|
||||
#define ERR_ELF_BITS 32
|
||||
#define ERR_ELF_ENDIANNESS 33
|
||||
#define ERR_CMD_CRC 34
|
||||
#define ERR_CMD_CHECK 35
|
||||
#define ERR_DATA_CRC 36
|
||||
#define ERR_DATA_FIFO 37
|
||||
#define ERR_BUF_ALIGNMENT 38
|
||||
#define FR_DISK_ERR 39
|
||||
#define FR_TIMEOUT 40
|
||||
|
||||
struct sdc_regs {
|
||||
volatile uint32_t argument;
|
||||
volatile uint32_t command;
|
||||
volatile uint32_t response1;
|
||||
volatile uint32_t response2;
|
||||
volatile uint32_t response3;
|
||||
volatile uint32_t response4;
|
||||
volatile uint32_t data_timeout;
|
||||
volatile uint32_t control;
|
||||
volatile uint32_t cmd_timeout;
|
||||
volatile uint32_t clock_divider;
|
||||
volatile uint32_t software_reset;
|
||||
volatile uint32_t power_control;
|
||||
volatile uint32_t capability;
|
||||
volatile uint32_t cmd_int_status;
|
||||
volatile uint32_t cmd_int_enable;
|
||||
volatile uint32_t dat_int_status;
|
||||
volatile uint32_t dat_int_enable;
|
||||
volatile uint32_t block_size;
|
||||
volatile uint32_t block_count;
|
||||
volatile uint32_t card_detect;
|
||||
volatile uint32_t res_50;
|
||||
volatile uint32_t res_54;
|
||||
volatile uint32_t res_58;
|
||||
volatile uint32_t res_5c;
|
||||
volatile uint64_t dma_addres;
|
||||
};
|
||||
|
||||
#define MAX_BLOCK_CNT 0x1000
|
||||
|
||||
#define SDC 0x00013000;
|
||||
|
||||
// static struct sdc_regs * const regs __attribute__((section(".rodata"))) = (struct sdc_regs *)0x00013000;
|
||||
|
||||
// static int errno __attribute__((section(".bss")));
|
||||
// static DSTATUS drv_status __attribute__((section(".bss")));
|
||||
// static BYTE card_type __attribute__((section(".bss")));
|
||||
// static uint32_t response[4] __attribute__((section(".bss")));
|
||||
// static int alt_mem __attribute__((section(".bss")));
|
||||
|
||||
/*static const char * errno_to_str(void) {
|
||||
switch (errno) {
|
||||
case ERR_EOF: return "Unexpected EOF";
|
||||
case ERR_NOT_ELF: return "Not an ELF file";
|
||||
case ERR_ELF_BITS: return "Wrong ELF word size";
|
||||
case ERR_ELF_ENDIANNESS: return "Wrong ELF endianness";
|
||||
case ERR_CMD_CRC: return "Command CRC error";
|
||||
case ERR_CMD_CHECK: return "Command code check error";
|
||||
case ERR_DATA_CRC: return "Data CRC error";
|
||||
case ERR_DATA_FIFO: return "Data FIFO error";
|
||||
case ERR_BUF_ALIGNMENT: return "Bad buffer alignment";
|
||||
case FR_DISK_ERR: return "Disk error";
|
||||
case FR_TIMEOUT: return "Timeout";
|
||||
}
|
||||
return "Unknown error code";
|
||||
}*/
|
||||
|
||||
static void usleep(unsigned us) {
|
||||
uintptr_t cycles0;
|
||||
uintptr_t cycles1;
|
||||
asm volatile ("csrr %0, 0xB00" : "=r" (cycles0));
|
||||
for (;;) {
|
||||
asm volatile ("csrr %0, 0xB00" : "=r" (cycles1));
|
||||
if (cycles1 - cycles0 >= us * 100) break;
|
||||
}
|
||||
}
|
||||
|
||||
static int sdc_cmd_finish(unsigned cmd, uint32_t * response) {
|
||||
struct sdc_regs * regs = (struct sdc_regs *)SDC;
|
||||
uint8_t crc = 0;
|
||||
crc = crc7(crc, 0x40 | SD_CMD_READ_BLOCK_MULTIPLE);
|
||||
crc = crc7(crc, (sector >> 24) & 0xff);
|
||||
crc = crc7(crc, (sector >> 16) & 0xff);
|
||||
crc = crc7(crc, (sector >> 8) & 0xff);
|
||||
crc = crc7(crc, sector & 0xff);
|
||||
crc = crc | 1;
|
||||
|
||||
while (1) {
|
||||
unsigned status = regs->cmd_int_status;
|
||||
if (status) {
|
||||
// clear interrupts
|
||||
regs->cmd_int_status = 0;
|
||||
while (regs->software_reset != 0) {}
|
||||
if (status == SDC_CMD_INT_STATUS_CC) {
|
||||
// get response
|
||||
response[0] = regs->response1;
|
||||
response[1] = regs->response2;
|
||||
response[2] = regs->response3;
|
||||
response[3] = regs->response4;
|
||||
return 0;
|
||||
}
|
||||
/* errno = FR_DISK_ERR;
|
||||
if (status & SDC_CMD_INT_STATUS_CTE) errno = FR_TIMEOUT;
|
||||
if (status & SDC_CMD_INT_STATUS_CCRC) errno = ERR_CMD_CRC;
|
||||
if (status & SDC_CMD_INT_STATUS_CIE) errno = ERR_CMD_CHECK;*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if ((r = sd_cmd(18, sector & 0xffffffff, crc) & 0xff) != 0x00) {
|
||||
print_uart("disk_read: CMD18 failed. r = 0x");
|
||||
print_uart_byte(r);
|
||||
print_uart("\r\n");
|
||||
fail();
|
||||
// return -1;
|
||||
}
|
||||
|
||||
static int sdc_data_finish(void) {
|
||||
int status;
|
||||
struct sdc_regs * regs = (struct sdc_regs *)SDC;
|
||||
print_uart("\r Blocks loaded: ");
|
||||
print_uart("0");
|
||||
print_uart("/");
|
||||
print_uart_dec(count);
|
||||
// write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_HOLD);
|
||||
// Begin reading blocks
|
||||
for (i = 0; i < count; i++) {
|
||||
uint16_t crc, crc_exp;
|
||||
uint64_t n = 0;
|
||||
|
||||
// Wait for data token
|
||||
while((r = spi_dummy()) != SD_DATA_TOKEN);
|
||||
// println_with_byte("Received data token: 0x", r & 0xff);
|
||||
|
||||
// println_with_dec("Block ", i);
|
||||
// Read block into memory.
|
||||
/* for (int j = 0; j < 64; j++) { */
|
||||
/* *buf = sd_read64(&crc); */
|
||||
/* println_with_addr("0x", *buf); */
|
||||
/* buf = buf + 64; */
|
||||
/* } */
|
||||
crc = 0;
|
||||
n = 512;
|
||||
do {
|
||||
uint8_t x = spi_dummy();
|
||||
*p++ = x;
|
||||
crc = crc16(crc, x);
|
||||
} while (--n > 0);
|
||||
|
||||
while ((status = regs->dat_int_status) == 0) {}
|
||||
regs->dat_int_status = 0;
|
||||
while (regs->software_reset != 0) {}
|
||||
// Read CRC16 and check
|
||||
crc_exp = ((uint16_t)spi_dummy() << 8);
|
||||
crc_exp |= spi_dummy();
|
||||
|
||||
if (status == SDC_DAT_INT_STATUS_TRS) return 0;
|
||||
/* errno = FR_DISK_ERR;
|
||||
if (status & SDC_DAT_INT_STATUS_CTE) errno = FR_TIMEOUT;
|
||||
if (status & SDC_DAT_INT_STATUS_CRC) errno = ERR_DATA_CRC;
|
||||
if (status & SDC_DAT_INT_STATUS_CFE) errno = ERR_DATA_FIFO;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int send_data_cmd(unsigned cmd, unsigned arg, void * buf, unsigned blocks, uint32_t * response) {
|
||||
struct sdc_regs * regs = (struct sdc_regs *)SDC;
|
||||
|
||||
unsigned command = (cmd & 0x3f) << 8;
|
||||
switch (cmd) {
|
||||
case CMD0:
|
||||
case CMD4:
|
||||
case CMD15:
|
||||
// No responce
|
||||
break;
|
||||
case CMD11:
|
||||
case CMD13:
|
||||
case CMD16:
|
||||
case CMD17:
|
||||
case CMD18:
|
||||
case CMD19:
|
||||
case CMD23:
|
||||
case CMD24:
|
||||
case CMD25:
|
||||
case CMD27:
|
||||
case CMD30:
|
||||
case CMD32:
|
||||
case CMD33:
|
||||
case CMD42:
|
||||
case CMD55:
|
||||
case CMD56:
|
||||
case ACMD6:
|
||||
// R1
|
||||
command |= 1; // 48 bits
|
||||
command |= 1 << 3; // resp CRC
|
||||
command |= 1 << 4; // resp OPCODE
|
||||
break;
|
||||
case CMD7:
|
||||
case CMD12:
|
||||
case CMD20:
|
||||
case CMD28:
|
||||
case CMD29:
|
||||
case CMD38:
|
||||
// R1b
|
||||
command |= 1; // 48 bits
|
||||
command |= 1 << 2; // busy
|
||||
command |= 1 << 3; // resp CRC
|
||||
command |= 1 << 4; // resp OPCODE
|
||||
break;
|
||||
case CMD2:
|
||||
case CMD9:
|
||||
case CMD10:
|
||||
// R2
|
||||
command |= 2; // 136 bits
|
||||
command |= 1 << 3; // resp CRC
|
||||
break;
|
||||
case ACMD41:
|
||||
// R3
|
||||
command |= 1; // 48 bits
|
||||
break;
|
||||
case CMD3:
|
||||
// R6
|
||||
command |= 1; // 48 bits
|
||||
command |= 1 << 2; // busy
|
||||
command |= 1 << 3; // resp CRC
|
||||
command |= 1 << 4; // resp OPCODE
|
||||
break;
|
||||
case CMD8:
|
||||
// R7
|
||||
command |= 1; // 48 bits
|
||||
command |= 1 << 3; // resp CRC
|
||||
command |= 1 << 4; // resp OPCODE
|
||||
break;
|
||||
if (crc != crc_exp) {
|
||||
print_uart("Stinking CRC16 didn't match on block read.\r\n");
|
||||
print_uart_int(i);
|
||||
print_uart("\r\n");
|
||||
//return -1;
|
||||
fail();
|
||||
}
|
||||
|
||||
if (blocks) {
|
||||
command |= 1 << 5;
|
||||
if ((intptr_t)buf & 3) {
|
||||
// errno = ERR_BUF_ALIGNMENT;
|
||||
return -1;
|
||||
}
|
||||
regs->dma_addres = (uint64_t)(intptr_t)buf;
|
||||
regs->block_size = 511;
|
||||
regs->block_count = blocks - 1;
|
||||
regs->data_timeout = 0x1FFFFFF;
|
||||
if ( (i % modulus) == 0 ) {
|
||||
print_uart("\r Blocks loaded: ");
|
||||
print_uart_dec(i);
|
||||
print_uart("/");
|
||||
print_uart_dec(count);
|
||||
}
|
||||
|
||||
regs->command = command;
|
||||
regs->cmd_timeout = 0xFFFFF;
|
||||
regs->argument = arg;
|
||||
}
|
||||
|
||||
if (sdc_cmd_finish(cmd, response) < 0) return -1;
|
||||
if (blocks) return sdc_data_finish();
|
||||
sd_cmd(SD_CMD_STOP_TRANSMISSION, 0, 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define send_cmd(cmd, arg, response) send_data_cmd(cmd, arg, NULL, 0, response)
|
||||
|
||||
static BYTE ini_sd(void) {
|
||||
struct sdc_regs * regs = (struct sdc_regs *)SDC;
|
||||
unsigned rca;
|
||||
BYTE card_type;
|
||||
uint32_t response[4];
|
||||
|
||||
/* Reset controller */
|
||||
regs->software_reset = 1;
|
||||
while ((regs->software_reset & 1) == 0) {}
|
||||
|
||||
// This clock divider is meant to initialize the card at
|
||||
// 400kHz
|
||||
|
||||
// 22MHz/400kHz = 55 (base 10) = 0x37 - 0x01 = 0x36
|
||||
regs->clock_divider = 0x36;
|
||||
regs->software_reset = 0;
|
||||
while (regs->software_reset) {}
|
||||
usleep(5000);
|
||||
|
||||
card_type = 0;
|
||||
// drv_status = STA_NOINIT;
|
||||
|
||||
if (regs->capability & SDC_CAPABILITY_SD_RESET) {
|
||||
/* Power cycle SD card */
|
||||
regs->control |= SDC_CONTROL_SD_RESET;
|
||||
usleep(1000000);
|
||||
regs->control &= ~SDC_CONTROL_SD_RESET;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
/* Enter Idle state */
|
||||
send_cmd(CMD0, 0, response);
|
||||
|
||||
card_type = CT_SD1;
|
||||
if (send_cmd(CMD8, 0x1AA, response) == 0) {
|
||||
if ((response[0] & 0xfff) != 0x1AA) {
|
||||
// errno = ERR_CMD_CHECK;
|
||||
return -1;
|
||||
}
|
||||
card_type = CT_SD2;
|
||||
}
|
||||
|
||||
/* Wait for leaving idle state (ACMD41 with HCS bit) */
|
||||
while (1) {
|
||||
/* ACMD41, Set Operating Conditions: Host High Capacity & 3.3V */
|
||||
if (send_cmd(CMD55, 0, response) < 0 || send_cmd(ACMD41, 0x40300000, response) < 0) return -1;
|
||||
if (response[0] & (1 << 31)) {
|
||||
if (response[0] & (1 << 30)) card_type |= CT_BLOCK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enter Identification state */
|
||||
if (send_cmd(CMD2, 0, response) < 0) return -1;
|
||||
|
||||
/* Get RCA (Relative Card Address) */
|
||||
rca = 0x1234;
|
||||
if (send_cmd(CMD3, rca << 16, response) < 0) return -1;
|
||||
rca = response[0] >> 16;
|
||||
|
||||
/* Select card */
|
||||
if (send_cmd(CMD7, rca << 16, response) < 0) return -1;
|
||||
|
||||
/* Clock 25MHz */
|
||||
// 22Mhz/2 = 11Mhz
|
||||
regs->clock_divider = 1;
|
||||
usleep(10000);
|
||||
|
||||
/* Bus width 1-bit */
|
||||
regs->control = 0;
|
||||
if (send_cmd(CMD55, rca << 16, response) < 0 || send_cmd(ACMD6, 0, response) < 0) return -1;
|
||||
|
||||
/* Set R/W block length to 512 */
|
||||
if (send_cmd(CMD16, 512, response) < 0) return -1;
|
||||
|
||||
// drv_status &= ~STA_NOINIT;
|
||||
return card_type;
|
||||
}
|
||||
|
||||
int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type) {
|
||||
|
||||
/* This is not needed. This has everything to do with the FAT
|
||||
filesystem stuff that I'm not including. All I need to do is
|
||||
initialize the SD card and read from it. Anything in here that is
|
||||
checking for potential errors, I'm going to have to temporarily
|
||||
do without.
|
||||
*/
|
||||
// if (!count) return RES_PARERR;
|
||||
/* if (drv_status & STA_NOINIT) return RES_NOTRDY; */
|
||||
|
||||
uint32_t response[4];
|
||||
struct sdc_regs * regs = (struct sdc_regs *)SDC;
|
||||
|
||||
/* Convert LBA to byte address if needed */
|
||||
if (!(card_type & CT_BLOCK)) sector *= 512;
|
||||
while (count > 0) {
|
||||
UINT bcnt = count > MAX_BLOCK_CNT ? MAX_BLOCK_CNT : count;
|
||||
unsigned bytes = bcnt * 512;
|
||||
if (send_data_cmd(bcnt == 1 ? CMD17 : CMD18, sector, buf, bcnt, response) < 0) return 1;
|
||||
if (bcnt > 1 && send_cmd(CMD12, 0, response) < 0) return 1;
|
||||
sector += (card_type & CT_BLOCK) ? bcnt : bytes;
|
||||
count -= bcnt;
|
||||
buf += bytes;
|
||||
}
|
||||
|
||||
return 0;;
|
||||
}
|
||||
|
||||
void copyFlash(QWORD address, QWORD * Dst, DWORD numBlocks) {
|
||||
BYTE card_type;
|
||||
int ret = 0;
|
||||
|
||||
card_type = ini_sd();
|
||||
|
||||
// BYTE * buf = (BYTE *)Dst;
|
||||
|
||||
// if (disk_read(buf, (LBA_t)address, (UINT)numBlocks, card_type) < 0) /* UART Print function?*/;
|
||||
|
||||
ret = gpt_load_partitions(card_type);
|
||||
}
|
||||
|
||||
/*
|
||||
int main() {
|
||||
ini_sd();
|
||||
|
||||
|
||||
print_uart("\r Blocks loaded: ");
|
||||
print_uart_dec(count);
|
||||
print_uart("/");
|
||||
print_uart_dec(count);
|
||||
// write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
|
||||
//spi_txrx(0xff);
|
||||
print_uart("\r\n");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// copyFlash: --------------------------------------------------------
|
||||
// A lot happens in this function:
|
||||
// * The Wally banner is printed
|
||||
// * The peripherals are initialized
|
||||
void copyFlash(QWORD address, QWORD * Dst, DWORD numBlocks) {
|
||||
int ret = 0;
|
||||
|
||||
// Initialize UART for messages
|
||||
init_uart(20000000, 115200);
|
||||
|
||||
// Print the wally banner
|
||||
print_uart(BANNER);
|
||||
|
||||
/* print_uart("System clock speed: "); */
|
||||
/* print_uart_dec(SYSTEMCLOCK); */
|
||||
/* print_uart("\r\n"); */
|
||||
|
||||
// Intialize the SD card
|
||||
init_sd(SYSTEMCLOCK, 5000000);
|
||||
|
||||
ret = gpt_load_partitions();
|
||||
}
|
||||
|
@ -1,3 +1,32 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// boot.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Header for boot.c, main bootloader entry point
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WALLYBOOT
|
||||
#define WALLYBOOT 10000
|
||||
|
||||
@ -19,8 +48,20 @@ typedef QWORD LBA_t;
|
||||
#define OPENSBI_ADDRESS 0x80000000 // FW_TEXT_START
|
||||
#define KERNEL_ADDRESS 0x80200000 // FW_JUMP_ADDR
|
||||
|
||||
#define BANNER " █▀█ █▀█ █▀█ █▀▀ █ █\r\n" \
|
||||
" █ █ █ █▄▀ █▄▄ ▄▄▄ █ █\r\n" \
|
||||
" █▄█ █▄█ █ █ █▄▄ ▀▄▀\r\n" \
|
||||
" ____ ____ ____ ___ ___ ____ ___\r\n" \
|
||||
" \\ \\ / / / \\ | | | | \\ \\ / /\r\n" \
|
||||
" \\ \\ __ / / / \\ | | | | \\ \\/ /\r\n" \
|
||||
" \\ \\/ \\/ / / /\\ \\ | | | | \\ /\r\n" \
|
||||
" \\ / / ____ \\ | |___ | |___ | |\r\n" \
|
||||
" \\___/\\___/ /___/ \\___\\|_______||_______| |___|\r\n\r\n"
|
||||
|
||||
// Export disk_read
|
||||
int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type);
|
||||
int disk_read(BYTE * buf, LBA_t sector, UINT count);
|
||||
|
||||
#define SYSTEMCLOCK 20000000
|
||||
|
||||
#endif // WALLYBOOT
|
||||
|
||||
|
49
fpga/zsbl/fail.c
Normal file
49
fpga/zsbl/fail.c
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// fail.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Prints information on the uart when a fatal bug is
|
||||
// encountered. Will expand this later.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 "fail.h"
|
||||
#include "uart.h"
|
||||
#include "riscv.h"
|
||||
#include "time.h"
|
||||
|
||||
void fail() {
|
||||
// Get address that led to failure
|
||||
register uint64_t addr;
|
||||
asm volatile ("mv %0, ra" : "=r"(addr) : : "memory");
|
||||
|
||||
// Print message
|
||||
print_time();
|
||||
println_with_addr("Failed at: 0x", addr);
|
||||
|
||||
// Loop forever
|
||||
while(1) {
|
||||
|
||||
}
|
||||
}
|
33
fpga/zsbl/fail.h
Normal file
33
fpga/zsbl/fail.h
Normal file
@ -0,0 +1,33 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// fail.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Function prototype for fail,
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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
|
||||
#include <stdint.h>
|
||||
|
||||
void fail();
|
@ -1,19 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// gpt.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Code to read GPT Partitions off of an SD card.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 "gpt.h"
|
||||
#include "boot.h"
|
||||
#include "uart.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/* PSUEDOCODE
|
||||
|
||||
Need to load GPT LBA 1 and read through the partition entries.
|
||||
I need to find each of the relevant partition entries, possibly
|
||||
by their partition names.
|
||||
|
||||
*/
|
||||
|
||||
int gpt_load_partitions(BYTE card_type) {
|
||||
// In this version of the GPT partition code
|
||||
// I'm going to assume that the SD card is already initialized.
|
||||
|
||||
int gpt_load_partitions() {
|
||||
// size_t block_size = 512/8;
|
||||
// long int lba1_buf[block_size];
|
||||
|
||||
@ -21,26 +40,51 @@ int gpt_load_partitions(BYTE card_type) {
|
||||
|
||||
int ret = 0;
|
||||
//ret = disk_read(/* BYTE * buf, LBA_t sector, UINT count, BYTE card_type */);
|
||||
ret = disk_read(lba1_buf, 1, 1, card_type);
|
||||
|
||||
/* Possible error handling with UART message
|
||||
if ( ret != 0 ) {
|
||||
|
||||
}*/
|
||||
print_time();
|
||||
println("Getting GPT information.");
|
||||
ret = disk_read(lba1_buf, 1, 1);
|
||||
|
||||
gpt_pth_t *lba1 = (gpt_pth_t *)lba1_buf;
|
||||
|
||||
print_time();
|
||||
println("Getting partition entries.");
|
||||
BYTE lba2_buf[512];
|
||||
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1, card_type);
|
||||
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1);
|
||||
|
||||
// Load parition entries for the relevant boot partitions.
|
||||
partition_entries_t *fdt = (partition_entries_t *)(lba2_buf);
|
||||
partition_entries_t *opensbi = (partition_entries_t *)(lba2_buf + 128);
|
||||
partition_entries_t *kernel = (partition_entries_t *)(lba2_buf + 256);
|
||||
|
||||
ret = disk_read((BYTE *)FDT_ADDRESS, fdt->first_lba, fdt->last_lba - fdt->first_lba + 1, card_type);
|
||||
ret = disk_read((BYTE *)OPENSBI_ADDRESS, opensbi->first_lba, opensbi->last_lba - opensbi->first_lba + 1, card_type);
|
||||
ret = disk_read((BYTE *)KERNEL_ADDRESS, kernel->first_lba,kernel->last_lba - kernel->first_lba + 1, card_type);
|
||||
// Load device tree
|
||||
print_time();
|
||||
println_with_int("Loading device tree at: 0x", FDT_ADDRESS);
|
||||
ret = disk_read((BYTE *)FDT_ADDRESS, fdt->first_lba, fdt->last_lba - fdt->first_lba + 1);
|
||||
if (ret < 0) {
|
||||
print_uart("Failed to load device tree!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load OpenSBI
|
||||
print_time();
|
||||
println_with_int("Loading OpenSBI at: 0x", OPENSBI_ADDRESS);
|
||||
ret = disk_read((BYTE *)OPENSBI_ADDRESS, opensbi->first_lba, opensbi->last_lba - opensbi->first_lba + 1);
|
||||
if (ret < 0) {
|
||||
print_uart("Failed to load OpenSBI!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load Linux
|
||||
print_time();
|
||||
println_with_int("Loading Linux Kernel at: 0x", KERNEL_ADDRESS);
|
||||
ret = disk_read((BYTE *)KERNEL_ADDRESS, kernel->first_lba,kernel->last_lba - kernel->first_lba + 1);
|
||||
if (ret < 0) {
|
||||
print_uart("Failed to load Linux!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
print_time();
|
||||
println("Done! Flashing LEDs and jumping to OpenSBI...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1,32 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// gpt.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Header for gpt.c, contains gpt structs
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <stdint.h>
|
||||
@ -37,4 +66,4 @@ typedef struct partition_entries
|
||||
} partition_entries_t;
|
||||
|
||||
// Find boot partition and load it to the destination
|
||||
int gpt_load_partitions(BYTE card_type);
|
||||
int gpt_load_partitions();
|
||||
|
58
fpga/zsbl/riscv.S
Normal file
58
fpga/zsbl/riscv.S
Normal file
@ -0,0 +1,58 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// riscv.S
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Basic utility functions for reading registers
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
.section .text
|
||||
.globl read_mcycle
|
||||
.type read_mcycle, @function
|
||||
read_mcycle:
|
||||
csrr a0, mcycle
|
||||
ret
|
||||
|
||||
.section .text
|
||||
.globl get_ra
|
||||
.type get_ra, @function
|
||||
get_ra:
|
||||
mv a0, ra
|
||||
ret
|
||||
|
||||
.section .text
|
||||
.globl set_status_fs
|
||||
.type set_status_fs, @function
|
||||
set_status_fs:
|
||||
lui t1, 0x6
|
||||
csrs mstatus, t1
|
||||
ret
|
||||
|
||||
.section .text
|
||||
.globl clear_status_fs
|
||||
.type clear_status_fs, @function
|
||||
clear_status_fs:
|
||||
lui t1, 0x6
|
||||
csrc mstatus, t1
|
||||
ret
|
36
fpga/zsbl/riscv.h
Normal file
36
fpga/zsbl/riscv.h
Normal file
@ -0,0 +1,36 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// riscv.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Function prototypes for riscv utility functions
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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
|
||||
#include <stdint.h>
|
||||
|
||||
uint64_t read_mcycle();
|
||||
uint64_t get_ra();
|
||||
void set_status_fs();
|
||||
void clear_status_fs();
|
255
fpga/zsbl/sd.c
Normal file
255
fpga/zsbl/sd.c
Normal file
@ -0,0 +1,255 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// sd.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: SD Card protocol functions
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 "sd.h"
|
||||
#include "spi.h"
|
||||
#include "uart.h"
|
||||
#include "fail.h"
|
||||
#include "time.h"
|
||||
|
||||
// Parallel byte update CRC7-CCITT algorithm.
|
||||
// The result is the CRC7 result, left shifted over by 1
|
||||
// which is perfect, since we append a 1 at the end anyway
|
||||
uint8_t crc7(uint8_t prev, uint8_t in) {
|
||||
// CRC polynomial 0x89
|
||||
uint8_t remainder = prev ^ in;
|
||||
remainder ^= (remainder >> 4) ^ (remainder >> 7);
|
||||
remainder = (remainder << 1) ^ (remainder << 4);
|
||||
return remainder & 0xff;
|
||||
}
|
||||
|
||||
// Need to check this. This could be wrong as well.
|
||||
uint16_t crc16(uint16_t crc, uint8_t data) {
|
||||
// CRC polynomial 0x11021
|
||||
crc = (uint8_t)(crc >> 8) | (crc << 8);
|
||||
crc ^= data;
|
||||
crc ^= (uint8_t)(crc >> 4) & 0xf;
|
||||
crc ^= crc << 12;
|
||||
crc ^= (crc & 0xff) << 5;
|
||||
return crc;
|
||||
}
|
||||
|
||||
// sd_cmd ------------------------------------------------------------
|
||||
// Sends SD card command using SPI mode.
|
||||
// This function:
|
||||
// * Chooses the response length based on the input command
|
||||
// * Makes use of SPI's full duplex. For every byte sent,
|
||||
// a byte is received. Thus for every byte sent as part of
|
||||
// a command, a useless byte must be read from the receive
|
||||
// FIFO.
|
||||
// * Takes advantage of the Sifive SPI peripheral spec's
|
||||
// watermark and interrupt features to determine when a
|
||||
// transfer is complete. This should save on cycles since
|
||||
// no arbitrary delays need to be added.
|
||||
|
||||
uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
|
||||
uint8_t response_len;
|
||||
uint8_t i;
|
||||
uint8_t shiftAmnt;
|
||||
uint64_t r;
|
||||
uint8_t rbyte;
|
||||
|
||||
// Initialize the response with 0's.
|
||||
r = 0;
|
||||
|
||||
// Choose response length based on cmd input.
|
||||
// Most commands return an R1 format response.
|
||||
switch (cmd) {
|
||||
case 8:
|
||||
response_len = R7_RESPONSE;
|
||||
break;
|
||||
case 12:
|
||||
response_len = R1B_RESPONSE;
|
||||
break;
|
||||
default:
|
||||
response_len = R1_RESPONSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make interrupt pending after response fifo receives the correct
|
||||
// response length. Probably unecessary so let's wait and see what
|
||||
// happens.
|
||||
// write_reg(SPI_RXMARK, response_len);
|
||||
|
||||
// Chip select must remain asserted during transaction
|
||||
if (cmd != SD_CMD_STOP_TRANSMISSION) {
|
||||
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_HOLD);
|
||||
}
|
||||
|
||||
// Write all 7 bytes into transfer fifo
|
||||
// spi_sendbyte(0xff);
|
||||
spi_dummy();
|
||||
spi_sendbyte(0x40 | cmd);
|
||||
spi_sendbyte(arg >> 24);
|
||||
spi_sendbyte(arg >> 16);
|
||||
spi_sendbyte(arg >> 8);
|
||||
spi_sendbyte(arg);
|
||||
spi_sendbyte(crc);
|
||||
|
||||
// Wait for command to send
|
||||
// The Transfer IP bit should go high when the txFIFO is empty
|
||||
// while(!(read_reg(SPI_IP) & 1)) {}
|
||||
waittx();
|
||||
|
||||
// Read the dummy rxFIFO entries to move the head back to the tail
|
||||
for (i = 0; i < 7; i++) {
|
||||
spi_readbyte();
|
||||
}
|
||||
|
||||
// Send "dummy signals". Since SPI is duplex,
|
||||
// useless bytes must be transferred
|
||||
/* for (i = 0; i < response_len; i++) { */
|
||||
/* spi_sendbyte(0xFF); */
|
||||
/* } */
|
||||
|
||||
/* // Wait for transfer fifo again */
|
||||
/* waittx(); */
|
||||
|
||||
// Wait for actual response from SD card
|
||||
// All responses start with a 0. Output of SDCIn is high, unless
|
||||
// a message is being transferred.
|
||||
do {
|
||||
rbyte = spi_dummy();
|
||||
} while ( (rbyte & 0x80) != 0 );
|
||||
|
||||
// Note about the compiler. In order to compile as sll instead of
|
||||
// sllw, the number to shift has to be a 64 bit number.
|
||||
r = ((uint64_t)rbyte) << ((response_len - 1)*8);
|
||||
|
||||
// Read rxfifo response
|
||||
for (i = 1; i < response_len; i++) {
|
||||
rbyte = spi_dummy();
|
||||
r = r | (((uint64_t)rbyte) << ((response_len - 1 - i)*8));
|
||||
}
|
||||
|
||||
if (cmd != 18) {
|
||||
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
|
||||
} else {
|
||||
spi_dummy();
|
||||
}
|
||||
return r;
|
||||
} // sd_cmd
|
||||
|
||||
uint64_t sd_read64(uint16_t * crc) {
|
||||
uint64_t r;
|
||||
uint8_t rbyte;
|
||||
int i;
|
||||
|
||||
/* for (i = 0; i < 8; i++) { */
|
||||
/* spi_sendbyte(0xFF); */
|
||||
/* } */
|
||||
|
||||
/* waittx(); */
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
rbyte = spi_dummy();
|
||||
*crc = crc16(*crc, rbyte);
|
||||
r = r | ((uint64_t)(rbyte) << ((8 - 1 - i)*8));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Utility defines for CMD0, CMD8, CMD55, and ACMD41
|
||||
#define CMD0() sd_cmd( 0, 0x00000000, 0x95) // Reset SD card into IDLE state
|
||||
#define CMD8() sd_cmd( 8, 0x000001aa, 0x87) //
|
||||
#define CMD55() sd_cmd(55, 0x00000000, 0x65) //
|
||||
#define ACMD41() sd_cmd(41, 0x40000000, 0x77) //
|
||||
|
||||
// init_sd: ----------------------------------------------------------
|
||||
// This first initializes the SPI peripheral then initializes the SD
|
||||
// card itself. We use the uart to display anything that goes wrong.
|
||||
int init_sd(uint32_t freq, uint32_t sdclk){
|
||||
print_time();
|
||||
println("Initializing SPI Controller.");
|
||||
spi_init();
|
||||
|
||||
uint64_t r;
|
||||
uint32_t newClockDiv;
|
||||
int n;
|
||||
|
||||
print_time();
|
||||
println("Initializing SD Card in SPI mode.");
|
||||
// This is necessary. This is the card's pre-init state initialization.
|
||||
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_OFF);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
spi_txrx(0xff);
|
||||
}
|
||||
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
|
||||
|
||||
// CMD0 --------------------------------------------------------------
|
||||
// Reset SD Card command
|
||||
// Initializes SD card into SPI mode if CS is asserted '0'
|
||||
// We expect to get the R1 response 0x01 which means that the
|
||||
// card has been put into the idle state.
|
||||
print_time();
|
||||
print_uart("CMD0: ");
|
||||
n = 0;
|
||||
do {
|
||||
r = CMD0();
|
||||
n++;
|
||||
if (n == 1000) {
|
||||
fail();
|
||||
}
|
||||
} while ( r != 0x01 );
|
||||
println_with_r1("Success, r = 0x", r & 0xff);
|
||||
|
||||
// CMD8 -------------------------------------------------------------
|
||||
//
|
||||
print_time();
|
||||
print_uart("CMD8: ");
|
||||
r = CMD8();
|
||||
if ((r & 0x000000ff0000ffff) != 0x01000001aa) {
|
||||
println_with_r7("Failed, 0x", r);
|
||||
fail();
|
||||
}
|
||||
println_with_r7("Success, 0x", r);
|
||||
|
||||
// ACMD41 -----------------------------------------------------------
|
||||
print_time();
|
||||
print_uart("ACMD41: ");
|
||||
n = 0;
|
||||
do {
|
||||
CMD55();
|
||||
r = ACMD41();
|
||||
n++;
|
||||
if (n == 1000) {
|
||||
fail();
|
||||
}
|
||||
} while (r == 0x1);
|
||||
println_with_r1("Success, r = 0x", r & 0xff);
|
||||
|
||||
print_time();
|
||||
println_with_dec("New clock frequency: ", (uint64_t)sdclk);
|
||||
spi_set_clock(freq, sdclk);
|
||||
|
||||
print_time();
|
||||
println("SD card is initialized.");
|
||||
}
|
||||
|
49
fpga/zsbl/sd.h
Normal file
49
fpga/zsbl/sd.h
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// sd.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Header file for SD card protocol functions. Defines some
|
||||
// useful macros.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Command names
|
||||
#define SD_CMD_STOP_TRANSMISSION 12
|
||||
#define SD_CMD_READ_BLOCK_MULTIPLE 18
|
||||
#define SD_DATA_TOKEN 0xfe
|
||||
|
||||
// Response lengths in bytes
|
||||
#define R1_RESPONSE 1
|
||||
#define R7_RESPONSE 5
|
||||
#define R1B_RESPONSE 2
|
||||
|
||||
uint8_t crc7(uint8_t prev, uint8_t in);
|
||||
uint16_t crc16(uint16_t crc, uint8_t data);
|
||||
uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc);
|
||||
uint64_t sd_read64(uint16_t * crc);
|
||||
int init_sd(uint32_t freq, uint32_t sdclk);
|
91
fpga/zsbl/spi.c
Normal file
91
fpga/zsbl/spi.c
Normal file
@ -0,0 +1,91 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spi.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: SPI Controller API for bootloader
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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"
|
||||
|
||||
uint8_t spi_txrx(uint8_t byte) {
|
||||
spi_sendbyte(byte);
|
||||
waittx();
|
||||
return spi_readbyte();
|
||||
}
|
||||
|
||||
uint8_t spi_dummy() {
|
||||
return spi_txrx(0xff);
|
||||
}
|
||||
|
||||
uint64_t spi_read64() {
|
||||
uint64_t r;
|
||||
uint8_t rbyte;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
spi_sendbyte(0xFF);
|
||||
}
|
||||
|
||||
waittx();
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
rbyte = spi_readbyte();
|
||||
r = r | (rbyte << ((8 - 1 - i)*8));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
87
fpga/zsbl/spi.h
Normal file
87
fpga/zsbl/spi.h
Normal file
@ -0,0 +1,87 @@
|
||||
#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
|
48
fpga/zsbl/splitfile.sh
Executable file
48
fpga/zsbl/splitfile.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#######################################################################
|
||||
# splitfile.sh
|
||||
#
|
||||
# Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
#
|
||||
# Purpose: Used to split boot.mem into two sections for FPGA
|
||||
#
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
######################################################################
|
||||
|
||||
|
||||
# Acquired from here.
|
||||
# https:##stackoverflow.com#questions#3066948#how-to-file-split-at-a-line-number
|
||||
file_name=$1
|
||||
|
||||
# set first K lines:
|
||||
K=512
|
||||
|
||||
# line count (N):
|
||||
N=$(wc -l < $file_name)
|
||||
|
||||
# length of the bottom file:
|
||||
L=$(( $N - $K ))
|
||||
|
||||
# create the top of file:
|
||||
head -n $K $file_name > boot.mem
|
||||
|
||||
# create bottom of file:
|
||||
tail -n $L $file_name > data.mem
|
49
fpga/zsbl/time.c
Normal file
49
fpga/zsbl/time.c
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// time.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Gets and prints the current time.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 "time.h"
|
||||
#include "boot.h"
|
||||
#include "riscv.h"
|
||||
#include "uart.h"
|
||||
|
||||
float getTime() {
|
||||
set_status_fs();
|
||||
float numCycles = (float)read_mcycle();
|
||||
float ret = numCycles/SYSTEMCLOCK;
|
||||
// clear_status_fs();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void print_time() {
|
||||
print_uart("[");
|
||||
set_status_fs();
|
||||
print_uart_float(getTime(),5);
|
||||
clear_status_fs();
|
||||
print_uart("] ");
|
||||
}
|
34
fpga/zsbl/time.h
Normal file
34
fpga/zsbl/time.h
Normal file
@ -0,0 +1,34 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spi.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Time function prototypes
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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
|
||||
#include <stdint.h>
|
||||
|
||||
float getTime();
|
||||
void print_time();
|
193
fpga/zsbl/uart.c
Normal file
193
fpga/zsbl/uart.c
Normal file
@ -0,0 +1,193 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// uart.c
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Uart printing functions, as well as functions for printing
|
||||
// hex, decimal, and floating point numbers.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 "uart.h"
|
||||
|
||||
void write_reg_u8(uintptr_t addr, uint8_t value)
|
||||
{
|
||||
volatile uint8_t *loc_addr = (volatile uint8_t *)addr;
|
||||
*loc_addr = value;
|
||||
}
|
||||
|
||||
uint8_t read_reg_u8(uintptr_t addr)
|
||||
{
|
||||
return *(volatile uint8_t *)addr;
|
||||
}
|
||||
|
||||
int is_transmit_empty()
|
||||
{
|
||||
return read_reg_u8(UART_LSR) & 0x20;
|
||||
}
|
||||
|
||||
int is_receive_empty()
|
||||
{
|
||||
return !(read_reg_u8(UART_LSR) & 0x1);
|
||||
}
|
||||
|
||||
void write_serial(char a)
|
||||
{
|
||||
while (is_transmit_empty() == 0) {};
|
||||
|
||||
write_reg_u8(UART_THR, a);
|
||||
}
|
||||
|
||||
void init_uart(uint32_t freq, uint32_t baud)
|
||||
{
|
||||
// Alternative divisor calculation. From OpenSBI code.
|
||||
// Reduces error for every possible frequency.
|
||||
uint32_t divisor = (freq + 8 * baud) /(baud << 4);
|
||||
|
||||
write_reg_u8(UART_IER, 0x00); // Disable all interrupts
|
||||
write_reg_u8(UART_LCR, 0x80); // Enable DLAB (set baud rate divisor)
|
||||
write_reg_u8(UART_DLL, divisor & 0xFF); // divisor (lo byte)
|
||||
write_reg_u8(UART_DLM, (divisor >> 8) & 0xFF); // divisor (hi byte)
|
||||
write_reg_u8(UART_LCR, 0x03); // 8 bits, no parity, one stop bit
|
||||
write_reg_u8(UART_FCR, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||
}
|
||||
|
||||
void print_uart(const char *str)
|
||||
{
|
||||
const char *cur = &str[0];
|
||||
while (*cur != '\0') {
|
||||
write_serial((uint8_t)*cur);
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t bin_to_hex_table[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
void bin_to_hex(uint8_t inp, uint8_t res[2])
|
||||
{
|
||||
res[1] = bin_to_hex_table[inp & 0xf];
|
||||
res[0] = bin_to_hex_table[(inp >> 4) & 0xf];
|
||||
return;
|
||||
}
|
||||
|
||||
void print_uart_hex(uint64_t addr, int n)
|
||||
{
|
||||
int i;
|
||||
for (i = n - 1; i > -1; i--) {
|
||||
uint8_t cur = (addr >> (i * 8)) & 0xff;
|
||||
uint8_t hex[2];
|
||||
bin_to_hex(cur, hex);
|
||||
write_serial(hex[0]);
|
||||
write_serial(hex[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void print_uart_dec(uint64_t addr) {
|
||||
|
||||
// floor(log(2^64)) = 19
|
||||
char str[19] = {'\0'};
|
||||
uint8_t length = 1;
|
||||
|
||||
uint64_t cur = addr;
|
||||
while (cur != 0) {
|
||||
char digit = bin_to_hex_table[cur % 10];
|
||||
// write_serial(digit);
|
||||
str[length] = digit;
|
||||
cur = cur/10;
|
||||
length++;
|
||||
}
|
||||
|
||||
for (int i = length; i > -1; i--) {
|
||||
write_serial(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Print a floating point number on the UART
|
||||
void print_uart_float(float num, int precision) {
|
||||
char str[32] = {'\0'};
|
||||
char digit;
|
||||
uint8_t length = precision + 1;
|
||||
int i;
|
||||
uint64_t cur;
|
||||
|
||||
str[precision] = '.';
|
||||
|
||||
int pow = 1;
|
||||
|
||||
// Calculate power for precision
|
||||
for (i = 0; i < precision; i++) {
|
||||
pow = pow * 10;
|
||||
}
|
||||
|
||||
cur = (uint64_t)(num * pow);
|
||||
for (i = 0; i < precision; i++) {
|
||||
digit = bin_to_hex_table[cur % 10];
|
||||
str[i] = digit;
|
||||
cur = cur / 10;
|
||||
}
|
||||
|
||||
cur = (uint64_t)num;
|
||||
do {
|
||||
digit = bin_to_hex_table[cur % 10];
|
||||
str[length] = digit;
|
||||
cur = cur/10;
|
||||
length++;
|
||||
} while (cur != 0);
|
||||
|
||||
for (i = length; i > -1; i--) {
|
||||
write_serial(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* void print_uart_int(uint32_t addr) */
|
||||
/* { */
|
||||
/* int i; */
|
||||
/* for (i = 3; i > -1; i--) { */
|
||||
/* uint8_t cur = (addr >> (i * 8)) & 0xff; */
|
||||
/* uint8_t hex[2]; */
|
||||
/* bin_to_hex(cur, hex); */
|
||||
/* write_serial(hex[0]); */
|
||||
/* write_serial(hex[1]); */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
/* void print_uart_addr(uint64_t addr) */
|
||||
/* { */
|
||||
/* int i; */
|
||||
/* for (i = 7; i > -1; i--) { */
|
||||
/* uint8_t cur = (addr >> (i * 8)) & 0xff; */
|
||||
/* uint8_t hex[2]; */
|
||||
/* bin_to_hex(cur, hex); */
|
||||
/* write_serial(hex[0]); */
|
||||
/* write_serial(hex[1]); */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
/* void print_uart_byte(uint8_t byte) */
|
||||
/* { */
|
||||
/* uint8_t hex[2]; */
|
||||
/* bin_to_hex(byte, hex); */
|
||||
/* write_serial(hex[0]); */
|
||||
/* write_serial(hex[1]); */
|
||||
/* } */
|
87
fpga/zsbl/uart.h
Normal file
87
fpga/zsbl/uart.h
Normal file
@ -0,0 +1,87 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// uart.h
|
||||
//
|
||||
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||
//
|
||||
// Purpose: Header for the UART functions.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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
|
||||
#include <stdint.h>
|
||||
#include "riscv.h"
|
||||
#include "time.h"
|
||||
|
||||
// UART register addresses
|
||||
#define UART_BASE 0x10000000
|
||||
|
||||
#define UART_RBR UART_BASE + 0x00
|
||||
#define UART_THR UART_BASE + 0x00
|
||||
#define UART_IER UART_BASE + 0x01
|
||||
#define UART_IIR UART_BASE + 0x02
|
||||
#define UART_FCR UART_BASE + 0x02
|
||||
#define UART_LCR UART_BASE + 0x03
|
||||
#define UART_MCR UART_BASE + 0x04
|
||||
#define UART_LSR UART_BASE + 0x05
|
||||
#define UART_MSR UART_BASE + 0x06
|
||||
#define UART_SCR UART_BASE + 0x07
|
||||
#define UART_DLL UART_BASE + 0x00
|
||||
#define UART_DLM UART_BASE + 0x01
|
||||
|
||||
// Primary function prototypes
|
||||
void init_uart(uint32_t freq, uint32_t baud);
|
||||
void write_reg_u8(uintptr_t addr, uint8_t value);
|
||||
uint8_t read_reg_u8(uintptr_t addr);
|
||||
int read_serial(uint8_t *res);
|
||||
void print_uart(const char* str);
|
||||
void print_uart_int(uint32_t addr);
|
||||
void print_uart_dec(uint64_t addr);
|
||||
void print_uart_addr(uint64_t addr);
|
||||
void print_uart_hex(uint64_t addr, int n);
|
||||
void print_uart_byte(uint8_t byte);
|
||||
void print_uart_float(float num, int precision);
|
||||
// void print_time();
|
||||
|
||||
// Print numbers in hex with specified widths
|
||||
#define print_uart_int(addr) print_uart_hex(addr, 4)
|
||||
#define print_uart_addr(addr) print_uart_hex(addr, 8)
|
||||
#define print_uart_byte(addr) print_uart_hex(addr, 1)
|
||||
#define print_r7(addr) print_uart_hex(addr, 5)
|
||||
#define print_r1(addr) print_uart_byte(addr)
|
||||
|
||||
// Print line with numbers utility macros
|
||||
#define println(msg) print_uart(msg "\r\n");
|
||||
#define println_with_dec(msg, num) print_uart(msg); print_uart_dec(num); print_uart("\r\n")
|
||||
#define println_with_byte(msg, num) print_uart(msg); print_uart_byte(num); print_uart("\r\n")
|
||||
#define println_with_int(msg, num) print_uart(msg); print_uart_int(num); print_uart("\r\n")
|
||||
#define println_with_addr(msg, num) print_uart(msg); print_uart_addr(num); print_uart("\r\n")
|
||||
#define println_with_r1(msg, num) print_uart(msg); print_r1(num); print_uart("\r\n")
|
||||
#define println_with_r7(msg, num) print_uart(msg); print_r7(num); print_uart("\r\n")
|
||||
#define println_with_float(msg, num) print_uart(msg); set_status_fs(); print_uart_float(num,5); clear_status_fs(); print_uart("\r\n")
|
||||
|
||||
/* #define print_time() print_uart("["); \ */
|
||||
/* set_status_fs(); \ */
|
||||
/* print_uart_float(getTime(),5); \ */
|
||||
/* clear_status_fs(); \ */
|
||||
/* print_uart("] ") */
|
||||
|
@ -107,7 +107,7 @@ $(IMAGES)/busybox:
|
||||
|
||||
# Generating new Buildroot directories --------------------------------
|
||||
|
||||
download: $(BUILDROOT)/package/fpga-axi-sdc $(WALLYBOARD)
|
||||
download: $(WALLYBOARD)
|
||||
cp $(WALLYBOARD)/main.config $(BUILDROOT)/.config
|
||||
@echo "Buildroot successfully download."
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/riscv 6.6.0 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="riscv64-buildroot-linux-gnu-gcc.br_real (Buildroot 2023.05.3-dirty) 12.3.0"
|
||||
CONFIG_CC_VERSION_TEXT="riscv64-buildroot-linux-gnu-gcc.br_real (Buildroot 2023.05.3) 12.3.0"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
CONFIG_GCC_VERSION=120300
|
||||
CONFIG_CLANG_VERSION=0
|
||||
@ -1042,7 +1042,7 @@ CONFIG_MMC_BLOCK_MINORS=8
|
||||
#
|
||||
# CONFIG_MMC_DEBUG is not set
|
||||
# CONFIG_MMC_SDHCI is not set
|
||||
# CONFIG_MMC_SPI is not set
|
||||
CONFIG_MMC_SPI=y
|
||||
# CONFIG_MMC_DW is not set
|
||||
# CONFIG_MMC_USDHI6ROL0 is not set
|
||||
# CONFIG_MMC_CQHCI is not set
|
||||
@ -1455,7 +1455,7 @@ CONFIG_CRYPTO_HASH2=y
|
||||
# CONFIG_CRYPTO_POLY1305 is not set
|
||||
# CONFIG_CRYPTO_RMD160 is not set
|
||||
# CONFIG_CRYPTO_SHA1 is not set
|
||||
# CONFIG_CRYPTO_SHA256 is not set
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
# CONFIG_CRYPTO_SHA512 is not set
|
||||
# CONFIG_CRYPTO_SHA3 is not set
|
||||
# CONFIG_CRYPTO_SM3_GENERIC is not set
|
||||
@ -1527,13 +1527,14 @@ CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
# CONFIG_CRYPTO_LIB_POLY1305 is not set
|
||||
# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
# end of Crypto library routines
|
||||
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
CONFIG_CRC16=y
|
||||
# CONFIG_CRC_T10DIF is not set
|
||||
# CONFIG_CRC64_ROCKSOFT is not set
|
||||
# CONFIG_CRC_ITU_T is not set
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_CRC32_SELFTEST is not set
|
||||
CONFIG_CRC32_SLICEBY8=y
|
||||
@ -1542,7 +1543,7 @@ CONFIG_CRC32_SLICEBY8=y
|
||||
# CONFIG_CRC32_BIT is not set
|
||||
# CONFIG_CRC64 is not set
|
||||
# CONFIG_CRC4 is not set
|
||||
# CONFIG_CRC7 is not set
|
||||
CONFIG_CRC7=y
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
# CONFIG_CRC8 is not set
|
||||
# CONFIG_RANDOM32_SELFTEST is not set
|
||||
@ -1599,7 +1600,7 @@ CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_STACKTRACE_BUILD_ID is not set
|
||||
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
|
||||
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
|
||||
# CONFIG_BOOT_PRINTK_DELAY is not set
|
||||
# CONFIG_DYNAMIC_DEBUG is not set
|
||||
# CONFIG_DYNAMIC_DEBUG_CORE is not set
|
||||
|
@ -5,11 +5,11 @@
|
||||
#size-cells = <0x02>;
|
||||
compatible = "wally-virt";
|
||||
model = "wally-virt,qemu";
|
||||
|
||||
|
||||
chosen {
|
||||
linux,initrd-end = <0x85c43a00>;
|
||||
linux,initrd-start = <0x84200000>;
|
||||
bootargs = "root=/dev/vda ro console=ttyS0,115200";
|
||||
bootargs = "root=/dev/vda ro console=ttyS0,115200 loglevel=7";
|
||||
stdout-path = "/soc/uart@10000000";
|
||||
};
|
||||
|
||||
@ -51,6 +51,25 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
refclk: refclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <0x1312D00>;
|
||||
clock-output-names = "xtal";
|
||||
};
|
||||
|
||||
gpio0: gpio@10060000 {
|
||||
compatible = "sifive,gpio0";
|
||||
interrupt-parent = <0x03>;
|
||||
interrupts = <3>;
|
||||
reg = <0x00 0x10060000 0x00 0x1000>;
|
||||
reg-names = "control";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
uart@10000000 {
|
||||
interrupts = <0x0a>;
|
||||
interrupt-parent = <0x03>;
|
||||
@ -70,18 +89,24 @@
|
||||
#address-cells = <0x00>;
|
||||
};
|
||||
|
||||
mmc@13000 {
|
||||
interrupts = <0x14>;
|
||||
compatible = "riscv,axi-sd-card-1.0";
|
||||
reg = <0x00 0x13000 0x00 0x7F>;
|
||||
fifo-depth = <256>;
|
||||
bus-width = <4>;
|
||||
spi@13000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <0x03>;
|
||||
clock = <0x1312D00>;
|
||||
max-frequency = <0x1312D00>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
no-sdio;
|
||||
interrupts = <0x14>;
|
||||
reg = <0x0 0x13000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <&refclk>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
mmc@0 {
|
||||
compatible = "mmc-spi-slot";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <5000000>;
|
||||
voltage-ranges = <3300 3300>;
|
||||
disable-wp;
|
||||
// gpios = <&gpio0 6 1>;
|
||||
};
|
||||
};
|
||||
|
||||
clint@2000000 {
|
||||
|
@ -31,6 +31,7 @@ set WALLY $::env(WALLY)
|
||||
set CONFIG ${WALLY}/config
|
||||
set SRC ${WALLY}/src
|
||||
set TB ${WALLY}/testbench
|
||||
set FCRVVI ${WALLY}/addins/cvw-arch-verif/fcov
|
||||
|
||||
# create library
|
||||
if [file exists ${WKDIR}] {
|
||||
@ -39,11 +40,16 @@ if [file exists ${WKDIR}] {
|
||||
vlib ${WKDIR}
|
||||
# Create directory for coverage data
|
||||
mkdir -p cov
|
||||
# Create directory for functional coverage data
|
||||
mkdir ${WALLY}/addins/cvw-arch-verif/work
|
||||
|
||||
set ccov 0
|
||||
set CoverageVoptArg ""
|
||||
set CoverageVsimArg ""
|
||||
|
||||
set FuncCovRVVI 0
|
||||
set FCdefineRVVI_COVERAGE ""
|
||||
|
||||
set FunctCoverage 0
|
||||
set riscvISACOVsrc ""
|
||||
set FCdefineINCLUDE_TRACE2COV ""
|
||||
@ -113,6 +119,13 @@ if {$CoverageIndex >= 0} {
|
||||
set lst [lreplace $lst $CoverageIndex $CoverageIndex]
|
||||
}
|
||||
|
||||
set FCoverageIndexRVVI [lsearch -exact $lst "--fcovrvvi"]
|
||||
if {$FCoverageIndexRVVI >= 0} {
|
||||
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} {
|
||||
@ -172,6 +185,7 @@ if {$DEBUG > 0} {
|
||||
echo "GUI = $GUI"
|
||||
echo "ccov = $ccov"
|
||||
echo "lockstep = $lockstep"
|
||||
echo "FuncCovRVVI = $FuncCovRVVI"
|
||||
echo "FunctCoverage = $FunctCoverage"
|
||||
echo "remaining list = $lst"
|
||||
echo "Extra +args = $PlusArgs"
|
||||
@ -197,7 +211,7 @@ set temp3 [lindex $PlusArgs 3]
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${idvFiles} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
|
||||
vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${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 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
|
||||
@ -224,6 +238,11 @@ if {$FunctCoverage} {
|
||||
coverage save -onexit ${UCDB}
|
||||
}
|
||||
|
||||
if {$FuncCovRVVI} {
|
||||
set UCDB ${WALLY}/addins/cvw-arch-verif/work/${CFG}_${TESTSUITE}.ucdb
|
||||
coverage save -onexit ${UCDB}
|
||||
}
|
||||
|
||||
run -all
|
||||
|
||||
if {$ccov} {
|
||||
|
@ -83,11 +83,30 @@ module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRE
|
||||
end else begin: ram
|
||||
bit [WIDTH-1:0] RAM[DEPTH-1:0];
|
||||
|
||||
if (PRELOAD_ENABLED) begin
|
||||
initial begin
|
||||
RAM[0] = 64'h00600100d2e3ca40;
|
||||
// if (PRELOAD_ENABLED) begin
|
||||
// initial begin
|
||||
// RAM[0] = 64'h00600100d2e3ca40;
|
||||
// end
|
||||
// end
|
||||
|
||||
`ifdef VERILATOR
|
||||
import "DPI-C" function string getenvval(input string env_name);
|
||||
`endif
|
||||
|
||||
initial
|
||||
if (PRELOAD_ENABLED) begin
|
||||
if (WIDTH == 64) begin
|
||||
`ifdef VERILATOR
|
||||
// because Verilator doesn't automatically accept $WALLY from shell
|
||||
string WALLY_DIR = getenvval("WALLY");
|
||||
$readmemh({WALLY_DIR,"/fpga/src/data.mem"}, RAM, 0); // load boot RAM for FPGA
|
||||
`else
|
||||
$readmemh({"$WALLY/fpga/src/data.mem"}, RAM, 0); // load boot RAM for FPGA
|
||||
`endif
|
||||
end else begin // put something in the RAM so it is not optimized away
|
||||
RAM[0] = 'h00002197;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Combinational read: register address and read after clock edge
|
||||
logic [$clog2(DEPTH)-1:0] addrd;
|
||||
|
@ -42,7 +42,8 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
output logic SPIOut,
|
||||
input logic SPIIn,
|
||||
output logic [3:0] SPICS,
|
||||
output logic SPIIntr
|
||||
output logic SPIIntr,
|
||||
output logic SPICLK
|
||||
);
|
||||
|
||||
// register map
|
||||
@ -99,7 +100,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
rsrstatetype ReceiveState;
|
||||
|
||||
// Transmission signals
|
||||
logic sck;
|
||||
// logic sck;
|
||||
logic [11:0] DivCounter; // Counter for sck
|
||||
logic SCLKenable; // Flip flop enable high every sclk edge
|
||||
|
||||
@ -147,6 +148,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
// APB access
|
||||
assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses
|
||||
assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase
|
||||
// JACOB: This shouldn't behave this way
|
||||
assign PREADY = TransmitInactive; // Tie PREADY to transmission for hardware interlock
|
||||
|
||||
// Account for subword read/write circuitry
|
||||
@ -358,29 +360,32 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
assign DelayMode = SckMode[0] ? (state == DELAY_1) : (state == ACTIVE_1 & ReceiveShiftFull);
|
||||
assign ChipSelectInternal = (state == CS_INACTIVE | state == INTER_CS | DelayMode & ~|(Delay0[15:8])) ? ChipSelectDef : ~ChipSelectDef;
|
||||
assign sck = (state == ACTIVE_0) ? ~SckMode[1] : SckMode[1];
|
||||
assign SPICLK = (state == ACTIVE_0) ? ~SckMode[1] : SckMode[1];
|
||||
assign Active = (state == ACTIVE_0 | state == ACTIVE_1);
|
||||
assign SampleEdge = SckMode[0] ? (state == ACTIVE_1) : (state == ACTIVE_0);
|
||||
assign ZeroDelayHoldMode = ((ChipSelectMode == 2'b10) & (~|(Delay1[7:4])));
|
||||
assign TransmitInactive = ((state == INTER_CS) | (state == CS_INACTIVE) | (state == INTER_XFR) | (ReceiveShiftFullDelayPCLK & ZeroDelayHoldMode));
|
||||
assign Active0 = (state == ACTIVE_0);
|
||||
|
||||
// Signal tracks which edge of sck to shift data
|
||||
// Signal tracks which edge of sck to shift data
|
||||
// Jacob: We need to confirm that this represents the actual polarity and phase options for sampling.
|
||||
// The first option now samples on the leading edge and shifts on the falling edge like it's supposed to.
|
||||
// We need to confirm the validity of the other options.
|
||||
always_comb
|
||||
case(SckMode[1:0])
|
||||
2'b00: ShiftEdge = ~sck & SCLKenable;
|
||||
2'b01: ShiftEdge = (sck & |(FrameCount) & SCLKenable);
|
||||
2'b10: ShiftEdge = sck & SCLKenable;
|
||||
2'b11: ShiftEdge = (~sck & |(FrameCount) & SCLKenable);
|
||||
default: ShiftEdge = sck & SCLKenable;
|
||||
2'b00: ShiftEdge = SPICLK & SCLKenable;
|
||||
2'b01: ShiftEdge = (SPICLK & |(FrameCount) & SCLKenable); // Probably wrong
|
||||
2'b10: ShiftEdge = ~SPICLK & SCLKenable; // Probably wrong
|
||||
2'b11: ShiftEdge = (~SPICLK & |(FrameCount) & SCLKenable); // Probably wrong
|
||||
default: ShiftEdge = SPICLK & SCLKenable;
|
||||
endcase
|
||||
|
||||
// Transmit shift register
|
||||
assign TransmitDataEndian = Format[0] ? {TransmitFIFOReadData[0], TransmitFIFOReadData[1], TransmitFIFOReadData[2], TransmitFIFOReadData[3], TransmitFIFOReadData[4], TransmitFIFOReadData[5], TransmitFIFOReadData[6], TransmitFIFOReadData[7]} : TransmitFIFOReadData[7:0];
|
||||
always_ff @(posedge PCLK)
|
||||
if(~PRESETn) TransmitShiftReg <= 8'b0;
|
||||
if(~PRESETn) TransmitShiftReg <= 8'b0; // Temporarily changing to 1s
|
||||
else if (TransmitShiftRegLoad) TransmitShiftReg <= TransmitDataEndian;
|
||||
else if (ShiftEdge & Active) TransmitShiftReg <= {TransmitShiftReg[6:0], 1'b0};
|
||||
else if (ShiftEdge & Active) TransmitShiftReg <= {TransmitShiftReg[6:0], TransmitShiftReg[0]}; // Temporarily changing to 1s
|
||||
|
||||
assign SPIOut = TransmitShiftReg[7];
|
||||
|
||||
|
@ -46,7 +46,6 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
output logic [P.AHBW-1:0] HRDATA,
|
||||
output logic HREADY, HRESP,
|
||||
output logic HSELEXT,
|
||||
output logic HSELEXTSDC,
|
||||
// peripheral pins
|
||||
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
|
||||
output logic MExtInt, SExtInt, // External interrupts from PLIC
|
||||
@ -55,16 +54,20 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
|
||||
input logic UARTSin, // UART serial input
|
||||
output logic UARTSout, // UART serial output
|
||||
input logic SDCIntr,
|
||||
input logic SPIIn,
|
||||
output logic SPIOut,
|
||||
output logic [3:0] SPICS
|
||||
output logic [3:0] SPICS,
|
||||
output logic SPICLK,
|
||||
input logic SDCIn,
|
||||
output logic SDCCmd,
|
||||
output logic [3:0] SDCCS,
|
||||
output logic SDCCLK
|
||||
);
|
||||
|
||||
logic [P.XLEN-1:0] HREADRam, HREADSDC;
|
||||
|
||||
logic [11:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSPI;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART,HSELSDC, HSELSPI;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD, HSELSPID;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
logic HREADYRam, HRESPSDCD;
|
||||
@ -75,18 +78,18 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
logic SDCIntM;
|
||||
|
||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||
logic [4:0] PSEL;
|
||||
logic [5:0] PSEL;
|
||||
logic [31:0] PADDR;
|
||||
logic [P.XLEN-1:0] PWDATA;
|
||||
logic [P.XLEN/8-1:0] PSTRB;
|
||||
/* verilator lint_off UNDRIVEN */ // undriven in rv32e configuration
|
||||
logic [4:0] PREADY;
|
||||
logic [4:0][P.XLEN-1:0] PRDATA;
|
||||
logic [5:0] PREADY;
|
||||
logic [5:0][P.XLEN-1:0] PRDATA;
|
||||
/* verilator lint_on UNDRIVEN */
|
||||
logic [P.XLEN-1:0] HREADBRIDGE;
|
||||
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
||||
|
||||
(* mark_debug = "true" *) logic HSELEXTSDCD;
|
||||
/* SDC Interrupt (SPI Controller) */
|
||||
logic SDCIntr;
|
||||
|
||||
|
||||
// Determine which region of physical memory (if any) is being accessed
|
||||
@ -95,14 +98,14 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
||||
|
||||
// unswizzle HSEL signals
|
||||
assign {HSELSPI, HSELEXTSDC, HSELPLIC, HSELUART, HSELGPIO, HSELCLINT, HSELRam, HSELBootRom, HSELEXT, HSELIROM, HSELDTIM} = HSELRegions[11:1];
|
||||
assign {HSELSPI, HSELSDC, HSELPLIC, HSELUART, HSELGPIO, HSELCLINT, HSELRam, HSELBootRom, HSELEXT, HSELIROM, HSELDTIM} = HSELRegions[11:1];
|
||||
|
||||
// AHB -> APB bridge
|
||||
ahbapbbridge #(P, 5) ahbapbbridge (
|
||||
.HCLK, .HRESETn, .HSEL({HSELSPI, HSELUART, HSELPLIC, HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
|
||||
ahbapbbridge #(P, 6) ahbapbbridge (
|
||||
.HCLK, .HRESETn, .HSEL({HSELSDC, HSELSPI, HSELUART, HSELPLIC, HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
|
||||
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
|
||||
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
|
||||
assign HSELBRIDGE = HSELGPIO | HSELCLINT | HSELPLIC | HSELUART | HSELSPI; // if any of the bridge signals are selected
|
||||
assign HSELBRIDGE = HSELGPIO | HSELCLINT | HSELPLIC | HSELUART | HSELSPI | HSELSDC; // if any of the bridge signals are selected
|
||||
|
||||
// on-chip RAM
|
||||
if (P.UNCORE_RAM_SUPPORTED) begin : ram
|
||||
@ -142,6 +145,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
end else begin : gpio
|
||||
assign GPIOOUT = '0; assign GPIOEN = '0; assign GPIOIntr = 1'b0;
|
||||
end
|
||||
|
||||
if (P.UART_SUPPORTED == 1) begin : uartgen // Hack to work around Verilator bug https://github.com/verilator/verilator/issues/4769
|
||||
uart_apb #(P) uart(
|
||||
.PCLK, .PRESETn, .PSEL(PSEL[3]), .PADDR(PADDR[2:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
@ -152,28 +156,39 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
end else begin : uart
|
||||
assign UARTSout = 1'b0; assign UARTIntr = 1'b0;
|
||||
end
|
||||
|
||||
if (P.SPI_SUPPORTED == 1) begin : spi
|
||||
spi_apb #(P) spi (
|
||||
.PCLK, .PRESETn, .PSEL(PSEL[4]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PREADY(PREADY[4]), .PRDATA(PRDATA[4]),
|
||||
.SPIOut, .SPIIn, .SPICS, .SPIIntr);
|
||||
.SPIOut, .SPIIn, .SPICS, .SPICLK, .SPIIntr);
|
||||
end else begin : spi
|
||||
assign SPIOut = 1'b0; assign SPICS = '0; assign SPIIntr = 1'b0;
|
||||
assign SPIOut = 1'b0; assign SPICS = '0; assign SPIIntr = 1'b0; assign SPICLK = 1'b0;
|
||||
end
|
||||
|
||||
if (P.SDC_SUPPORTED == 1) begin : sdc
|
||||
spi_apb #(P) sdc(
|
||||
.PCLK, .PRESETn, .PSEL(PSEL[5]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PREADY(PREADY[5]), .PRDATA(PRDATA[5]),
|
||||
.SPIOut(SDCCmd), .SPIIn(SDCIn), .SPICS(SDCCS), .SPICLK(SDCCLK), .SPIIntr(SDCIntr));
|
||||
end else begin : sdc
|
||||
assign SDCCmd = '0; assign SDCCS = 4'b0; assign SDCIntr = 1'b0; assign SDCCLK = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
// AHB Read Multiplexer
|
||||
assign HRDATA = ({P.XLEN{HSELRamD}} & HREADRam) |
|
||||
({P.XLEN{HSELEXTD | HSELEXTSDCD}} & HRDATAEXT) |
|
||||
({P.XLEN{HSELEXTD}} & HRDATAEXT) |
|
||||
({P.XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
||||
({P.XLEN{HSELBootRomD}} & HREADBootRom);
|
||||
|
||||
assign HRESP = HSELRamD & HRESPRam |
|
||||
(HSELEXTD | HSELEXTSDCD) & HRESPEXT |
|
||||
HSELEXTD & HRESPEXT |
|
||||
HSELBRIDGE & HRESPBRIDGE |
|
||||
HSELBootRomD & HRESPBootRom;
|
||||
|
||||
assign HREADY = HSELRamD & HREADYRam |
|
||||
(HSELEXTD | HSELEXTSDCD) & HREADYEXT |
|
||||
HSELEXTD & HREADYEXT |
|
||||
HSELBRIDGED & HREADYBRIDGE |
|
||||
HSELBootRomD & HREADYBootRom |
|
||||
HSELNoneD; // don't lock up the bus if no region is being accessed
|
||||
@ -184,7 +199,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
// device is ready. Hense this register must be selectively enabled by HREADY.
|
||||
// However on reset None must be seleted.
|
||||
flopenl #(12) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions, 12'b1,
|
||||
{HSELSPID, HSELEXTSDCD, HSELPLICD, HSELUARTD, HSELGPIOD, HSELCLINTD,
|
||||
{HSELSPID, HSELSDCD, HSELPLICD, HSELUARTD, HSELGPIOD, HSELCLINTD,
|
||||
HSELRamD, HSELBootRomD, HSELEXTD, HSELIROMD, HSELDTIMD, HSELNoneD});
|
||||
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
|
||||
endmodule
|
||||
|
@ -35,7 +35,6 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic HSELEXT,
|
||||
output logic HSELEXTSDC,
|
||||
// fpga debug signals
|
||||
input logic ExternalStall,
|
||||
// outputs to external memory, shared with uncore memory
|
||||
@ -57,10 +56,14 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
output logic [31:0] GPIOEN, // output enables for GPIO
|
||||
input logic UARTSin, // UART serial data input
|
||||
output logic UARTSout, // UART serial data output
|
||||
input logic SDCIntr,
|
||||
input logic SPIIn, // SPI pins in
|
||||
output logic SPIOut, // SPI pins out
|
||||
output logic [3:0] SPICS // SPI chip select pins
|
||||
output logic [3:0] SPICS, // SPI chip select pins
|
||||
output logic SPICLK, // SPI clock
|
||||
input logic SDCIn, // SDC DATA[0] to SPI DI
|
||||
output logic SDCCmd, // SDC CMD from SPI DO
|
||||
output logic [3:0] SDCCS, // SDC Card Detect from SPI CS
|
||||
output logic SDCCLK // SDC Clock from SPI Clock
|
||||
);
|
||||
|
||||
// Uncore signals
|
||||
@ -84,12 +87,12 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
if (P.BUS_SUPPORTED) begin : uncoregen // Hack to work around Verilator bug https://github.com/verilator/verilator/issues/4769
|
||||
uncore #(P) uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT, .HSELEXTSDC,
|
||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT,
|
||||
.MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin,
|
||||
.UARTSout, .MTIME_CLINT, .SDCIntr, .SPIIn, .SPIOut, .SPICS);
|
||||
.UARTSout, .MTIME_CLINT, .SPIIn, .SPIOut, .SPICS, .SPICLK, .SDCIn, .SDCCmd, .SDCCS, .SDCCLK);
|
||||
end else begin
|
||||
assign {HRDATA, HREADY, HRESP, HSELEXT, HSELEXTSDC, MTimerInt, MSwInt, MExtInt, SExtInt,
|
||||
MTIME_CLINT, GPIOOUT, GPIOEN, UARTSout, SPIOut, SPICS} = '0;
|
||||
assign {HRDATA, HREADY, HRESP, HSELEXT, MTimerInt, MSwInt, MExtInt, SExtInt,
|
||||
MTIME_CLINT, GPIOOUT, GPIOEN, UARTSout, SPIOut, SPICS, SPICLK, SDCCmd, SDCCS, SDCCLK} = '0;
|
||||
end
|
||||
|
||||
|
||||
|
@ -33,6 +33,12 @@
|
||||
`include "idv/idv.svh"
|
||||
`endif
|
||||
|
||||
`ifdef RVVI_COVERAGE
|
||||
`include "RISCV_trace_data.svh"
|
||||
`include "rvvicov.svh"
|
||||
`include "wrapper.sv"
|
||||
`endif
|
||||
|
||||
import cvw::*;
|
||||
|
||||
module testbench;
|
||||
@ -76,8 +82,7 @@ module testbench;
|
||||
|
||||
// DUT signals
|
||||
logic [P.AHBW-1:0] HRDATAEXT;
|
||||
logic HREADYEXT, HRESPEXT;
|
||||
logic HSELEXTSDC;
|
||||
logic HREADYEXT, HRESPEXT;
|
||||
logic [P.PA_BITS-1:0] HADDR;
|
||||
logic [P.AHBW-1:0] HWDATA;
|
||||
logic [P.XLEN/8-1:0] HWSTRB;
|
||||
@ -93,7 +98,11 @@ module testbench;
|
||||
logic UARTSin, UARTSout;
|
||||
logic SPIIn, SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
logic SDCIntr;
|
||||
logic SPICLK;
|
||||
logic SDCCmd;
|
||||
logic SDCIn;
|
||||
logic [3:0] SDCCS;
|
||||
logic SDCCLK;
|
||||
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
@ -372,6 +381,11 @@ module testbench;
|
||||
uartoutfile = $fopen(uartoutfilename, "w"); // delete UART output file
|
||||
ProgramAddrMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.addr"};
|
||||
ProgramLabelMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.lab"};
|
||||
end else if(TEST == "fpga") begin
|
||||
bootmemfilename = {WALLY_DIR, "/fpga/src/boot.mem"};
|
||||
memfilename = {WALLY_DIR, "/fpga/src/data.mem"};
|
||||
ProgramAddrMapFile = {WALLY_DIR, "/fpga/zsbl/bin/boot.objdump.addr"};
|
||||
ProgramLabelMapFile = {WALLY_DIR, "/fpga/zsbl/bin/boot.objdump.lab"};
|
||||
end else if(ElfFile != "none") begin
|
||||
elffilename = ElfFile;
|
||||
memfilename = {ElfFile, ".memfile"};
|
||||
@ -506,6 +520,23 @@ module testbench;
|
||||
end
|
||||
readResult = $fread(dut.uncoregen.uncore.ram.ram.memory.ram.RAM, memFile);
|
||||
$fclose(memFile);
|
||||
end else if (TEST == "fpga") begin
|
||||
memFile = $fopen(bootmemfilename, "rb");
|
||||
if (memFile == 0) begin
|
||||
$display("Error: Could not open file %s", memfilename);
|
||||
$finish;
|
||||
end
|
||||
if (P.BOOTROM_SUPPORTED) begin
|
||||
readResult = $fread(dut.uncoregen.uncore.bootrom.bootrom.memory.ROM, memFile);
|
||||
end
|
||||
$fclose(memFile);
|
||||
memFile = $fopen(memfilename, "rb");
|
||||
if (memFile == 0) begin
|
||||
$display("Error: Could not open file %s", memfilename);
|
||||
$finish;
|
||||
end
|
||||
readResult = $fread(dut.uncoregen.uncore.ram.ram.memory.ram.RAM, memFile);
|
||||
$fclose(memFile);
|
||||
end else begin
|
||||
uncoreMemFile = $fopen(memfilename, "r"); // Is there a better way to test if a file exists?
|
||||
if (uncoreMemFile == 0) begin
|
||||
@ -585,16 +616,16 @@ module testbench;
|
||||
assign SDCDat = sd_dat_reg_t ? sd_dat_reg_o : sd_dat_i;
|
||||
assign SDCDatIn = SDCDat;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
assign SDCIntr = 1'b0;
|
||||
end else begin
|
||||
assign SDCIntr = 1'b0;
|
||||
assign SDCIn = 1'b1;
|
||||
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall(RVVIStall),
|
||||
.HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPIIn, .SPIOut, .SPICS);
|
||||
.UARTSin, .UARTSout, .SPIIn, .SPIOut, .SPICS, .SPICLK, .SDCIn, .SDCCmd, .SDCCS, .SDCCLK);
|
||||
|
||||
// generate clock to sequence tests
|
||||
always begin
|
||||
@ -957,6 +988,12 @@ test_pmp_coverage #(P) pmp_inst(clk);
|
||||
/* verilator lint_on WIDTHTRUNC */
|
||||
/* verilator lint_on WIDTHEXPAND */
|
||||
|
||||
`ifdef RVVI_COVERAGE
|
||||
rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi();
|
||||
wallyTracer #(P) wallyTracer(rvvi);
|
||||
wrapper #(P) wrap(clk);
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
|
||||
/* verilator lint_on STMTDLY */
|
||||
|
@ -32,7 +32,7 @@ module wallywrapper import cvw::*;(
|
||||
input logic clk,
|
||||
input logic reset_ext,
|
||||
input logic SPIIn,
|
||||
input logic SDCIntr
|
||||
input logic SDCIn
|
||||
);
|
||||
|
||||
`include "parameter-defs.vh"
|
||||
@ -56,10 +56,15 @@ module wallywrapper import cvw::*;(
|
||||
logic UARTSin, UARTSout;
|
||||
logic SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
logic SPICLK;
|
||||
|
||||
logic SDCCmd;
|
||||
logic [3:0] SDCCS;
|
||||
logic SDCCLK;
|
||||
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
logic HSELEXTSDC;
|
||||
|
||||
logic ExternalStall;
|
||||
|
||||
// instantiate device to be tested
|
||||
@ -72,9 +77,9 @@ module wallywrapper import cvw::*;(
|
||||
|
||||
assign ExternalStall = '0;
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC,
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SPIIn, .SPIOut, .SPICS, .SDCIntr);
|
||||
.UARTSin, .UARTSout, .SPIIn, .SPIOut, .SPICS, .SPICLK, .SDCIn, .SDCCmd, .SDCCS, .SDCCLK);
|
||||
|
||||
endmodule
|
||||
|
@ -4,13 +4,18 @@ work_dir = ./riscof_work
|
||||
work = ./work
|
||||
arch_workdir = $(work)/riscv-arch-test
|
||||
wally_workdir = $(work)/wally-riscv-arch-test
|
||||
custom_test_dir = ../../addins/cvw-arch-verif/test
|
||||
submodule_work_dir = ../../addins/cvw-arch-verif/riscof_work
|
||||
|
||||
current_dir = $(shell pwd)
|
||||
#XLEN ?= 64
|
||||
|
||||
all: root arch32 wally32 arch32e arch64 wally64
|
||||
|
||||
wally-riscv-arch-test: root wally64 wally32
|
||||
|
||||
custom: new_test
|
||||
|
||||
root:
|
||||
mkdir -p $(work_dir)
|
||||
mkdir -p $(work)
|
||||
@ -47,6 +52,9 @@ wally64:
|
||||
|
||||
quad64:
|
||||
riscof run --work-dir=$(work_dir) --config=config64.ini --suite=$(wally_dir)/riscv-test-suite/rv64i_m/Q/riscv-ctg/tests/ --env=$(wally_dir)/riscv-test-suite/env
|
||||
|
||||
new_test:
|
||||
riscof run --work-dir=$(submodule_work_dir) --config=config64.ini --suite=$(custom_test_dir)/ --env=$(wally_dir)/riscv-test-suite/env --no-browser
|
||||
|
||||
#wally32e:
|
||||
# riscof run --work-dir=$(work_dir) --config=config32e.ini --suite=$(wally_dir)/riscv-test-suite/ --env=$(wally_dir)/riscv-test-suite/env --no-browser --no-dut-run
|
||||
@ -66,3 +74,4 @@ clean:
|
||||
rm -rf $(work_dir)
|
||||
rm -rf $(wally_workdir)
|
||||
rm -rf $(arch_workdir)
|
||||
rm -rf $(submodule_wor_dir)
|
||||
|
Loading…
Reference in New Issue
Block a user