Add external memory
This commit is contained in:
@@ -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
|
||||
@@ -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),
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
61
src/verilog6502_external_memory.sv
Normal file
61
src/verilog6502_external_memory.sv
Normal 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
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user