diff --git a/.gitmodules b/.gitmodules index 4ac190d..ef62624 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,18 +1,15 @@ [submodule "hw/super6502_fpga/src/sub/rtl-common"] path = hw/super6502_fpga/src/sub/rtl-common url = ../rtl-common.git -[submodule "hw/super6502_fpga/src/sub/axi_crossbar"] - path = hw/super6502_fpga/src/sub/axi_crossbar - url = ../axi_crossbar.git [submodule "sw/toolchain/cc65"] path = sw/toolchain/cc65 url = ../cc65.git [submodule "hw/super6502_fpga/src/sim/sub/verilog-6502"] path = hw/super6502_fpga/src/sim/sub/verilog-6502 url = ../verilog-6502.git -[submodule "hw/super6502_fpga/src/sub/sd_controller"] - path = hw/super6502_fpga/src/sub/sd_controller - url = ../sd_controller.git -[submodule "hw/super6502_fpga/src/sim/sub/verilog-sd-emulator"] - path = hw/super6502_fpga/src/sim/sub/verilog-sd-emulator - url = ../verilog-sd-emulator.git +[submodule "hw/super6502_fpga/src/sub/wb2axip"] + path = hw/super6502_fpga/src/sub/wb2axip + url = ../wb2axip.git +[submodule "hw/super6502_fpga/src/sub/sdspi"] + path = hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi + url = ../sdspi.git diff --git a/Makefile b/Makefile index 96f4ed7..aab0a02 100644 --- a/Makefile +++ b/Makefile @@ -22,12 +22,14 @@ waves: sim gtkwave hw/super6502_fpga/src/sim/sim_top.vcd # SW -$(CC65): +$(CC65): $(MAKE) -C sw/toolchain/cc65 -j $(shell nproc) $(INIT_HEX): $(CC65) script/generate_rom_image.py $(HEX) python script/generate_rom_image.py -i $(HEX) -o $@ +# This should get dependencies of rom, not be phony +.PHONY: $(HEX) $(HEX): $(MAKE) -C sw/$(ROM_TARGET) $(notdir $@) diff --git a/hw/super6502_fpga/sources.list b/hw/super6502_fpga/sources.list index 0ef340c..4e453fe 100644 --- a/hw/super6502_fpga/sources.list +++ b/hw/super6502_fpga/sources.list @@ -1,9 +1,4 @@ src/rtl/super_6502_fpga.sv -src/sub/axi_crossbar/src/rtl/axi_crossbar.sv -src/sub/axi_crossbar/src/rtl/axi_master.sv -src/sub/axi_crossbar/src/rtl/axi_slave.sv -src/sub/axi_crossbar/src/rtl/rr_scheduler.sv -src/sub/axi_crossbar/src/rtl/slave_addr_decoder.sv src/sub/cpu_wrapper/cpu_wrapper.sv src/sub/rtl-common/src/rtl/async_fifo.sv src/sub/rtl-common/src/rtl/axi4_lite_ram.sv @@ -13,12 +8,28 @@ src/sub/rtl-common/src/rtl/shallow_async_fifo.sv src/sub/rtl-common/src/rtl/sync_fifo.sv src/sub/rtl-common/src/rtl/axi4_lite_to_apb4.sv ip/sdram_controller/sdram_controller.v -src/sub/sd_controller/src/regs/sd_controller_regs_pkg.sv -src/sub/sd_controller/src/regs/sd_controller_regs.sv -src/sub/sd_controller/src/crc7.sv -src/sub/sd_controller/src/crc16.sv -src/sub/sd_controller/src/sd_command.sv -src/sub/sd_controller/src/sd_control.sv -src/sub/sd_controller/src/sd_controller_top.sv -src/sub/sd_controller/src/sd_data.sv -src/sub/sd_controller/src/sd_dma.sv \ No newline at end of file +src/sub/wb2axip/rtl/axilxbar.v +src/sub/wb2axip/rtl/addrdecode.v +src/sub/wb2axip/rtl/skidbuffer.v +src/sub/sd_controller_wrapper/sd_controller_wrapper.sv +src/sub/sd_controller_wrapper/shadow_regs.sv +src/sub/sd_controller_wrapper/sdspi/rtl/sdckgen.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma_rxgears.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdrxframe.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdtxframe.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma_s2mm_axi.v +src/sub/sd_controller_wrapper/sdspi/rtl/afifo.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma_txgears.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdskid.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdfrontend.v +src/sub/sd_controller_wrapper/sdspi/rtl/spicmd.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdaxil.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s.v +src/sub/sd_controller_wrapper/sdspi/rtl/sddma_mm2s_axi.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdio_top.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdwb.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdio.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdcmd.v +src/sub/sd_controller_wrapper/sdspi/rtl/sdfifo.v \ No newline at end of file diff --git a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv index a1fae5c..2e877f0 100644 --- a/hw/super6502_fpga/src/rtl/super_6502_fpga.sv +++ b/hw/super6502_fpga/src/rtl/super_6502_fpga.sv @@ -4,7 +4,7 @@ module super6502_fpga( input logic i_tACclk, // t_ac clock (200MHz) input clk_cpu, - input button_reset, + input button_resetn, input pll_cpu_locked, output logic pll_cpu_reset, @@ -43,8 +43,8 @@ module super6502_fpga( input i_sd_dat, output o_sd_dat, output o_sd_dat_oe, - output o_sd_clk, - output o_sd_cs + output o_sd_clk + // input i_sd_cd ); @@ -60,23 +60,26 @@ assign o_clk_phi2 = clk_cpu; assign o_cpu0_data_oe = {8{i_cpu0_rwb}}; -logic vio0_reset; -assign vio0_reset = '1; +logic vio0_resetn; +assign vio0_resetn = '1; -logic master_reset; +logic master_resetn; logic sdram_ready; logic [3:0] w_sdr_state; -logic pre_reset; +logic pre_resetn; -assign pre_reset = button_reset & vio0_reset; +assign pre_resetn = button_resetn & vio0_resetn; assign sdram_ready = |w_sdr_state; -assign master_reset = pre_reset & sdram_ready; +assign master_resetn = pre_resetn & sdram_ready; assign o_sd_cs = '1; +logic i_sd_cd; +assign i_sd_cd = '1; + logic cpu0_AWVALID; logic cpu0_AWREADY; @@ -153,23 +156,23 @@ logic [1:0] sdram_RRESP; // These are for the control/status registers -logic sd_controller_csr_AWVALID; -logic sd_controller_csr_AWREADY; -logic [ADDR_WIDTH-1:0] sd_controller_csr_AWADDR; -logic sd_controller_csr_WVALID; -logic sd_controller_csr_WREADY; -logic [DATA_WIDTH-1:0] sd_controller_csr_WDATA; -logic [DATA_WIDTH/8-1:0] sd_controller_csr_WSTRB; -logic sd_controller_csr_BVALID; -logic sd_controller_csr_BREADY; -logic [1:0] sd_controller_csr_BRESP; -logic sd_controller_csr_ARVALID; -logic sd_controller_csr_ARREADY; -logic [ADDR_WIDTH-1:0] sd_controller_csr_ARADDR; -logic sd_controller_csr_RVALID; -logic sd_controller_csr_RREADY; -logic [DATA_WIDTH-1:0] sd_controller_csr_RDATA; -logic [1:0] sd_controller_csr_RRESP; +logic sd_controller_ctrl_AWVALID; +logic sd_controller_ctrl_AWREADY; +logic [ADDR_WIDTH-1:0] sd_controller_ctrl_AWADDR; +logic sd_controller_ctrl_WVALID; +logic sd_controller_ctrl_WREADY; +logic [DATA_WIDTH-1:0] sd_controller_ctrl_WDATA; +logic [DATA_WIDTH/8-1:0] sd_controller_ctrl_WSTRB; +logic sd_controller_ctrl_BVALID; +logic sd_controller_ctrl_BREADY; +logic [1:0] sd_controller_ctrl_BRESP; +logic sd_controller_ctrl_ARVALID; +logic sd_controller_ctrl_ARREADY; +logic [ADDR_WIDTH-1:0] sd_controller_ctrl_ARADDR; +logic sd_controller_ctrl_RVALID; +logic sd_controller_ctrl_RREADY; +logic [DATA_WIDTH-1:0] sd_controller_ctrl_RDATA; +logic [1:0] sd_controller_ctrl_RRESP; // these are for the dma master. logic sd_controller_dma_AWVALID; @@ -194,7 +197,7 @@ logic [1:0] sd_controller_dma_RRESP; cpu_wrapper u_cpu_wrapper_0( .i_clk_cpu (clk_cpu), .i_clk_100 (i_sysclk), - .i_rst (~master_reset), + .i_rst (~master_resetn), .o_cpu_rst (o_cpu0_reset), .o_cpu_rdy (o_cpu0_rdy), @@ -235,56 +238,63 @@ cpu_wrapper u_cpu_wrapper_0( ); -axi_crossbar #( - .N_INITIATORS(2), - .N_TARGETS(4) +axilxbar #( + .NM(2), + .NS(4), + .SLAVE_ADDR({ + {32'h000001ff, 32'h00000000}, + {32'h0000ffff, 32'h0000f000}, + {32'h0000dfff, 32'h00000200}, + {32'h0000e03f, 32'h0000e000} + }) ) u_crossbar ( - .clk(i_sysclk), - .rst(~master_reset), + .S_AXI_ACLK (i_sysclk), + .S_AXI_ARESETN (master_resetn), - .ini_araddr ({cpu0_ARADDR, sd_controller_dma_ARADDR }), - .ini_arvalid ({cpu0_ARVALID, sd_controller_dma_ARVALID }), - .ini_arready ({cpu0_ARREADY, sd_controller_dma_ARREADY }), - .ini_rdata ({cpu0_RDATA, sd_controller_dma_RDATA }), - .ini_rresp ({cpu0_RRESP, sd_controller_dma_RRESP }), - .ini_rvalid ({cpu0_RVALID, sd_controller_dma_RVALID }), - .ini_rready ({cpu0_RREADY, sd_controller_dma_RREADY }), - .ini_awaddr ({cpu0_AWADDR, sd_controller_dma_AWADDR }), - .ini_awready ({cpu0_AWREADY, sd_controller_dma_AWREADY }), - .ini_awvalid ({cpu0_AWVALID, sd_controller_dma_AWVALID }), - .ini_wvalid ({cpu0_WVALID, sd_controller_dma_WVALID }), - .ini_wready ({cpu0_WREADY, sd_controller_dma_WREADY }), - .ini_wdata ({cpu0_WDATA, sd_controller_dma_WDATA }), - .ini_wstrb ({cpu0_WSTRB, sd_controller_dma_WSTRB }), - .ini_bresp ({cpu0_BRESP, sd_controller_dma_BRESP }), - .ini_bvalid ({cpu0_BVALID, sd_controller_dma_BVALID }), - .ini_bready ({cpu0_BREADY, sd_controller_dma_BREADY }), - .tgt_araddr ({ram_araddr, rom_araddr, sdram_ARADDR, sd_controller_csr_ARADDR }), - .tgt_arvalid ({ram_arvalid, rom_arvalid, sdram_ARVALID, sd_controller_csr_ARVALID }), - .tgt_arready ({ram_arready, rom_arready, sdram_ARREADY, sd_controller_csr_ARREADY }), - .tgt_rdata ({ram_rdata, rom_rdata, sdram_RDATA, sd_controller_csr_RDATA }), - .tgt_rresp ({ram_rresp, rom_rresp, sdram_RRESP, sd_controller_csr_RRESP }), - .tgt_rvalid ({ram_rvalid, rom_rvalid, sdram_RVALID, sd_controller_csr_RVALID }), - .tgt_rready ({ram_rready, rom_rready, sdram_RREADY, sd_controller_csr_RREADY }), - .tgt_awaddr ({ram_awaddr, rom_awaddr, sdram_AWADDR, sd_controller_csr_AWADDR }), - .tgt_awvalid ({ram_awvalid, rom_awvalid, sdram_AWVALID, sd_controller_csr_AWVALID }), - .tgt_awready ({ram_awready, rom_awready, sdram_AWREADY, sd_controller_csr_AWREADY }), - .tgt_wdata ({ram_wdata, rom_wdata, sdram_WDATA, sd_controller_csr_WDATA }), - .tgt_wvalid ({ram_wvalid, rom_wvalid, sdram_WVALID, sd_controller_csr_WVALID }), - .tgt_wready ({ram_wready, rom_wready, sdram_WREADY, sd_controller_csr_WREADY }), - .tgt_wstrb ({ram_wstrb, rom_wstrb, sdram_WSTRB, sd_controller_csr_WSTRB }), - .tgt_bresp ({ram_bresp, rom_bresp, sdram_BRESP, sd_controller_csr_BRESP }), - .tgt_bvalid ({ram_bvalid, rom_bvalid, sdram_BVALID, sd_controller_csr_BVALID }), - .tgt_bready ({ram_bready, rom_bready, sdram_BREADY, sd_controller_csr_BREADY }) + .S_AXI_ARADDR ({cpu0_ARADDR, sd_controller_dma_ARADDR }), + .S_AXI_ARVALID ({cpu0_ARVALID, sd_controller_dma_ARVALID }), + .S_AXI_ARREADY ({cpu0_ARREADY, sd_controller_dma_ARREADY }), + .S_AXI_RDATA ({cpu0_RDATA, sd_controller_dma_RDATA }), + .S_AXI_RRESP ({cpu0_RRESP, sd_controller_dma_RRESP }), + .S_AXI_RVALID ({cpu0_RVALID, sd_controller_dma_RVALID }), + .S_AXI_RREADY ({cpu0_RREADY, sd_controller_dma_RREADY }), + .S_AXI_AWADDR ({cpu0_AWADDR, sd_controller_dma_AWADDR }), + .S_AXI_AWREADY ({cpu0_AWREADY, sd_controller_dma_AWREADY }), + .S_AXI_AWVALID ({cpu0_AWVALID, sd_controller_dma_AWVALID }), + .S_AXI_WVALID ({cpu0_WVALID, sd_controller_dma_WVALID }), + .S_AXI_WREADY ({cpu0_WREADY, sd_controller_dma_WREADY }), + .S_AXI_WDATA ({cpu0_WDATA, sd_controller_dma_WDATA }), + .S_AXI_WSTRB ({cpu0_WSTRB, sd_controller_dma_WSTRB }), + .S_AXI_BRESP ({cpu0_BRESP, sd_controller_dma_BRESP }), + .S_AXI_BVALID ({cpu0_BVALID, sd_controller_dma_BVALID }), + .S_AXI_BREADY ({cpu0_BREADY, sd_controller_dma_BREADY }), + .M_AXI_ARADDR ({ram_araddr, rom_araddr, sdram_ARADDR, sd_controller_ctrl_ARADDR }), + .M_AXI_ARVALID ({ram_arvalid, rom_arvalid, sdram_ARVALID, sd_controller_ctrl_ARVALID }), + .M_AXI_ARREADY ({ram_arready, rom_arready, sdram_ARREADY, sd_controller_ctrl_ARREADY }), + .M_AXI_RDATA ({ram_rdata, rom_rdata, sdram_RDATA, sd_controller_ctrl_RDATA }), + .M_AXI_RRESP ({ram_rresp, rom_rresp, sdram_RRESP, sd_controller_ctrl_RRESP }), + .M_AXI_RVALID ({ram_rvalid, rom_rvalid, sdram_RVALID, sd_controller_ctrl_RVALID }), + .M_AXI_RREADY ({ram_rready, rom_rready, sdram_RREADY, sd_controller_ctrl_RREADY }), + .M_AXI_AWADDR ({ram_awaddr, rom_awaddr, sdram_AWADDR, sd_controller_ctrl_AWADDR }), + .M_AXI_AWVALID ({ram_awvalid, rom_awvalid, sdram_AWVALID, sd_controller_ctrl_AWVALID }), + .M_AXI_AWREADY ({ram_awready, rom_awready, sdram_AWREADY, sd_controller_ctrl_AWREADY }), + .M_AXI_WDATA ({ram_wdata, rom_wdata, sdram_WDATA, sd_controller_ctrl_WDATA }), + .M_AXI_WVALID ({ram_wvalid, rom_wvalid, sdram_WVALID, sd_controller_ctrl_WVALID }), + .M_AXI_WREADY ({ram_wready, rom_wready, sdram_WREADY, sd_controller_ctrl_WREADY }), + .M_AXI_WSTRB ({ram_wstrb, rom_wstrb, sdram_WSTRB, sd_controller_ctrl_WSTRB }), + .M_AXI_BRESP ({ram_bresp, rom_bresp, sdram_BRESP, sd_controller_ctrl_BRESP }), + .M_AXI_BVALID ({ram_bvalid, rom_bvalid, sdram_BVALID, sd_controller_ctrl_BVALID }), + .M_AXI_BREADY ({ram_bready, rom_bready, sdram_BREADY, sd_controller_ctrl_BREADY }) ); axi4_lite_rom #( - .ROM_SIZE(8), + .ROM_SIZE(12), + .BASE_ADDRESS(32'h0000f000), .ROM_INIT_FILE("init_hex.mem") ) u_rom ( .i_clk(i_sysclk), - .i_rst(~master_reset), + .i_rst(~master_resetn), .o_AWREADY(rom_awready), .o_WREADY(rom_wready), @@ -313,10 +323,11 @@ axi4_lite_rom #( ); axi4_lite_ram #( - .RAM_SIZE(9) + .RAM_SIZE(9), + .ZERO_INIT(1) ) u_ram( .i_clk(i_sysclk), - .i_rst(~master_reset), + .i_rst(~master_resetn), .o_AWREADY(ram_awready), .o_WREADY(ram_wready), @@ -367,7 +378,7 @@ assign o_sdr_DATA_oe = w_sdr_DATA_oe[0+:16]; assign o_sdr_DQM = w_sdr_DQM[0+:2]; sdram_controller u_sdram_controller( - .i_aresetn (pre_reset), + .i_aresetn (pre_resetn), .i_sysclk (i_sysclk), .i_sdrclk (i_sdrclk), .i_tACclk (i_tACclk), @@ -417,96 +428,60 @@ sdram_controller u_sdram_controller( .o_sdr_DQM (w_sdr_DQM) ); -logic sd_controller_apb_psel; -logic sd_controller_apb_penable; -logic sd_controller_apb_pwrite; -logic [2:0] sd_controller_apb_pprot; -logic [ADDR_WIDTH-1:0] sd_controller_apb_paddr; -logic [DATA_WIDTH-1:0] sd_controller_apb_pwdata; -logic [DATA_WIDTH/8-1:0] sd_controller_apb_pstrb; -logic sd_controller_apb_pready; -logic [DATA_WIDTH-1:0] sd_controller_apb_prdata; -logic sd_controller_apb_pslverr; +logic sd_irq; +sd_controller_wrapper #( + .NUMIO (1), // board as it stands is in 1 bit mode + .BASE_ADDRESS (32'h0000E000) +) u_sdio_top ( + .i_clk (i_sysclk), + .i_reset (~master_resetn), -axi4_lite_to_apb4 u_sd_axi_apb_converter ( - .i_clk(i_sysclk), - .i_rst(~master_reset), + .S_AXIL_AWVALID (sd_controller_ctrl_AWVALID), + .S_AXIL_AWREADY (sd_controller_ctrl_AWREADY), + .S_AXIL_AWADDR (sd_controller_ctrl_AWADDR), + .S_AXIL_WVALID (sd_controller_ctrl_WVALID), + .S_AXIL_WREADY (sd_controller_ctrl_WREADY), + .S_AXIL_WDATA (sd_controller_ctrl_WDATA), + .S_AXIL_WSTRB (sd_controller_ctrl_WSTRB), + .S_AXIL_BVALID (sd_controller_ctrl_BVALID), + .S_AXIL_BREADY (sd_controller_ctrl_BREADY), + .S_AXIL_BRESP (sd_controller_ctrl_BRESP), + .S_AXIL_ARVALID (sd_controller_ctrl_ARVALID), + .S_AXIL_ARREADY (sd_controller_ctrl_ARREADY), + .S_AXIL_ARADDR (sd_controller_ctrl_ARADDR), + .S_AXIL_RVALID (sd_controller_ctrl_RVALID), + .S_AXIL_RREADY (sd_controller_ctrl_RREADY), + .S_AXIL_RDATA (sd_controller_ctrl_RDATA), + .S_AXIL_RRESP (sd_controller_ctrl_RRESP), - .i_AWVALID(sd_controller_csr_AWVALID), - .o_AWREADY(sd_controller_csr_AWREADY), - .i_AWADDR(sd_controller_csr_AWADDR), - .i_WVALID(sd_controller_csr_AWVALID), - .o_WREADY(sd_controller_csr_WREADY), - .i_WDATA(sd_controller_csr_WDATA), - .i_WSTRB(sd_controller_csr_WSTRB), - .o_BVALID(sd_controller_csr_BVALID), - .i_BREADY(sd_controller_csr_BREADY), - .o_BRESP(sd_controller_csr_BRESP), - .i_ARVALID(sd_controller_csr_ARVALID), - .o_ARREADY(sd_controller_csr_ARREADY), - .i_ARADDR(sd_controller_csr_ARADDR), - .i_ARPROT('0), - .o_RVALID(sd_controller_csr_RVALID), - .i_RREADY(sd_controller_csr_RREADY), - .o_RDATA(sd_controller_csr_RDATA), - .o_RRESP(sd_controller_csr_RRESP), + .M_AXI_AWVALID (sd_controller_dma_AWVALID), + .M_AXI_AWREADY (sd_controller_dma_AWREADY), + .M_AXI_AWADDR (sd_controller_dma_AWADDR), + .M_AXI_WVALID (sd_controller_dma_WVALID), + .M_AXI_WREADY (sd_controller_dma_WREADY), + .M_AXI_WDATA (sd_controller_dma_WDATA), + .M_AXI_WSTRB (sd_controller_dma_WSTRB), + .M_AXI_BVALID (sd_controller_dma_BVALID), + .M_AXI_BREADY (sd_controller_dma_BREADY), + .M_AXI_BRESP (sd_controller_dma_BRESP), + .M_AXI_ARVALID (sd_controller_dma_ARVALID), + .M_AXI_ARREADY (sd_controller_dma_ARREADY), + .M_AXI_ARADDR (sd_controller_dma_ARADDR), + .M_AXI_RVALID (sd_controller_dma_RVALID), + .M_AXI_RREADY (sd_controller_dma_RREADY), + .M_AXI_RDATA (sd_controller_dma_RDATA), + .M_AXI_RRESP (sd_controller_dma_RRESP), - .m_apb_psel(sd_controller_apb_psel), - .m_apb_penable(sd_controller_apb_penable), - .m_apb_pwrite(sd_controller_apb_pwrite), - .m_apb_pprot(sd_controller_apb_pprot), - .m_apb_paddr(sd_controller_apb_paddr), - .m_apb_pwdata(sd_controller_apb_pwdata), - .m_apb_pstrb(sd_controller_apb_pstrb), - .m_apb_pready(sd_controller_apb_pready), - .m_apb_prdata(sd_controller_apb_prdata), - .m_apb_pslverr(sd_controller_apb_pslverr) -); - -sd_controller_top u_sd_controller ( - .clk(i_sysclk), - .rst(~master_reset), - - .s_apb_psel(sd_controller_apb_psel), - .s_apb_penable(sd_controller_apb_penable), - .s_apb_pwrite(sd_controller_apb_pwrite), - .s_apb_pprot(sd_controller_apb_pprot), - .s_apb_paddr(sd_controller_apb_paddr[5:0]), - .s_apb_pwdata(sd_controller_apb_pwdata), - .s_apb_pstrb(sd_controller_apb_pstrb), - .s_apb_pready(sd_controller_apb_pready), - .s_apb_prdata(sd_controller_apb_prdata), - .s_apb_pslverr(sd_controller_apb_pslverr), - - .o_AWVALID (sd_controller_dma_AWVALID), - .i_AWREADY (sd_controller_dma_AWREADY), - .o_AWADDR (sd_controller_dma_AWADDR), - .o_WVALID (sd_controller_dma_WVALID), - .i_WREADY (sd_controller_dma_WREADY), - .o_WDATA (sd_controller_dma_WDATA), - .o_WSTRB (sd_controller_dma_WSTRB), - .i_BVALID (sd_controller_dma_BVALID), - .o_BREADY (sd_controller_dma_BREADY), - .i_BRESP (sd_controller_dma_BRESP), - .o_ARVALID (sd_controller_dma_ARVALID), - .i_ARREADY (sd_controller_dma_ARREADY), - .o_ARADDR (sd_controller_dma_ARADDR), - .i_RVALID (sd_controller_dma_RVALID), - .o_RREADY (sd_controller_dma_RREADY), - .i_RDATA (sd_controller_dma_RDATA), - .i_RRESP (sd_controller_dma_RRESP), - - - - .i_sd_cmd(i_sd_cmd), - .o_sd_cmd(o_sd_cmd), - .o_sd_cmd_oe(o_sd_cmd_oe), - .o_sd_clk(o_sd_clk), - - .i_sd_dat(i_sd_dat), - .o_sd_dat(o_sd_dat), - .o_sd_dat_oe(o_sd_dat_oe) + .i_dat (i_sd_dat), + .o_dat (o_sd_dat), + .io_dat_tristate (o_sd_dat_oe), + .i_cmd (i_sd_cmd), + .o_cmd (o_sd_cmd), + .io_cmd_tristate (o_sd_cmd_oe), + .o_ck (o_sd_clk), + .i_card_detect (i_sd_cd), + .o_int (sd_irq) ); endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sim/Makefile b/hw/super6502_fpga/src/sim/Makefile index 5c25611..e1930d4 100644 --- a/hw/super6502_fpga/src/sim/Makefile +++ b/hw/super6502_fpga/src/sim/Makefile @@ -9,17 +9,23 @@ INCLUDE=include/sdram_controller_define.vh TB_NAME=sim_top COPY_FILES=addr_map.mem init_hex.mem +SD_IMAGE=sd_image.bin -FLAGS=-DSIM -DRTL_SIM +FLAGS=-DSIM -DRTL_SIM -DVERILATOR -DSDIO_AXI all: waves waves: $(TB_NAME) ./$(TB_NAME) -fst -$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) +$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) $(SD_IMAGE) iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INCLUDE) $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) -I ../../ +$(SD_IMAGE): + dd if=/dev/urandom bs=1 count=65536 of=$(SD_IMAGE) + +# I feel like this should also realize that the outside files are newer... +.PHONY: $(COPY_FILES) $(COPY_FILES): ../../$@ cp ../../$@ . diff --git a/hw/super6502_fpga/src/sim/hvl/sim_top.sv b/hw/super6502_fpga/src/sim/hvl/sim_top.sv index c8ba47e..35db4bb 100644 --- a/hw/super6502_fpga/src/sim/hvl/sim_top.sv +++ b/hw/super6502_fpga/src/sim/hvl/sim_top.sv @@ -49,7 +49,7 @@ initial begin $dumpvars(0,sim_top); end -logic button_reset; +logic button_resetn; logic w_cpu0_reset; logic [15:0] w_cpu0_addr; @@ -120,9 +120,8 @@ logic o_sd_cmd; logic o_sd_cmd_oe; logic i_sd_dat; logic o_sd_dat; -logic i_sd_dat_oe; +logic o_sd_dat_oe; logic o_sd_clk; -logic o_sd_cs; super6502_fpga u_dut ( .i_sysclk (clk_100), @@ -130,7 +129,7 @@ super6502_fpga u_dut ( .i_tACclk (~clk_200), .clk_cpu (clk_cpu), - .button_reset (button_reset), + .button_resetn (button_resetn), .o_cpu0_reset (w_cpu0_reset), .i_cpu0_addr (w_cpu0_addr), @@ -160,26 +159,42 @@ super6502_fpga u_dut ( .i_sd_dat (i_sd_dat), .o_sd_dat (o_sd_dat), .o_sd_dat_oe (o_sd_dat_oe), - .o_sd_clk (o_sd_clk), - .o_sd_cs (o_sd_cs) + .o_sd_clk (o_sd_clk) ); -sd_card_emu u_sd_card_emu( - .clk(o_sd_clk), - .rst(~button_reset), - .i_cmd(o_sd_cmd), - .o_cmd(i_sd_cmd), - .i_dat(o_sd_dat), - .o_dat(i_sd_dat) +wire w_sd_cmd; +wire w_sd_dat; + +IOBUF cmd_buf ( + .T(o_sd_cmd_oe), + .I(o_sd_cmd), + .O(i_sd_cmd), + .IO(w_sd_cmd) +); + +IOBUF dat_buf ( + .T(o_sd_dat_oe), + .I(o_sd_dat), + .O(i_sd_dat), + .IO(w_sd_dat) +); + +mdl_sdio #( + .LGMEMSZ(16), + .MEMFILE("sd_image.bin") +) u_sd_card_emu ( + .sd_clk(o_sd_clk), + .sd_cmd(w_sd_cmd), + .sd_dat(w_sd_dat) ); initial begin - button_reset <= '1; + button_resetn <= '1; repeat(10) @(clk_cpu); - button_reset <= '0; + button_resetn <= '0; repeat(10) @(clk_cpu); - button_reset <= '1; - repeat(4000) @(posedge clk_cpu); + button_resetn <= '1; + repeat(20000) @(posedge clk_cpu); $finish(); end diff --git a/hw/super6502_fpga/src/sim/sources.list b/hw/super6502_fpga/src/sim/sources.list index 76909da..6ea3783 100644 --- a/hw/super6502_fpga/src/sim/sources.list +++ b/hw/super6502_fpga/src/sim/sources.list @@ -2,7 +2,8 @@ hvl/sim_top.sv sub/verilog-6502/ALU.v sub/verilog-6502/cpu_65c02.v sub/sim_sdram/generic_sdr.v -sub/verilog-sd-emulator/src/sd_card_command.sv -sub/verilog-sd-emulator/src/sd_card_emu.sv -sub/verilog-sd-emulator/src/sd_card_state_controller.sv -sub/verilog-sd-emulator/src/sd_card_data.sv \ No newline at end of file +../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdio.v +../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdcmd.v +../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdrx.v +../sub/sd_controller_wrapper/sdspi/bench/verilog/mdl_sdtx.v +../sub/sd_controller_wrapper/sdspi/bench/verilog/IOBUF.v \ No newline at end of file diff --git a/hw/super6502_fpga/src/sim/sub/verilog-sd-emulator b/hw/super6502_fpga/src/sim/sub/verilog-sd-emulator deleted file mode 160000 index 265c636..0000000 --- a/hw/super6502_fpga/src/sim/sub/verilog-sd-emulator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 265c636c86076662e1b6405dd47a71a6077d51d0 diff --git a/hw/super6502_fpga/src/sub/axi_crossbar b/hw/super6502_fpga/src/sub/axi_crossbar deleted file mode 160000 index 5c61f56..0000000 --- a/hw/super6502_fpga/src/sub/axi_crossbar +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5c61f56e7b66853abe2a079745d1cf010bd18175 diff --git a/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv b/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv index 51958e5..b78a726 100644 --- a/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv +++ b/hw/super6502_fpga/src/sub/cpu_wrapper/cpu_wrapper.sv @@ -82,6 +82,9 @@ logic w_write_data_en; logic [7:0] r_write_data, r_write_data_next; logic w_write_data_empty; +logic latched_awvalid, latched_awvalid_next; +logic latched_wvalid, latched_wvalid_next; + logic [2:0] counter; logic w_reset; @@ -160,7 +163,7 @@ always @(posedge i_clk_100 or posedge i_rst) begin end else begin flag <= '0; end - end + end end // // This uses inverted clock, remember in sdc? @@ -204,7 +207,7 @@ always @(posedge i_clk_100 or posedge i_rst) begin end else begin flag2 <= '0; end - end + end end localparam MAX_DELAY = 8; @@ -232,6 +235,9 @@ always_ff @(posedge i_clk_100 or posedge i_rst) begin end rdy_dly <= {rdy_dly[1:0], too_late}; + + latched_awvalid <= latched_awvalid_next; + latched_wvalid <= latched_wvalid_next; end end @@ -244,11 +250,11 @@ always_comb begin // Set defaults o_AWVALID = '0; o_AWADDR = '0; - o_AWPROT = '0; + o_AWPROT = '0; o_WVALID = '0; o_WDATA = '0; - o_WSTRB = '0; - o_BREADY = '0; + o_WSTRB = '0; + o_BREADY = '0; o_ARVALID = '0; o_ARADDR = '0; o_ARPROT = '0; @@ -259,6 +265,9 @@ always_comb begin read_data_next = read_data; did_delay_next = did_delay; + latched_awvalid_next = latched_awvalid; + latched_wvalid_next = latched_wvalid; + case (state) RESET: begin // Is this a CDC violation? @@ -273,6 +282,8 @@ always_comb begin end did_delay_next = '0; + latched_awvalid_next = '0; + latched_wvalid_next = '0; end ADDR_CONTROL: begin @@ -327,9 +338,22 @@ always_comb begin end WRITE_DATA: begin - o_AWVALID = '1; + if (~latched_awvalid) begin + o_AWVALID = i_AWREADY; + latched_awvalid_next = '1; + end else begin + o_AWVALID = '0; + end o_AWADDR = {r_addr[15:2], 2'b0}; - o_WVALID = '1; + + if (~latched_wvalid) begin + o_WVALID = i_WREADY; + latched_wvalid_next = '1; + end else begin + o_WVALID = '0; + end + + o_WSTRB = 4'b1 << r_addr[1:0]; o_WDATA = r_write_data << 8*r_addr[1:0]; diff --git a/hw/super6502_fpga/src/sub/rtl-common b/hw/super6502_fpga/src/sub/rtl-common index 401042b..6bb56be 160000 --- a/hw/super6502_fpga/src/sub/rtl-common +++ b/hw/super6502_fpga/src/sub/rtl-common @@ -1 +1 @@ -Subproject commit 401042bb0ff9db0f44dab9cb6e08c71058a1bcb1 +Subproject commit 6bb56be03a32ea76c7477e2403b396ede5818c31 diff --git a/hw/super6502_fpga/src/sub/sd_controller b/hw/super6502_fpga/src/sub/sd_controller deleted file mode 160000 index a16ffb4..0000000 --- a/hw/super6502_fpga/src/sub/sd_controller +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a16ffb427c6ac8857fd14b6fb9fe1614399b3cbc diff --git a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sd_controller_wrapper.sv b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sd_controller_wrapper.sv new file mode 100644 index 0000000..3157a52 --- /dev/null +++ b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sd_controller_wrapper.sv @@ -0,0 +1,195 @@ +module sd_controller_wrapper #( + parameter NUMIO=4, + parameter BASE_ADDRESS=32'h00000000 +)( + input wire i_clk, + input wire i_reset, + + input wire S_AXIL_AWVALID, + output wire S_AXIL_AWREADY, + input wire [31:0] S_AXIL_AWADDR, + + input wire S_AXIL_WVALID, + output wire S_AXIL_WREADY, + input wire [31:0] S_AXIL_WDATA, + input wire [3:0] S_AXIL_WSTRB, + + output wire S_AXIL_BVALID, + input wire S_AXIL_BREADY, + output wire [1:0] S_AXIL_BRESP, + + input wire S_AXIL_ARVALID, + output wire S_AXIL_ARREADY, + input wire [31:0] S_AXIL_ARADDR, + + output wire S_AXIL_RVALID, + input wire S_AXIL_RREADY, + output wire [31:0] S_AXIL_RDATA, + output wire [1:0] S_AXIL_RRESP, + + output wire M_AXI_AWVALID, + input wire M_AXI_AWREADY, + output wire [31:0] M_AXI_AWADDR, + + output wire M_AXI_WVALID, + input wire M_AXI_WREADY, + output wire [31:0] M_AXI_WDATA, + output wire [3:0] M_AXI_WSTRB, + output wire M_AXI_WLAST, + + input wire M_AXI_BVALID, + output wire M_AXI_BREADY, + input wire [1:0] M_AXI_BRESP, + + output wire M_AXI_ARVALID, + input wire M_AXI_ARREADY, + output wire [31:0] M_AXI_ARADDR, + + + input wire M_AXI_RVALID, + output wire M_AXI_RREADY, + input wire [31:0] M_AXI_RDATA, + input wire [1:0] M_AXI_RRESP, + + output wire o_ck, + output wire io_cmd_tristate, + output wire o_cmd, + input wire i_cmd, + + output wire [NUMIO-1:0] io_dat_tristate, + output wire [NUMIO-1:0] o_dat, + input wire [NUMIO-1:0] i_dat, + + input wire i_card_detect, + output wire o_hwreset_n, + output wire o_1p8v, + output wire o_int +); + +logic shadow_AXI_AWVALID; +logic shadow_AXI_AWREADY; +logic [31:0] shadow_AXI_AWADDR; +logic shadow_AXI_WVALID; +logic shadow_AXI_WREADY; +logic [31:0] shadow_AXI_WDATA; +logic [3:0] shadow_AXI_WSTRB; +logic shadow_AXI_BVALID; +logic shadow_AXI_BREADY; +logic [1:0] shadow_AXI_BRESP; +logic shadow_AXI_ARVALID; +logic shadow_AXI_ARREADY; +logic [31:0] shadow_AXI_ARADDR; +logic shadow_AXI_RVALID; +logic shadow_AXI_RREADY; +logic [31:0] shadow_AXI_RDATA; +logic [1:0] shadow_AXI_RRESP; + +shadow_regs #(.N(8)) u_shadow_regs ( + .i_clk (i_clk), + .i_reset (i_reset), + + .S_AXIL_AWVALID (S_AXIL_AWVALID), + .S_AXIL_AWREADY (S_AXIL_AWREADY), + .S_AXIL_AWADDR (S_AXIL_AWADDR-BASE_ADDRESS), + .S_AXIL_WVALID (S_AXIL_WVALID), + .S_AXIL_WREADY (S_AXIL_WREADY), + .S_AXIL_WDATA (S_AXIL_WDATA), + .S_AXIL_WSTRB (S_AXIL_WSTRB), + .S_AXIL_BVALID (S_AXIL_BVALID), + .S_AXIL_BREADY (S_AXIL_BREADY), + .S_AXIL_BRESP (S_AXIL_BRESP), + .S_AXIL_ARVALID (S_AXIL_ARVALID), + .S_AXIL_ARREADY (S_AXIL_ARREADY), + .S_AXIL_ARADDR (S_AXIL_ARADDR-BASE_ADDRESS), + .S_AXIL_RVALID (S_AXIL_RVALID), + .S_AXIL_RREADY (S_AXIL_RREADY), + .S_AXIL_RDATA (S_AXIL_RDATA), + .S_AXIL_RRESP (S_AXIL_RRESP), + + .M_AXI_AWVALID (shadow_AXI_AWVALID), + .M_AXI_AWREADY (shadow_AXI_AWREADY), + .M_AXI_AWADDR (shadow_AXI_AWADDR), + .M_AXI_WVALID (shadow_AXI_WVALID), + .M_AXI_WREADY (shadow_AXI_WREADY), + .M_AXI_WDATA (shadow_AXI_WDATA), + .M_AXI_WSTRB (shadow_AXI_WSTRB), + .M_AXI_BVALID (shadow_AXI_BVALID), + .M_AXI_BREADY (shadow_AXI_BREADY), + .M_AXI_BRESP (shadow_AXI_BRESP), + .M_AXI_ARVALID (shadow_AXI_ARVALID), + .M_AXI_ARREADY (shadow_AXI_ARREADY), + .M_AXI_ARADDR (shadow_AXI_ARADDR), + .M_AXI_RVALID (shadow_AXI_RVALID), + .M_AXI_RREADY (shadow_AXI_RREADY), + .M_AXI_RDATA (shadow_AXI_RDATA), + .M_AXI_RRESP (shadow_AXI_RRESP) +); + + +sdio_top #( + .NUMIO (NUMIO), // board as it stands is in 1 bit mode + .ADDRESS_WIDTH (32), + .DW (32), + .OPT_DMA (1), + .OPT_EMMC (0), + .OPT_SERDES (0), + .OPT_DDR (0), + .OPT_1P8V (0) // doesn't really matter but we don't need it +) u_sdio_top ( + .i_clk (i_clk), + .i_reset (i_reset), + .i_hsclk ('0), // Not using serdes + + .S_AXIL_AWVALID (shadow_AXI_AWVALID), + .S_AXIL_AWREADY (shadow_AXI_AWREADY), + .S_AXIL_AWADDR (shadow_AXI_AWADDR), + .S_AXIL_AWPROT (), + .S_AXIL_WVALID (shadow_AXI_WVALID), + .S_AXIL_WREADY (shadow_AXI_WREADY), + .S_AXIL_WDATA (shadow_AXI_WDATA), + .S_AXIL_WSTRB (shadow_AXI_WSTRB), + .S_AXIL_BVALID (shadow_AXI_BVALID), + .S_AXIL_BREADY (shadow_AXI_BREADY), + .S_AXIL_BRESP (shadow_AXI_BRESP), + .S_AXIL_ARVALID (shadow_AXI_ARVALID), + .S_AXIL_ARREADY (shadow_AXI_ARREADY), + .S_AXIL_ARADDR (shadow_AXI_ARADDR), + .S_AXIL_ARPROT (), + .S_AXIL_RVALID (shadow_AXI_RVALID), + .S_AXIL_RREADY (shadow_AXI_RREADY), + .S_AXIL_RDATA (shadow_AXI_RDATA), + .S_AXIL_RRESP (shadow_AXI_RRESP), + + .M_AXI_AWVALID (M_AXI_AWVALID), + .M_AXI_AWREADY (M_AXI_AWREADY), + .M_AXI_AWADDR (M_AXI_AWADDR), + .M_AXI_AWPROT (), + .M_AXI_WVALID (M_AXI_WVALID), + .M_AXI_WREADY (M_AXI_WREADY), + .M_AXI_WDATA (M_AXI_WDATA), + .M_AXI_WSTRB (M_AXI_WSTRB), + .M_AXI_BVALID (M_AXI_BVALID), + .M_AXI_BREADY (M_AXI_BREADY), + .M_AXI_BRESP (M_AXI_BRESP), + .M_AXI_ARVALID (M_AXI_ARVALID), + .M_AXI_ARREADY (M_AXI_ARREADY), + .M_AXI_ARADDR (M_AXI_ARADDR), + .M_AXI_ARPROT (), + .M_AXI_RVALID (M_AXI_RVALID), + .M_AXI_RREADY (M_AXI_RREADY), + .M_AXI_RDATA (M_AXI_RDATA), + .M_AXI_RRESP (M_AXI_RRESP), + + .i_dat (i_dat), + .o_dat (o_dat), + .io_dat_tristate (io_dat_tristate), + .i_cmd (i_cmd), + .o_cmd (o_cmd), + .io_cmd_tristate (io_cmd_tristate), + .o_ck (o_ck), + .i_ds ('0), //emmc, don't care + .i_card_detect (i_card_detect), + .o_int (o_int) +); + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi new file mode 160000 index 0000000..4738e69 --- /dev/null +++ b/hw/super6502_fpga/src/sub/sd_controller_wrapper/sdspi @@ -0,0 +1 @@ +Subproject commit 4738e699cadfdc7eedc5a9406563dd15a1c1950b diff --git a/hw/super6502_fpga/src/sub/sd_controller_wrapper/shadow_regs.sv b/hw/super6502_fpga/src/sub/sd_controller_wrapper/shadow_regs.sv new file mode 100644 index 0000000..0e5fc6b --- /dev/null +++ b/hw/super6502_fpga/src/sub/sd_controller_wrapper/shadow_regs.sv @@ -0,0 +1,174 @@ +module shadow_regs #( + parameter N = 8 +)( + input logic i_clk, + input logic i_reset, + + input logic S_AXIL_AWVALID, + output logic S_AXIL_AWREADY, + input logic [31:0] S_AXIL_AWADDR, + + input logic S_AXIL_WVALID, + output logic S_AXIL_WREADY, + input logic [31:0] S_AXIL_WDATA, + input logic [3:0] S_AXIL_WSTRB, + + output logic S_AXIL_BVALID, + input logic S_AXIL_BREADY, + output logic [1:0] S_AXIL_BRESP, + + input logic S_AXIL_ARVALID, + output logic S_AXIL_ARREADY, + input logic [31:0] S_AXIL_ARADDR, + + output logic S_AXIL_RVALID, + input logic S_AXIL_RREADY, + output logic [31:0] S_AXIL_RDATA, + output logic [1:0] S_AXIL_RRESP, + + output logic M_AXI_AWVALID, + input logic M_AXI_AWREADY, + output logic [31:0] M_AXI_AWADDR, + + output logic M_AXI_WVALID, + input logic M_AXI_WREADY, + output logic [31:0] M_AXI_WDATA, + output logic [3:0] M_AXI_WSTRB, + + input logic M_AXI_BVALID, + output logic M_AXI_BREADY, + input logic [1:0] M_AXI_BRESP, + + output logic M_AXI_ARVALID, + input logic M_AXI_ARREADY, + output logic [31:0] M_AXI_ARADDR, + + + input logic M_AXI_RVALID, + output logic M_AXI_RREADY, + input logic [31:0] M_AXI_RDATA, + input logic [1:0] M_AXI_RRESP +); + +assign M_AXI_ARVALID = S_AXIL_ARVALID; +assign S_AXIL_ARREADY = M_AXI_ARREADY; +assign M_AXI_ARADDR = S_AXIL_ARADDR; +assign S_AXIL_RVALID = M_AXI_RVALID; +assign M_AXI_RREADY = S_AXIL_RREADY; +assign S_AXIL_RDATA = M_AXI_RDATA; +assign S_AXIL_RRESP = M_AXI_RRESP; + + +logic [$clog2(N)-1:0] addr; + +logic [31:0] REGS [N]; +logic [31:0] prev; + +logic [31:0] prev_data; +logic [31:0] strobe_expanded; + + +logic addr_valid; +logic wdata_valid; +logic [31:0] wdata; + +logic passthrough; + +logic awready_seen; + +function automatic logic [31:0] strobe_expand(input logic [3:0] wstrb); + logic [31:0] expanded; + for (int i = 0; i < 4; i++) begin + expanded[i*8 +: 8] = {8{wstrb[i]}}; + end + + return expanded; +endfunction + +always_comb begin + S_AXIL_AWREADY = '0; + M_AXI_AWADDR = '0; + M_AXI_AWVALID = '0; + M_AXI_WVALID = '0; + M_AXI_WDATA = '0; + M_AXI_WSTRB = '0; + S_AXIL_WREADY = '0; + + M_AXI_BREADY = S_AXIL_BREADY; + S_AXIL_BVALID = M_AXI_BVALID; + S_AXIL_BRESP = M_AXI_BRESP; + + + if (S_AXIL_AWVALID && S_AXIL_WSTRB != 4'b0001) begin + S_AXIL_AWREADY = '1; + end + + if (S_AXIL_AWVALID && S_AXIL_WSTRB == 4'b0001) begin + M_AXI_AWVALID = '1; + S_AXIL_AWREADY = M_AXI_AWREADY; + end + + if (S_AXIL_WVALID && !passthrough) begin + S_AXIL_WREADY = '1; + S_AXIL_BVALID = '1; + end + + if (passthrough) begin + M_AXI_AWADDR = addr << 2; + M_AXI_AWVALID = ~awready_seen; + + M_AXI_WVALID = S_AXIL_WVALID; + S_AXIL_WREADY = M_AXI_WREADY; + M_AXI_WDATA = {REGS[addr][31:8], wdata[7:0]}; + M_AXI_WSTRB = {4'b111}; + M_AXI_WVALID = '1; + end +end + +always_ff @(posedge i_clk) begin + if (i_reset) begin + addr <= '0; + addr_valid <= '0; + prev_data <= '0; + strobe_expanded <= '0; + passthrough <= '0; + wdata_valid <= '0; + wdata <= '0; + awready_seen <= '0; + end else begin + if (S_AXIL_AWVALID) begin + addr <= S_AXIL_AWADDR[31:2]; + addr_valid <= '1; + prev_data <= REGS[S_AXIL_AWADDR[31:2]]; + end + + if (S_AXIL_WVALID) begin + passthrough <= S_AXIL_WSTRB == 4'b0001; + wdata <= S_AXIL_WDATA; + wdata_valid <= '1; + strobe_expanded <= strobe_expand(S_AXIL_WSTRB); + end + + if (wdata_valid && addr_valid) begin + REGS[addr] <= (prev_data & ~strobe_expanded) | wdata & strobe_expanded; + wdata_valid <= '0; + addr_valid <= '0; + end + + if (passthrough && M_AXI_WREADY) begin + passthrough <= '0; + end + + if (!passthrough) begin + awready_seen <= '0; + end + + if (M_AXI_AWREADY && M_AXI_AWVALID) begin + awready_seen <= '1; + end + + end +end + + +endmodule \ No newline at end of file diff --git a/hw/super6502_fpga/src/sub/wb2axip b/hw/super6502_fpga/src/sub/wb2axip new file mode 160000 index 0000000..bf09db6 --- /dev/null +++ b/hw/super6502_fpga/src/sub/wb2axip @@ -0,0 +1 @@ +Subproject commit bf09db69cbeba4f8b52edeb6bd6dfe824bb741da diff --git a/hw/super6502_fpga/super6502_fpga.peri.xml b/hw/super6502_fpga/super6502_fpga.peri.xml index b9051f9..3acb418 100644 --- a/hw/super6502_fpga/super6502_fpga.peri.xml +++ b/hw/super6502_fpga/super6502_fpga.peri.xml @@ -18,8 +18,8 @@ - - + + diff --git a/hw/super6502_fpga/super6502_fpga.xml b/hw/super6502_fpga/super6502_fpga.xml index cb3545b..e6ebffc 100644 --- a/hw/super6502_fpga/super6502_fpga.xml +++ b/hw/super6502_fpga/super6502_fpga.xml @@ -1,4 +1,4 @@ - + @@ -11,22 +11,33 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -67,14 +78,16 @@ + + - + - + diff --git a/init_env.sh b/init_env.sh index 0bac1ed..7302039 100644 --- a/init_env.sh +++ b/init_env.sh @@ -6,16 +6,14 @@ export REPO_TOP=$(git rev-parse --show-toplevel) export KICAD7_SYMBOL_DIR=$REPO_TOP/hw/kicad_library/symbols export KICAD7_3DMODEL_DIR=$REPO_TOP/hw/kicad_library/3dmodels -export KICAD7_FOOTPRINT_DIR=$REPO_TOP/hw/kicad_library/footprints +export KICAD7_FOOTPRINT_DIR=$REPO_TOP/hw/kicad_library/footprints python3.11 -m venv .user_venv . .user_venv/bin/activate -if [ -n "$EFX_SETUP" ]; then - source $EFX_SETUP -else - echo "EFX_SETUP not defined!" -fi +module load efinity/2023.1 +module load iverilog/12.0 +module load gtkwave/3.3_gtk3 # pip install -r requirements.txt diff --git a/sw/test_code/sd_controller_test/link.ld b/sw/test_code/sd_controller_test/link.ld index 44fc445..da9724e 100644 --- a/sw/test_code/sd_controller_test/link.ld +++ b/sw/test_code/sd_controller_test/link.ld @@ -1,7 +1,8 @@ MEMORY { RAM: start = $0000, size = $200; - ROM: start = $FF00, size = $100, file = %O; + SDRAM: start = $200, size = $de00; + ROM: start = $F000, size = $1000, file = %O; } SEGMENTS { @@ -25,6 +26,6 @@ FEATURES { SYMBOLS { # Define the stack size for the application - __STACKSIZE__: value = $0200, type = weak; - __STACKSTART__: type = weak, value = $0800; # 2k stack + __STACKSIZE__: value = $0800, type = weak; + __STACKSTART__: type = weak, value = $0200; # 2k stack } diff --git a/sw/test_code/sd_controller_test/main.s b/sw/test_code/sd_controller_test/main.s index 8576a2a..ffc55e8 100644 --- a/sw/test_code/sd_controller_test/main.s +++ b/sw/test_code/sd_controller_test/main.s @@ -1,5 +1,9 @@ .export _init, _nmi_int, _irq_int +.include "zeropage.inc" + +.autoimport + .segment "VECTORS" .addr _nmi_int ; NMI vector @@ -7,12 +11,27 @@ .addr _irq_int ; IRQ/BRK vector SD_CONTROLLER = $e000 -SD_ARG = SD_CONTROLLER + $4 -SD_RESP = SD_CONTROLLER + $10 -CLK_DIV = $20 -SD_DMA_BASE = SD_CONTROLLER + $28 -SD_DMA_STAT_CTRL = SD_CONTROLLER + $2C +SD_CMD = SD_CONTROLLER +SD_ARG = SD_CONTROLLER + $4 +SD_DATA = SD_ARG +SD_FIFO_0 = SD_CONTROLLER + $8 +SD_FIFO_1 = SD_CONTROLLER + $C + + +SD_PHY = SD_CONTROLLER + $10 +SD_PHY_CLKDIV = SD_PHY +SD_PHY_CLKCTRL = SD_PHY + $1 +SD_PHY_SAMP_VOLT = SD_PHY + $2 +SD_PHY_BLKSIZ = SD_PHY + $3 + +SD_DMA_BASE = SD_CONTROLLER + $14 +SD_DMA_BASE2 = SD_CONTROLLER + $18 +SD_DMA_LEN = SD_CONTROLLER + $1C + +SDIOCLK_100KHZ = $FC +SDIOCLK_25MHZ = $03 +SPEED_512B = $09 .zeropage rca: .res 4 @@ -23,117 +42,294 @@ _nmi_int: _irq_int: _init: - ldx #$ff - txs + ldx #$ff + txs + cld - lda #$00 - sta SD_CONTROLLER + lda #<(__STACKSTART__ + __STACKSIZE__) + sta sp + lda #>(__STACKSTART__ + __STACKSIZE__) + sta sp+1 - lda #$aa - sta SD_ARG - lda #$01 - sta SD_ARG+1 - lda #$00 - sta SD_ARG+2 - sta SD_ARG+3 - lda #$08 - sta SD_CONTROLLER - jsr delay + stz SD_PHY_CLKCTRL + stz SD_PHY_SAMP_VOLT + lda #SPEED_512B + sta SD_PHY_BLKSIZ + lda #SDIOCLK_100KHZ + sta SD_PHY_CLKDIV - lda #55 - sta SD_CONTROLLER - jsr delay - lda #41 - sta SD_CONTROLLER - jsr delay +@wait_clk: lda SD_PHY_CLKDIV + cmp #SDIOCLK_100KHZ + bne @wait_clk + + ; send_goidle(); + jsr send_goidle + + ; send_r1(8, 0x1aa); + lda #$0 + sta sreg+1 + lda #$0 + sta sreg + ldx #$01 + lda #$aa + jsr pusheax + lda #$08 + jsr send_r1 @acmd41: - lda #55 - sta SD_CONTROLLER + ; send_r1(55, 0x00); + lda #$0 + sta sreg+1 + lda #$0 + sta sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #55 + jsr send_r1 - jsr delay + ; send_r1(41, 0x4000ff80); + lda #$40 + sta sreg+1 + lda #$0 + sta sreg + ldx #$ff + lda #$80 + jsr pusheax + lda #41 + jsr send_r1 - lda #$80 - sta SD_ARG+1 - lda #$ff - sta SD_ARG+2 - lda #$40 - sta SD_ARG+3 - lda #41 - sta SD_CONTROLLER + lda sreg+1 + bpl @acmd41 - jsr delay + ; send_r2(2, 0x00); + stz sreg+1 + stz sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #2 + jsr send_r2 - lda SD_RESP+3 - bmi card_ready + lda SD_FIFO_0 + lda SD_FIFO_0 + lda SD_FIFO_0 + lda SD_FIFO_0 + + ; send_r1(3, 0x00); + stz sreg+1 + stz sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #3 + jsr send_r1 + + lda #$30 + sta SD_PHY_CLKCTRL + stz SD_PHY_SAMP_VOLT + lda #SPEED_512B + sta SD_PHY_BLKSIZ + lda #SDIOCLK_25MHZ + sta SD_PHY_CLKDIV + +@wait_clk2: lda SD_PHY_CLKDIV + cmp #SDIOCLK_25MHZ + bne @wait_clk2 + + ; The upper 16 bits are the RCA, but they are already in sreg + ; The lower 16 are don't cares, so we can leave them. + + jsr pusheax + lda #7 + jsr send_r1b + + ; Now we need to DMA the first sector into memory, say at $1000 + ; The example code reads multiple, but we can probably just read 1 (cmd17) + ; write to address $1000 + ; dma length is 1 + stz SD_DMA_BASE+$3 + stz SD_DMA_BASE+$2 + lda #$10 + sta SD_DMA_BASE+$1 + stz SD_DMA_BASE + + stz SD_DMA_LEN + $3 + stz SD_DMA_LEN + $2 + stz SD_DMA_LEN + $1 + lda #$01 + sta SD_DMA_LEN + + ; address 0 + stz sreg+1 + stz sreg + ldx #$00 + lda #$00 + jsr pusheax + lda #18 + jsr send_dma + + ; dumb sleep to wait for DMA to be done. + lda #$3a + @sleep: dec + bne @sleep + + ; Try reading again just to make sure it works. + stz SD_DMA_BASE+$3 + stz SD_DMA_BASE+$2 + lda #$12 + sta SD_DMA_BASE+$1 + stz SD_DMA_BASE + + stz SD_DMA_LEN + $3 + stz SD_DMA_LEN + $2 + stz SD_DMA_LEN + $1 + lda #$01 + sta SD_DMA_LEN + + ; address 2 + stz sreg+1 + stz sreg + ldx #$00 + lda #$02 + jsr pusheax + lda #18 + jsr send_dma + + ; dumb sleep to wait for DMA to be done. + lda #$3a + @sleep2:dec + bne @sleep2 + + ; Write the first sector into the second sector + stz SD_DMA_BASE+$3 + stz SD_DMA_BASE+$2 + lda #$10 + sta SD_DMA_BASE+$1 + stz SD_DMA_BASE + + stz SD_DMA_LEN + $3 + stz SD_DMA_LEN + $2 + stz SD_DMA_LEN + $1 + lda #$2 + sta SD_DMA_LEN + + ; address 2 + stz sreg+1 + stz sreg + ldx #$00 + lda #$02 + jsr pusheax + lda #25 + jsr write_dma - ldx #$10 -@loop: dex - bne @loop - - bra @acmd41 - -card_ready: - lda #2 - sta SD_CONTROLLER - - jsr delay - - lda #3 - sta SD_CONTROLLER - - jsr delay - - lda SD_RESP - sta rca - lda SD_RESP+1 - sta rca+1 - lda SD_RESP+2 - sta rca+2 - lda SD_RESP+3 - sta rca+3 - - lda rca - sta SD_ARG - lda rca+1 - sta SD_ARG+1 - lda rca+2 - sta SD_ARG+2 - lda rca+3 - sta SD_ARG+3 - lda #7 - sta SD_CONTROLLER - - jsr delay - - lda #17 - sta SD_CONTROLLER - - lda #$10 - sta SD_DMA_BASE + 1 - lda #1 - sta SD_DMA_STAT_CTRL - -@poll: lda SD_DMA_STAT_CTRL+2 - cmp #$1 - bne @poll - stz SD_DMA_STAT_CTRL - - lda $1000 - lda $1001 - lda $1002 - lda $1003 +@end: + bra @end -@end: bra @end +wait_busy: lda SD_CMD+$1 + bit #$40 + bne wait_busy + rts -delay: - nop - nop - nop - nop - nop - nop - nop - rts \ No newline at end of file + +; No arguments, no response +; sends cmd0 +; also clears removed and error flags? +send_goidle: + stz SD_ARG+$3 + stz SD_ARG+$2 + stz SD_ARG+$1 + stz SD_ARG + + stz SD_CMD+$3 + lda #$04 + sta SD_CMD+$2 + lda #$80 + sta SD_CMD+$1 + lda #$40 + sta SD_CMD + + jsr wait_busy + + rts + +; Command in A +; Arg on stack as 32 bits +; returns the response in eax +; (How can we signal a failure then?) +send_r1: stz tmp1 + inc tmp1 + bra send + +send_r1b: stz tmp1 + inc tmp1 + inc tmp1 + inc tmp1 + bra send + +send_dma: pha + lda #$20 + sta tmp1 + pla + bra send + +write_dma: pha + lda #$a4 + sta tmp1 + pla + bra send + +send: pha ; push command to stack + jsr popeax + PHA + stx SD_ARG+$1 + lda sreg + sta SD_ARG+$2 + lda sreg+1 + sta SD_ARG+$3 + pla + sta SD_ARG ; lsb has to be the last written. + lda #$80 ; This also clears error flag (only for acmd41?) + ora tmp1 + sta SD_CMD+$1 + pla + ora #$40 + sta SD_CMD + + jsr wait_busy + + lda SD_DATA + $3 + sta sreg+1 + lda SD_DATA + $2 + sta sreg + ldx SD_DATA + $1 + lda SD_DATA + + rts + +; Command in A +; Arg on stack as 32 bits +; returns the response in eax +; (How can we signal a failure then?) +send_r2: + pha ; push command to stack + jsr popeax + PHA + stx SD_ARG+$1 + lda sreg + sta SD_ARG+$2 + lda sreg+1 + sta SD_ARG+$3 + pla + sta SD_ARG ; lsb has to be the last written. + lda #$82 ; This also clears error flag (only for acmd41?) + sta SD_CMD+$1 + pla + ora #$40 + sta SD_CMD + + jsr wait_busy + + rts \ No newline at end of file