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_addr_decoder.sv
../src/verilog6502_internal_memory.sv ../src/verilog6502_internal_memory.sv
../src/verilog6502_apb_adapter.sv ../src/verilog6502_apb_adapter.sv
../src/verilog6502_external_memory.sv
../src/verilog6502_wrapper.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/apb/rtl/taxi_apb_if.sv
../sub/taxi/src/axi/rtl/taxi_axi_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_rd.sv
../sub/taxi/src/axi/rtl/taxi_axi_ram_if_wr.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/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/apb/rtl/taxi_apb_tie.sv
../sub/taxi/src/prim/rtl/taxi_arbiter.sv ../sub/taxi/src/prim/rtl/taxi_arbiter.sv
../sub/taxi/src/prim/rtl/taxi_penc.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 `define SIM
taxi_apb_if s_apb(); taxi_apb_if s_apb();
taxi_axi_if m_axi(); taxi_axil_if m_axil();
taxi_axi_if s_axi(); taxi_axi_if s_axi();
logic clk; logic clk;
@@ -18,8 +18,8 @@ verilog6502_wrapper u_dut(
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
.s_apb(s_apb), .s_apb(s_apb),
.m_axi_rd(m_axi), .m_axil_rd(m_axil),
.m_axi_wr(m_axi), .m_axil_wr(m_axil),
.s_axi_rd(s_axi), .s_axi_rd(s_axi),
.s_axi_wr(s_axi), .s_axi_wr(s_axi),
.o_irq_ext(o_irq_ext), .o_irq_ext(o_irq_ext),

View File

@@ -5,7 +5,7 @@ from cocotb.clock import Clock
from cocotb.triggers import Timer, RisingEdge from cocotb.triggers import Timer, RisingEdge
from cocotbext.axi.apb import ApbMaster, ApbBus 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_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) 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) dut.rst.value = Immediate(1)
@@ -29,7 +32,8 @@ async def test_sanity(dut):
for _ in range(10): for _ in range(10):
await RisingEdge(dut.clk) 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)) cocotb.start_soon(s_axi.read(0x200, 8))

View File

@@ -15,6 +15,19 @@ addrmap verilog6502_io_regs {
} core_ctrl @ 0x0; } 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 { reg {
name = "nmi"; name = "nmi";

View File

@@ -87,6 +87,7 @@ module verilog6502_io_regs (
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
typedef struct { typedef struct {
logic core_ctrl; logic core_ctrl;
logic axi_base_address;
logic nmi; logic nmi;
logic reset_brq; logic reset_brq;
} decoded_reg_strb_t; } decoded_reg_strb_t;
@@ -104,6 +105,7 @@ module verilog6502_io_regs (
is_valid_addr = '1; // No valid address check is_valid_addr = '1; // No valid address check
is_valid_rw = '1; // No valid RW check is_valid_rw = '1; // No valid RW check
decoded_reg_strb.core_ctrl = cpuif_req_masked & (cpuif_addr == 12'h0); 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.nmi = cpuif_req_masked & (cpuif_addr == 12'hff8);
decoded_reg_strb.reset_brq = cpuif_req_masked & (cpuif_addr == 12'hffc); decoded_reg_strb.reset_brq = cpuif_req_masked & (cpuif_addr == 12'hffc);
decoded_err = '0; decoded_err = '0;
@@ -126,6 +128,12 @@ module verilog6502_io_regs (
logic load_next; logic load_next;
} reset; } reset;
} core_ctrl; } core_ctrl;
struct {
struct {
logic [31:0] next;
logic load_next;
} val;
} axi_base_address;
struct { struct {
struct { struct {
logic [15:0] next; logic [15:0] next;
@@ -151,6 +159,11 @@ module verilog6502_io_regs (
logic value; logic value;
} reset; } reset;
} core_ctrl; } core_ctrl;
struct {
struct {
logic [31:0] value;
} val;
} axi_base_address;
struct { struct {
struct { struct {
logic [15:0] value; logic [15:0] value;
@@ -190,6 +203,29 @@ module verilog6502_io_regs (
end end
end end
assign hwif_out.core_ctrl.reset.value = field_storage.core_ctrl.reset.value; 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 // Field: verilog6502_io_regs.nmi.nmi
always_comb begin always_comb begin
automatic logic [15:0] next_c; automatic logic [15:0] next_c;
@@ -283,6 +319,9 @@ module verilog6502_io_regs (
if(rd_mux_addr == 12'h0) begin if(rd_mux_addr == 12'h0) begin
readback_data_var[0] = field_storage.core_ctrl.reset.value; readback_data_var[0] = field_storage.core_ctrl.reset.value;
end 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 if(rd_mux_addr == 12'hff8) begin
readback_data_var[31:16] = field_storage.nmi.nmi.value; readback_data_var[31:16] = field_storage.nmi.nmi.value;
end 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__reset__out_t reset;
} verilog6502_io_regs__core_ctrl__out_t; } 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 { typedef struct {
logic [15:0] value; logic [15:0] value;
} verilog6502_io_regs__nmi__nmi__out_t; } verilog6502_io_regs__nmi__nmi__out_t;
@@ -38,6 +46,7 @@ package verilog6502_io_regs_pkg;
typedef struct { typedef struct {
verilog6502_io_regs__core_ctrl__out_t core_ctrl; 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__nmi__out_t nmi;
verilog6502_io_regs__reset_brq__out_t reset_brq; verilog6502_io_regs__reset_brq__out_t reset_brq;
} verilog6502_io_regs__out_t; } 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_apb_if.slv s_apb,
taxi_axi_if.rd_mst m_axi_rd, taxi_axil_if.wr_mst m_axil_wr,
taxi_axi_if.wr_mst m_axi_wr, taxi_axil_if.rd_mst m_axil_rd,
taxi_axi_if.rd_slv s_axi_rd, taxi_axi_if.rd_slv s_axi_rd,
taxi_axi_if.wr_slv s_axi_wr, taxi_axi_if.wr_slv s_axi_wr,
@@ -83,6 +83,13 @@ logic mem_rd;
logic mem_we; logic mem_we;
logic mem_rdy; 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 [15:0] io_addr;
logic [7:0] io_data_in; logic [7:0] io_data_in;
logic [7:0] io_data_out; logic [7:0] io_data_out;
@@ -125,12 +132,12 @@ verilog6502_addr_decoder u_addr_decoder(
.o_mem_we (mem_we), .o_mem_we (mem_we),
.i_mem_rdy (mem_rdy), .i_mem_rdy (mem_rdy),
.o_external_addr (), .o_external_addr (ext_addr),
.o_external_data (), .o_external_data (ext_data_in),
.i_external_data ('0), .i_external_data (ext_data_out),
.o_external_rd (), .o_external_rd (ext_rd),
.o_external_we (), .o_external_we (ext_we),
.i_external_rdy ('1), .i_external_rdy (ext_rdy),
.o_io_addr (io_addr), .o_io_addr (io_addr),
.o_io_data (io_data_in), .o_io_data (io_data_in),
@@ -155,6 +162,23 @@ verilog6502_internal_memory u_internal_memory(
.o_rdy (mem_rdy) .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( verilog6502_apb_adapter u_io_apb_adapter(
.i_clk (cpu_clk), .i_clk (cpu_clk),
.i_rst (rst), .i_rst (rst),