Add external memory

This commit is contained in:
2026-04-18 18:40:30 -07:00
parent 756b96d9e2
commit 048af1c341
8 changed files with 168 additions and 14 deletions

View File

@@ -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,6 +16,7 @@ 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
@@ -22,3 +24,5 @@ verilog6502_wrapper_tb.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
../sub/taxi/src/apb/rtl/taxi_apb_axil_adapter.sv

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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