diff --git a/sim/sources.list b/sim/sources.list index 047d32a..9efdf34 100644 --- a/sim/sources.list +++ b/sim/sources.list @@ -7,6 +7,7 @@ verilog6502_wrapper_tb.sv ../src/verilog6502_addr_decoder.sv ../src/verilog6502_internal_memory.sv ../src/verilog6502_apb_adapter.sv +../src/verilog6502_external_memory.sv ../src/verilog6502_wrapper.sv @@ -15,10 +16,13 @@ verilog6502_wrapper_tb.sv ../sub/taxi/src/apb/rtl/taxi_apb_if.sv ../sub/taxi/src/axi/rtl/taxi_axi_if.sv +../sub/taxi/src/axi/rtl/taxi_axil_if.sv ../sub/taxi/src/axi/rtl/taxi_axi_ram_if_rd.sv ../sub/taxi/src/axi/rtl/taxi_axi_ram_if_wr.sv ../sub/taxi/src/axi/rtl/taxi_axi_ram_if_rdwr.sv ../sub/taxi/src/apb/rtl/taxi_apb_interconnect.sv ../sub/taxi/src/apb/rtl/taxi_apb_tie.sv ../sub/taxi/src/prim/rtl/taxi_arbiter.sv -../sub/taxi/src/prim/rtl/taxi_penc.sv \ No newline at end of file +../sub/taxi/src/prim/rtl/taxi_penc.sv + +../sub/taxi/src/apb/rtl/taxi_apb_axil_adapter.sv \ No newline at end of file diff --git a/sim/verilog6502_wrapper_tb.sv b/sim/verilog6502_wrapper_tb.sv index b833611..8eea85f 100644 --- a/sim/verilog6502_wrapper_tb.sv +++ b/sim/verilog6502_wrapper_tb.sv @@ -3,7 +3,7 @@ module verilog6502_wrapper_tb(); `define SIM taxi_apb_if s_apb(); -taxi_axi_if m_axi(); +taxi_axil_if m_axil(); taxi_axi_if s_axi(); logic clk; @@ -18,8 +18,8 @@ verilog6502_wrapper u_dut( .clk(clk), .rst(rst), .s_apb(s_apb), - .m_axi_rd(m_axi), - .m_axi_wr(m_axi), + .m_axil_rd(m_axil), + .m_axil_wr(m_axil), .s_axi_rd(s_axi), .s_axi_wr(s_axi), .o_irq_ext(o_irq_ext), diff --git a/sim/verilog6502_wrapper_test.py b/sim/verilog6502_wrapper_test.py index 30c2be0..f24348e 100644 --- a/sim/verilog6502_wrapper_test.py +++ b/sim/verilog6502_wrapper_test.py @@ -5,7 +5,7 @@ from cocotb.clock import Clock from cocotb.triggers import Timer, RisingEdge from cocotbext.axi.apb import ApbMaster, ApbBus -from cocotbext.axi import AxiMaster, AxiBus +from cocotbext.axi import AxiMaster, AxiBus, AxiLiteBus, AxiLiteRam @@ -20,6 +20,9 @@ async def test_sanity(dut): s_apb = ApbMaster(ApbBus.from_prefix(dut.s_apb, ""), dut.clk, dut.rst) s_axi = AxiMaster(AxiBus.from_prefix(dut.s_axi, ""), dut.clk, dut.rst) + m_axil = AxiLiteRam(AxiLiteBus.from_prefix(dut.m_axil, ""), dut.clk, dut.rst, size=2**32) + + m_axil.write(0, b"Hello, world!") dut.rst.value = Immediate(1) @@ -29,7 +32,8 @@ async def test_sanity(dut): for _ in range(10): await RisingEdge(dut.clk) - await s_axi.write(0x200, [0x58, 0xa9, 0x00, 0x1a, 0xcb, 0x4c, 0x02, 0x03]) + # await s_axi.write(0x200, [0x58, 0xa9, 0x00, 0x1a, 0xcb, 0x4c, 0x03, 0x02]) + await s_axi.write(0x200, [0xAD, 0x00, 0xE0, 0xAD, 0x01, 0xE0, 0xAD, 0x02, 0xE0, 0xAD, 0x03, 0xE0, 0xAD, 0x04, 0xE0, 0xCB]) cocotb.start_soon(s_axi.read(0x200, 8)) diff --git a/src/regs/verilog6502_io_regs.rdl b/src/regs/verilog6502_io_regs.rdl index 853c8f6..7aeefef 100644 --- a/src/regs/verilog6502_io_regs.rdl +++ b/src/regs/verilog6502_io_regs.rdl @@ -15,6 +15,19 @@ addrmap verilog6502_io_regs { } core_ctrl @ 0x0; + reg { + name = "AXI Base Address"; + desc = ""; + + field { + name = "val"; + desc = ""; + hw = r; + sw = rw; + } val[31:0] = 0x0; + + } axi_base_address @ 0x10; + reg { name = "nmi"; diff --git a/src/regs/verilog6502_io_regs.sv b/src/regs/verilog6502_io_regs.sv index 93c8a16..147881d 100644 --- a/src/regs/verilog6502_io_regs.sv +++ b/src/regs/verilog6502_io_regs.sv @@ -87,6 +87,7 @@ module verilog6502_io_regs ( //-------------------------------------------------------------------------- typedef struct { logic core_ctrl; + logic axi_base_address; logic nmi; logic reset_brq; } decoded_reg_strb_t; @@ -104,6 +105,7 @@ module verilog6502_io_regs ( is_valid_addr = '1; // No valid address check is_valid_rw = '1; // No valid RW check decoded_reg_strb.core_ctrl = cpuif_req_masked & (cpuif_addr == 12'h0); + decoded_reg_strb.axi_base_address = cpuif_req_masked & (cpuif_addr == 12'h10); decoded_reg_strb.nmi = cpuif_req_masked & (cpuif_addr == 12'hff8); decoded_reg_strb.reset_brq = cpuif_req_masked & (cpuif_addr == 12'hffc); decoded_err = '0; @@ -126,6 +128,12 @@ module verilog6502_io_regs ( logic load_next; } reset; } core_ctrl; + struct { + struct { + logic [31:0] next; + logic load_next; + } val; + } axi_base_address; struct { struct { logic [15:0] next; @@ -151,6 +159,11 @@ module verilog6502_io_regs ( logic value; } reset; } core_ctrl; + struct { + struct { + logic [31:0] value; + } val; + } axi_base_address; struct { struct { logic [15:0] value; @@ -190,6 +203,29 @@ module verilog6502_io_regs ( end end assign hwif_out.core_ctrl.reset.value = field_storage.core_ctrl.reset.value; + // Field: verilog6502_io_regs.axi_base_address.val + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.axi_base_address.val.value; + load_next_c = '0; + if(decoded_reg_strb.axi_base_address && decoded_req_is_wr) begin // SW write + next_c = (field_storage.axi_base_address.val.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.axi_base_address.val.next = next_c; + field_combo.axi_base_address.val.load_next = load_next_c; + end + always_ff @(posedge clk) begin + if(rst) begin + field_storage.axi_base_address.val.value <= 32'h0; + end else begin + if(field_combo.axi_base_address.val.load_next) begin + field_storage.axi_base_address.val.value <= field_combo.axi_base_address.val.next; + end + end + end + assign hwif_out.axi_base_address.val.value = field_storage.axi_base_address.val.value; // Field: verilog6502_io_regs.nmi.nmi always_comb begin automatic logic [15:0] next_c; @@ -283,6 +319,9 @@ module verilog6502_io_regs ( if(rd_mux_addr == 12'h0) begin readback_data_var[0] = field_storage.core_ctrl.reset.value; end + if(rd_mux_addr == 12'h10) begin + readback_data_var[31:0] = field_storage.axi_base_address.val.value; + end if(rd_mux_addr == 12'hff8) begin readback_data_var[31:16] = field_storage.nmi.nmi.value; end diff --git a/src/regs/verilog6502_io_regs_pkg.sv b/src/regs/verilog6502_io_regs_pkg.sv index 99cacae..d533c72 100644 --- a/src/regs/verilog6502_io_regs_pkg.sv +++ b/src/regs/verilog6502_io_regs_pkg.sv @@ -15,6 +15,14 @@ package verilog6502_io_regs_pkg; verilog6502_io_regs__core_ctrl__reset__out_t reset; } verilog6502_io_regs__core_ctrl__out_t; + typedef struct { + logic [31:0] value; + } verilog6502_io_regs__axi_base_address__val__out_t; + + typedef struct { + verilog6502_io_regs__axi_base_address__val__out_t val; + } verilog6502_io_regs__axi_base_address__out_t; + typedef struct { logic [15:0] value; } verilog6502_io_regs__nmi__nmi__out_t; @@ -38,6 +46,7 @@ package verilog6502_io_regs_pkg; typedef struct { verilog6502_io_regs__core_ctrl__out_t core_ctrl; + verilog6502_io_regs__axi_base_address__out_t axi_base_address; verilog6502_io_regs__nmi__out_t nmi; verilog6502_io_regs__reset_brq__out_t reset_brq; } verilog6502_io_regs__out_t; diff --git a/src/verilog6502_external_memory.sv b/src/verilog6502_external_memory.sv new file mode 100644 index 0000000..778e9cb --- /dev/null +++ b/src/verilog6502_external_memory.sv @@ -0,0 +1,61 @@ +module verilog6502_external_memory ( + input i_clk, + input i_rst, + + input logic [15:0] i_addr, + input logic [7:0] i_data, + output logic [7:0] o_data, + input logic i_rd, + input logic i_we, + output logic o_rdy, + + input logic [31:0] i_axi_base_addr, + + + taxi_axil_if.wr_mst m_axil_wr, + taxi_axil_if.rd_mst m_axil_rd +); + +taxi_apb_if internal_apb(); +taxi_apb_if addr_shift_apb(); + +verilog6502_apb_adapter u_internal_apb_adapter ( + .i_clk (i_clk), + .i_rst (i_rst), + + .i_addr (i_addr), + .i_data (i_data), + .o_data (o_data), + .i_rd (i_rd), + .i_we (i_we), + .o_rdy (o_rdy), + + .m_apb (internal_apb) +); + +assign addr_shift_apb.paddr = {i_axi_base_addr[31:12], {internal_apb.paddr[11:0]}}; +assign addr_shift_apb.pprot = internal_apb.pprot; +assign addr_shift_apb.psel = internal_apb.psel; +assign addr_shift_apb.penable = internal_apb.penable; +assign addr_shift_apb.pwrite = internal_apb.pwrite; +assign addr_shift_apb.pwdata = internal_apb.pwdata; +assign addr_shift_apb.pstrb = internal_apb.pstrb; +assign internal_apb.pready = addr_shift_apb.pready; +assign internal_apb.prdata = addr_shift_apb.prdata; +assign internal_apb.pslverr = addr_shift_apb.pslverr; +assign addr_shift_apb.pauser = '0; +assign addr_shift_apb.pwuser = '0; +assign internal_apb.pruser = '0; +assign internal_apb.pbuser = '0; + +taxi_apb_axil_adapter u_apb_axil_adapter ( + .clk (i_clk), + .rst (i_rst), + + .s_apb (addr_shift_apb), + + .m_axil_wr (m_axil_wr), + .m_axil_rd (m_axil_rd) +); + +endmodule \ No newline at end of file diff --git a/src/verilog6502_wrapper.sv b/src/verilog6502_wrapper.sv index 3c452f7..a4ff43f 100644 --- a/src/verilog6502_wrapper.sv +++ b/src/verilog6502_wrapper.sv @@ -13,8 +13,8 @@ module verilog6502_wrapper( taxi_apb_if.slv s_apb, - taxi_axi_if.rd_mst m_axi_rd, - taxi_axi_if.wr_mst m_axi_wr, + taxi_axil_if.wr_mst m_axil_wr, + taxi_axil_if.rd_mst m_axil_rd, taxi_axi_if.rd_slv s_axi_rd, taxi_axi_if.wr_slv s_axi_wr, @@ -83,6 +83,13 @@ logic mem_rd; logic mem_we; logic mem_rdy; +logic [15:0] ext_addr; +logic [7:0] ext_data_in; +logic [7:0] ext_data_out; +logic ext_rd; +logic ext_we; +logic ext_rdy; + logic [15:0] io_addr; logic [7:0] io_data_in; logic [7:0] io_data_out; @@ -125,12 +132,12 @@ verilog6502_addr_decoder u_addr_decoder( .o_mem_we (mem_we), .i_mem_rdy (mem_rdy), - .o_external_addr (), - .o_external_data (), - .i_external_data ('0), - .o_external_rd (), - .o_external_we (), - .i_external_rdy ('1), + .o_external_addr (ext_addr), + .o_external_data (ext_data_in), + .i_external_data (ext_data_out), + .o_external_rd (ext_rd), + .o_external_we (ext_we), + .i_external_rdy (ext_rdy), .o_io_addr (io_addr), .o_io_data (io_data_in), @@ -155,6 +162,23 @@ verilog6502_internal_memory u_internal_memory( .o_rdy (mem_rdy) ); +verilog6502_external_memory u_external_memory ( + .i_clk (clk), + .i_rst (rst), + + .i_addr (ext_addr), + .i_data (ext_data_in), + .o_data (ext_data_out), + .i_rd (ext_rd), + .i_we (ext_we), + .o_rdy (ext_rdy), + + .i_axi_base_addr (hwif_out.axi_base_address.val.value), + + .m_axil_rd (m_axil_rd), + .m_axil_wr (m_axil_wr) +); + verilog6502_apb_adapter u_io_apb_adapter( .i_clk (cpu_clk), .i_rst (rst),