Add external memory
This commit is contained in:
@@ -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
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
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_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),
|
||||||
|
|||||||
Reference in New Issue
Block a user