mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-22 04:47:41 -04:00
Merge branch 'boot' into mergeBoot
Merges Jacob's new sdc controller into wally.
This commit is contained in:
commit
a89a1e675c
65 changed files with 11119 additions and 372 deletions
|
@ -117,6 +117,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd64;
|
||||
|
@ -134,6 +137,7 @@ localparam PLIC_NUM_SRC = 32'd53;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_SDC_ID = 32'd20;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -106,9 +106,9 @@ localparam BOOTROM_SUPPORTED = 1'b1;
|
|||
localparam logic [63:0] BOOTROM_BASE = 64'h00001000;
|
||||
localparam logic [63:0] BOOTROM_RANGE = 64'h00000FFF;
|
||||
|
||||
localparam UNCORE_RAM_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] UNCORE_RAM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] UNCORE_RAM_RANGE = 64'h7FFFFFFF;
|
||||
localparam UNCORE_RAM_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] UNCORE_RAM_BASE = 64'h80002000;
|
||||
localparam logic [63:0] UNCORE_RAM_RANGE = 64'h00000FFF;
|
||||
|
||||
localparam EXT_MEM_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] EXT_MEM_BASE = 64'h80000000;
|
||||
|
@ -130,10 +130,15 @@ localparam PLIC_SUPPORTED = 1'b1;
|
|||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
|
||||
localparam SDC_SUPPORTED = 1'b1;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
|
||||
// Temporary Boot Process Stuff
|
||||
localparam SDC2_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
|
@ -148,6 +153,7 @@ localparam PLIC_NUM_SRC = 32'd53;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd20;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -118,6 +118,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -136,6 +139,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 0;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -119,6 +119,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -137,6 +140,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -118,6 +118,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -136,6 +139,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 0;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -117,6 +117,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -135,6 +138,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 0;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -123,6 +123,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -138,6 +141,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -126,6 +126,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -141,6 +144,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -123,6 +123,9 @@ localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
|||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -138,6 +141,7 @@ localparam PLIC_NUM_SRC = 32'd10;
|
|||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 0;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
|
|
|
@ -72,12 +72,16 @@ parameter cvw_t P = '{
|
|||
SDC_SUPPORTED : SDC_SUPPORTED,
|
||||
SDC_BASE : SDC_BASE,
|
||||
SDC_RANGE : SDC_RANGE,
|
||||
SDC2_SUPPORTED : SDC2_SUPPORTED,
|
||||
SDC2_BASE : SDC2_BASE,
|
||||
SDC2_RANGE : SDC2_RANGE,
|
||||
GPIO_LOOPBACK_TEST : GPIO_LOOPBACK_TEST,
|
||||
UART_PRESCALE : UART_PRESCALE ,
|
||||
PLIC_NUM_SRC : PLIC_NUM_SRC,
|
||||
PLIC_NUM_SRC_LT_32 : PLIC_NUM_SRC_LT_32,
|
||||
PLIC_GPIO_ID : PLIC_GPIO_ID,
|
||||
PLIC_UART_ID : PLIC_UART_ID,
|
||||
PLIC_SDC_ID : PLIC_SDC_ID,
|
||||
BPRED_SUPPORTED : BPRED_SUPPORTED,
|
||||
/* verilator lint_off ENUMVALUE */
|
||||
// *** definitely need to fix this.
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
# mmcm_clkout0 is the clock output of the DDR4 memory interface / 4.
|
||||
# This clock is not used by wally or the AHBLite Bus. However it is used by the AXI BUS on the DD4 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 2 [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/O]
|
||||
# create_generated_clock -name CLKDiv64_Gen -source [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/I0] -multiply_by 1 -divide_by 2 [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/O]
|
||||
create_generated_clock -name CLKDiv64_Gen -source [get_pins xlnx_ddr4_c0/addn_ui_clkout1] -multiply_by 1 -divide_by 1 [get_pins axiSDC/clock_posedge_reg/Q]
|
||||
|
||||
##### GPI ####
|
||||
set_property PACKAGE_PIN E34 [get_ports {GPI[0]}]
|
||||
|
@ -16,7 +17,7 @@ set_property IOSTANDARD LVCMOS12 [get_ports {GPI[1]}]
|
|||
set_property IOSTANDARD LVCMOS12 [get_ports {GPI[0]}]
|
||||
set_input_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 2.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 2.000 [get_ports {GPI[*]}]
|
||||
set_max_delay -from [get_ports {GPI[*]}] 10.000
|
||||
set_max_delay -from [get_ports {GPI[*]}] 10.000n
|
||||
|
||||
##### GPO ####
|
||||
set_property PACKAGE_PIN AT32 [get_ports {GPO[0]}]
|
||||
|
@ -92,23 +93,32 @@ set_input_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 2.000 [get_port
|
|||
|
||||
|
||||
##### SD Card I/O #####
|
||||
set_property PACKAGE_PIN BC14 [get_ports {SDCDat[3]}]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[3]}]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[2]}]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[1]}]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[0]}]
|
||||
set_property PACKAGE_PIN BF7 [get_ports {SDCDat[2]}]
|
||||
set_property PACKAGE_PIN BC13 [get_ports {SDCDat[1]}]
|
||||
set_property PACKAGE_PIN AW16 [get_ports {SDCDat[0]}]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports SDCCLK]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports {SDCCmd}]
|
||||
set_property PACKAGE_PIN BB16 [get_ports SDCCLK]
|
||||
set_property PACKAGE_PIN BA10 [get_ports {SDCCmd}]
|
||||
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 PACKAGE_PIN BC14 [get_ports {SDCDat[3]}]
|
||||
# set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[3]}]
|
||||
# set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[2]}]
|
||||
# set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[1]}]
|
||||
# set_property IOSTANDARD LVCMOS18 [get_ports {SDCDat[0]}]
|
||||
# set_property PACKAGE_PIN BF7 [get_ports {SDCDat[2]}]
|
||||
# set_property PACKAGE_PIN BC13 [get_ports {SDCDat[1]}]
|
||||
# set_property PACKAGE_PIN AW16 [get_ports {SDCDat[0]}]
|
||||
# set_property IOSTANDARD LVCMOS18 [get_ports SDCCLK]
|
||||
# set_property IOSTANDARD LVCMOS18 [get_ports {SDCCmd}]
|
||||
# set_property PACKAGE_PIN BB16 [get_ports SDCCLK]
|
||||
# set_property PACKAGE_PIN BA10 [get_ports {SDCCmd}]
|
||||
# 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 -dict {PACKAGE_PIN BC14 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {SDCDat[3]}]
|
||||
set_property -dict {PACKAGE_PIN BF7 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {SDCDat[2]}]
|
||||
set_property -dict {PACKAGE_PIN BC13 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {SDCDat[1]}]
|
||||
set_property -dict {PACKAGE_PIN AW16 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {SDCDat[0]}]
|
||||
set_property -dict {PACKAGE_PIN BA10 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {SDCCmd}]
|
||||
set_property -dict {PACKAGE_PIN AW12 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {SDCCD}]
|
||||
set_property -dict {PACKAGE_PIN BB16 IOSTANDARD LVCMOS18} [get_ports SDCCLK]
|
||||
|
||||
|
||||
set_input_delay -clock [get_clocks CLKDiv64_Gen] -min -add_delay 2.500 [get_ports {SDCDat[*]}]
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -14,7 +14,6 @@ ieu/regfile.sv: logic rf
|
|||
ieu/datapath.sv: logic RegWriteW
|
||||
hazard/hazard.sv: logic BPPredWrongE
|
||||
hazard/hazard.sv: logic LoadStallD
|
||||
hazard/hazard.sv: logic LSUStallM
|
||||
hazard/hazard.sv: logic FCvtIntStallD
|
||||
hazard/hazard.sv: logic DivBusyE
|
||||
hazard/hazard.sv: logic EcallFaultM
|
||||
|
@ -30,6 +29,7 @@ wally/wallypipelinedcore.sv: logic MemRWM
|
|||
wally/wallypipelinedcore.sv: logic InstrValidM
|
||||
wally/wallypipelinedcore.sv: logic WriteDataM
|
||||
wally/wallypipelinedcore.sv: logic IEUAdrM
|
||||
wally/wallypipelinedcore.sv: logic HRDATA
|
||||
ifu/spill.sv: statetype CurrState
|
||||
ifu/ifu.sv: logic IFUStallF
|
||||
ifu/ifu.sv: logic IFUHADDR
|
||||
|
@ -101,6 +101,7 @@ uncore/uartPC16550D.sv: logic RXerr
|
|||
uncore/uartPC16550D.sv: logic THRE
|
||||
uncore/uartPC16550D.sv: logic rxdataavailintr
|
||||
uncore/uartPC16550D.sv: logic intrID
|
||||
uncore/uncore.sv: logic HSELEXTSDCD
|
||||
uncore/plic_apb.sv: logic MExtInt
|
||||
uncore/plic_apb.sv: logic Din
|
||||
uncore/plic_apb.sv: logic requests
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
dst := IP
|
||||
sdc_src := ~/repos/sdc.tar.gz
|
||||
|
||||
# Select the desired board and the all build rules
|
||||
# vcu118
|
||||
#export XILINX_PART := xcvu9p-flga2104-2L-e
|
||||
#export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
|
||||
|
@ -32,13 +30,21 @@ FPGA_VCU: PreProcessFiles IP_VCU SDC
|
|||
IP_VCU: $(dst)/xlnx_proc_sys_reset.log \
|
||||
$(dst)/xlnx_ddr4-$(board).log \
|
||||
$(dst)/xlnx_axi_clock_converter.log \
|
||||
$(dst)/xlnx_ahblite_axi_bridge.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
|
||||
|
||||
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
|
||||
|
||||
SDC:
|
||||
cp $(sdc_src) ../src/
|
||||
|
|
|
@ -26,6 +26,11 @@ if {$board=="ArtyA7"} {
|
|||
read_ip IP/xlnx_proc_sys_reset.srcs/sources_1/ip/xlnx_proc_sys_reset/xlnx_proc_sys_reset.xci
|
||||
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
|
||||
|
||||
if {$board=="ArtyA7"} {
|
||||
read_ip IP/xlnx_ddr3.srcs/sources_1/ip/xlnx_ddr3/xlnx_ddr3.xci
|
||||
|
@ -36,8 +41,7 @@ if {$board=="ArtyA7"} {
|
|||
|
||||
# read in all other rtl
|
||||
read_verilog -sv [glob -type f ../src/CopiedFiles_do_not_add_to_repo/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/*/*/*.sv]
|
||||
|
||||
read_verilog -sv [glob -type f ../src/sdc/*.sv]
|
||||
read_verilog [glob -type f ../../pipelined/src/uncore/newsdc/*.v]
|
||||
|
||||
set_property include_dirs {../../config/fpga ../../config/shared} [current_fileset]
|
||||
|
||||
|
@ -64,7 +68,11 @@ synth_design -rtl -name rtl_1
|
|||
|
||||
report_clocks -file reports/clocks.rpt
|
||||
|
||||
# this does synthesis.
|
||||
# Temp
|
||||
set_param messaging.defaultLimit 100000
|
||||
|
||||
# this does synthesis?
|
||||
|
||||
launch_runs synth_1 -jobs 4
|
||||
|
||||
wait_on_run synth_1
|
||||
|
|
32
fpga/generator/xlnx_axi_crossbar.tcl
Normal file
32
fpga/generator/xlnx_axi_crossbar.tcl
Normal file
|
@ -0,0 +1,32 @@
|
|||
set partNumber $::env(XILINX_PART)
|
||||
set boardName $::env(XILINX_BOARD)
|
||||
|
||||
# vcu118 board
|
||||
#set partNumber xcvu9p-flga2104-2L-e
|
||||
#set boardName xilinx.com:vcu118:part0:2.4
|
||||
|
||||
# kcu105 board
|
||||
#set partNumber xcku040-ffva1156-2-e
|
||||
#set boardName xilinx.com:kcu105:part0:1.7
|
||||
|
||||
set ipName xlnx_axi_crossbar
|
||||
|
||||
create_project $ipName . -force -part $partNumber
|
||||
set_property board_part $boardName [current_project]
|
||||
|
||||
create_ip -name axi_crossbar -vendor xilinx.com -library ip -version 2.1 -module_name $ipName
|
||||
|
||||
set_property -dict [list CONFIG.NUM_SI {2} \
|
||||
CONFIG.DATA_WIDTH {64} \
|
||||
CONFIG.ID_WIDTH {4} \
|
||||
CONFIG.M01_S01_READ_CONNECTIVITY {0} \
|
||||
CONFIG.M01_S01_WRITE_CONNECTIVITY {0} \
|
||||
CONFIG.M00_A00_BASE_ADDR {0x0000000080000000} \
|
||||
CONFIG.M01_A00_BASE_ADDR {0x0000000000013000} \
|
||||
CONFIG.M00_A00_ADDR_WIDTH {31}] [get_ips $ipName]
|
||||
|
||||
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
launch_run -jobs 8 ${ipName}_synth_1
|
||||
wait_on_run ${ipName}_synth_1
|
25
fpga/generator/xlnx_axi_dwidth_conv_32to64.tcl
Normal file
25
fpga/generator/xlnx_axi_dwidth_conv_32to64.tcl
Normal file
|
@ -0,0 +1,25 @@
|
|||
set partNumber $::env(XILINX_PART)
|
||||
set boardName $::env(XILINX_BOARD)
|
||||
|
||||
# vcu118 board
|
||||
#set partNumber xcvu9p-flga2104-2L-e
|
||||
#set boardName xilinx.com:vcu118:part0:2.4
|
||||
|
||||
# kcu105 board
|
||||
#set partNumber xcku040-ffva1156-2-e
|
||||
#set boardName xilinx.com:kcu105:part0:1.7
|
||||
|
||||
set ipName xlnx_axi_dwidth_conv_32to64
|
||||
|
||||
create_project $ipName . -force -part $partNumber
|
||||
set_property board_part $boardName [current_project]
|
||||
|
||||
create_ip -name axi_dwidth_converter -vendor xilinx.com -library ip -version 2.1 -module_name $ipName
|
||||
|
||||
set_property -dict [list CONFIG.Component_Name {axi_dwidth_conv_32to64}] [get_ips $ipName]
|
||||
|
||||
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
launch_run -jobs 8 ${ipName}_synth_1
|
||||
wait_on_run ${ipName}_synth_1
|
27
fpga/generator/xlnx_axi_dwidth_conv_64to32.tcl
Normal file
27
fpga/generator/xlnx_axi_dwidth_conv_64to32.tcl
Normal file
|
@ -0,0 +1,27 @@
|
|||
set partNumber $::env(XILINX_PART)
|
||||
set boardName $::env(XILINX_BOARD)
|
||||
|
||||
# vcu118 board
|
||||
#set partNumber xcvu9p-flga2104-2L-e
|
||||
#set boardName xilinx.com:vcu118:part0:2.4
|
||||
|
||||
# kcu105 board
|
||||
#set partNumber xcku040-ffva1156-2-e
|
||||
#set boardName xilinx.com:kcu105:part0:1.7
|
||||
|
||||
set ipName xlnx_axi_dwidth_conv_64to32
|
||||
|
||||
create_project $ipName . -force -part $partNumber
|
||||
set_property board_part $boardName [current_project]
|
||||
|
||||
create_ip -name axi_dwidth_converter -vendor xilinx.com -library ip -version 2.1 -module_name $ipName
|
||||
|
||||
set_property -dict [list CONFIG.Component_Name {axi_dwidth_conv_64to32} \
|
||||
CONFIG.SI_DATA_WIDTH {64} \
|
||||
CONFIG.MI_DATA_WIDTH {32}] [get_ips $ipName]
|
||||
|
||||
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
launch_run -jobs 8 ${ipName}_synth_1
|
||||
wait_on_run ${ipName}_synth_1
|
25
fpga/generator/xlnx_axi_dwidth_converter.tcl
Normal file
25
fpga/generator/xlnx_axi_dwidth_converter.tcl
Normal file
|
@ -0,0 +1,25 @@
|
|||
set partNumber $::env(XILINX_PART)
|
||||
set boardName $::env(XILINX_BOARD)
|
||||
|
||||
# vcu118 board
|
||||
#set partNumber xcvu9p-flga2104-2L-e
|
||||
#set boardName xilinx.com:vcu118:part0:2.4
|
||||
|
||||
# kcu105 board
|
||||
#set partNumber xcku040-ffva1156-2-e
|
||||
#set boardName xilinx.com:kcu105:part0:1.7
|
||||
|
||||
set ipName xlnx_axi_dwidth_converter
|
||||
|
||||
create_project $ipName . -force -part $partNumber
|
||||
set_property board_part $boardName [current_project]
|
||||
|
||||
create_ip -name axi_dwidth_converter -vendor xilinx.com -library ip -version 2.1 -module_name $ipName
|
||||
|
||||
set_property -dict [list CONFIG.Component_Name {axi_dwidth_converter}] [get_ips $ipName]
|
||||
|
||||
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
launch_run -jobs 8 ${ipName}_synth_1
|
||||
wait_on_run ${ipName}_synth_1
|
23
fpga/generator/xlnx_axi_prtcl_conv.tcl
Normal file
23
fpga/generator/xlnx_axi_prtcl_conv.tcl
Normal file
|
@ -0,0 +1,23 @@
|
|||
set partNumber $::env(XILINX_PART)
|
||||
set boardName $::env(XILINX_BOARD)
|
||||
|
||||
# vcu118 board
|
||||
#set partNumber xcvu9p-flga2104-2L-e
|
||||
#set boardName xilinx.com:vcu118:part0:2.4
|
||||
|
||||
# kcu105 board
|
||||
#set partNumber xcku040-ffva1156-2-e
|
||||
#set boardName xilinx.com:kcu105:part0:1.7
|
||||
|
||||
set ipName xlnx_axi_prtcl_conv
|
||||
|
||||
create_project $ipName . -force -part $partNumber
|
||||
set_property board_part $boardName [current_project]
|
||||
|
||||
create_ip -name axi_protocol_converter -vendor xilinx.com -library ip -version 2.1 -module_name $ipName
|
||||
|
||||
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
|
||||
launch_run -jobs 8 ${ipName}_synth_1
|
||||
wait_on_run ${ipName}_synth_1
|
78
fpga/proberange
Executable file
78
fpga/proberange
Executable file
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
|
||||
def usage():
|
||||
print("Usage: ./probes list_of_probes outfile")
|
||||
|
||||
def header():
|
||||
return """create_debug_core u_ila_0 ila
|
||||
|
||||
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
|
||||
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
|
||||
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
|
||||
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
|
||||
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
|
||||
startgroup
|
||||
set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ]
|
||||
set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ]
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
|
||||
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
|
||||
endgroup
|
||||
connect_debug_port u_ila_0/clk [get_nets [list xlnx_ddr4_c0/inst/u_ddr4_infrastructure/addn_ui_clkout1 ]]"""
|
||||
|
||||
def convertLine(x):
|
||||
temp = x.split()
|
||||
temp[1] = int(temp[1])
|
||||
temp[2] = int(temp[2])
|
||||
return tuple(temp)
|
||||
|
||||
def probeBits( probe ):
|
||||
str = ''
|
||||
|
||||
if (probe[1] > 1):
|
||||
for i in range(probe[1]):
|
||||
if i != (probe[1]-1):
|
||||
str = str + f"{{{probe[0]}[{i}]}} "
|
||||
else:
|
||||
str = str + f"{{{probe[0]}[{i}]}} "
|
||||
|
||||
else:
|
||||
str = f'{{{probe[0]}}}'
|
||||
|
||||
return str
|
||||
|
||||
def printProbe( probe,):
|
||||
bits = probeBits(probe)
|
||||
|
||||
return (
|
||||
f'create_debug_port u_ila_0 probe\n'
|
||||
f'set_property port_width {probe[1]} [get_debug_ports u_ila_0/probe{probe[2]}]\n'
|
||||
f'set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe{probe[2]}]\n'
|
||||
f'connect_debug_port u_ila_0/probe{probe[2]} [get_nets [list {bits}]]\n\n'
|
||||
)
|
||||
|
||||
def main(args):
|
||||
if (len(args) != 2):
|
||||
usage()
|
||||
exit()
|
||||
|
||||
probeList = []
|
||||
|
||||
with open(args[0]) as probeListFile:
|
||||
probeList = list(map(convertLine, probeListFile.readlines()))
|
||||
|
||||
with open(args[1], 'w') as outfile:
|
||||
# outfile.write(header())
|
||||
# outfile.write("\n\n")
|
||||
for i in range(len(probeList)):
|
||||
outfile.write(printProbe(probeList[i]))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
|
||||
|
||||
|
76
fpga/probes
Executable file
76
fpga/probes
Executable file
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
|
||||
def usage():
|
||||
print("Usage: ./probes list_of_probes outfile")
|
||||
|
||||
def header():
|
||||
return """create_debug_core u_ila_0 ila
|
||||
|
||||
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
|
||||
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
|
||||
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
|
||||
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
|
||||
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
|
||||
startgroup
|
||||
set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ]
|
||||
set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ]
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
|
||||
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
|
||||
endgroup
|
||||
connect_debug_port u_ila_0/clk [get_nets [list xlnx_ddr4_c0/inst/u_ddr4_infrastructure/addn_ui_clkout1 ]]"""
|
||||
|
||||
def convertLine(x):
|
||||
temp = x.split()
|
||||
temp[1] = int(temp[1])
|
||||
return tuple(temp)
|
||||
|
||||
def probeBits( probe ):
|
||||
str = ''
|
||||
|
||||
if (probe[1] > 1):
|
||||
for i in range(probe[1]):
|
||||
if i != (probe[1]-1):
|
||||
str = str + f"{{{probe[0]}[{i}]}} "
|
||||
else:
|
||||
str = str + f"{{{probe[0]}[{i}]}} "
|
||||
|
||||
else:
|
||||
str = f'{{{probe[0]}}}'
|
||||
|
||||
return str
|
||||
|
||||
def printProbe( probe, i ):
|
||||
bits = probeBits(probe)
|
||||
|
||||
return (
|
||||
f'create_debug_port u_ila_0 probe\n'
|
||||
f'set_property port_width {probe[1]} [get_debug_ports u_ila_0/probe{i}]\n'
|
||||
f'set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe{i}]\n'
|
||||
f'connect_debug_port u_ila_0/probe{i} [get_nets [list {bits}]]\n\n'
|
||||
)
|
||||
|
||||
def main(args):
|
||||
if (len(args) != 2):
|
||||
usage()
|
||||
exit()
|
||||
|
||||
probeList = []
|
||||
|
||||
with open(args[0]) as probeListFile:
|
||||
probeList = list(map(convertLine, probeListFile.readlines()))
|
||||
|
||||
with open(args[1], 'w') as outfile:
|
||||
outfile.write(header())
|
||||
outfile.write("\n\n")
|
||||
for i in range(len(probeList)):
|
||||
outfile.write(printProbe(probeList[i], i))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
|
||||
|
|
@ -26,23 +26,24 @@
|
|||
|
||||
module fpgaTop
|
||||
(input default_250mhz_clk1_0_n,
|
||||
input default_250mhz_clk1_0_p,
|
||||
input reset,
|
||||
input south_rst,
|
||||
input default_250mhz_clk1_0_p,
|
||||
input reset,
|
||||
input south_rst,
|
||||
|
||||
input [3:0] GPI,
|
||||
input [3:0] GPI,
|
||||
output [4:0] GPO,
|
||||
|
||||
input UARTSin,
|
||||
output UARTSout,
|
||||
input UARTSin,
|
||||
output UARTSout,
|
||||
|
||||
input [3:0] SDCDat,
|
||||
output SDCCLK,
|
||||
inout SDCCmd,
|
||||
inout [3:0] SDCDat,
|
||||
output SDCCLK,
|
||||
inout SDCCmd,
|
||||
input SDCCD,
|
||||
|
||||
output calib,
|
||||
output cpu_reset,
|
||||
output ahblite_resetn,
|
||||
output calib,
|
||||
output cpu_reset,
|
||||
output ahblite_resetn,
|
||||
|
||||
output [16 : 0] c0_ddr4_adr,
|
||||
output [1 : 0] c0_ddr4_ba,
|
||||
|
@ -54,8 +55,8 @@ module fpgaTop
|
|||
inout [7 : 0] c0_ddr4_dqs_t,
|
||||
output [0 : 0] c0_ddr4_odt,
|
||||
output [0 : 0] c0_ddr4_bg,
|
||||
output c0_ddr4_reset_n,
|
||||
output c0_ddr4_act_n,
|
||||
output c0_ddr4_reset_n,
|
||||
output c0_ddr4_act_n,
|
||||
output [0 : 0] c0_ddr4_ck_c,
|
||||
output [0 : 0] c0_ddr4_ck_t
|
||||
);
|
||||
|
@ -73,7 +74,8 @@ module fpgaTop
|
|||
wire [64-1:0] HRDATAEXT;
|
||||
wire HREADYEXT;
|
||||
wire HRESPEXT;
|
||||
wire HSELEXT;
|
||||
(* mark_debug = "true" *) wire HSELEXT;
|
||||
(* mark_debug = "true" *) wire HSELEXTSDC; // TEMP BOOT SIGNAL - JACOB
|
||||
wire [31:0] HADDR;
|
||||
wire [64-1:0] HWDATA;
|
||||
wire HWRITE;
|
||||
|
@ -88,51 +90,54 @@ module fpgaTop
|
|||
|
||||
wire [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
|
||||
wire SDCCmdIn;
|
||||
wire SDCCmdOE;
|
||||
wire SDCCmdOut;
|
||||
// Old SDC connections
|
||||
// wire SDCCmdIn;
|
||||
// wire SDCCmdOE;
|
||||
// wire SDCCmdOut;
|
||||
|
||||
wire [3:0] m_axi_awid;
|
||||
wire [7:0] m_axi_awlen;
|
||||
wire [2:0] m_axi_awsize;
|
||||
wire [1:0] m_axi_awburst;
|
||||
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 [63:0] m_axi_wdata;
|
||||
wire [7:0] m_axi_wstrb;
|
||||
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 [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 [31:0] m_axi_araddr;
|
||||
wire m_axi_arlock;
|
||||
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 [3:0] m_axi_awid;
|
||||
wire [7:0] m_axi_awlen;
|
||||
wire [2:0] m_axi_awsize;
|
||||
wire [1:0] m_axi_awburst;
|
||||
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 [63:0] m_axi_wdata;
|
||||
wire [7:0] m_axi_wstrb;
|
||||
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 [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 [31:0] m_axi_araddr;
|
||||
wire m_axi_arlock;
|
||||
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;
|
||||
|
||||
// Extra Bus signals
|
||||
wire [3:0] BUS_axi_arregion;
|
||||
wire [3:0] BUS_axi_arqos;
|
||||
wire [3:0] BUS_axi_awregion;
|
||||
wire [3:0] BUS_axi_awqos;
|
||||
|
||||
// Bus signals
|
||||
wire [3:0] BUS_axi_awid;
|
||||
wire [7:0] BUS_axi_awlen;
|
||||
wire [2:0] BUS_axi_awsize;
|
||||
|
@ -168,7 +173,7 @@ module fpgaTop
|
|||
wire BUS_axi_rvalid;
|
||||
wire BUS_axi_rlast;
|
||||
wire BUS_axi_rready;
|
||||
|
||||
|
||||
wire BUSCLK;
|
||||
|
||||
|
||||
|
@ -177,23 +182,290 @@ module fpgaTop
|
|||
wire [511 : 0] dbg_bus;
|
||||
|
||||
wire CLK208;
|
||||
|
||||
|
||||
|
||||
|
||||
assign GPIOIN = {28'b0, GPI};
|
||||
assign GPO = GPIOOUT[4:0];
|
||||
// Crossbar to Bus ------------------------------------------------
|
||||
|
||||
(* mark_debug = "true" *)wire s00_axi_aclk;
|
||||
(* mark_debug = "true" *)wire s00_axi_aresetn;
|
||||
(* mark_debug = "true" *)wire [3:0] s00_axi_awid;
|
||||
(* mark_debug = "true" *)wire [31:0]s00_axi_awaddr;
|
||||
(* mark_debug = "true" *)wire [7:0]s00_axi_awlen;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_awsize;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_awburst;
|
||||
(* mark_debug = "true" *)wire [0:0]s00_axi_awlock;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_awcache;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_awprot;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_awregion;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_awqos;
|
||||
(* mark_debug = "true" *) wire s00_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire s00_axi_awready;
|
||||
(* mark_debug = "true" *)wire [63:0]s00_axi_wdata;
|
||||
(* mark_debug = "true" *)wire [7:0]s00_axi_wstrb;
|
||||
(* mark_debug = "true" *)wire s00_axi_wlast;
|
||||
(* mark_debug = "true" *)wire s00_axi_wvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_wready;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_bresp;
|
||||
(* mark_debug = "true" *)wire s00_axi_bvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_bready;
|
||||
(* mark_debug = "true" *)wire [31:0]s00_axi_araddr;
|
||||
(* mark_debug = "true" *)wire [7:0]s00_axi_arlen;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_arsize;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_arburst;
|
||||
(* mark_debug = "true" *)wire [0:0]s00_axi_arlock;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_arcache;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_arprot;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_arregion;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_arqos;
|
||||
(* mark_debug = "true" *)wire s00_axi_arvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_arready;
|
||||
(* mark_debug = "true" *)wire [63:0]s00_axi_rdata;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_rresp;
|
||||
(* mark_debug = "true" *)wire s00_axi_rlast;
|
||||
(* mark_debug = "true" *)wire s00_axi_rvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_rready;
|
||||
|
||||
(* mark_debug = "true" *)wire [3:0] s00_axi_bid;
|
||||
(* mark_debug = "true" *)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
|
||||
(* mark_debug = "true" *) wire s01_axi_awvalid;
|
||||
(* mark_debug = "true" *) 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 [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;
|
||||
(* mark_debug = "true" *) wire axi4in_axi_awvalid;
|
||||
(* mark_debug = "true" *) 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
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_awaddr;
|
||||
(* mark_debug = "true" *) wire [2:0]SDCin_axi_awprot;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_awready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_wdata;
|
||||
(* mark_debug = "true" *) wire [3:0]SDCin_axi_wstrb;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_wvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_wready;
|
||||
(* mark_debug = "true" *) wire [1:0]SDCin_axi_bresp;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_bvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_bready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_araddr;
|
||||
(* mark_debug = "true" *) wire [2:0]SDCin_axi_arprot;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_arvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_arready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_rdata;
|
||||
(* mark_debug = "true" *) wire [1:0]SDCin_axi_rresp;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_rvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_rready;
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// 32to64 dwidth converter input interface -----------------------
|
||||
(* mark_debug = "true" *) wire [31:0]SDCout_axi_awaddr;
|
||||
(* mark_debug = "true" *) 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;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_awready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCout_axi_wdata;
|
||||
wire [3:0]SDCout_axi_wstrb;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_wlast;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_wvalid;
|
||||
(* mark_debug = "true" *)wire SDCout_axi_wready;
|
||||
(* mark_debug = "true" *) wire [1:0]SDCout_axi_bresp;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_bvalid;
|
||||
(* mark_debug = "true" *) 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
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awid;
|
||||
(* mark_debug = "true" *) wire [31:0]m01_axi_awaddr;
|
||||
(* mark_debug = "true" *) wire [7:0]m01_axi_awlen;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_awsize;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_awburst;
|
||||
(* mark_debug = "true" *) wire [0:0]m01_axi_awlock;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awcache;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_awprot;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awregion;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awqos;
|
||||
(* mark_debug = "true" *) wire m01_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_awready;
|
||||
(* mark_debug = "true" *) wire [63:0]m01_axi_wdata;
|
||||
(* mark_debug = "true" *) wire [7:0]m01_axi_wstrb;
|
||||
(* mark_debug = "true" *) wire m01_axi_wlast;
|
||||
(* mark_debug = "true" *) wire m01_axi_wvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_wready;
|
||||
(* mark_debug = "true" *) wire [3:0] m01_axi_bid;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_bresp;
|
||||
(* mark_debug = "true" *) wire m01_axi_bvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_bready;
|
||||
(* mark_debug = "true" *) wire [3:0] m01_axi_arid;
|
||||
(* mark_debug = "true" *) wire [31:0]m01_axi_araddr;
|
||||
(* mark_debug = "true" *) wire [7:0]m01_axi_arlen;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_arsize;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_arburst;
|
||||
(* mark_debug = "true" *) wire [0:0]m01_axi_arlock;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_arcache;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_arprot;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_arregion;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_arqos;
|
||||
(* mark_debug = "true" *) wire m01_axi_arvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_arready;
|
||||
(* mark_debug = "true" *) wire [3:0] m01_axi_rid;
|
||||
(* mark_debug = "true" *) wire [63:0]m01_axi_rdata;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_rresp;
|
||||
(* mark_debug = "true" *) wire m01_axi_rlast;
|
||||
(* mark_debug = "true" *) wire m01_axi_rvalid;
|
||||
(* mark_debug = "true" *) 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
|
||||
(* mark_debug = "true" *) 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;
|
||||
|
||||
assign GPIOPinsIn = {28'b0, GPI};
|
||||
assign GPO = GPIOPinsOut[4:0];
|
||||
assign ahblite_resetn = peripheral_aresetn;
|
||||
assign cpu_reset = bus_struct_reset;
|
||||
assign calib = c0_init_calib_complete;
|
||||
|
||||
|
||||
|
||||
|
||||
// SD Card Tristate
|
||||
/*
|
||||
IOBUF iobufSDCMD(.T(~SDCCmdOE), // iobuf's T is active low
|
||||
.I(SDCCmdOut),
|
||||
.O(SDCCmdIn),
|
||||
.IO(SDCCmd));
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 4; i = i + 1) begin
|
||||
IOBUF iobufSDCDat(.T(1'b1),
|
||||
.I(1'b0),
|
||||
.O(SDCDatIn[i]),
|
||||
.IO(SDCDat[i]));
|
||||
end
|
||||
endgenerate
|
||||
*/
|
||||
|
||||
// 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
|
||||
|
||||
// IOBUF IOBUF_dat0 (.O(sd_dat_i[0]), .IO(sdio_dat[0]), .I(sd_dat_reg_o[0]), .T(sd_dat_reg_t));
|
||||
// IOBUF IOBUF_dat1 (.O(sd_dat_i[1]), .IO(sdio_dat[1]), .I(sd_dat_reg_o[1]), .T(sd_dat_reg_t));
|
||||
// IOBUF IOBUF_dat2 (.O(sd_dat_i[2]), .IO(sdio_dat[2]), .I(sd_dat_reg_o[2]), .T(sd_dat_reg_t));
|
||||
// IOBUF IOBUF_dat3 (.O(sd_dat_i[3]), .IO(sdio_dat[3]), .I(sd_dat_reg_o[3]), .T(sd_dat_reg_t));
|
||||
|
||||
|
||||
|
||||
// reset controller XILINX IP
|
||||
xlnx_proc_sys_reset xlnx_proc_sys_reset_0
|
||||
(.slowest_sync_clk(CPUCLK),
|
||||
|
@ -209,6 +481,7 @@ module fpgaTop
|
|||
|
||||
|
||||
// wally
|
||||
// *** FIXME add sdc interrupt and HSELEXTSDC, remove old sdc
|
||||
wallypipelinedsocwrapper wallypipelinedsocwrapper
|
||||
(.clk(CPUCLK),
|
||||
.reset_ext(bus_struct_reset),
|
||||
|
@ -217,6 +490,7 @@ module fpgaTop
|
|||
.HREADYEXT(HREADYEXT),
|
||||
.HRESPEXT(HRESPEXT),
|
||||
.HSELEXT(HSELEXT),
|
||||
.HSELEXTSDC(HSELEXTSDC),
|
||||
.HCLK(HCLKOpen), // open
|
||||
.HRESETn(HRESETnOpen), // open
|
||||
.HADDR(HADDR),
|
||||
|
@ -234,19 +508,21 @@ module fpgaTop
|
|||
.GPIOEN(GPIOEN),
|
||||
// UART
|
||||
.UARTSin(UARTSin),
|
||||
.UARTSout(UARTSout),
|
||||
.UARTSout(UARTSout),
|
||||
.SDCIntr(SDCIntr)
|
||||
// SD Card
|
||||
.SDCDatIn(SDCDat),
|
||||
/*.SDCDatIn(SDCDatIn),
|
||||
.SDCCmdIn(SDCCmdIn),
|
||||
.SDCCmdOut(SDCCmdOut),
|
||||
.SDCCmdOE(SDCCmdOE),
|
||||
.SDCCLK(SDCCLK));
|
||||
|
||||
.SDCCLK(SDCCLK));*/
|
||||
);
|
||||
|
||||
// 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),
|
||||
.s_ahb_hsel(HSELEXT | HSELEXTSDC),
|
||||
.s_ahb_haddr(HADDR),
|
||||
.s_ahb_hprot(HPROT),
|
||||
.s_ahb_htrans(HTRANS),
|
||||
|
@ -294,48 +570,431 @@ module fpgaTop
|
|||
.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),
|
||||
|
||||
// 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 --------------------------------------------
|
||||
|
||||
xlnx_axi_clock_converter xlnx_axi_clock_converter_0
|
||||
(.s_axi_aclk(CPUCLK),
|
||||
.s_axi_aresetn(peripheral_aresetn),
|
||||
.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_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_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(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_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_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(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),
|
||||
.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),
|
||||
|
||||
.m_axi_aclk(BUSCLK),
|
||||
.m_axi_aresetn(~reset),
|
||||
|
@ -378,7 +1037,7 @@ module fpgaTop
|
|||
.m_axi_rvalid(BUS_axi_rvalid),
|
||||
.m_axi_rlast(BUS_axi_rlast),
|
||||
.m_axi_rready(BUS_axi_rready));
|
||||
|
||||
|
||||
xlnx_ddr4 xlnx_ddr4_c0
|
||||
(.c0_init_calib_complete(c0_init_calib_complete),
|
||||
.dbg_clk(dbg_clk), // open
|
||||
|
|
|
@ -69,6 +69,7 @@ module fpgaTop
|
|||
wire [63:0] HRDATAEXT;
|
||||
wire HREADYEXT;
|
||||
wire HRESPEXT;
|
||||
wire HSELEXTSDC; // TEMP BOOT SIGNAL - JACOB
|
||||
wire HSELEXT;
|
||||
wire [55:0] HADDR;
|
||||
wire [63:0] HWDATA;
|
||||
|
@ -165,6 +166,243 @@ module fpgaTop
|
|||
wire BUS_axi_rready;
|
||||
|
||||
wire BUSCLK;
|
||||
|
||||
// Crossbar to Bus ------------------------------------------------
|
||||
|
||||
(* mark_debug = "true" *)wire s00_axi_aclk;
|
||||
(* mark_debug = "true" *)wire s00_axi_aresetn;
|
||||
(* mark_debug = "true" *)wire [3:0] s00_axi_awid;
|
||||
(* mark_debug = "true" *)wire [31:0]s00_axi_awaddr;
|
||||
(* mark_debug = "true" *)wire [7:0]s00_axi_awlen;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_awsize;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_awburst;
|
||||
(* mark_debug = "true" *)wire [0:0]s00_axi_awlock;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_awcache;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_awprot;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_awregion;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_awqos;
|
||||
(* mark_debug = "true" *) wire s00_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire s00_axi_awready;
|
||||
(* mark_debug = "true" *)wire [63:0]s00_axi_wdata;
|
||||
(* mark_debug = "true" *)wire [7:0]s00_axi_wstrb;
|
||||
(* mark_debug = "true" *)wire s00_axi_wlast;
|
||||
(* mark_debug = "true" *)wire s00_axi_wvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_wready;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_bresp;
|
||||
(* mark_debug = "true" *)wire s00_axi_bvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_bready;
|
||||
(* mark_debug = "true" *)wire [31:0]s00_axi_araddr;
|
||||
(* mark_debug = "true" *)wire [7:0]s00_axi_arlen;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_arsize;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_arburst;
|
||||
(* mark_debug = "true" *)wire [0:0]s00_axi_arlock;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_arcache;
|
||||
(* mark_debug = "true" *)wire [2:0]s00_axi_arprot;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_arregion;
|
||||
(* mark_debug = "true" *)wire [3:0]s00_axi_arqos;
|
||||
(* mark_debug = "true" *)wire s00_axi_arvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_arready;
|
||||
(* mark_debug = "true" *)wire [63:0]s00_axi_rdata;
|
||||
(* mark_debug = "true" *)wire [1:0]s00_axi_rresp;
|
||||
(* mark_debug = "true" *)wire s00_axi_rlast;
|
||||
(* mark_debug = "true" *)wire s00_axi_rvalid;
|
||||
(* mark_debug = "true" *)wire s00_axi_rready;
|
||||
|
||||
(* mark_debug = "true" *)wire [3:0] s00_axi_bid;
|
||||
(* mark_debug = "true" *)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
|
||||
(* mark_debug = "true" *) wire s01_axi_awvalid;
|
||||
(* mark_debug = "true" *) 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 [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;
|
||||
(* mark_debug = "true" *) wire axi4in_axi_awvalid;
|
||||
(* mark_debug = "true" *) 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
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_awaddr;
|
||||
(* mark_debug = "true" *) wire [2:0]SDCin_axi_awprot;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_awready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_wdata;
|
||||
(* mark_debug = "true" *) wire [3:0]SDCin_axi_wstrb;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_wvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_wready;
|
||||
(* mark_debug = "true" *) wire [1:0]SDCin_axi_bresp;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_bvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_bready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_araddr;
|
||||
(* mark_debug = "true" *) wire [2:0]SDCin_axi_arprot;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_arvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_arready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCin_axi_rdata;
|
||||
(* mark_debug = "true" *) wire [1:0]SDCin_axi_rresp;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_rvalid;
|
||||
(* mark_debug = "true" *) wire SDCin_axi_rready;
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// 32to64 dwidth converter input interface -----------------------
|
||||
(* mark_debug = "true" *) wire [31:0]SDCout_axi_awaddr;
|
||||
(* mark_debug = "true" *) 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;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_awready;
|
||||
(* mark_debug = "true" *) wire [31:0]SDCout_axi_wdata;
|
||||
wire [3:0]SDCout_axi_wstrb;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_wlast;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_wvalid;
|
||||
(* mark_debug = "true" *)wire SDCout_axi_wready;
|
||||
(* mark_debug = "true" *) wire [1:0]SDCout_axi_bresp;
|
||||
(* mark_debug = "true" *) wire SDCout_axi_bvalid;
|
||||
(* mark_debug = "true" *) 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
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awid;
|
||||
(* mark_debug = "true" *) wire [31:0]m01_axi_awaddr;
|
||||
(* mark_debug = "true" *) wire [7:0]m01_axi_awlen;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_awsize;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_awburst;
|
||||
(* mark_debug = "true" *) wire [0:0]m01_axi_awlock;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awcache;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_awprot;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awregion;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_awqos;
|
||||
(* mark_debug = "true" *) wire m01_axi_awvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_awready;
|
||||
(* mark_debug = "true" *) wire [63:0]m01_axi_wdata;
|
||||
(* mark_debug = "true" *) wire [7:0]m01_axi_wstrb;
|
||||
(* mark_debug = "true" *) wire m01_axi_wlast;
|
||||
(* mark_debug = "true" *) wire m01_axi_wvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_wready;
|
||||
(* mark_debug = "true" *) wire [3:0] m01_axi_bid;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_bresp;
|
||||
(* mark_debug = "true" *) wire m01_axi_bvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_bready;
|
||||
(* mark_debug = "true" *) wire [3:0] m01_axi_arid;
|
||||
(* mark_debug = "true" *) wire [31:0]m01_axi_araddr;
|
||||
(* mark_debug = "true" *) wire [7:0]m01_axi_arlen;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_arsize;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_arburst;
|
||||
(* mark_debug = "true" *) wire [0:0]m01_axi_arlock;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_arcache;
|
||||
(* mark_debug = "true" *) wire [2:0]m01_axi_arprot;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_arregion;
|
||||
(* mark_debug = "true" *) wire [3:0]m01_axi_arqos;
|
||||
(* mark_debug = "true" *) wire m01_axi_arvalid;
|
||||
(* mark_debug = "true" *) wire m01_axi_arready;
|
||||
(* mark_debug = "true" *) wire [3:0] m01_axi_rid;
|
||||
(* mark_debug = "true" *) wire [63:0]m01_axi_rdata;
|
||||
(* mark_debug = "true" *) wire [1:0]m01_axi_rresp;
|
||||
(* mark_debug = "true" *) wire m01_axi_rlast;
|
||||
(* mark_debug = "true" *) wire m01_axi_rvalid;
|
||||
(* mark_debug = "true" *) 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
|
||||
(* mark_debug = "true" *) 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;
|
||||
|
||||
|
||||
(* mark_debug = "true" *) wire c0_init_calib_complete;
|
||||
|
@ -204,11 +442,26 @@ module fpgaTop
|
|||
.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
|
||||
xlnx_proc_sys_reset xlnx_proc_sys_reset_0
|
||||
|
@ -224,6 +477,7 @@ module fpgaTop
|
|||
.peripheral_aresetn(peripheral_aresetn));
|
||||
|
||||
// wally
|
||||
// *** FIXME add sdc interrupt and HSELEXTSDC, remove old sdc
|
||||
wallypipelinedsocwrapper wallypipelinedsocwrapper
|
||||
(.clk(CPUCLK),
|
||||
.reset_ext(bus_struct_reset),
|
||||
|
@ -233,6 +487,7 @@ module fpgaTop
|
|||
.HREADYEXT(HREADYEXT),
|
||||
.HRESPEXT(HRESPEXT),
|
||||
.HSELEXT(HSELEXT),
|
||||
.HSELEXTSDC(HSELEXTSDC),
|
||||
.HCLK(HCLKOpen), // open
|
||||
.HRESETn(HRESETnOpen), // open
|
||||
.HADDR(HADDR),
|
||||
|
@ -253,13 +508,17 @@ module fpgaTop
|
|||
.GPIOEN(GPIOEN),
|
||||
// UART
|
||||
.UARTSin(UARTSin),
|
||||
.UARTSout(UARTSout),
|
||||
.UARTSout(UARTSout),
|
||||
.SDCIntr(SDCIntr)
|
||||
// SD Card
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
.SDCDatIn(SDCDat),
|
||||
.SDCCmdIn(SDCCmdIn),
|
||||
.SDCCmdOut(SDCCmdOut),
|
||||
.SDCCmdOE(SDCCmdOE),
|
||||
.SDCCLK(SDCCLK));
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
);
|
||||
|
||||
// ahb lite to axi bridge
|
||||
xlnx_ahblite_axi_bridge xlnx_ahblite_axi_bridge_0
|
||||
|
@ -313,51 +572,434 @@ module fpgaTop
|
|||
.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),
|
||||
|
||||
// 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 --------------------------------------------
|
||||
|
||||
xlnx_axi_clock_converter xlnx_axi_clock_converter_0
|
||||
(.s_axi_aclk(CPUCLK),
|
||||
.s_axi_aresetn(peripheral_aresetn),
|
||||
.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_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_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(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_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_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(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),
|
||||
.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),
|
||||
|
||||
.m_axi_aclk(BUSCLK),
|
||||
.m_axi_aresetn(resetn),
|
||||
.m_axi_aresetn(~reset),
|
||||
.m_axi_awid(BUS_axi_awid),
|
||||
.m_axi_awlen(BUS_axi_awlen),
|
||||
.m_axi_awsize(BUS_axi_awsize),
|
||||
|
@ -398,6 +1040,7 @@ module fpgaTop
|
|||
.m_axi_rlast(BUS_axi_rlast),
|
||||
.m_axi_rready(BUS_axi_rready));
|
||||
|
||||
|
||||
assign CPUCLK = CLK208;
|
||||
|
||||
xlnx_ddr3 xlnx_ddr3_c0
|
||||
|
|
|
@ -38,6 +38,7 @@ module wallypipelinedsocwrapper (
|
|||
input logic [64-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic HSELEXT,
|
||||
output logic HSELEXTSDC,
|
||||
// outputs to external memory, shared with uncore memory
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [55:0] HADDR,
|
||||
|
@ -57,17 +58,13 @@ module wallypipelinedsocwrapper (
|
|||
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 SDCCmdIn, // SDC Command input
|
||||
output logic SDCCmdOut, // SDC Command output
|
||||
output logic SDCCmdOE, // SDC Command output enable
|
||||
input logic [3:0] SDCDatIn, // SDC data input
|
||||
output logic SDCCLK // SDC clock
|
||||
input logic SDCIntr
|
||||
);
|
||||
`include "parameter-defs.vh"
|
||||
|
||||
wallypipelinedsoc #(P) wallypipelinedsoc(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
wallypipelinedsoc #(P) wallypipelinedsoc(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT, .HSELEXT,
|
||||
.HSELEXTSDC, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||
.UARTSin, .UARTSout, .SDCIntr);
|
||||
|
||||
endmodule
|
||||
|
|
6
linux/buildroot-packages/fpga-axi-sdc/Config.in
Normal file
6
linux/buildroot-packages/fpga-axi-sdc/Config.in
Normal file
|
@ -0,0 +1,6 @@
|
|||
config BR2_PACKAGE_FPGA_AXI_SDC
|
||||
bool "FPGA AXI SDC"
|
||||
help
|
||||
The Vivado-RISC-V SDC Drivers.
|
||||
|
||||
https://www.github.com/eugene-tarassov/vivado-risc-v
|
10
linux/buildroot-packages/fpga-axi-sdc/fpga-axi-sdc.mk
Normal file
10
linux/buildroot-packages/fpga-axi-sdc/fpga-axi-sdc.mk
Normal file
|
@ -0,0 +1,10 @@
|
|||
FPGA_AXI_SDC_MODULE_VERSION = 1.0
|
||||
# TODO This variable needs to change based on where the package
|
||||
# contents are stored on each individual computer. Might parameterize
|
||||
# this somehow.
|
||||
FPGA_AXI_SDC_SITE = /home/jpease/repos/fpga-axi-sdc
|
||||
FPGA_AXI_SDC_SITE_METHOD = local
|
||||
FPGA_AXI_SDC_LICENSE = GPLv2
|
||||
|
||||
$(eval $(kernel-module))
|
||||
$(eval $(generic-package))
|
7
linux/buildroot-packages/fpga-axi-sdc/fpga-axi-sdc.mk~
Normal file
7
linux/buildroot-packages/fpga-axi-sdc/fpga-axi-sdc.mk~
Normal file
|
@ -0,0 +1,7 @@
|
|||
FPGA_AXI_SDC_MODULE_VERSION = 1.0
|
||||
FPGA_AXI_SDC_SITE = /home/jpease/repos/fpga-axi-sdc
|
||||
FPGA_AXI_SDC_SITE_METHOD = local
|
||||
FPGA_AXI_SDC_LICENSE = GPLv2
|
||||
|
||||
$(eval $(kernel-module))
|
||||
$(eval $(generic-package))
|
1423
linux/buildroot-packages/linux.config
Normal file
1423
linux/buildroot-packages/linux.config
Normal file
File diff suppressed because it is too large
Load diff
9
linux/buildroot-packages/package-source/Makefile
Normal file
9
linux/buildroot-packages/package-source/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
.PHONY: all clean
|
||||
obj-m += fpga-axi-sdc.o
|
||||
|
||||
all:
|
||||
$(MAKE) -C '$(LINUX-DIR)' M='$(PWD)' modules
|
||||
$(MAKE) -C '$(LINUX-DIR)' M='$(PWD)' modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C '$(LINUX-DIR)' M='$(PWD)' clean
|
498
linux/buildroot-packages/package-source/fpga-axi-sdc.c
Normal file
498
linux/buildroot-packages/package-source/fpga-axi-sdc.c
Normal file
|
@ -0,0 +1,498 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mmc/slot-gpio.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
/*
|
||||
* AXI SD Card driver.
|
||||
*
|
||||
* AXI SD Card is open source Verilog implementation of high speed SD card controller.
|
||||
* It is mainly used in FPGA designs.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_INFO
|
||||
#pragma GCC optimize("O0")
|
||||
#endif
|
||||
|
||||
// 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 CMD_TIMEOUT_MS 1000
|
||||
#define BUSY_TIMEOUT_MS 500
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct sdc_host {
|
||||
struct platform_device * pdev;
|
||||
struct sdc_regs __iomem * regs;
|
||||
uint32_t clk_freq;
|
||||
spinlock_t lock;
|
||||
struct mmc_request * mrq;
|
||||
struct mmc_data * data;
|
||||
unsigned dma_addr_bits;
|
||||
unsigned dma_count;
|
||||
dma_addr_t dma_addr;
|
||||
unsigned dma_size;
|
||||
int irq;
|
||||
};
|
||||
|
||||
static const struct of_device_id axi_sdc_of_match_table[] = {
|
||||
{ .compatible = "riscv,axi-sd-card-1.0" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axi_sdc_of_match_table);
|
||||
|
||||
/* Set clock prescalar value based on the required clock in HZ */
|
||||
static void sdc_set_clock(struct sdc_host * host, uint clock) {
|
||||
unsigned clk_div;
|
||||
|
||||
/* Min clock frequency should be 400KHz */
|
||||
if (clock < 400000) clock = 400000;
|
||||
|
||||
clk_div = host->clk_freq / (2 * clock);
|
||||
if (clk_div > 0x100) clk_div = 0x100;
|
||||
if (clk_div < 1) clk_div = 1;
|
||||
|
||||
if (host->regs->clock_divider != clk_div - 1) {
|
||||
host->regs->clock_divider = clk_div - 1;
|
||||
udelay(10000);
|
||||
}
|
||||
}
|
||||
|
||||
static void sdc_cmd_finish(struct sdc_host * host, struct mmc_command * cmd) {
|
||||
while (1) {
|
||||
unsigned status = host->regs->cmd_int_status;
|
||||
if (status) {
|
||||
// clear interrupts
|
||||
host->regs->cmd_int_status = 0;
|
||||
while (host->regs->software_reset != 0) {}
|
||||
if (status == SDC_CMD_INT_STATUS_CC) {
|
||||
// get response
|
||||
cmd->resp[0] = host->regs->response1;
|
||||
if (cmd->flags & MMC_RSP_136) {
|
||||
cmd->resp[1] = host->regs->response2;
|
||||
cmd->resp[2] = host->regs->response3;
|
||||
cmd->resp[3] = host->regs->response4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
cmd->error = (status & SDC_CMD_INT_STATUS_CTE) ? -ETIME : -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int sdc_setup_data_xfer(struct sdc_host * host, struct mmc_host * mmc, struct mmc_data * data) {
|
||||
uint64_t timeout = 0;
|
||||
|
||||
data->bytes_xfered = 0;
|
||||
|
||||
if (host->dma_addr & 3) return -EINVAL;
|
||||
if (data->blksz & 3) return -EINVAL;
|
||||
if (data->blksz < 4) return -EINVAL;
|
||||
if (data->blksz > 0x1000) return -EINVAL;
|
||||
if (data->blocks > 0x10000) return -EINVAL;
|
||||
if (host->dma_addr + data->blksz * data->blocks > ((uint64_t)1 << host->dma_addr_bits)) return -EINVAL;
|
||||
if (data->sg->length < data->blksz * data->blocks) return -EINVAL;
|
||||
|
||||
// SD card data transfer time
|
||||
timeout += data->blocks * data->blksz * 8 / (1 << mmc->ios.bus_width);
|
||||
// SD card "busy" time
|
||||
timeout += (uint64_t)mmc->ios.clock * BUSY_TIMEOUT_MS / 1000 * data->blocks;
|
||||
|
||||
host->regs->dma_addres = (uint64_t)host->dma_addr;
|
||||
host->regs->block_size = data->blksz - 1;
|
||||
host->regs->block_count = data->blocks - 1;
|
||||
host->regs->data_timeout = (uint32_t)timeout;
|
||||
if (host->regs->data_timeout != timeout) host->regs->data_timeout = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdc_send_cmd(struct sdc_host * host, struct mmc_host * mmc, struct mmc_command * cmd, struct mmc_data * data) {
|
||||
int command = cmd->opcode << 8;
|
||||
uint64_t timeout = 0;
|
||||
int xfer = 0;
|
||||
|
||||
if (cmd->flags & MMC_RSP_PRESENT) {
|
||||
if (cmd->flags & MMC_RSP_136)
|
||||
command |= 2;
|
||||
else {
|
||||
command |= 1;
|
||||
}
|
||||
}
|
||||
if (cmd->flags & MMC_RSP_BUSY) command |= 1 << 2;
|
||||
if (cmd->flags & MMC_RSP_CRC) command |= 1 << 3;
|
||||
if (cmd->flags & MMC_RSP_OPCODE) command |= 1 << 4;
|
||||
|
||||
if (data && (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) && data->blocks) {
|
||||
host->dma_count = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
|
||||
if (host->dma_count != 1) {
|
||||
dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
|
||||
return data->error = -EIO;
|
||||
}
|
||||
host->dma_addr = sg_dma_address(data->sg);
|
||||
host->dma_size = sg_dma_len(data->sg);
|
||||
if (data->flags & MMC_DATA_READ) command |= 1 << 5;
|
||||
if (data->flags & MMC_DATA_WRITE) command |= 1 << 6;
|
||||
data->error = sdc_setup_data_xfer(host, mmc, data);
|
||||
if (data->error < 0) {
|
||||
dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
|
||||
return data->error;
|
||||
}
|
||||
xfer = 1;
|
||||
}
|
||||
|
||||
timeout = (uint64_t)mmc->ios.clock * CMD_TIMEOUT_MS / 1000;
|
||||
|
||||
host->regs->command = command;
|
||||
host->regs->cmd_timeout = (uint32_t)timeout;
|
||||
if (host->regs->cmd_timeout != timeout) host->regs->cmd_timeout = 0;
|
||||
host->regs->argument = cmd->arg;
|
||||
|
||||
sdc_cmd_finish(host, cmd);
|
||||
if (cmd->error < 0) {
|
||||
if (xfer) dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
|
||||
return cmd->error;
|
||||
}
|
||||
if (xfer) host->data = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdc_request(struct mmc_host * mmc, struct mmc_request * mrq) {
|
||||
struct sdc_host * host = mmc_priv(mmc);
|
||||
|
||||
/* Clear the error statuses in case this is a retry */
|
||||
if (mrq->sbc) mrq->sbc->error = 0;
|
||||
if (mrq->cmd) mrq->cmd->error = 0;
|
||||
if (mrq->data) mrq->data->error = 0;
|
||||
if (mrq->stop) mrq->stop->error = 0;
|
||||
|
||||
spin_lock_irq(&host->lock);
|
||||
host->data = NULL;
|
||||
host->mrq = mrq;
|
||||
|
||||
if (!mrq->sbc || sdc_send_cmd(host, mmc, mrq->sbc, NULL) == 0) {
|
||||
sdc_send_cmd(host, mmc, mrq->cmd, mrq->data);
|
||||
}
|
||||
|
||||
if (host->data == NULL) {
|
||||
mmc_request_done(mmc, mrq);
|
||||
host->mrq = NULL;
|
||||
}
|
||||
else {
|
||||
host->regs->dat_int_enable = SDC_DAT_INT_STATUS_TRS | SDC_DAT_INT_STATUS_ERR;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
}
|
||||
|
||||
static void sdc_set_ios(struct mmc_host * mmc, struct mmc_ios * ios) {
|
||||
struct sdc_host * host = mmc_priv(mmc);
|
||||
|
||||
spin_lock_irq(&host->lock);
|
||||
|
||||
sdc_set_clock(host, ios->clock);
|
||||
host->regs->control = ios->bus_width == MMC_BUS_WIDTH_4 ? SDC_CONTROL_SD_4BIT : 0;
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
}
|
||||
|
||||
static void sdc_reset(struct mmc_host * mmc) {
|
||||
struct sdc_host * host = mmc_priv(mmc);
|
||||
uint32_t card_detect = 0;
|
||||
|
||||
spin_lock_irq(&host->lock);
|
||||
|
||||
sdc_set_clock(host, 400000);
|
||||
|
||||
// software reset
|
||||
host->regs->software_reset = 1;
|
||||
while ((host->regs->software_reset & 1) == 0) {}
|
||||
// clear software reset
|
||||
host->regs->software_reset = 0;
|
||||
while (host->regs->software_reset != 0) {}
|
||||
udelay(10000);
|
||||
|
||||
// set bus width 1 bit
|
||||
host->regs->control = 0;
|
||||
|
||||
// disable cmd/data interrupts
|
||||
host->regs->cmd_int_enable = 0;
|
||||
host->regs->dat_int_enable = 0;
|
||||
// clear cmd/data interrupts
|
||||
host->regs->cmd_int_status = 0;
|
||||
host->regs->dat_int_status = 0;
|
||||
// enable card detect interrupt
|
||||
card_detect = host->regs->card_detect;
|
||||
if (card_detect & SDC_CARD_INSERT_INT_REQ) {
|
||||
host->regs->card_detect = SDC_CARD_REMOVE_INT_EN;
|
||||
}
|
||||
else if (card_detect & SDC_CARD_REMOVE_INT_REQ) {
|
||||
host->regs->card_detect = SDC_CARD_INSERT_INT_EN;
|
||||
}
|
||||
while (host->regs->software_reset != 0) {}
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
}
|
||||
|
||||
static void sdc_card_reset(struct mmc_host * mmc) {
|
||||
struct sdc_host * host = mmc_priv(mmc);
|
||||
uint32_t control = 0;
|
||||
|
||||
spin_lock_irq(&host->lock);
|
||||
|
||||
control = host->regs->control;
|
||||
host->regs->control = control | SDC_CONTROL_SD_RESET;
|
||||
udelay(10);
|
||||
host->regs->control = control & ~(uint32_t)SDC_CONTROL_SD_RESET;
|
||||
udelay(10);
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
}
|
||||
|
||||
static int sdc_get_cd(struct mmc_host * mmc) {
|
||||
struct sdc_host * host = mmc_priv(mmc);
|
||||
uint32_t card_detect = host->regs->card_detect;
|
||||
if (card_detect == 0) return 1; /* Card detect not supported */
|
||||
return (card_detect & SDC_CARD_INSERT_INT_REQ) != 0;
|
||||
}
|
||||
|
||||
static irqreturn_t sdc_isr(int irq, void * dev_id) {
|
||||
struct mmc_host * mmc = (struct mmc_host *)dev_id;
|
||||
struct sdc_host * host = mmc_priv(mmc);
|
||||
uint32_t card_detect = 0;
|
||||
uint32_t data_status = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
card_detect = host->regs->card_detect;
|
||||
if (card_detect & SDC_CARD_INSERT_INT_REQ) {
|
||||
if (card_detect & SDC_CARD_INSERT_INT_EN) {
|
||||
host->regs->card_detect = SDC_CARD_REMOVE_INT_EN;
|
||||
mmc_detect_change(mmc, 0);
|
||||
}
|
||||
}
|
||||
else if (card_detect & SDC_CARD_REMOVE_INT_REQ) {
|
||||
if (card_detect & SDC_CARD_REMOVE_INT_EN) {
|
||||
host->regs->card_detect = SDC_CARD_INSERT_INT_EN;
|
||||
mmc_detect_change(mmc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_status = host->regs->dat_int_status) != 0) {
|
||||
host->regs->dat_int_enable = 0;
|
||||
host->regs->dat_int_status = 0;
|
||||
while (host->regs->software_reset != 0) {}
|
||||
if (host->data) {
|
||||
struct mmc_request * mrq = host->mrq;
|
||||
struct mmc_data * data = host->data;
|
||||
if (data_status == SDC_DAT_INT_STATUS_TRS) {
|
||||
data->bytes_xfered = data->blksz * data->blocks;
|
||||
}
|
||||
else {
|
||||
data->error = -EIO;
|
||||
if (data_status & SDC_DAT_INT_STATUS_CTE) data->error = -ETIME;
|
||||
}
|
||||
if (mrq->stop) sdc_send_cmd(host, mmc, mrq->stop, NULL);
|
||||
mmc_request_done(mmc, mrq);
|
||||
dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
|
||||
host->data = NULL;
|
||||
host->mrq = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
// JACOB: Had to modify this to resemble the older version of Linux
|
||||
// Used to be called hw_reset in older versions. Now it's
|
||||
// called .card_hw_reset to make it unambiguous what it's
|
||||
// resetting. When I update Linux, this will be changed back.
|
||||
static const struct mmc_host_ops axi_sdc_ops = {
|
||||
.request = sdc_request,
|
||||
.set_ios = sdc_set_ios,
|
||||
.get_cd = sdc_get_cd,
|
||||
.hw_reset = sdc_card_reset,
|
||||
};
|
||||
|
||||
static int axi_sdc_probe(struct platform_device * pdev) {
|
||||
struct device * dev = &pdev->dev;
|
||||
struct resource * iomem;
|
||||
struct sdc_host * host;
|
||||
struct mmc_host * mmc;
|
||||
void __iomem * ioaddr;
|
||||
uint32_t capability;
|
||||
int irq;
|
||||
int ret;
|
||||
|
||||
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ioaddr = devm_ioremap_resource(dev, iomem);
|
||||
if (IS_ERR(ioaddr)) return PTR_ERR(ioaddr);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0) return -ENXIO;
|
||||
|
||||
mmc = mmc_alloc_host(sizeof(*host), dev);
|
||||
if (!mmc) return -ENOMEM;
|
||||
|
||||
mmc->ops = &axi_sdc_ops;
|
||||
host = mmc_priv(mmc);
|
||||
host->pdev = pdev;
|
||||
host->regs = (struct sdc_regs __iomem *)ioaddr;
|
||||
host->irq = irq;
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "clock", &host->clk_freq);
|
||||
if (ret) host->clk_freq = 100000000;
|
||||
|
||||
ret = mmc_of_parse(mmc);
|
||||
if (ret) {
|
||||
mmc_free_host(mmc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mmc->f_min == 0) mmc->f_min = host->clk_freq / 0x200; /* maximum clock division 256 * 2 */
|
||||
if (mmc->f_max == 0) mmc->f_max = host->clk_freq / 2; /* minimum clock division 2 */
|
||||
if ((mmc->caps2 & MMC_CAP2_NO_SDIO) == 0) {
|
||||
/* TODO: deprecated 10/19/2022, set in DTS */
|
||||
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||
mmc->caps2 |= MMC_CAP2_NO_SDIO;
|
||||
}
|
||||
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||
mmc->max_segs = 1;
|
||||
mmc->max_req_size = 0x2000000;
|
||||
mmc->max_seg_size = 0x2000000;
|
||||
mmc->max_blk_size = 0x1000;
|
||||
mmc->max_blk_count = 0x10000;
|
||||
|
||||
ret = request_irq(host->irq, sdc_isr, IRQF_TRIGGER_HIGH, "fpga-axi-sdc", mmc);
|
||||
if (ret) {
|
||||
mmc_free_host(mmc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
host->dma_addr_bits = 32;
|
||||
capability = host->regs->capability;
|
||||
if (capability & SDC_CAPABILITY_ADDR) {
|
||||
host->dma_addr_bits = (capability & SDC_CAPABILITY_ADDR) >> __builtin_ctz(SDC_CAPABILITY_ADDR);
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(host->dma_addr_bits));
|
||||
if (ret) {
|
||||
printk(KERN_ERR "AXI-SDC: Can't set DMA mask\n");
|
||||
mmc_free_host(mmc);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
sdc_reset(mmc);
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "AXI-SDC: Can't register device\n");
|
||||
mmc_free_host(mmc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_init(&host->lock);
|
||||
|
||||
platform_set_drvdata(pdev, host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axi_sdc_remove(struct platform_device * pdev) {
|
||||
struct sdc_host * host = platform_get_drvdata(pdev);
|
||||
struct mmc_host * mmc = mmc_from_priv(host);
|
||||
|
||||
free_irq(host->irq, mmc);
|
||||
mmc_remove_host(mmc);
|
||||
mmc_free_host(mmc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver axi_sdc_driver = {
|
||||
.driver = {
|
||||
.name = "riscv-axi-sdc",
|
||||
.of_match_table = axi_sdc_of_match_table,
|
||||
},
|
||||
.probe = axi_sdc_probe,
|
||||
.remove = axi_sdc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(axi_sdc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("AXI SD Card driver");
|
||||
MODULE_AUTHOR("Eugene Tarassov");
|
||||
MODULE_LICENSE("GPL v2");
|
12
linux/buildroot-packages/package.patch
Normal file
12
linux/buildroot-packages/package.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
diff --git a/package/Config.in b/package/Config.in
|
||||
index 82b28d2835..29e8bb66ac 100644
|
||||
--- a/package/Config.in
|
||||
+++ b/package/Config.in
|
||||
@@ -469,6 +469,7 @@ endmenu
|
||||
source "package/fconfig/Config.in"
|
||||
source "package/flashrom/Config.in"
|
||||
source "package/fmtools/Config.in"
|
||||
+ source "package/fpga-axi-sdc/Config.in"
|
||||
source "package/freescale-imx/Config.in"
|
||||
source "package/fxload/Config.in"
|
||||
source "package/gcnano-binaries/Config.in"
|
3808
linux/buildroot-packages/wally.config
Normal file
3808
linux/buildroot-packages/wally.config
Normal file
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,7 @@ all:
|
|||
generate:
|
||||
# generating device tree binary
|
||||
dtc -I dts -O dtb ../devicetree/wally-virt.dts > ${IMAGES}/wally-virt.dtb
|
||||
dtc -I dts -O dtb ../devicetree/wally-vcu108.dts > ${IMAGES}/wally-vcu108.dtb
|
||||
|
||||
disassemble:
|
||||
mkdir -p ${DIS}
|
||||
|
|
|
@ -67,6 +67,20 @@
|
|||
#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>;
|
||||
interrupt-parent = <0x03>;
|
||||
clock = <0x14FB180>;
|
||||
max-frequency = <0xA7D8C0>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
no-sdio;
|
||||
};
|
||||
|
||||
clint@2000000 {
|
||||
interrupts-extended = <0x02 0x03 0x02 0x07>;
|
||||
reg = <0x00 0x2000000 0x00 0x10000>;
|
||||
|
|
9
linux/sdcard/Makefile
Normal file
9
linux/sdcard/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
RISCV := /opt/riscv
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
./make-img.sh test.img
|
||||
|
||||
clean:
|
||||
rm -f test.img
|
120
linux/sdcard/flash-sd.sh
Executable file
120
linux/sdcard/flash-sd.sh
Executable file
|
@ -0,0 +1,120 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit on any error (return code != 0)
|
||||
set -e
|
||||
|
||||
# Output colors
|
||||
GREEN='\033[1;32m'
|
||||
RED='\033[1;31m'
|
||||
NC='\033[0m'
|
||||
NAME="$GREEN"${0:2}"$NC"
|
||||
|
||||
# File location variables
|
||||
RISCV=/opt/riscv
|
||||
IMAGES=$RISCV/buildroot/output/images
|
||||
FW_JUMP=$IMAGES/fw_jump.bin
|
||||
LINUX_KERNEL=$IMAGES/Image
|
||||
DEVICE_TREE=$IMAGES/wally-vcu108.dtb
|
||||
|
||||
# Mount Directory
|
||||
MNT_DIR=wallyimg
|
||||
|
||||
if [ "$#" -eq "0" ] ; then
|
||||
echo "$NAME: $RED ERROR $NC: You must supply the SD card device."
|
||||
echo "usage: ./flash-sd.sh <sd device> <mount directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$1" ] ; then
|
||||
echo "$NAME:$RED ERROR $NC: SD card device does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -z "$2" ] ; then
|
||||
MNT_DIR=$2
|
||||
fi
|
||||
|
||||
# If images are not built, exit
|
||||
if [ ! -e $FW_JUMP ] || [ ! -e $LINUX_KERNEL ] ; then
|
||||
echo 'ERROR: Missing images in buildroot output directory.'
|
||||
echo ' Build images before running this script.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e $DEVICE_TREE ] ; then
|
||||
echo 'ERROR: Missing device tree file'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Size of OpenSBI and the Kernel in 512B blocks
|
||||
DST_SIZE=$(ls -la --block-size=512 $DEVICE_TREE | cut -d' ' -f 5 )
|
||||
FW_JUMP_SIZE=$(ls -la --block-size=512 $FW_JUMP | cut -d' ' -f 5 )
|
||||
KERNEL_SIZE=$(ls -la --block-size=512 $LINUX_KERNEL | cut -d' ' -f 5 )
|
||||
|
||||
# Start sectors of OpenSBI and Kernel Partitions
|
||||
FW_JUMP_START=$(( 34 + $DST_SIZE ))
|
||||
KERNEL_START=$(( $FW_JUMP_START + $FW_JUMP_SIZE ))
|
||||
FS_START=$(( $KERNEL_START + $KERNEL_SIZE ))
|
||||
|
||||
# Print out the sizes of the binaries in 512B blocks
|
||||
echo -e "$NAME: Device tree block size: $DST_SIZE"
|
||||
echo -e "$NAME: OpenSBI FW_JUMP block size: $FW_JUMP_SIZE"
|
||||
echo -e "$NAME: Kernel block size: $KERNEL_SIZE"
|
||||
|
||||
read -p "Warning: " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]] ; then
|
||||
# Make empty image
|
||||
#echo -e "$NAME: Creating blank image"
|
||||
#sudo dd if=/dev/zero of=$1 bs=4k conv=noerror status=progress && sync
|
||||
|
||||
# GUID Partition Tables (GPT)
|
||||
# ===============================================
|
||||
# -g Converts any existing mbr record to a gpt record
|
||||
# --clear clears any GPT partition table that already exists.
|
||||
# --set-alignment=1 that we want to align partition starting sectors
|
||||
# to 1 sector boundaries I think? This would normally be set to 2048
|
||||
# apparently.
|
||||
|
||||
# sudo sgdisk -g --clear --set-alignment=1 \
|
||||
# --new=1:34:+$FW_JUMP_SIZE: --change-name=1:'opensbi' --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985 \
|
||||
# --new=2:$KERNEL_START:+$KERNEL_SIZE --change-name=2:'kernel' --typecode=2:3000 \
|
||||
# --new=3:$FS_START:-0 --change-name=3:'filesystem' \
|
||||
# $1
|
||||
|
||||
echo -e "$NAME: Creating GUID Partition Table"
|
||||
sudo sgdisk -g --clear --set-alignment=1 \
|
||||
--new=1:34:+$DST_SIZE: --change-name=1:'fdt' \
|
||||
--new=2:$FW_JUMP_START:+$FW_JUMP_SIZE --change-name=2:'opensbi' --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985 \
|
||||
--new=3:$KERNEL_START:+$KERNEL_SIZE --change-name=3:'kernel' \
|
||||
--new=4:$FS_START:-0 --change-name=4:'filesystem' \
|
||||
$1
|
||||
|
||||
sudo partprobe $1
|
||||
|
||||
echo -e "$NAME: Copying binaries into their partitions."
|
||||
DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress"
|
||||
|
||||
echo -e "$NAME: Copying device tree"
|
||||
sudo dd if=$DEVICE_TREE of="$1"1 $DD_FLAGS
|
||||
|
||||
echo -e "$NAME: Copying OpenSBI"
|
||||
sudo dd if=$FW_JUMP of="$1"2 $DD_FLAGS
|
||||
|
||||
echo -e "$NAME: Copying Kernel"
|
||||
sudo dd if=$LINUX_KERNEL of="$1"3 $DD_FLAGS
|
||||
|
||||
sudo mkfs.ext4 "$1"4
|
||||
sudo mkdir /mnt/$MNT_DIR
|
||||
|
||||
sudo mount -v "$1"4 /mnt/$MNT_DIR
|
||||
|
||||
sudo umount -v /mnt/$MNT_DIR
|
||||
|
||||
sudo rmdir /mnt/$MNT_DIR
|
||||
#sudo losetup -d $LOOPDEVICE
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "GPT Information for $1 ==================================="
|
||||
sgdisk -p $1
|
110
linux/sdcard/make-img.sh
Executable file
110
linux/sdcard/make-img.sh
Executable file
|
@ -0,0 +1,110 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit on any error (return code != 0)
|
||||
set -e
|
||||
|
||||
# Output colors
|
||||
GREEN='\033[1;32m'
|
||||
NC='\033[0m'
|
||||
NAME="$GREEN"${0:2}"$NC"
|
||||
|
||||
# File location variables
|
||||
RISCV=/opt/riscv
|
||||
IMAGES=$RISCV/buildroot/output/images
|
||||
FW_JUMP=$IMAGES/fw_jump.bin
|
||||
LINUX_KERNEL=$IMAGES/Image
|
||||
DEVICE_TREE=$IMAGES/wally-vcu108.dtb
|
||||
|
||||
# Mount Directory
|
||||
MNT_DIR=wallyimg
|
||||
|
||||
if [ ! -z "$2" ] ; then
|
||||
MNT_DIR=$2
|
||||
fi
|
||||
|
||||
# If images are not built, exit
|
||||
if [ ! -e $FW_JUMP ] || [ ! -e $LINUX_KERNEL ] ; then
|
||||
echo 'ERROR: Missing images in buildroot output directory.'
|
||||
echo ' Build images before running this script.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e $DEVICE_TREE ] ; then
|
||||
echo 'ERROR: Missing device tree file'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Size of OpenSBI and the Kernel in 512B blocks
|
||||
DST_SIZE=$(ls -la --block-size=512 $DEVICE_TREE | cut -d' ' -f 5 )
|
||||
FW_JUMP_SIZE=$(ls -la --block-size=512 $FW_JUMP | cut -d' ' -f 5 )
|
||||
KERNEL_SIZE=$(ls -la --block-size=512 $LINUX_KERNEL | cut -d' ' -f 5 )
|
||||
|
||||
# Start sectors of OpenSBI and Kernel Partitions
|
||||
FW_JUMP_START=$(( 34 + $DST_SIZE ))
|
||||
KERNEL_START=$(( $FW_JUMP_START + $FW_JUMP_SIZE ))
|
||||
FS_START=$(( $KERNEL_START + $KERNEL_SIZE ))
|
||||
|
||||
# Print out the sizes of the binaries in 512B blocks
|
||||
echo -e "$NAME: Device tree block size: $DST_SIZE"
|
||||
echo -e "$NAME: OpenSBI FW_JUMP block size: $FW_JUMP_SIZE"
|
||||
echo -e "$NAME: Kernel block size: $KERNEL_SIZE"
|
||||
|
||||
if [ ! -e $1 ] ; then
|
||||
# Make empty image
|
||||
echo -e "$NAME: Creating blank image"
|
||||
sudo dd if=/dev/zero of=$1 bs=1M count=1536
|
||||
|
||||
# GUID Partition Tables (GPT)
|
||||
# ===============================================
|
||||
# -g Converts any existing mbr record to a gpt record
|
||||
# --clear clears any GPT partition table that already exists.
|
||||
# --set-alignment=1 that we want to align partition starting sectors
|
||||
# to 1 sector boundaries I think? This would normally be set to 2048
|
||||
# apparently.
|
||||
|
||||
# sudo sgdisk -g --clear --set-alignment=1 \
|
||||
# --new=1:34:+$FW_JUMP_SIZE: --change-name=1:'opensbi' --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985 \
|
||||
# --new=2:$KERNEL_START:+$KERNEL_SIZE --change-name=2:'kernel' --typecode=2:3000 \
|
||||
# --new=3:$FS_START:-0 --change-name=3:'filesystem' \
|
||||
# $1
|
||||
|
||||
echo -e "$NAME: Creating GUID Partition Table"
|
||||
sudo sgdisk -g --clear --set-alignment=1 \
|
||||
--new=1:34:+$DST_SIZE: --change-name=1:'fdt' \
|
||||
--new=2:$FW_JUMP_START:+$FW_JUMP_SIZE --change-name=2:'opensbi' --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985 \
|
||||
--new=3:$KERNEL_START:+$KERNEL_SIZE --change-name=3:'kernel' \
|
||||
--new=4:$FS_START:-0 --change-name=4:'filesystem' \
|
||||
$1
|
||||
|
||||
LOOPDEVICE=$(sudo losetup -f)
|
||||
echo -e "$NAME: Loop device: $LOOPDEVICE"
|
||||
|
||||
sudo losetup --partscan $LOOPDEVICE $1
|
||||
|
||||
echo -e "$NAME: Copying binaries into their partitions."
|
||||
DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress"
|
||||
# Store device tree in device tree partition
|
||||
|
||||
echo -e "$NAME: Copying device tree"
|
||||
sudo dd if=$DEVICE_TREE of="$LOOPDEVICE"p1 $DD_FLAGS
|
||||
|
||||
echo -e "$NAME: Copying OpenSBI"
|
||||
sudo dd if=$FW_JUMP of="$LOOPDEVICE"p2 $DD_FLAGS
|
||||
|
||||
echo -e "$NAME: Copying Kernel"
|
||||
sudo dd if=$LINUX_KERNEL of="$LOOPDEVICE"p3 $DD_FLAGS
|
||||
|
||||
sudo mkfs.ext4 "$LOOPDEVICE"p4
|
||||
sudo mkdir /mnt/$MNT_DIR
|
||||
|
||||
sudo mount -v "$LOOPDEVICE"p4 /mnt/$MNT_DIR
|
||||
|
||||
sudo umount -v /mnt/$MNT_DIR
|
||||
|
||||
sudo rmdir /mnt/$MNT_DIR
|
||||
sudo losetup -d $LOOPDEVICE
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "GPT Information for $1 ==================================="
|
||||
sgdisk -p $1
|
669
pipelined/src/uncore/newsdc/axi_sdc_controller.v
Normal file
669
pipelined/src/uncore/newsdc/axi_sdc_controller.v
Normal file
|
@ -0,0 +1,669 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sdc_controller #(
|
||||
parameter dma_addr_bits = 32,
|
||||
parameter fifo_addr_bits = 7,
|
||||
parameter sdio_card_detect_level = 1,
|
||||
parameter voltage_controll_reg = 3300,
|
||||
parameter capabilies_reg = 16'b0000_0000_0000_0011
|
||||
) (
|
||||
input wire async_resetn,
|
||||
|
||||
(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 clock CLK" *)
|
||||
(* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF M_AXI:S_AXI_LITE, FREQ_HZ 100000000" *)
|
||||
input wire clock,
|
||||
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE AWADDR" *)
|
||||
(* X_INTERFACE_PARAMETER = "CLK_DOMAIN clock, ID_WIDTH 0, PROTOCOL AXI4LITE, DATA_WIDTH 32" *)
|
||||
input wire [15:0] s_axi_awaddr,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE AWVALID" *)
|
||||
input wire s_axi_awvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE AWREADY" *)
|
||||
output wire s_axi_awready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE WDATA" *)
|
||||
input wire [31:0] s_axi_wdata,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE WVALID" *)
|
||||
input wire s_axi_wvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE WREADY" *)
|
||||
output wire s_axi_wready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE BRESP" *)
|
||||
output reg [1:0] s_axi_bresp,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE BVALID" *)
|
||||
output reg s_axi_bvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE BREADY" *)
|
||||
input wire s_axi_bready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE ARADDR" *)
|
||||
input wire [15:0] s_axi_araddr,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE ARVALID" *)
|
||||
input wire s_axi_arvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE ARREADY" *)
|
||||
output wire s_axi_arready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE RDATA" *)
|
||||
output reg [31:0] s_axi_rdata,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE RRESP" *)
|
||||
output reg [1:0] s_axi_rresp,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE RVALID" *)
|
||||
output reg s_axi_rvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_LITE RREADY" *)
|
||||
input wire s_axi_rready,
|
||||
|
||||
(* X_INTERFACE_PARAMETER = "CLK_DOMAIN clock, ID_WIDTH 0, PROTOCOL AXI4, DATA_WIDTH 32" *)
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWADDR" *)
|
||||
output reg [dma_addr_bits-1:0] m_axi_awaddr,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWLEN" *)
|
||||
output reg [7:0] m_axi_awlen,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWVALID" *)
|
||||
output reg m_axi_awvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWREADY" *)
|
||||
input wire m_axi_awready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WDATA" *)
|
||||
output wire [31:0] m_axi_wdata,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WLAST" *)
|
||||
output reg m_axi_wlast,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WVALID" *)
|
||||
output reg m_axi_wvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WREADY" *)
|
||||
input wire m_axi_wready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BRESP" *)
|
||||
input wire [1:0] m_axi_bresp,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BVALID" *)
|
||||
input wire m_axi_bvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BREADY" *)
|
||||
output wire m_axi_bready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARADDR" *)
|
||||
output reg [dma_addr_bits-1:0] m_axi_araddr,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARLEN" *)
|
||||
output reg [7:0] m_axi_arlen,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARVALID" *)
|
||||
output reg m_axi_arvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARREADY" *)
|
||||
input wire m_axi_arready,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RDATA" *)
|
||||
input wire [31:0] m_axi_rdata,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RLAST" *)
|
||||
input wire m_axi_rlast,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RRESP" *)
|
||||
input wire [1:0] m_axi_rresp,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RVALID" *)
|
||||
input wire m_axi_rvalid,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RREADY" *)
|
||||
output wire m_axi_rready,
|
||||
|
||||
// SD BUS
|
||||
//inout wire sdio_cmd,
|
||||
//inout wire [3:0] sdio_dat,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 sdio_clk CLK" *)
|
||||
(* X_INTERFACE_PARAMETER = "FREQ_HZ 50000000" *)
|
||||
output reg sdio_clk,
|
||||
(* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 sdio_reset RST" *)
|
||||
(* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_HIGH" *)
|
||||
output reg sdio_reset,
|
||||
input wire sdio_cd,
|
||||
|
||||
output reg sd_dat_reg_t,
|
||||
output reg [3:0] sd_dat_reg_o,
|
||||
input wire [3:0] sd_dat_i,
|
||||
|
||||
output reg sd_cmd_reg_t,
|
||||
output reg sd_cmd_reg_o,
|
||||
input wire sd_cmd_i,
|
||||
|
||||
// Interrupts
|
||||
output wire interrupt
|
||||
);
|
||||
|
||||
`include "sd_defines.h"
|
||||
|
||||
wire reset;
|
||||
|
||||
wire go_idle;
|
||||
reg cmd_start;
|
||||
wire [1:0] cmd_setting;
|
||||
wire cmd_start_tx;
|
||||
wire [39:0] cmd;
|
||||
wire [119:0] cmd_response;
|
||||
wire cmd_crc_ok;
|
||||
wire cmd_index_ok;
|
||||
wire cmd_finish;
|
||||
|
||||
wire d_write;
|
||||
wire d_read;
|
||||
wire [31:0] data_in_rx_fifo;
|
||||
wire en_tx_fifo;
|
||||
wire en_rx_fifo;
|
||||
wire sd_data_busy;
|
||||
(* mark_debug = "true" *) wire data_busy;
|
||||
wire data_crc_ok;
|
||||
wire tx_fifo_re;
|
||||
wire rx_fifo_we;
|
||||
|
||||
reg data_start_rx;
|
||||
reg data_start_tx;
|
||||
reg data_prepare_tx;
|
||||
reg cmd_int_rst;
|
||||
reg data_int_rst;
|
||||
reg ctrl_rst;
|
||||
|
||||
// AXI accessible registers
|
||||
(* mark_debug = "true" *) reg [31:0] argument_reg;
|
||||
(* mark_debug = "true" *) reg [`CMD_REG_SIZE-1:0] command_reg;
|
||||
(* mark_debug = "true" *) reg [`CMD_TIMEOUT_W-1:0] cmd_timeout_reg;
|
||||
(* mark_debug = "true" *) reg [`DATA_TIMEOUT_W-1:0] data_timeout_reg;
|
||||
(* mark_debug = "true" *) reg [0:0] software_reset_reg;
|
||||
(* mark_debug = "true" *) wire [31:0] response_0_reg;
|
||||
(* mark_debug = "true" *) wire [31:0] response_1_reg;
|
||||
(* mark_debug = "true" *) wire [31:0] response_2_reg;
|
||||
(* mark_debug = "true" *) wire [31:0] response_3_reg;
|
||||
(* mark_debug = "true" *) reg [`BLKSIZE_W-1:0] block_size_reg;
|
||||
(* mark_debug = "true" *) reg [1:0] controller_setting_reg;
|
||||
(* mark_debug = "true" *) wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg;
|
||||
(* mark_debug = "true" *) wire [`INT_DATA_SIZE-1:0] data_int_status_reg;
|
||||
(* mark_debug = "true" *) wire [`INT_DATA_SIZE-1:0] data_int_status;
|
||||
(* mark_debug = "true" *) reg [`INT_CMD_SIZE-1:0] cmd_int_enable_reg;
|
||||
(* mark_debug = "true" *) reg [`INT_DATA_SIZE-1:0] data_int_enable_reg;
|
||||
(* mark_debug = "true" *) reg [`BLKCNT_W-1:0] block_count_reg;
|
||||
(* mark_debug = "true" *) reg [dma_addr_bits-1:0] dma_addr_reg;
|
||||
(* mark_debug = "true" *) reg [7:0] clock_divider_reg = 124; // 400KHz
|
||||
|
||||
// ------ Clocks and resets
|
||||
|
||||
(* ASYNC_REG="true" *)
|
||||
reg [2:0] reset_sync;
|
||||
assign reset = reset_sync[2];
|
||||
|
||||
always @(posedge clock)
|
||||
reset_sync <= {reset_sync[1:0], !async_resetn};
|
||||
|
||||
reg [7:0] clock_cnt;
|
||||
reg clock_state;
|
||||
(* mark_debug = "true" *) reg clock_posedge;
|
||||
reg clock_data_in;
|
||||
wire fifo_almost_full;
|
||||
wire fifo_almost_empty;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
clock_posedge <= 0;
|
||||
clock_data_in <= 0;
|
||||
clock_state <= 0;
|
||||
clock_cnt <= 0;
|
||||
end else if (clock_cnt < clock_divider_reg) begin
|
||||
clock_posedge <= 0;
|
||||
clock_data_in <= 0;
|
||||
clock_cnt <= clock_cnt + 1;
|
||||
end else if (clock_cnt < 124 && data_busy && en_rx_fifo && fifo_almost_full) begin
|
||||
// Prevent Rx FIFO overflow
|
||||
clock_posedge <= 0;
|
||||
clock_data_in <= 0;
|
||||
clock_cnt <= clock_cnt + 1;
|
||||
end else if (clock_cnt < 124 && data_busy && en_tx_fifo && fifo_almost_empty) begin
|
||||
// Prevent Tx FIFO underflow
|
||||
clock_posedge <= 0;
|
||||
clock_data_in <= 0;
|
||||
clock_cnt <= clock_cnt + 1;
|
||||
end else begin
|
||||
clock_state <= !clock_state;
|
||||
clock_posedge <= !clock_state;
|
||||
if (clock_divider_reg == 0)
|
||||
clock_data_in <= !clock_state;
|
||||
else
|
||||
clock_data_in <= clock_state;
|
||||
clock_cnt <= 0;
|
||||
end
|
||||
sdio_clk <= sdio_reset || clock_state;
|
||||
|
||||
if (reset) sdio_reset <= 0;
|
||||
else if (clock_posedge) sdio_reset <= controller_setting_reg[1];
|
||||
end
|
||||
|
||||
// ------ SD IO Buffers
|
||||
|
||||
// wire sd_cmd_i;
|
||||
wire sd_cmd_o;
|
||||
wire sd_cmd_oe;
|
||||
// reg sd_cmd_reg_o;
|
||||
// reg sd_cmd_reg_t;
|
||||
// wire [3:0] sd_dat_i;
|
||||
wire [3:0] sd_dat_o;
|
||||
wire sd_dat_oe;
|
||||
// reg [3:0] sd_dat_reg_o;
|
||||
// reg sd_dat_reg_t;
|
||||
|
||||
// IOBUF IOBUF_cmd (.O(sd_cmd_i), .IO(sdio_cmd), .I(sd_cmd_reg_o), .T(sd_cmd_reg_t));
|
||||
// IOBUF IOBUF_dat0 (.O(sd_dat_i[0]), .IO(sdio_dat[0]), .I(sd_dat_reg_o[0]), .T(sd_dat_reg_t));
|
||||
// IOBUF IOBUF_dat1 (.O(sd_dat_i[1]), .IO(sdio_dat[1]), .I(sd_dat_reg_o[1]), .T(sd_dat_reg_t));
|
||||
// IOBUF IOBUF_dat2 (.O(sd_dat_i[2]), .IO(sdio_dat[2]), .I(sd_dat_reg_o[2]), .T(sd_dat_reg_t));
|
||||
// IOBUF IOBUF_dat3 (.O(sd_dat_i[3]), .IO(sdio_dat[3]), .I(sd_dat_reg_o[3]), .T(sd_dat_reg_t));
|
||||
|
||||
always @(negedge clock) begin
|
||||
// Output data delayed by 1/2 clock cycle (5ns) to ensure
|
||||
// required hold time: default speed - min 5ns, high speed - min 2ns (actual 5ns)
|
||||
if (sdio_reset) begin
|
||||
sd_cmd_reg_o <= 0;
|
||||
sd_dat_reg_o <= 0;
|
||||
sd_cmd_reg_t <= 0;
|
||||
sd_dat_reg_t <= 0;
|
||||
end else begin
|
||||
sd_cmd_reg_o <= sd_cmd_o;
|
||||
sd_dat_reg_o <= sd_dat_o;
|
||||
sd_cmd_reg_t <= !sd_cmd_oe;
|
||||
sd_dat_reg_t <= !(sd_dat_oe || (cmd_start_tx && (command_reg == 0)));
|
||||
end
|
||||
end
|
||||
|
||||
// ------ SD card detect
|
||||
|
||||
reg [25:0] sd_detect_cnt;
|
||||
wire sd_insert_int = sd_detect_cnt[25];
|
||||
wire sd_remove_int = !sd_detect_cnt[25];
|
||||
reg sd_insert_ie;
|
||||
reg sd_remove_ie;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (sdio_cd != sdio_card_detect_level) begin
|
||||
sd_detect_cnt <= 0;
|
||||
end else if (!sd_insert_int) begin
|
||||
sd_detect_cnt <= sd_detect_cnt + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// ------ AXI Slave Interface
|
||||
|
||||
reg [15:0] read_addr;
|
||||
reg [15:0] write_addr;
|
||||
reg [31:0] write_data;
|
||||
reg rd_req;
|
||||
reg [1:0] wr_req;
|
||||
|
||||
assign s_axi_arready = !rd_req && !s_axi_rvalid;
|
||||
assign s_axi_awready = !wr_req[0] && !s_axi_bvalid;
|
||||
assign s_axi_wready = !wr_req[1] && !s_axi_bvalid;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
s_axi_rdata <= 0;
|
||||
s_axi_rresp <= 0;
|
||||
s_axi_rvalid <= 0;
|
||||
s_axi_bresp <= 0;
|
||||
s_axi_bvalid <= 0;
|
||||
rd_req <= 0;
|
||||
wr_req <= 0;
|
||||
read_addr <= 0;
|
||||
write_addr <= 0;
|
||||
write_data <= 0;
|
||||
cmd_start <= 0;
|
||||
data_int_rst <= 0;
|
||||
cmd_int_rst <= 0;
|
||||
ctrl_rst <= 0;
|
||||
argument_reg <= 0;
|
||||
command_reg <= 0;
|
||||
cmd_timeout_reg <= 0;
|
||||
data_timeout_reg <= 0;
|
||||
block_size_reg <= `RESET_BLOCK_SIZE;
|
||||
controller_setting_reg <= 0;
|
||||
cmd_int_enable_reg <= 0;
|
||||
data_int_enable_reg <= 0;
|
||||
software_reset_reg <= 0;
|
||||
clock_divider_reg <= `RESET_CLOCK_DIV;
|
||||
block_count_reg <= 0;
|
||||
sd_insert_ie <= 0;
|
||||
sd_remove_ie <= 0;
|
||||
dma_addr_reg <= 0;
|
||||
end else begin
|
||||
if (clock_posedge) begin
|
||||
cmd_start <= 0;
|
||||
data_int_rst <= 0;
|
||||
cmd_int_rst <= 0;
|
||||
ctrl_rst <= software_reset_reg[0];
|
||||
end
|
||||
if (s_axi_arready && s_axi_arvalid) begin
|
||||
read_addr <= s_axi_araddr;
|
||||
rd_req <= 1;
|
||||
end
|
||||
if (s_axi_rvalid && s_axi_rready) begin
|
||||
s_axi_rvalid <= 0;
|
||||
end else if (!s_axi_rvalid && rd_req) begin
|
||||
s_axi_rdata <= 0;
|
||||
if (read_addr[15:8] == 0) begin
|
||||
case (read_addr[7:0])
|
||||
`argument : s_axi_rdata <= argument_reg;
|
||||
`command : s_axi_rdata <= command_reg;
|
||||
`resp0 : s_axi_rdata <= response_0_reg;
|
||||
`resp1 : s_axi_rdata <= response_1_reg;
|
||||
`resp2 : s_axi_rdata <= response_2_reg;
|
||||
`resp3 : s_axi_rdata <= response_3_reg;
|
||||
`controller : s_axi_rdata <= controller_setting_reg;
|
||||
`blksize : s_axi_rdata <= block_size_reg;
|
||||
`voltage : s_axi_rdata <= voltage_controll_reg;
|
||||
`capa : s_axi_rdata <= capabilies_reg | (dma_addr_bits << 8);
|
||||
`clock_d : s_axi_rdata <= clock_divider_reg;
|
||||
`reset : s_axi_rdata <= { cmd_start, data_int_rst, cmd_int_rst, ctrl_rst };
|
||||
`cmd_timeout : s_axi_rdata <= cmd_timeout_reg;
|
||||
`data_timeout : s_axi_rdata <= data_timeout_reg;
|
||||
`cmd_isr : s_axi_rdata <= cmd_int_status_reg;
|
||||
`cmd_iser : s_axi_rdata <= cmd_int_enable_reg;
|
||||
`data_isr : s_axi_rdata <= data_int_status_reg;
|
||||
`data_iser : s_axi_rdata <= data_int_enable_reg;
|
||||
`blkcnt : s_axi_rdata <= block_count_reg;
|
||||
`card_detect : s_axi_rdata <= { sd_remove_int, sd_remove_ie, sd_insert_int, sd_insert_ie };
|
||||
`dst_src_addr : s_axi_rdata <= dma_addr_reg[31:0];
|
||||
`dst_src_addr_high : if (dma_addr_bits > 32) s_axi_rdata <= dma_addr_reg[dma_addr_bits-1:32];
|
||||
endcase
|
||||
end
|
||||
s_axi_rresp <= 0;
|
||||
s_axi_rvalid <= 1;
|
||||
rd_req <= 0;
|
||||
end
|
||||
if (s_axi_awready && s_axi_awvalid) begin
|
||||
write_addr <= s_axi_awaddr;
|
||||
wr_req[0] <= 1;
|
||||
end
|
||||
if (s_axi_wready && s_axi_wvalid) begin
|
||||
write_data <= s_axi_wdata;
|
||||
wr_req[1] <= 1;
|
||||
end
|
||||
if (s_axi_bvalid && s_axi_bready) begin
|
||||
s_axi_bvalid <= 0;
|
||||
end else if (!s_axi_bvalid && wr_req == 2'b11) begin
|
||||
if (write_addr[15:8] == 0) begin
|
||||
case (write_addr[7:0])
|
||||
`argument : begin argument_reg <= write_data; cmd_start <= 1; end
|
||||
`command : command_reg <= write_data;
|
||||
`reset : software_reset_reg <= write_data;
|
||||
`cmd_timeout : cmd_timeout_reg <= write_data;
|
||||
`data_timeout : data_timeout_reg <= write_data;
|
||||
`blksize : block_size_reg <= write_data;
|
||||
`controller : controller_setting_reg <= write_data;
|
||||
`cmd_isr : cmd_int_rst <= 1;
|
||||
`cmd_iser : cmd_int_enable_reg <= write_data;
|
||||
`clock_d : clock_divider_reg <= write_data;
|
||||
`data_isr : data_int_rst <= 1;
|
||||
`data_iser : data_int_enable_reg <= write_data;
|
||||
`blkcnt : block_count_reg <= write_data;
|
||||
`card_detect : begin sd_remove_ie <= write_data[2]; sd_insert_ie <= write_data[0]; end
|
||||
`dst_src_addr : dma_addr_reg[31:0] <= write_data;
|
||||
`dst_src_addr_high : if (dma_addr_bits > 32) dma_addr_reg[dma_addr_bits-1:32] <= write_data;
|
||||
endcase
|
||||
end
|
||||
s_axi_bresp <= 0;
|
||||
s_axi_bvalid <= 1;
|
||||
wr_req <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ------ Data FIFO
|
||||
|
||||
reg [31:0] fifo_mem [(1<<fifo_addr_bits)-1:0];
|
||||
reg [fifo_addr_bits-1:0] fifo_inp_pos;
|
||||
reg [fifo_addr_bits-1:0] fifo_out_pos;
|
||||
wire [fifo_addr_bits-1:0] fifo_inp_nxt = fifo_inp_pos + 1;
|
||||
wire [fifo_addr_bits-1:0] fifo_out_nxt = fifo_out_pos + 1;
|
||||
wire [fifo_addr_bits-1:0] fifo_data_len = fifo_inp_pos - fifo_out_pos;
|
||||
wire [fifo_addr_bits-1:0] fifo_free_len = fifo_out_pos - fifo_inp_nxt;
|
||||
wire fifo_full = fifo_inp_nxt == fifo_out_pos;
|
||||
wire fifo_empty = fifo_inp_pos == fifo_out_pos;
|
||||
wire fifo_ready = fifo_data_len >= (1 << fifo_addr_bits) / 2;
|
||||
wire [31:0] fifo_din = en_rx_fifo ? data_in_rx_fifo : m_bus_dat_i;
|
||||
wire fifo_we = en_rx_fifo ? rx_fifo_we && clock_posedge : m_axi_rready && m_axi_rvalid;
|
||||
wire fifo_re = en_rx_fifo ? m_axi_wready && m_axi_wvalid : tx_fifo_re && clock_posedge;
|
||||
reg [31:0] fifo_dout;
|
||||
|
||||
assign fifo_almost_full = fifo_data_len > (1 << fifo_addr_bits) * 3 / 4;
|
||||
assign fifo_almost_empty = fifo_free_len > (1 << fifo_addr_bits) * 3 / 4;
|
||||
|
||||
wire tx_stb = en_tx_fifo && fifo_free_len >= (1 << fifo_addr_bits) / 3;
|
||||
wire rx_stb = en_rx_fifo && m_axi_bresp_cnt != 3'b111 && (fifo_data_len >= (1 << fifo_addr_bits) / 3 || (!fifo_empty && !data_busy));
|
||||
|
||||
always @(posedge clock)
|
||||
if (reset || ctrl_rst || !(en_rx_fifo || en_tx_fifo)) begin
|
||||
fifo_inp_pos <= 0;
|
||||
fifo_out_pos <= 0;
|
||||
end else begin
|
||||
if (fifo_we && !fifo_full) begin
|
||||
fifo_mem[fifo_inp_pos] <= fifo_din;
|
||||
fifo_inp_pos <= fifo_inp_nxt;
|
||||
if (fifo_empty) fifo_dout <= fifo_din;
|
||||
end
|
||||
if (fifo_re && !fifo_empty) begin
|
||||
if (fifo_we && !fifo_full && fifo_out_nxt == fifo_inp_pos) fifo_dout <= fifo_din;
|
||||
else fifo_dout <= fifo_mem[fifo_out_nxt];
|
||||
fifo_out_pos <= fifo_out_nxt;
|
||||
end
|
||||
end
|
||||
|
||||
// ------ AXI Master Interface
|
||||
|
||||
// AXI transaction (DDR access) is over 80 clock cycles
|
||||
// Must use burst to achive required throughput
|
||||
|
||||
reg m_axi_cyc;
|
||||
wire m_axi_write = en_rx_fifo;
|
||||
reg [7:0] m_axi_wcnt;
|
||||
reg [dma_addr_bits-1:2] m_bus_adr_o;
|
||||
wire [31:0] m_bus_dat_i;
|
||||
reg [2:0] m_axi_bresp_cnt;
|
||||
reg m_bus_error;
|
||||
|
||||
assign m_axi_bready = m_axi_bresp_cnt != 0;
|
||||
assign m_axi_rready = m_axi_cyc & !m_axi_write;
|
||||
assign m_bus_dat_i = {m_axi_rdata[7:0],m_axi_rdata[15:8],m_axi_rdata[23:16],m_axi_rdata[31:24]};
|
||||
assign m_axi_wdata = {fifo_dout[7:0],fifo_dout[15:8],fifo_dout[23:16],fifo_dout[31:24]};
|
||||
|
||||
// AXI burst cannot cross a 4KB boundary
|
||||
wire [fifo_addr_bits-1:0] tx_burst_len;
|
||||
wire [fifo_addr_bits-1:0] rx_burst_len;
|
||||
assign tx_burst_len = m_bus_adr_o[11:2] + fifo_free_len >= m_bus_adr_o[11:2] ? fifo_free_len - 1 : ~m_bus_adr_o[fifo_addr_bits+1:2];
|
||||
assign rx_burst_len = m_bus_adr_o[11:2] + fifo_data_len >= m_bus_adr_o[11:2] ? fifo_data_len - 1 : ~m_bus_adr_o[fifo_addr_bits+1:2];
|
||||
|
||||
assign data_int_status_reg = { data_int_status[`INT_DATA_SIZE-1:1],
|
||||
!en_rx_fifo && !en_tx_fifo && !m_axi_cyc && m_axi_bresp_cnt == 0 && data_int_status[0] };
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset | ctrl_rst) begin
|
||||
m_axi_arvalid <= 0;
|
||||
m_axi_awvalid <= 0;
|
||||
m_axi_wvalid <= 0;
|
||||
m_axi_cyc <= 0;
|
||||
end else if (m_axi_cyc) begin
|
||||
if (m_axi_awvalid && m_axi_awready) begin
|
||||
m_axi_awvalid <= 0;
|
||||
end
|
||||
if (m_axi_arvalid && m_axi_arready) begin
|
||||
m_axi_arvalid <= 0;
|
||||
end
|
||||
if (m_axi_wvalid && m_axi_wready) begin
|
||||
if (m_axi_wlast) begin
|
||||
m_axi_wvalid <= 0;
|
||||
m_axi_cyc <= 0;
|
||||
end else begin
|
||||
m_axi_wlast <= m_axi_wcnt + 1 == m_axi_awlen;
|
||||
m_axi_wcnt <= m_axi_wcnt + 1;
|
||||
end
|
||||
end
|
||||
if (m_axi_rvalid && m_axi_rready && m_axi_rlast) begin
|
||||
m_axi_cyc <= 0;
|
||||
end
|
||||
end else if (tx_stb || rx_stb) begin
|
||||
m_axi_cyc <= 1;
|
||||
m_axi_wcnt <= 0;
|
||||
if (m_axi_write) begin
|
||||
m_axi_awaddr <= { m_bus_adr_o, 2'b00 };
|
||||
m_axi_awlen <= rx_burst_len < 8'hff ? rx_burst_len : 8'hff;
|
||||
m_axi_wlast <= rx_burst_len == 0;
|
||||
m_axi_awvalid <= 1;
|
||||
m_axi_wvalid <= 1;
|
||||
end else begin
|
||||
m_axi_araddr <= { m_bus_adr_o, 2'b00 };
|
||||
m_axi_arlen <= tx_burst_len < 8'hff ? tx_burst_len : 8'hff;
|
||||
m_axi_arvalid <= 1;
|
||||
end
|
||||
end
|
||||
if (reset | ctrl_rst) begin
|
||||
m_bus_adr_o <= 0;
|
||||
end else if ((m_axi_wready && m_axi_wvalid) || (m_axi_rready && m_axi_rvalid)) begin
|
||||
m_bus_adr_o <= m_bus_adr_o + 1;
|
||||
end else if (!m_axi_cyc && !en_rx_fifo && !en_tx_fifo) begin
|
||||
m_bus_adr_o <= dma_addr_reg[dma_addr_bits-1:2];
|
||||
end
|
||||
if (reset | ctrl_rst) begin
|
||||
m_axi_bresp_cnt <= 0;
|
||||
end else if ((m_axi_awvalid && m_axi_awready) && !(m_axi_bvalid && m_axi_bready)) begin
|
||||
m_axi_bresp_cnt <= m_axi_bresp_cnt + 1;
|
||||
end else if (!(m_axi_awvalid && m_axi_awready) && (m_axi_bvalid && m_axi_bready)) begin
|
||||
m_axi_bresp_cnt <= m_axi_bresp_cnt - 1;
|
||||
end
|
||||
if (reset | ctrl_rst | cmd_start) begin
|
||||
m_bus_error <= 0;
|
||||
end else if (m_axi_bvalid && m_axi_bready && m_axi_bresp) begin
|
||||
m_bus_error <= 1;
|
||||
end else if (m_axi_rvalid && m_axi_rready && m_axi_rresp) begin
|
||||
m_bus_error <= 1;
|
||||
end
|
||||
if (reset | ctrl_rst) begin
|
||||
data_start_tx <= 0;
|
||||
data_start_rx <= 0;
|
||||
data_prepare_tx <= 0;
|
||||
end else if (clock_posedge) begin
|
||||
data_start_tx <= 0;
|
||||
data_start_rx <= 0;
|
||||
if (cmd_start) begin
|
||||
data_prepare_tx <= 0;
|
||||
if (command_reg[`CMD_WITH_DATA] == 2'b01) data_start_rx <= 1;
|
||||
else if (command_reg[`CMD_WITH_DATA] != 2'b00) data_prepare_tx <= 1;
|
||||
end else if (data_prepare_tx) begin
|
||||
if (cmd_int_status_reg[`INT_CMD_CC]) begin
|
||||
data_prepare_tx <= 0;
|
||||
data_start_tx <= 1;
|
||||
end else if (cmd_int_status_reg[`INT_CMD_EI]) begin
|
||||
data_prepare_tx <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ------ SD Card Interface
|
||||
|
||||
sd_cmd_master sd_cmd_master0(
|
||||
.clock (clock),
|
||||
.clock_posedge (clock_posedge),
|
||||
.reset (reset | ctrl_rst),
|
||||
.start (cmd_start),
|
||||
.int_status_rst (cmd_int_rst),
|
||||
.setting (cmd_setting),
|
||||
.start_xfr (cmd_start_tx),
|
||||
.go_idle (go_idle),
|
||||
.cmd (cmd),
|
||||
.response (cmd_response),
|
||||
.crc_error (!cmd_crc_ok),
|
||||
.index_ok (cmd_index_ok),
|
||||
.busy (sd_data_busy),
|
||||
.finish (cmd_finish),
|
||||
.argument (argument_reg),
|
||||
.command (command_reg),
|
||||
.timeout (cmd_timeout_reg),
|
||||
.int_status (cmd_int_status_reg),
|
||||
.response_0 (response_0_reg),
|
||||
.response_1 (response_1_reg),
|
||||
.response_2 (response_2_reg),
|
||||
.response_3 (response_3_reg)
|
||||
);
|
||||
|
||||
sd_cmd_serial_host cmd_serial_host0(
|
||||
.clock (clock),
|
||||
.clock_posedge (clock_posedge),
|
||||
.clock_data_in (clock_data_in),
|
||||
.reset (reset | ctrl_rst | go_idle),
|
||||
.setting (cmd_setting),
|
||||
.cmd (cmd),
|
||||
.start (cmd_start_tx),
|
||||
.finish (cmd_finish),
|
||||
.response (cmd_response),
|
||||
.crc_ok (cmd_crc_ok),
|
||||
.index_ok (cmd_index_ok),
|
||||
.cmd_i (sd_cmd_i),
|
||||
.cmd_o (sd_cmd_o),
|
||||
.cmd_oe (sd_cmd_oe)
|
||||
);
|
||||
|
||||
sd_data_master sd_data_master0(
|
||||
.clock (clock),
|
||||
.clock_posedge (clock_posedge),
|
||||
.reset (reset | ctrl_rst),
|
||||
.start_tx (data_start_tx),
|
||||
.start_rx (data_start_rx),
|
||||
.timeout (data_timeout_reg),
|
||||
.d_write (d_write),
|
||||
.d_read (d_read),
|
||||
.en_tx_fifo (en_tx_fifo),
|
||||
.en_rx_fifo (en_rx_fifo),
|
||||
.fifo_empty (fifo_empty),
|
||||
.fifo_ready (fifo_ready),
|
||||
.fifo_full (fifo_full),
|
||||
.bus_cycle (m_axi_cyc || m_axi_bresp_cnt != 0),
|
||||
.xfr_complete (!data_busy),
|
||||
.crc_error (!data_crc_ok),
|
||||
.bus_error (m_bus_error),
|
||||
.int_status (data_int_status),
|
||||
.int_status_rst (data_int_rst)
|
||||
);
|
||||
|
||||
sd_data_serial_host sd_data_serial_host0(
|
||||
.clock (clock),
|
||||
.clock_posedge (clock_posedge),
|
||||
.clock_data_in (clock_data_in),
|
||||
.reset (reset | ctrl_rst),
|
||||
.data_in (fifo_dout),
|
||||
.rd (tx_fifo_re),
|
||||
.data_out (data_in_rx_fifo),
|
||||
.we (rx_fifo_we),
|
||||
.dat_oe (sd_dat_oe),
|
||||
.dat_o (sd_dat_o),
|
||||
.dat_i (sd_dat_i),
|
||||
.blksize (block_size_reg),
|
||||
.bus_4bit (controller_setting_reg[0]),
|
||||
.blkcnt (block_count_reg),
|
||||
.start ({d_read, d_write}),
|
||||
.byte_alignment (dma_addr_reg[1:0]),
|
||||
.sd_data_busy (sd_data_busy),
|
||||
.busy (data_busy),
|
||||
.crc_ok (data_crc_ok)
|
||||
);
|
||||
|
||||
assign interrupt =
|
||||
|(cmd_int_status_reg & cmd_int_enable_reg) ||
|
||||
|(data_int_status_reg & data_int_enable_reg) ||
|
||||
(sd_insert_int & sd_insert_ie) ||
|
||||
(sd_remove_int & sd_remove_ie);
|
||||
|
||||
endmodule
|
502
pipelined/src/uncore/newsdc/license.txt
Normal file
502
pipelined/src/uncore/newsdc/license.txt
Normal file
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
152
pipelined/src/uncore/newsdc/sd_cmd_master.v
Normal file
152
pipelined/src/uncore/newsdc/sd_cmd_master.v
Normal file
|
@ -0,0 +1,152 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
`include "sd_defines.h"
|
||||
|
||||
module sd_cmd_master(
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input reset,
|
||||
input start,
|
||||
input int_status_rst,
|
||||
output [1:0] setting,
|
||||
output reg start_xfr,
|
||||
output reg go_idle,
|
||||
output reg [39:0] cmd,
|
||||
input [119:0] response,
|
||||
input crc_error,
|
||||
input index_ok,
|
||||
input finish,
|
||||
input busy, // direct signal from data sd data input (data[0])
|
||||
//input card_detect,
|
||||
input [31:0] argument,
|
||||
input [`CMD_REG_SIZE-1:0] command,
|
||||
input [`CMD_TIMEOUT_W-1:0] timeout,
|
||||
output [`INT_CMD_SIZE-1:0] int_status,
|
||||
output reg [31:0] response_0,
|
||||
output reg [31:0] response_1,
|
||||
output reg [31:0] response_2,
|
||||
output reg [31:0] response_3
|
||||
);
|
||||
|
||||
reg expect_response;
|
||||
reg long_response;
|
||||
reg [`INT_CMD_SIZE-1:0] int_status_reg;
|
||||
reg [`CMD_TIMEOUT_W-1:0] watchdog;
|
||||
reg watchdog_enable;
|
||||
|
||||
reg [2:0] state;
|
||||
parameter IDLE = 3'b001;
|
||||
parameter EXECUTE = 3'b010;
|
||||
parameter BUSY_CHECK = 3'b100;
|
||||
|
||||
assign setting[1:0] = {long_response, expect_response};
|
||||
assign int_status = state == IDLE ? int_status_reg : 5'h0;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
response_0 <= 0;
|
||||
response_1 <= 0;
|
||||
response_2 <= 0;
|
||||
response_3 <= 0;
|
||||
int_status_reg <= 0;
|
||||
expect_response <= 0;
|
||||
long_response <= 0;
|
||||
cmd <= 0;
|
||||
start_xfr <= 0;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= 0;
|
||||
go_idle <= 0;
|
||||
state <= IDLE;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
IDLE: begin
|
||||
go_idle <= 0;
|
||||
if (command[`CMD_RESPONSE_CHECK] == 2'b10 || command[`CMD_RESPONSE_CHECK] == 2'b11) begin
|
||||
expect_response <= 1;
|
||||
long_response <= 1;
|
||||
end else if (command[`CMD_RESPONSE_CHECK] == 2'b01) begin
|
||||
expect_response <= 1;
|
||||
long_response <= 0;
|
||||
end else begin
|
||||
expect_response <= 0;
|
||||
long_response <= 0;
|
||||
end
|
||||
cmd[39:38] <= 2'b01;
|
||||
cmd[37:32] <= command[`CMD_INDEX];
|
||||
cmd[31:0] <= argument;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= timeout != 0;
|
||||
if (start) begin
|
||||
start_xfr <= 1;
|
||||
int_status_reg <= 0;
|
||||
state <= EXECUTE;
|
||||
end
|
||||
end
|
||||
EXECUTE: begin
|
||||
start_xfr <= 0;
|
||||
if (watchdog_enable && watchdog >= timeout) begin
|
||||
int_status_reg[`INT_CMD_CTE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
go_idle <= 1;
|
||||
state <= IDLE;
|
||||
end else if (finish) begin
|
||||
if (command[`CMD_CRC_CHECK] && crc_error) begin
|
||||
int_status_reg[`INT_CMD_CCRCE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
end
|
||||
if (command[`CMD_IDX_CHECK] && !index_ok) begin
|
||||
int_status_reg[`INT_CMD_CIE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
end
|
||||
int_status_reg[`INT_CMD_CC] <= 1;
|
||||
if (expect_response) begin
|
||||
response_0 <= response[119:88];
|
||||
response_1 <= response[87:56];
|
||||
response_2 <= response[55:24];
|
||||
response_3 <= {response[23:0], 8'h00};
|
||||
end
|
||||
if (command[`CMD_BUSY_CHECK]) state <= BUSY_CHECK;
|
||||
else state <= IDLE;
|
||||
end else if (watchdog_enable) begin
|
||||
watchdog <= watchdog + 1;
|
||||
end
|
||||
end
|
||||
BUSY_CHECK: begin
|
||||
if (!busy) state <= IDLE;
|
||||
end
|
||||
endcase
|
||||
if (int_status_rst)
|
||||
int_status_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
263
pipelined/src/uncore/newsdc/sd_cmd_serial_host.v
Normal file
263
pipelined/src/uncore/newsdc/sd_cmd_serial_host.v
Normal file
|
@ -0,0 +1,263 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sd_cmd_serial_host (
|
||||
//---------------Input ports---------------
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input clock_data_in,
|
||||
input reset,
|
||||
input [1:0] setting,
|
||||
input [39:0] cmd,
|
||||
input start,
|
||||
input cmd_i,
|
||||
//---------------Output ports---------------
|
||||
output reg [119:0] response,
|
||||
output reg finish,
|
||||
output reg crc_ok,
|
||||
output reg index_ok,
|
||||
output reg cmd_oe,
|
||||
output reg cmd_o
|
||||
);
|
||||
|
||||
//-------------Internal Constant-------------
|
||||
parameter INIT_DELAY = 4;
|
||||
parameter BITS_TO_SEND = 48;
|
||||
parameter CMD_SIZE = 40;
|
||||
parameter RESP_SIZE = 128;
|
||||
|
||||
//---------------Internal variable-----------
|
||||
reg cmd_dat_reg;
|
||||
integer resp_len;
|
||||
reg with_response;
|
||||
reg [CMD_SIZE-1:0] cmd_buff;
|
||||
reg [RESP_SIZE-1:0] resp_buff;
|
||||
integer resp_idx;
|
||||
//CRC
|
||||
reg crc_rst;
|
||||
reg [6:0]crc_in;
|
||||
wire [6:0] crc_val;
|
||||
reg crc_enable;
|
||||
reg crc_bit;
|
||||
reg crc_match;
|
||||
//-Internal Counterns
|
||||
integer counter;
|
||||
//-State Machine
|
||||
parameter
|
||||
STATE_SIZE = 8,
|
||||
INIT = 8'b00000001,
|
||||
IDLE = 8'b00000010,
|
||||
SETUP_CRC = 8'b00000100,
|
||||
WRITE = 8'b00001000,
|
||||
READ_WAIT = 8'b00010000,
|
||||
READ = 8'b00100000,
|
||||
FINISH_WR = 8'b01000000,
|
||||
FINISH_WO = 8'b10000000;
|
||||
reg [STATE_SIZE-1:0] state;
|
||||
|
||||
//Misc
|
||||
`define cmd_idx (CMD_SIZE-1-counter)
|
||||
|
||||
//sd cmd input pad register
|
||||
always @(posedge clock) begin
|
||||
if (clock_data_in) cmd_dat_reg <= cmd_i;
|
||||
end
|
||||
|
||||
//------------------------------------------
|
||||
sd_crc_7 CRC_7(
|
||||
crc_bit,
|
||||
crc_enable & clock_posedge,
|
||||
clock,
|
||||
crc_rst,
|
||||
crc_val);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
resp_len <= 0;
|
||||
with_response <= 0;
|
||||
cmd_buff <= 0;
|
||||
crc_enable <= 0;
|
||||
resp_idx <= 0;
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= 1;
|
||||
resp_buff <= 0;
|
||||
finish <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_bit <= 0;
|
||||
crc_in <= 0;
|
||||
response <= 0;
|
||||
index_ok <= 0;
|
||||
crc_ok <= 0;
|
||||
crc_match <= 0;
|
||||
counter <= 0;
|
||||
state <= INIT;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
INIT: begin
|
||||
counter <= counter+1;
|
||||
// Pull cmd line up
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= 1;
|
||||
if (counter >= INIT_DELAY) state <= IDLE;
|
||||
end
|
||||
IDLE: begin
|
||||
cmd_oe <= 0;
|
||||
counter <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_enable <= 0;
|
||||
response <= 0;
|
||||
resp_idx <= 0;
|
||||
crc_ok <= 0;
|
||||
index_ok <= 0;
|
||||
finish <= 0;
|
||||
if (start) begin
|
||||
resp_len <= setting[1] ? 127 : 39;
|
||||
with_response <= setting[0];
|
||||
cmd_buff <= cmd;
|
||||
state <= SETUP_CRC;
|
||||
end
|
||||
end
|
||||
SETUP_CRC: begin
|
||||
crc_rst <= 0;
|
||||
crc_enable <= 1;
|
||||
crc_bit <= cmd_buff[`cmd_idx];
|
||||
state <= WRITE;
|
||||
end
|
||||
WRITE: begin
|
||||
if (counter < BITS_TO_SEND-8) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= cmd_buff[`cmd_idx];
|
||||
if (counter < BITS_TO_SEND-9) begin //1 step ahead
|
||||
crc_bit <= cmd_buff[`cmd_idx-1];
|
||||
end else begin
|
||||
crc_enable <= 0;
|
||||
end
|
||||
end else if (counter < BITS_TO_SEND-1) begin
|
||||
cmd_oe <= 1;
|
||||
crc_enable <= 0;
|
||||
cmd_o <= crc_val[BITS_TO_SEND-counter-2];
|
||||
end else if (counter == BITS_TO_SEND-1) begin
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= 1'b1;
|
||||
end else begin
|
||||
cmd_oe <= 0;
|
||||
cmd_o <= 1'b1;
|
||||
end
|
||||
counter <= counter + 1;
|
||||
if (counter >= BITS_TO_SEND && with_response) state <= READ_WAIT;
|
||||
else if (counter >= BITS_TO_SEND) state <= FINISH_WO;
|
||||
end
|
||||
READ_WAIT: begin
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 1;
|
||||
cmd_oe <= 0;
|
||||
resp_buff[RESP_SIZE-1] <= cmd_dat_reg;
|
||||
if (!cmd_dat_reg) state <= READ;
|
||||
end
|
||||
FINISH_WO: begin
|
||||
finish <= 1;
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
cmd_oe <= 0;
|
||||
state <= IDLE;
|
||||
end
|
||||
READ: begin
|
||||
crc_rst <= 0;
|
||||
crc_enable <= (resp_len != RESP_SIZE-1 || counter > 7);
|
||||
cmd_oe <= 0;
|
||||
if (counter <= resp_len) begin
|
||||
if (counter < 8) //1+1+6 (S,T,Index)
|
||||
resp_buff[RESP_SIZE-1-counter] <= cmd_dat_reg;
|
||||
else begin
|
||||
resp_idx <= resp_idx + 1;
|
||||
resp_buff[RESP_SIZE-9-resp_idx] <= cmd_dat_reg;
|
||||
end
|
||||
crc_bit <= cmd_dat_reg;
|
||||
end else if (counter-resp_len <= 7) begin
|
||||
crc_in[(resp_len+7)-(counter)] <= cmd_dat_reg;
|
||||
crc_enable <= 0;
|
||||
end else begin
|
||||
crc_enable <= 0;
|
||||
crc_match <= crc_in == crc_val;
|
||||
end
|
||||
counter <= counter + 1;
|
||||
if (counter >= resp_len+8) state <= FINISH_WR;
|
||||
end
|
||||
FINISH_WR: begin
|
||||
index_ok <= cmd_buff[37:32] == resp_buff[125:120];
|
||||
crc_ok <= crc_match;
|
||||
finish <= 1;
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
cmd_oe <= 0;
|
||||
response <= resp_buff[119:0];
|
||||
state <= IDLE;
|
||||
end
|
||||
default:
|
||||
state <= INIT;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module sd_crc_7(
|
||||
input BITVAL, // Next input bit
|
||||
input ENABLE, // Enable calculation
|
||||
input BITSTRB, // Current bit valid (Clock)
|
||||
input CLEAR, // Init CRC value
|
||||
output reg [6:0] CRC // Current output CRC value
|
||||
);
|
||||
|
||||
wire inv;
|
||||
assign inv = BITVAL ^ CRC[6];
|
||||
|
||||
always @(posedge BITSTRB or posedge CLEAR) begin
|
||||
if (CLEAR) begin
|
||||
CRC <= 0;
|
||||
end else if (ENABLE == 1) begin
|
||||
CRC[6] <= CRC[5];
|
||||
CRC[5] <= CRC[4];
|
||||
CRC[4] <= CRC[3];
|
||||
CRC[3] <= CRC[2] ^ inv;
|
||||
CRC[2] <= CRC[1];
|
||||
CRC[1] <= CRC[0];
|
||||
CRC[0] <= inv;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
150
pipelined/src/uncore/newsdc/sd_data_master.v
Normal file
150
pipelined/src/uncore/newsdc/sd_data_master.v
Normal file
|
@ -0,0 +1,150 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
`include "sd_defines.h"
|
||||
|
||||
module sd_data_master (
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input reset,
|
||||
input start_tx,
|
||||
input start_rx,
|
||||
input [`DATA_TIMEOUT_W-1:0] timeout,
|
||||
// Output to SD-Host Reg
|
||||
output reg d_write,
|
||||
output reg d_read,
|
||||
// To fifo filler
|
||||
(* mark_debug = "true" *) output reg en_tx_fifo,
|
||||
output reg en_rx_fifo,
|
||||
(* mark_debug = "true" *) input fifo_empty,
|
||||
input fifo_ready,
|
||||
input fifo_full,
|
||||
(* mark_debug = "true" *) input bus_cycle,
|
||||
// SD-DATA_Host
|
||||
input xfr_complete,
|
||||
input crc_error,
|
||||
input bus_error,
|
||||
// status output
|
||||
output reg [`INT_DATA_SIZE-1:0] int_status,
|
||||
input int_status_rst
|
||||
);
|
||||
|
||||
reg [3:0] state;
|
||||
localparam IDLE = 4'b0001;
|
||||
localparam START_TX_FIFO = 4'b0010;
|
||||
localparam START_RX_FIFO = 4'b0100;
|
||||
localparam DATA_TRANSFER = 4'b1000;
|
||||
|
||||
(* mark_debug = "true" *) reg [`DATA_TIMEOUT_W-1:0] watchdog;
|
||||
reg watchdog_enable;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
en_tx_fifo <= 0;
|
||||
en_rx_fifo <= 0;
|
||||
d_write <= 0;
|
||||
d_read <= 0;
|
||||
int_status <= 0;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= 0;
|
||||
state <= IDLE;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
IDLE: begin
|
||||
en_tx_fifo <= 0;
|
||||
en_rx_fifo <= 0;
|
||||
d_write <= 0;
|
||||
d_read <= 0;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= timeout != 0;
|
||||
if (start_tx) state <= START_TX_FIFO;
|
||||
else if (start_rx) state <= START_RX_FIFO;
|
||||
end
|
||||
START_RX_FIFO: begin
|
||||
en_rx_fifo <= 1;
|
||||
en_tx_fifo <= 0;
|
||||
d_read <= 1;
|
||||
if (!xfr_complete) state <= DATA_TRANSFER;
|
||||
end
|
||||
START_TX_FIFO: begin
|
||||
en_rx_fifo <= 0;
|
||||
en_tx_fifo <= 1;
|
||||
if (fifo_ready) begin
|
||||
d_write <= 1;
|
||||
if (!xfr_complete) state <= DATA_TRANSFER;
|
||||
end
|
||||
end
|
||||
DATA_TRANSFER: begin
|
||||
d_read <= 0;
|
||||
d_write <= 0;
|
||||
if (en_tx_fifo && fifo_empty) begin
|
||||
int_status[`INT_DATA_CFE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
state <= IDLE;
|
||||
// stop sd_data_serial_host
|
||||
d_write <= 1;
|
||||
d_read <= 1;
|
||||
end else if (en_rx_fifo && fifo_full) begin
|
||||
int_status[`INT_DATA_CFE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
state <= IDLE;
|
||||
// stop sd_data_serial_host
|
||||
d_write <= 1;
|
||||
d_read <= 1;
|
||||
end else if (watchdog_enable && watchdog >= timeout) begin
|
||||
int_status[`INT_DATA_CTE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
state <= IDLE;
|
||||
// stop sd_data_serial_host
|
||||
d_write <= 1;
|
||||
d_read <= 1;
|
||||
end else if (xfr_complete && !bus_cycle && (en_tx_fifo || fifo_empty)) begin
|
||||
state <= IDLE;
|
||||
if (crc_error) begin
|
||||
int_status[`INT_DATA_CCRCE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
end
|
||||
if (bus_error) begin
|
||||
int_status[`INT_DATA_CBE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
end
|
||||
int_status[`INT_DATA_CC] <= 1;
|
||||
end else if (watchdog_enable) begin
|
||||
watchdog <= watchdog + 1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (int_status_rst)
|
||||
int_status <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
311
pipelined/src/uncore/newsdc/sd_data_serial_host.v
Normal file
311
pipelined/src/uncore/newsdc/sd_data_serial_host.v
Normal file
|
@ -0,0 +1,311 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
`include "sd_defines.h"
|
||||
|
||||
module sd_data_serial_host(
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input clock_data_in,
|
||||
input reset,
|
||||
// Tx Fifo
|
||||
input [31:0] data_in,
|
||||
output reg rd,
|
||||
// Rx Fifo
|
||||
output reg [31:0] data_out,
|
||||
output reg we,
|
||||
// tristate data
|
||||
output reg dat_oe,
|
||||
output reg[3:0] dat_o,
|
||||
input [3:0] dat_i,
|
||||
// Controll signals
|
||||
input [`BLKSIZE_W-1:0] blksize,
|
||||
input bus_4bit,
|
||||
input [`BLKCNT_W-1:0] blkcnt,
|
||||
input [1:0] start,
|
||||
input [1:0] byte_alignment,
|
||||
output sd_data_busy,
|
||||
output busy,
|
||||
output reg crc_ok
|
||||
);
|
||||
|
||||
reg [3:0] DAT_dat_reg;
|
||||
reg bus_4bit_reg;
|
||||
reg crc_en;
|
||||
reg crc_rst;
|
||||
wire [15:0] crc_out [3:0];
|
||||
reg [`BLKSIZE_W+4-1:0] data_cycles;
|
||||
reg [`BLKSIZE_W+4-1:0] transf_cnt;
|
||||
reg [3:0] drt_bit;
|
||||
reg [3:0] drt_reg;
|
||||
(* mark_debug = "true" *) reg [`BLKCNT_W-1:0] blkcnt_reg;
|
||||
reg [1:0] byte_alignment_reg;
|
||||
reg [3:0] crc_bit;
|
||||
reg [3:0] last_din;
|
||||
reg [4:0] data_index;
|
||||
|
||||
reg [6:0] state;
|
||||
parameter IDLE = 7'b0000001;
|
||||
parameter WRITE_DAT = 7'b0000010;
|
||||
parameter WRITE_WAIT = 7'b0000100;
|
||||
parameter WRITE_DRT = 7'b0001000;
|
||||
parameter WRITE_BUSY = 7'b0010000;
|
||||
parameter READ_WAIT = 7'b0100000;
|
||||
parameter READ_DAT = 7'b1000000;
|
||||
|
||||
// sd data input pad register
|
||||
always @(posedge clock) begin
|
||||
if (clock_data_in) DAT_dat_reg <= dat_i;
|
||||
end
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<4; i=i+1) begin: CRC_16_gen
|
||||
sd_crc_16 CRC_16_i (last_din[i], crc_en & clock_posedge, clock, crc_rst, crc_out[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign busy = (state != IDLE);
|
||||
assign sd_data_busy = !DAT_dat_reg[0];
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
state <= IDLE;
|
||||
dat_oe <= 0;
|
||||
crc_en <= 0;
|
||||
crc_rst <= 1;
|
||||
transf_cnt <= 0;
|
||||
rd <= 0;
|
||||
last_din <= 0;
|
||||
crc_bit <= 0;
|
||||
dat_o <= 4'b1111;
|
||||
drt_bit <= 0;
|
||||
drt_reg <= 0;
|
||||
we <= 0;
|
||||
data_out <= 0;
|
||||
crc_ok <= 0;
|
||||
data_index <= 0;
|
||||
blkcnt_reg <= 0;
|
||||
byte_alignment_reg <= 0;
|
||||
data_cycles <= 0;
|
||||
bus_4bit_reg <= 0;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
IDLE: begin
|
||||
dat_oe <= 0;
|
||||
dat_o <= 4'b1111;
|
||||
transf_cnt <= 0;
|
||||
crc_en <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_bit <= 15;
|
||||
we <= 0;
|
||||
rd <= 0;
|
||||
data_index <= 0;
|
||||
blkcnt_reg <= blkcnt;
|
||||
byte_alignment_reg <= byte_alignment;
|
||||
data_cycles <= (bus_4bit ? {3'b000, blksize, 1'b0} + 2 : {1'b0, blksize, 3'b000} + 8);
|
||||
bus_4bit_reg <= bus_4bit;
|
||||
if (start == 2'b01) state <= WRITE_DAT;
|
||||
else if (start == 2'b10) state <= READ_WAIT;
|
||||
end
|
||||
WRITE_DAT: begin
|
||||
rd <= 0;
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
if (transf_cnt == 0) begin
|
||||
crc_ok <= 0;
|
||||
crc_bit <= 15;
|
||||
end else if (transf_cnt == 1) begin
|
||||
crc_rst <= 0;
|
||||
crc_en <= 1;
|
||||
if (bus_4bit_reg) begin
|
||||
last_din <= {
|
||||
data_in[31-(byte_alignment_reg << 3)],
|
||||
data_in[30-(byte_alignment_reg << 3)],
|
||||
data_in[29-(byte_alignment_reg << 3)],
|
||||
data_in[28-(byte_alignment_reg << 3)]
|
||||
};
|
||||
end else begin
|
||||
last_din <= {3'h7, data_in[31-(byte_alignment_reg << 3)]};
|
||||
end
|
||||
dat_oe <= 1;
|
||||
dat_o <= bus_4bit_reg ? 4'h0 : 4'he;
|
||||
data_index <= bus_4bit_reg ? {2'b00, byte_alignment_reg, 1'b1} : {byte_alignment_reg, 3'b001};
|
||||
end else if (transf_cnt <= data_cycles+1) begin
|
||||
if (bus_4bit_reg) begin
|
||||
last_din <= {
|
||||
data_in[31-(data_index[2:0]<<2)],
|
||||
data_in[30-(data_index[2:0]<<2)],
|
||||
data_in[29-(data_index[2:0]<<2)],
|
||||
data_in[28-(data_index[2:0]<<2)]
|
||||
};
|
||||
if (data_index[2:0] == 3'h6 && transf_cnt <= data_cycles-1) rd <= 1;
|
||||
end else begin
|
||||
last_din <= {3'h7, data_in[31-data_index]};
|
||||
if (data_index == 30) rd <= 1;
|
||||
end
|
||||
data_index <= data_index + 5'h1;
|
||||
dat_o <= last_din;
|
||||
if (transf_cnt == data_cycles+1) crc_en <= 0;
|
||||
end else if (transf_cnt <= data_cycles+17) begin
|
||||
crc_en <= 0;
|
||||
dat_o[0] <= crc_out[0][crc_bit];
|
||||
if (bus_4bit_reg)
|
||||
dat_o[3:1] <= {crc_out[3][crc_bit], crc_out[2][crc_bit], crc_out[1][crc_bit]};
|
||||
crc_bit <= crc_bit - 1;
|
||||
end else if (transf_cnt == data_cycles+18) begin
|
||||
dat_o <= 4'hf;
|
||||
end else if (transf_cnt == data_cycles+19) begin
|
||||
dat_oe <= 0;
|
||||
end else begin
|
||||
state <= WRITE_WAIT;
|
||||
end
|
||||
end
|
||||
WRITE_WAIT: begin
|
||||
drt_bit <= 0;
|
||||
if (!DAT_dat_reg[0]) state <= WRITE_DRT;
|
||||
end
|
||||
WRITE_DRT: begin
|
||||
// See 7.3.3.1 Data Response Token
|
||||
if (drt_bit <= 3) begin
|
||||
drt_reg[drt_bit] <= DAT_dat_reg[0];
|
||||
end else if (drt_bit == 15) begin
|
||||
crc_ok <= drt_reg[3:0] == 4'b1010;
|
||||
state <= WRITE_BUSY;
|
||||
end
|
||||
drt_bit <= drt_bit + 1;
|
||||
end
|
||||
WRITE_BUSY: begin
|
||||
if (DAT_dat_reg[0]) begin
|
||||
if (blkcnt_reg != 0 && crc_ok) begin
|
||||
transf_cnt <= 0;
|
||||
blkcnt_reg <= blkcnt_reg - 1;
|
||||
byte_alignment_reg <= byte_alignment_reg + blksize[1:0] + 2'b1;
|
||||
crc_rst <= 1;
|
||||
state <= WRITE_DAT;
|
||||
end else begin
|
||||
state <= IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
READ_WAIT: begin
|
||||
dat_oe <= 0;
|
||||
crc_bit <= 15;
|
||||
last_din <= 0;
|
||||
transf_cnt <= 0;
|
||||
data_index <= bus_4bit_reg ? (byte_alignment_reg << 1) : (byte_alignment_reg << 3);
|
||||
if (!DAT_dat_reg[0]) begin
|
||||
crc_rst <= 0;
|
||||
crc_en <= 1;
|
||||
state <= READ_DAT;
|
||||
end
|
||||
end
|
||||
READ_DAT: begin
|
||||
last_din <= DAT_dat_reg;
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
if (transf_cnt < data_cycles) begin
|
||||
if (bus_4bit_reg) begin
|
||||
we <= (data_index[2:0] == 7 || (transf_cnt == data_cycles-1 && !blkcnt_reg));
|
||||
data_out[31-(data_index[2:0]<<2)] <= DAT_dat_reg[3];
|
||||
data_out[30-(data_index[2:0]<<2)] <= DAT_dat_reg[2];
|
||||
data_out[29-(data_index[2:0]<<2)] <= DAT_dat_reg[1];
|
||||
data_out[28-(data_index[2:0]<<2)] <= DAT_dat_reg[0];
|
||||
end else begin
|
||||
we <= (data_index == 31 || (transf_cnt == data_cycles-1 && !blkcnt_reg));
|
||||
data_out[31-data_index] <= DAT_dat_reg[0];
|
||||
end
|
||||
data_index <= data_index + 5'h1;
|
||||
crc_ok <= 1;
|
||||
end else if (transf_cnt == data_cycles) begin
|
||||
crc_en <= 0;
|
||||
we <= 0;
|
||||
end else if (transf_cnt <= data_cycles+16) begin
|
||||
if (crc_out[0][crc_bit] != last_din[0]) crc_ok <= 0;
|
||||
if (bus_4bit_reg) begin
|
||||
if (crc_out[1][crc_bit] != last_din[1]) crc_ok <= 0;
|
||||
if (crc_out[2][crc_bit] != last_din[2]) crc_ok <= 0;
|
||||
if (crc_out[3][crc_bit] != last_din[3]) crc_ok <= 0;
|
||||
end
|
||||
if (crc_bit == 0) begin
|
||||
byte_alignment_reg <= byte_alignment_reg + blksize[1:0] + 2'b1;
|
||||
crc_rst <= 1;
|
||||
end else begin
|
||||
crc_bit <= crc_bit - 1;
|
||||
end
|
||||
end else if (blkcnt_reg != 0 && crc_ok) begin
|
||||
blkcnt_reg <= blkcnt_reg - 1;
|
||||
state <= READ_WAIT;
|
||||
end else begin
|
||||
state <= IDLE;
|
||||
end
|
||||
end
|
||||
default:
|
||||
state <= IDLE;
|
||||
endcase
|
||||
if (start == 2'b11) state <= IDLE; // Abort
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module sd_crc_16(
|
||||
input BITVAL, // Next input bit
|
||||
input ENABLE, // Enable calculation
|
||||
input BITSTRB, // Current bit valid (Clock)
|
||||
input CLEAR, // Init CRC value
|
||||
output reg [15:0] CRC // Current output CRC value
|
||||
);
|
||||
|
||||
assign inv = BITVAL ^ CRC[15];
|
||||
|
||||
always @(posedge BITSTRB) begin
|
||||
if (CLEAR) begin
|
||||
CRC <= 0;
|
||||
end else if (ENABLE == 1) begin
|
||||
CRC[15] <= CRC[14];
|
||||
CRC[14] <= CRC[13];
|
||||
CRC[13] <= CRC[12];
|
||||
CRC[12] <= CRC[11] ^ inv;
|
||||
CRC[11] <= CRC[10];
|
||||
CRC[10] <= CRC[9];
|
||||
CRC[9] <= CRC[8];
|
||||
CRC[8] <= CRC[7];
|
||||
CRC[7] <= CRC[6];
|
||||
CRC[6] <= CRC[5];
|
||||
CRC[5] <= CRC[4] ^ inv;
|
||||
CRC[4] <= CRC[3];
|
||||
CRC[3] <= CRC[2];
|
||||
CRC[2] <= CRC[1];
|
||||
CRC[1] <= CRC[0];
|
||||
CRC[0] <= inv;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
91
pipelined/src/uncore/newsdc/sd_defines.h
Normal file
91
pipelined/src/uncore/newsdc/sd_defines.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// global defines
|
||||
`define BLKSIZE_W 12
|
||||
`define BLKCNT_W 16
|
||||
`define CMD_TIMEOUT_W 25
|
||||
`define DATA_TIMEOUT_W 28
|
||||
|
||||
// cmd module interrupts
|
||||
`define INT_CMD_SIZE 5
|
||||
`define INT_CMD_CC 0
|
||||
`define INT_CMD_EI 1
|
||||
`define INT_CMD_CTE 2
|
||||
`define INT_CMD_CCRCE 3
|
||||
`define INT_CMD_CIE 4
|
||||
|
||||
// data module interrupts
|
||||
`define INT_DATA_SIZE 6
|
||||
`define INT_DATA_CC 0
|
||||
`define INT_DATA_EI 1
|
||||
`define INT_DATA_CTE 2 // Timeout
|
||||
`define INT_DATA_CCRCE 3 // CRC error
|
||||
`define INT_DATA_CFE 4 // FIFO error
|
||||
`define INT_DATA_CBE 5 // Bus error
|
||||
|
||||
// command register defines
|
||||
`define CMD_REG_SIZE 14
|
||||
`define CMD_RESPONSE_CHECK 1:0
|
||||
`define CMD_BUSY_CHECK 2
|
||||
`define CMD_CRC_CHECK 3
|
||||
`define CMD_IDX_CHECK 4
|
||||
`define CMD_WITH_DATA 6:5
|
||||
`define CMD_INDEX 13:8
|
||||
|
||||
// register addreses
|
||||
`define argument 8'h00
|
||||
`define command 8'h04
|
||||
`define resp0 8'h08
|
||||
`define resp1 8'h0c
|
||||
`define resp2 8'h10
|
||||
`define resp3 8'h14
|
||||
`define data_timeout 8'h18
|
||||
`define controller 8'h1c
|
||||
`define cmd_timeout 8'h20
|
||||
`define clock_d 8'h24
|
||||
`define reset 8'h28
|
||||
`define voltage 8'h2c
|
||||
`define capa 8'h30
|
||||
`define cmd_isr 8'h34
|
||||
`define cmd_iser 8'h38
|
||||
`define data_isr 8'h3c
|
||||
`define data_iser 8'h40
|
||||
`define blksize 8'h44
|
||||
`define blkcnt 8'h48
|
||||
`define card_detect 8'h4c
|
||||
`define dst_src_addr 8'h60
|
||||
`define dst_src_addr_high 8'h64
|
||||
|
||||
// register contents
|
||||
`define RESET_BLOCK_SIZE 12'd511
|
||||
`define RESET_CLOCK_DIV 124
|
|
@ -5,7 +5,7 @@ export PATH=$PATH:/usr/local/bin/
|
|||
verilator=`which verilator`
|
||||
|
||||
basepath=$(dirname $0)/..
|
||||
for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do
|
||||
for config in fpga rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do
|
||||
#for config in rv64gc; do
|
||||
echo "$config linting..."
|
||||
if !($verilator --no-timing --lint-only "$@" --top-module wallywrapper "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then
|
||||
|
|
|
@ -127,6 +127,9 @@ typedef struct packed {
|
|||
logic SDC_SUPPORTED;
|
||||
logic [63:0] SDC_BASE;
|
||||
logic [63:0] SDC_RANGE;
|
||||
logic SDC2_SUPPORTED;
|
||||
logic [63:0] SDC2_BASE;
|
||||
logic [63:0] SDC2_RANGE;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -141,6 +144,7 @@ typedef struct packed {
|
|||
logic PLIC_NUM_SRC_LT_32;
|
||||
int PLIC_GPIO_ID;
|
||||
int PLIC_UART_ID;
|
||||
int PLIC_SDC_ID;
|
||||
|
||||
logic BPRED_SUPPORTED;
|
||||
logic [31:0] BPRED_TYPE;
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
|
||||
// WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words
|
||||
|
||||
module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=44) (
|
||||
module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=44,
|
||||
parameter PRELOAD_ENABLED=0) (
|
||||
input logic clk,
|
||||
input logic ce,
|
||||
input logic [$clog2(DEPTH)-1:0] addr,
|
||||
|
@ -83,6 +84,12 @@ module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=
|
|||
end else begin: ram
|
||||
integer i;
|
||||
|
||||
if (PRELOAD_ENABLED) begin
|
||||
initial begin
|
||||
RAM[0] = 64'h00600100d2e3ca40;
|
||||
end
|
||||
end
|
||||
|
||||
// Read
|
||||
logic [$clog2(DEPTH)-1:0] addrd;
|
||||
flopen #($clog2(DEPTH)) adrreg(clk, ce, addr, addrd);
|
||||
|
|
|
@ -48,52 +48,152 @@ module rom1p1r #(parameter ADDR_WIDTH = 8,
|
|||
end
|
||||
|
||||
// for FPGA, initialize with zero-stage bootloader
|
||||
if(PRELOAD_ENABLED)
|
||||
initial begin
|
||||
ROM[0] = 64'h95c1819300002197;
|
||||
ROM[1] = 64'h4281420141014081;
|
||||
ROM[2] = 64'h4481440143814301;
|
||||
ROM[3] = 64'h4681460145814501;
|
||||
ROM[4] = 64'h4881480147814701;
|
||||
ROM[5] = 64'h4a814a0149814901;
|
||||
ROM[6] = 64'h4c814c014b814b01;
|
||||
ROM[7] = 64'h4e814e014d814d01;
|
||||
ROM[8] = 64'h0110011b4f814f01;
|
||||
ROM[9] = 64'h059b45011161016e;
|
||||
ROM[10] = 64'h0004063705fe0010;
|
||||
ROM[11] = 64'h05a000ef8006061b;
|
||||
ROM[12] = 64'h0ff003930000100f;
|
||||
ROM[13] = 64'h4e952e3110060e37;
|
||||
ROM[14] = 64'hc602829b0053f2b7;
|
||||
ROM[15] = 64'h2023fe02dfe312fd;
|
||||
ROM[16] = 64'h829b0053f2b7007e;
|
||||
ROM[17] = 64'hfe02dfe312fdc602;
|
||||
ROM[18] = 64'h4de31efd000e2023;
|
||||
ROM[19] = 64'h059bf1402573fdd0;
|
||||
ROM[20] = 64'h0000061705e20870;
|
||||
ROM[21] = 64'h0010029b01260613;
|
||||
ROM[22] = 64'h71790002806702fe;
|
||||
ROM[23] = 64'h89aa84b2e44eec26;
|
||||
ROM[24] = 64'h892ee84af4064511;
|
||||
ROM[25] = 64'h072000ef084000ef;
|
||||
ROM[26] = 64'hf02204a602905263;
|
||||
ROM[27] = 64'h41390933844e94ce;
|
||||
ROM[28] = 64'h04138522008905b3;
|
||||
ROM[29] = 64'h19e3016000ef2004;
|
||||
ROM[30] = 64'h64e270a27402fe94;
|
||||
ROM[31] = 64'h8082614569a26942;
|
||||
ROM[32] = 64'h431c104707136749;
|
||||
ROM[33] = 64'hb82366c9dff58b85;
|
||||
ROM[34] = 64'h4691674967c910a6;
|
||||
ROM[35] = 64'h1047071310d7a423;
|
||||
ROM[36] = 64'h6749fff58b89431c;
|
||||
ROM[37] = 64'h1187071320058693;
|
||||
ROM[38] = 64'hfef5bc2305a1631c;
|
||||
ROM[39] = 64'h67498082fed59ce3;
|
||||
ROM[40] = 64'h8b85431c10470713;
|
||||
ROM[41] = 64'h4015551b8082dff5;
|
||||
ROM[42] = 64'ha0239f0967c94705;
|
||||
ROM[43] = 64'h00000000808210e7;
|
||||
end
|
||||
if(PRELOAD_ENABLED) begin
|
||||
initial begin
|
||||
ROM[0]=64'h8001819300002197;
|
||||
ROM[1]=64'h4281420141014081;
|
||||
ROM[2]=64'h4481440143814301;
|
||||
ROM[3]=64'h4681460145814501;
|
||||
ROM[4]=64'h4881480147814701;
|
||||
ROM[5]=64'h4a814a0149814901;
|
||||
ROM[6]=64'h4c814c014b814b01;
|
||||
ROM[7]=64'h4e814e014d814d01;
|
||||
ROM[8]=64'h0110011b4f814f01;
|
||||
ROM[9]=64'h059b45011161016e;
|
||||
ROM[10]=64'h0004063705fe0010;
|
||||
ROM[11]=64'h1f6000ef8006061b;
|
||||
ROM[12]=64'h0ff003930000100f;
|
||||
ROM[13]=64'h4e952e3110060e37;
|
||||
ROM[14]=64'hc602829b0053f2b7;
|
||||
ROM[15]=64'h2023fe02dfe312fd;
|
||||
ROM[16]=64'h829b0053f2b7007e;
|
||||
ROM[17]=64'hfe02dfe312fdc602;
|
||||
ROM[18]=64'h4de31efd000e2023;
|
||||
ROM[19]=64'h059bf1402573fdd0;
|
||||
ROM[20]=64'h0000061705e20870;
|
||||
ROM[21]=64'h0010029b01260613;
|
||||
ROM[22]=64'h68110002806702fe;
|
||||
ROM[23]=64'h0085179bf0080813;
|
||||
ROM[24]=64'h038008130107f7b3;
|
||||
ROM[25]=64'h480508a86c632781;
|
||||
ROM[26]=64'h1533357902a87963;
|
||||
ROM[27]=64'h38030000181700a8;
|
||||
ROM[28]=64'h1c6301057833f268;
|
||||
ROM[29]=64'h081a403018370808;
|
||||
ROM[30]=64'h0105783342280813;
|
||||
ROM[31]=64'h1815751308081063;
|
||||
ROM[32]=64'h00367513c295e14d;
|
||||
ROM[33]=64'h654ded510207e793;
|
||||
ROM[34]=64'hc1701ff00613f130;
|
||||
ROM[35]=64'h0637c530fff6861b;
|
||||
ROM[36]=64'h664dcd10167d0200;
|
||||
ROM[37]=64'h17fd001007b7c25c;
|
||||
ROM[38]=64'h859b5a5cc20cd21c;
|
||||
ROM[39]=64'h02062a23dfed0007;
|
||||
ROM[40]=64'h4785fffd561c664d;
|
||||
ROM[41]=64'h4501461c06f59063;
|
||||
ROM[42]=64'h4a1cc35c465cc31c;
|
||||
ROM[43]=64'he29dc75c4a5cc71c;
|
||||
ROM[44]=64'h0c63086008138082;
|
||||
ROM[45]=64'h1ae30a9008130105;
|
||||
ROM[46]=64'hb7710017e793f905;
|
||||
ROM[47]=64'he793b75901d7e793;
|
||||
ROM[48]=64'h5f5c674db7410197;
|
||||
ROM[49]=64'h66cd02072e23dffd;
|
||||
ROM[50]=64'hfff78513ff7d5698;
|
||||
ROM[51]=64'h40a0053300a03533;
|
||||
ROM[52]=64'hbfb100a7e7938082;
|
||||
ROM[53]=64'he0a2715d8082557d;
|
||||
ROM[54]=64'he486f052f44ef84a;
|
||||
ROM[55]=64'hfa13e85aec56fc26;
|
||||
ROM[56]=64'h843289ae892a0086;
|
||||
ROM[57]=64'h00959993000a1463;
|
||||
ROM[58]=64'h864ac4396b054a85;
|
||||
ROM[59]=64'h0009859b4549870a;
|
||||
ROM[60]=64'h0004049b05540363;
|
||||
ROM[61]=64'h86a66485008b7363;
|
||||
ROM[62]=64'h870a87aaec7ff0ef;
|
||||
ROM[63]=64'h4531458146014681;
|
||||
ROM[64]=64'hf0ef0207c9639c05;
|
||||
ROM[65]=64'h17820094979beb1f;
|
||||
ROM[66]=64'h873e020541639381;
|
||||
ROM[67]=64'h993e99ba020a1963;
|
||||
ROM[68]=64'h870aa8094501f85d;
|
||||
ROM[69]=64'he8bff0ef45454685;
|
||||
ROM[70]=64'h60a64505fe0559e3;
|
||||
ROM[71]=64'h79a2794274e26406;
|
||||
ROM[72]=64'h61616b426ae27a02;
|
||||
ROM[73]=64'h9301020497138082;
|
||||
ROM[74]=64'hf40647057179b7f1;
|
||||
ROM[75]=64'hd79867cdec26f022;
|
||||
ROM[76]=64'hdff58b85571c674d;
|
||||
ROM[77]=64'h2423d35c03600793;
|
||||
ROM[78]=64'hfffd571c674d0207;
|
||||
ROM[79]=64'h0007a737b00026f3;
|
||||
ROM[80]=64'hb00027f311f70713;
|
||||
ROM[81]=64'h674dfef77de38f95;
|
||||
ROM[82]=64'h4f5ccf9d8b895b1c;
|
||||
ROM[83]=64'h26f3cf5c0027e793;
|
||||
ROM[84]=64'h071305f5e737b000;
|
||||
ROM[85]=64'h8f95b00027f30ff7;
|
||||
ROM[86]=64'h4f5c674dfef77de3;
|
||||
ROM[87]=64'hb00026f3cf5c9bf5;
|
||||
ROM[88]=64'h67f7071300989737;
|
||||
ROM[89]=64'h7de38f95b00027f3;
|
||||
ROM[90]=64'h458146014681fef7;
|
||||
ROM[91]=64'hddbff0ef4501870a;
|
||||
ROM[92]=64'h059346014681870a;
|
||||
ROM[93]=64'hdcbff0ef45211aa0;
|
||||
ROM[94]=64'h1aa007134782e939;
|
||||
ROM[95]=64'h816393d117d24411;
|
||||
ROM[96]=64'h85220ff0041302e7;
|
||||
ROM[97]=64'h614564e270a27402;
|
||||
ROM[98]=64'h46e3da5ff0efa0cd;
|
||||
ROM[99]=64'h0207c7634782fe05;
|
||||
ROM[100]=64'h458146014681870a;
|
||||
ROM[101]=64'hd8bff0ef03700513;
|
||||
ROM[102]=64'h46014681870a87aa;
|
||||
ROM[103]=64'h0a900513403005b7;
|
||||
ROM[104]=64'h4409bf7dfc07d9e3;
|
||||
ROM[105]=64'hc3998b8583f9bfe1;
|
||||
ROM[106]=64'h4681870a00846413;
|
||||
ROM[107]=64'hf0ef450945814601;
|
||||
ROM[108]=64'h870afa0540e3d59f;
|
||||
ROM[109]=64'h123405b746014681;
|
||||
ROM[110]=64'h46e3d45ff0ef450d;
|
||||
ROM[111]=64'h870a77c14482f805;
|
||||
ROM[112]=64'h85a6460146818cfd;
|
||||
ROM[113]=64'h4ae3d2dff0ef451d;
|
||||
ROM[114]=64'hd3d8470567cdf605;
|
||||
ROM[115]=64'h000f4737b00026f3;
|
||||
ROM[116]=64'hb00027f323f70713;
|
||||
ROM[117]=64'h67cdfef77de38f95;
|
||||
ROM[118]=64'h4681870a0007ae23;
|
||||
ROM[119]=64'h0370051385a64601;
|
||||
ROM[120]=64'hf2054fe3cf7ff0ef;
|
||||
ROM[121]=64'h458146014681870a;
|
||||
ROM[122]=64'hce3ff0ef08600513;
|
||||
ROM[123]=64'h4681870af20545e3;
|
||||
ROM[124]=64'h4541200005934601;
|
||||
ROM[125]=64'hf0055de3ccfff0ef;
|
||||
ROM[126]=64'h3023bf010113bf09;
|
||||
ROM[127]=64'h4605842a86aa4081;
|
||||
ROM[128]=64'h40113423850a4585;
|
||||
ROM[129]=64'h86a265a6da5ff0ef;
|
||||
ROM[130]=64'hd99ff0ef04084605;
|
||||
ROM[131]=64'h2201358322813603;
|
||||
ROM[132]=64'h86a2260508700513;
|
||||
ROM[133]=64'hd81ff0ef05629e0d;
|
||||
ROM[134]=64'h2a0135832a813603;
|
||||
ROM[135]=64'h9e0d86a226054505;
|
||||
ROM[136]=64'h3603d6bff0ef057e;
|
||||
ROM[137]=64'h0513320135833281;
|
||||
ROM[138]=64'h9e0d86a226054010;
|
||||
ROM[139]=64'h3083d53ff0ef0556;
|
||||
ROM[140]=64'h4501400134034081;
|
||||
ROM[141]=64'h0000808241010113;
|
||||
|
||||
end // if (PRELOAD_ENABLED)
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -32,7 +32,7 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.PA_BITS-1:0] PhysicalAddress,
|
||||
input logic AccessRW, AccessRX, AccessRWX,
|
||||
input logic [1:0] Size,
|
||||
output logic [10:0] SelRegions
|
||||
output logic [11:0] SelRegions
|
||||
);
|
||||
|
||||
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
|
||||
|
@ -47,9 +47,9 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
|
|||
adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[3]);
|
||||
adrdec #(P.PA_BITS) plicdec(PhysicalAddress, P.PLIC_BASE[P.PA_BITS-1:0], P.PLIC_RANGE[P.PA_BITS-1:0], P.PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]);
|
||||
adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[1]);
|
||||
adrdec #(P.PA_BITS) newsdc(PhysicalAddress, P.SDC2_BASE[P.PA_BITS-1:0], P.SDC2_RANGE[P.PA_BITS-1:0], P.SDC2_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[11]);
|
||||
|
||||
assign SelRegions[0] = ~|(SelRegions[10:1]); // none of the regions are selected
|
||||
|
||||
assign SelRegions[0] = ~|(SelRegions[11:1]); // none of the regions are selected
|
||||
endmodule
|
||||
|
||||
// verilator lint_on UNOPTFLAT
|
||||
|
|
|
@ -43,7 +43,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
logic PMAAccessFault;
|
||||
logic AccessRW, AccessRWX, AccessRX;
|
||||
logic [10:0] SelRegions;
|
||||
logic [11:0] SelRegions;
|
||||
logic AtomicAllowed;
|
||||
|
||||
// Determine what type of access is being made
|
||||
|
|
|
@ -49,7 +49,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
|||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic UARTIntr,GPIOIntr,
|
||||
input logic UARTIntr,GPIOIntr,SDCIntr,
|
||||
output logic MExtInt, SExtInt
|
||||
);
|
||||
|
||||
|
@ -166,6 +166,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
|||
requests = {P.PLIC_NUM_SRC{1'b0}};
|
||||
if(P.PLIC_GPIO_ID != 0) requests[P.PLIC_GPIO_ID] = GPIOIntr;
|
||||
if(P.PLIC_UART_ID != 0) requests[P.PLIC_UART_ID] = UARTIntr;
|
||||
if(P.PLIC_SDC_ID !=0) requests[P.PLIC_SDC_ID] = SDCIntr;
|
||||
end
|
||||
|
||||
// pending interrupt request
|
||||
|
|
|
@ -71,7 +71,7 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
|
|||
mux2 #(P.PA_BITS) adrmux(HADDR, HADDRD, memwriteD | ~HREADY, RamAddr);
|
||||
|
||||
// single-ported RAM
|
||||
ram1p1rwbe #(.P(P), .DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1),
|
||||
ram1p1rwbe #(.P(P), .DEPTH(RANGE/8), .WIDTH(P.XLEN), .PRELOAD_ENABLED(P.FPGA)) memory(.clk(HCLK), .ce(1'b1),
|
||||
.addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam));
|
||||
|
||||
// use this to add arbitrary latency to ram. Helps test AHB controller correctness
|
||||
|
|
|
@ -45,6 +45,7 @@ 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
|
||||
|
@ -53,16 +54,12 @@ 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
|
||||
output logic SDCCmdOut, // SD Card command output
|
||||
output logic SDCCmdOE, // SD Card command output enable
|
||||
input logic SDCCmdIn, // SD Card command input
|
||||
input logic [3:0] SDCDatIn, // SD Card data input
|
||||
output logic SDCCLK // SD Card clock
|
||||
input logic SDCIntr
|
||||
);
|
||||
|
||||
logic [P.XLEN-1:0] HREADRam, HREADSDC;
|
||||
|
||||
logic [10:0] HSELRegions;
|
||||
logic [11:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
|
@ -82,13 +79,16 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
logic [P.XLEN-1:0] HREADBRIDGE;
|
||||
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
||||
|
||||
(* mark_debug = "true" *) logic HSELEXTSDCD;
|
||||
|
||||
|
||||
// Determine which region of physical memory (if any) is being accessed
|
||||
// Use a trimmed down portion of the PMA checker - only the address decoders
|
||||
// Set access types to all 1 as don't cares because the MMU has already done access checking
|
||||
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
||||
|
||||
// unswizzle HSEL signals
|
||||
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[10:1];
|
||||
assign {HSELEXTSDC, HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[11:1];
|
||||
|
||||
// AHB -> APB bridge
|
||||
ahbapbbridge #(P, 4) ahbapbbridge (
|
||||
|
@ -121,7 +121,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
|
||||
if (P.PLIC_SUPPORTED == 1) begin : plic
|
||||
plic_apb #(P) plic(.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .MExtInt, .SExtInt);
|
||||
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .SDCIntr, .MExtInt, .SExtInt);
|
||||
end else begin : plic
|
||||
assign MExtInt = 0;
|
||||
assign SExtInt = 0;
|
||||
|
@ -145,35 +145,22 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
end else begin : uart
|
||||
assign UARTSout = 0; assign UARTIntr = 0;
|
||||
end
|
||||
if (P.SDC_SUPPORTED == 1) begin : sdc
|
||||
SDC #(P) SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS,
|
||||
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
|
||||
// sdc interface
|
||||
.SDCCmdOut, .SDCCmdIn, .SDCCmdOE, .SDCDatIn, .SDCCLK,
|
||||
// interrupt to PLIC
|
||||
.SDCIntM
|
||||
);
|
||||
end else begin : sdc
|
||||
assign SDCCLK = 0;
|
||||
assign SDCCmdOut = 0;
|
||||
assign SDCCmdOE = 0;
|
||||
end
|
||||
|
||||
// AHB Read Multiplexer
|
||||
assign HRDATA = ({P.XLEN{HSELRamD}} & HREADRam) |
|
||||
({P.XLEN{HSELEXTD}} & HRDATAEXT) |
|
||||
({P.XLEN{HSELEXTD | HSELEXTSDCD}} & HRDATAEXT) |
|
||||
({P.XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
||||
({P.XLEN{HSELBootRomD}} & HREADBootRom) |
|
||||
({P.XLEN{HSELSDCD}} & HREADSDC);
|
||||
|
||||
assign HRESP = HSELRamD & HRESPRam |
|
||||
HSELEXTD & HRESPEXT |
|
||||
(HSELEXTD | HSELEXTSDCD) & HRESPEXT |
|
||||
HSELBRIDGE & HRESPBRIDGE |
|
||||
HSELBootRomD & HRESPBootRom |
|
||||
HSELSDC & HRESPSDC;
|
||||
|
||||
assign HREADY = HSELRamD & HREADYRam |
|
||||
HSELEXTD & HREADYEXT |
|
||||
(HSELEXTD | HSELEXTSDCD) & HREADYEXT |
|
||||
HSELBRIDGED & HREADYBRIDGE |
|
||||
HSELBootRomD & HREADYBootRom |
|
||||
HSELSDCD & HREADYSDC |
|
||||
|
@ -184,8 +171,6 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
// takes more than 1 cycle to repsond it needs to hold on to the old select until the
|
||||
// device is ready. Hense this register must be selectively enabled by HREADY.
|
||||
// However on reset None must be seleted.
|
||||
flopenl #(11) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions, 11'b1,
|
||||
{HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD,
|
||||
HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD});
|
||||
flopenl #(12) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions[11:0], 12'b1, {HSELEXTSDCD, HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD});
|
||||
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
|
||||
endmodule
|
||||
|
|
|
@ -34,6 +34,7 @@ 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,
|
||||
// outputs to external memory, shared with uncore memory
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [P.PA_BITS-1:0] HADDR,
|
||||
|
@ -53,11 +54,7 @@ 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 SDCCmdIn, // SDC Command input
|
||||
output logic SDCCmdOut, // SDC Command output
|
||||
output logic SDCCmdOE, // SDC Command output enable
|
||||
input logic [3:0] SDCDatIn, // SDC data input
|
||||
output logic SDCCLK // SDC clock
|
||||
input logic SDCIntr
|
||||
);
|
||||
|
||||
// Uncore signals
|
||||
|
@ -81,10 +78,9 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.BUS_SUPPORTED) begin : uncore
|
||||
uncore #(P) uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT,
|
||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT, .HSELEXTSDC,
|
||||
.MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin,
|
||||
.UARTSout, .MTIME_CLINT,
|
||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK);
|
||||
.UARTSout, .MTIME_CLINT, .SDCIntr);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -239,6 +239,7 @@ module testbench;
|
|||
logic HCLK, HRESETn;
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
logic HSELEXTSDC;
|
||||
logic [P.PA_BITS-1:0] HADDR;
|
||||
logic [P.AHBW-1:0] HWDATA;
|
||||
logic [P.XLEN/8-1:0] HWSTRB;
|
||||
|
@ -253,24 +254,21 @@ module testbench;
|
|||
logic UARTSin, UARTSout;
|
||||
|
||||
// FPGA-specific Stuff
|
||||
logic SDCCLK;
|
||||
logic SDCCmdIn;
|
||||
logic SDCCmdOut;
|
||||
logic SDCCmdOE;
|
||||
logic [3:0] SDCDatIn;
|
||||
logic SDCIntr;
|
||||
|
||||
// Hardwire UART, GPIO pins
|
||||
assign GPIOIN = 0;
|
||||
assign UARTSin = 1;
|
||||
assign SDCIntr = 0;
|
||||
|
||||
// Wally
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset, .reset_ext,
|
||||
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
|
||||
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HSELEXTSDC, .HRESPEXT, .HCLK,
|
||||
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK,
|
||||
.TIMECLK('0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout,
|
||||
.SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn);
|
||||
.SDCIntr);
|
||||
|
||||
// W-stage hardware not needed by Wally itself
|
||||
parameter nop = 'h13;
|
||||
|
|
|
@ -50,6 +50,7 @@ module testbench;
|
|||
// DUT signals
|
||||
logic [P.AHBW-1:0] HRDATAEXT;
|
||||
logic HREADYEXT, HRESPEXT;
|
||||
logic HSELEXTSDC;
|
||||
logic [P.PA_BITS-1:0] HADDR;
|
||||
logic [P.AHBW-1:0] HWDATA;
|
||||
logic [P.XLEN/8-1:0] HWSTRB;
|
||||
|
@ -64,13 +65,7 @@ module testbench;
|
|||
logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
|
||||
logic SDCCLK;
|
||||
logic SDCCmdIn;
|
||||
logic SDCCmdOut;
|
||||
logic SDCCmdOE;
|
||||
logic [3:0] SDCDatIn;
|
||||
tri1 [3:0] SDCDat;
|
||||
tri1 SDCCmd;
|
||||
logic SDCIntr;
|
||||
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
|
@ -383,6 +378,8 @@ module testbench;
|
|||
end
|
||||
|
||||
if(P.FPGA) begin : sdcard
|
||||
// *** fix later
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
sdModel sdcard
|
||||
(.sdClk(SDCCLK),
|
||||
.cmd(SDCCmd),
|
||||
|
@ -391,15 +388,16 @@ module testbench;
|
|||
assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz;
|
||||
assign SDCCmdIn = SDCCmd;
|
||||
assign SDCDatIn = SDCDat;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
assign SDCIntr = '0;
|
||||
end else begin
|
||||
assign SDCCmd = '0;
|
||||
assign SDCDat = '0;
|
||||
assign SDCIntr = '0;
|
||||
end
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||
.UARTSin, .UARTSout, .SDCIntr);
|
||||
|
||||
// generate clock to sequence tests
|
||||
always begin
|
||||
|
|
|
@ -51,17 +51,12 @@ module wallywrapper;
|
|||
|
||||
logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
|
||||
logic SDCCLK;
|
||||
logic SDCCmdIn;
|
||||
logic SDCCmdOut;
|
||||
logic SDCCmdOE;
|
||||
logic [3:0] SDCDatIn;
|
||||
tri1 [3:0] SDCDat;
|
||||
tri1 SDCCmd;
|
||||
logic SDCIntr;
|
||||
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
logic HSELEXTSDC;
|
||||
|
||||
|
||||
// instantiate device to be tested
|
||||
assign GPIOIN = 0;
|
||||
|
@ -71,12 +66,10 @@ module wallywrapper;
|
|||
assign HRESPEXT = 0;
|
||||
assign HRDATAEXT = 0;
|
||||
|
||||
assign SDCCmd = '0;
|
||||
assign SDCDat = '0;
|
||||
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||
.UARTSin, .UARTSout, .SDCIntr);
|
||||
|
||||
endmodule
|
||||
|
|
114
tests/custom/boot/Makefile
Normal file
114
tests/custom/boot/Makefile
Normal file
|
@ -0,0 +1,114 @@
|
|||
CEXT := c
|
||||
CPPEXT := cpp
|
||||
AEXT := s
|
||||
SEXT := S
|
||||
SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\)
|
||||
OBJEXT := o
|
||||
DEPEXT := d
|
||||
SRCDIR := .
|
||||
BUILDDIR := OBJ
|
||||
|
||||
SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort)
|
||||
OBJECTS := $(SOURCES:.$(CEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(OBJECTS:.$(AEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(OBJECTS:.$(SEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT))
|
||||
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS))
|
||||
|
||||
TARGETDIR := bin
|
||||
TARGET := $(TARGETDIR)/boot
|
||||
ROOT := ..
|
||||
LIBRARY_DIRS :=
|
||||
LIBRARY_FILES :=
|
||||
|
||||
MARCH :=-march=rv64imfdc
|
||||
MABI :=-mabi=lp64d
|
||||
LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles
|
||||
LINKER :=$(ROOT)/linker1000.x
|
||||
|
||||
|
||||
AFLAGS =$(MARCH) $(MABI) -W
|
||||
# Override directive allows us to prepend other options on the command line
|
||||
# e.g. $ make CFLAGS=-g
|
||||
override CFLAGS +=$(MARCH) $(MABI) -mcmodel=medany -O2
|
||||
AS=riscv64-unknown-elf-as
|
||||
CC=riscv64-unknown-elf-gcc
|
||||
AR=riscv64-unknown-elf-ar
|
||||
|
||||
|
||||
#Default Make
|
||||
all: directories $(TARGET).memfile
|
||||
|
||||
#Remake
|
||||
remake: clean all
|
||||
|
||||
#Make the Directories
|
||||
directories:
|
||||
@mkdir -p $(TARGETDIR)
|
||||
@mkdir -p $(BUILDDIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump
|
||||
|
||||
|
||||
#Needed for building additional library projects
|
||||
ifdef LIBRARY_DIRS
|
||||
LIBS+=${LIBRARY_DIRS:%=-L%} ${LIBRARY_FILES:%=-l%}
|
||||
INC+=${LIBRARY_DIRS:%=-I%}
|
||||
|
||||
${LIBRARY_DIRS}:
|
||||
make -C $@ -j 1
|
||||
|
||||
.PHONY: $(LIBRARY_DIRS) $(TARGET)
|
||||
endif
|
||||
|
||||
|
||||
#Pull in dependency info for *existing* .o files
|
||||
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
|
||||
|
||||
#Link
|
||||
$(TARGET): $(OBJECTS) $(LIBRARY_DIRS)
|
||||
$(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER}
|
||||
|
||||
|
||||
#Compile
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
|
||||
# gcc won't output dependencies for assembly files for some reason
|
||||
# most asm files don't have dependencies so the echo will work for now.
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
|
||||
# C++
|
||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
|
||||
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||
|
||||
# convert to hex
|
||||
$(TARGET).memfile: $(TARGET)
|
||||
@echo 'Making object dump file.'
|
||||
riscv64-unknown-elf-objdump -DS $< > $<.objdump
|
||||
@echo 'Making memory file'
|
||||
riscv64-unknown-elf-elf2hex --bit-width 64 --input $^ --output $@
|
||||
extractFunctionRadix.sh $<.objdump
|
||||
mkdir -p ../../imperas-riscv-tests/work/rv64BP/
|
||||
cp -f $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/
|
101
tests/custom/boot/bios.s
Normal file
101
tests/custom/boot/bios.s
Normal file
|
@ -0,0 +1,101 @@
|
|||
PERIOD = 11000000
|
||||
#PERIOD = 20
|
||||
|
||||
.section .init
|
||||
.global _start
|
||||
.type _start, @function
|
||||
|
||||
|
||||
_start:
|
||||
# Initialize global pointer
|
||||
.option push
|
||||
.option norelax
|
||||
1:auipc gp, %pcrel_hi(__global_pointer$)
|
||||
addi gp, gp, %pcrel_lo(1b)
|
||||
.option pop
|
||||
|
||||
li x1, 0
|
||||
li x2, 0
|
||||
li x4, 0
|
||||
li x5, 0
|
||||
li x6, 0
|
||||
li x7, 0
|
||||
li x8, 0
|
||||
li x9, 0
|
||||
li x10, 0
|
||||
li x11, 0
|
||||
li x12, 0
|
||||
li x13, 0
|
||||
li x14, 0
|
||||
li x15, 0
|
||||
li x16, 0
|
||||
li x17, 0
|
||||
li x18, 0
|
||||
li x19, 0
|
||||
li x20, 0
|
||||
li x21, 0
|
||||
li x22, 0
|
||||
li x23, 0
|
||||
li x24, 0
|
||||
li x25, 0
|
||||
li x26, 0
|
||||
li x27, 0
|
||||
li x28, 0
|
||||
li x29, 0
|
||||
li x30, 0
|
||||
li x31, 0
|
||||
|
||||
|
||||
# set the stack pointer to the top of memory - 8 bytes (pointer size)
|
||||
li sp, 0x87FFFFF8
|
||||
|
||||
li a0, 0x00000000
|
||||
li a1, 0x80000000
|
||||
#li a2, 128*1024*1024/512 # copy 128MB
|
||||
li a2, 127*1024*1024/512 # copy 127MB upper 1MB contains the return address (ra)
|
||||
#li a2, 800 # copy 400KB
|
||||
jal ra, copyFlash
|
||||
|
||||
fence.i
|
||||
# now toggle led so we know the copy completed.
|
||||
|
||||
# write to gpio
|
||||
li t2, 0xFF
|
||||
la t3, 0x1006000C
|
||||
li t4, 5
|
||||
|
||||
loop:
|
||||
|
||||
# delay
|
||||
li t0, PERIOD/2
|
||||
delay1:
|
||||
addi t0, t0, -1
|
||||
bge t0, x0, delay1
|
||||
sw t2, 0x0(t3)
|
||||
|
||||
li t0, PERIOD/2
|
||||
delay2:
|
||||
addi t0, t0, -1
|
||||
bge t0, x0, delay2
|
||||
sw x0, 0x0(t3)
|
||||
|
||||
addi t4, t4, -1
|
||||
bgt t4, x0, loop
|
||||
|
||||
|
||||
# now that the card is copied and the led toggled we
|
||||
# jump to the copied contents of the sd card.
|
||||
|
||||
jumpToLinux:
|
||||
csrrs a0, 0xF14, x0 # copy hart ID to a0
|
||||
li a1, 0x87000000 # end of memory? not 100% sure on this but it's 112MB
|
||||
la a2, end_of_bios
|
||||
li t0, 0x80000000 # start of code
|
||||
|
||||
jalr x0, t0, 0
|
||||
|
||||
end_of_bios:
|
||||
|
||||
|
||||
|
||||
|
422
tests/custom/boot/boot.c
Normal file
422
tests/custom/boot/boot.c
Normal file
|
@ -0,0 +1,422 @@
|
|||
#include <stddef.h>
|
||||
#include "boot.h"
|
||||
#include "gpt.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 */
|
||||
|
||||
#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) */
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int sdc_data_finish(void) {
|
||||
int status;
|
||||
struct sdc_regs * regs = (struct sdc_regs *)SDC;
|
||||
|
||||
while ((status = regs->dat_int_status) == 0) {}
|
||||
regs->dat_int_status = 0;
|
||||
while (regs->software_reset != 0) {}
|
||||
|
||||
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 (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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
26
tests/custom/boot/boot.h
Normal file
26
tests/custom/boot/boot.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef WALLYBOOT
|
||||
#define WALLYBOOT 10000
|
||||
|
||||
#include <stdint.h>
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
typedef WORD WCHAR;
|
||||
|
||||
typedef QWORD LBA_t;
|
||||
|
||||
// Define memory locations of boot images =====================
|
||||
// These locations are copied from the generic configuration
|
||||
// of OpenSBI. These addresses can be found in:
|
||||
// buildroot/output/build/opensbi-0.9/platform/generic/config.mk
|
||||
#define FDT_ADDRESS 0x87000000 // FW_JUMP_FDT_ADDR
|
||||
#define OPENSBI_ADDRESS 0x80000000 // FW_TEXT_START
|
||||
#define KERNEL_ADDRESS 0x80200000 // FW_JUMP_ADDR
|
||||
|
||||
// Export disk_read
|
||||
int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type);
|
||||
|
||||
#endif // WALLYBOOT
|
||||
|
46
tests/custom/boot/gpt.c
Normal file
46
tests/custom/boot/gpt.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "gpt.h"
|
||||
#include "boot.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.
|
||||
|
||||
// size_t block_size = 512/8;
|
||||
// long int lba1_buf[block_size];
|
||||
|
||||
BYTE lba1_buf[512];
|
||||
|
||||
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 ) {
|
||||
|
||||
}*/
|
||||
|
||||
gpt_pth_t *lba1 = (gpt_pth_t *)lba1_buf;
|
||||
|
||||
BYTE lba2_buf[512];
|
||||
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1, card_type);
|
||||
|
||||
// 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);
|
||||
|
||||
return 0;
|
||||
}
|
40
tests/custom/boot/gpt.h
Normal file
40
tests/custom/boot/gpt.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "boot.h"
|
||||
|
||||
// LBA 0: Protective MBR
|
||||
// ignored here
|
||||
|
||||
// Partition Table Header (LBA 1)
|
||||
typedef struct gpt_pth
|
||||
{
|
||||
uint64_t signature;
|
||||
uint32_t revision;
|
||||
uint32_t header_size; //! little endian, usually 0x5c = 92
|
||||
uint32_t crc_header;
|
||||
uint32_t reserved; //! must be 0
|
||||
uint64_t current_lba;
|
||||
uint64_t backup_lba;
|
||||
uint64_t first_usable_lba;
|
||||
uint64_t last_usable_lba;
|
||||
uint8_t disk_guid[16];
|
||||
uint64_t partition_entries_lba;
|
||||
uint32_t nr_partition_entries;
|
||||
uint32_t size_partition_entry; //! usually 0x80 = 128
|
||||
uint32_t crc_partition_entry;
|
||||
} gpt_pth_t;
|
||||
|
||||
// Partition Entries (LBA 2-33)
|
||||
typedef struct partition_entries
|
||||
{
|
||||
uint8_t partition_type_guid[16];
|
||||
uint8_t partition_guid[16];
|
||||
uint64_t first_lba;
|
||||
uint64_t last_lba; //! inclusive
|
||||
uint64_t attributes;
|
||||
uint8_t name[72]; //! utf16 encoded
|
||||
} partition_entries_t;
|
||||
|
||||
// Find boot partition and load it to the destination
|
||||
int gpt_load_partitions(BYTE card_type);
|
|
@ -72,6 +72,7 @@ SECTIONS
|
|||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
. = 0x0000000000002000;
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.sdata2 :
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue