Kinda working
This commit is contained in:
@@ -11,6 +11,7 @@ logic rst;
|
|||||||
|
|
||||||
logic o_irq_ext;
|
logic o_irq_ext;
|
||||||
logic i_irq_ext;
|
logic i_irq_ext;
|
||||||
|
logic i_nmi_ext;
|
||||||
|
|
||||||
|
|
||||||
verilog6502_wrapper u_dut(
|
verilog6502_wrapper u_dut(
|
||||||
@@ -22,7 +23,8 @@ verilog6502_wrapper u_dut(
|
|||||||
.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),
|
||||||
.i_irq_ext(i_irq_ext)
|
.i_irq_ext(i_irq_ext),
|
||||||
|
.i_nmi_ext(i_nmi_ext)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@@ -29,12 +29,16 @@ 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(0x0, [0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
|
await s_axi.write(0x200, [0x58, 0xa9, 0x00, 0x1a, 0xcb, 0x4c, 0x02, 0x03])
|
||||||
|
|
||||||
cocotb.start_soon(s_axi.read(0x0, 8))
|
cocotb.start_soon(s_axi.read(0x200, 8))
|
||||||
|
|
||||||
await Timer(10, "us")
|
await Timer(10, "us")
|
||||||
|
|
||||||
await s_apb.write_dword(0x0, 0)
|
await s_apb.write_dword(0x0, 0)
|
||||||
|
|
||||||
await Timer(10, "us")
|
await Timer(1, "us")
|
||||||
|
|
||||||
|
dut.i_nmi_ext.value = Immediate(1)
|
||||||
|
|
||||||
|
await Timer(1, "us")
|
||||||
@@ -15,6 +15,16 @@ addrmap verilog6502_io_regs {
|
|||||||
|
|
||||||
} core_ctrl @ 0x0;
|
} core_ctrl @ 0x0;
|
||||||
|
|
||||||
|
reg {
|
||||||
|
name = "nmi";
|
||||||
|
|
||||||
|
field {
|
||||||
|
name = "nmi";
|
||||||
|
desc = "";
|
||||||
|
hw = r;
|
||||||
|
sw = rw;
|
||||||
|
} nmi[31:16] = 0x200;
|
||||||
|
} nmi @ 0xff8;
|
||||||
|
|
||||||
reg {
|
reg {
|
||||||
name = "reset_brq";
|
name = "reset_brq";
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ module verilog6502_io_regs (
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
logic core_ctrl;
|
logic core_ctrl;
|
||||||
|
logic nmi;
|
||||||
logic reset_brq;
|
logic reset_brq;
|
||||||
} decoded_reg_strb_t;
|
} decoded_reg_strb_t;
|
||||||
decoded_reg_strb_t decoded_reg_strb;
|
decoded_reg_strb_t decoded_reg_strb;
|
||||||
@@ -103,6 +104,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.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;
|
||||||
end
|
end
|
||||||
@@ -124,6 +126,12 @@ module verilog6502_io_regs (
|
|||||||
logic load_next;
|
logic load_next;
|
||||||
} reset;
|
} reset;
|
||||||
} core_ctrl;
|
} core_ctrl;
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
logic [15:0] next;
|
||||||
|
logic load_next;
|
||||||
|
} nmi;
|
||||||
|
} nmi;
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
logic [15:0] next;
|
logic [15:0] next;
|
||||||
@@ -143,6 +151,11 @@ module verilog6502_io_regs (
|
|||||||
logic value;
|
logic value;
|
||||||
} reset;
|
} reset;
|
||||||
} core_ctrl;
|
} core_ctrl;
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
logic [15:0] value;
|
||||||
|
} nmi;
|
||||||
|
} nmi;
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
logic [15:0] value;
|
logic [15:0] value;
|
||||||
@@ -177,6 +190,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.nmi.nmi
|
||||||
|
always_comb begin
|
||||||
|
automatic logic [15:0] next_c;
|
||||||
|
automatic logic load_next_c;
|
||||||
|
next_c = field_storage.nmi.nmi.value;
|
||||||
|
load_next_c = '0;
|
||||||
|
if(decoded_reg_strb.nmi && decoded_req_is_wr) begin // SW write
|
||||||
|
next_c = (field_storage.nmi.nmi.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]);
|
||||||
|
load_next_c = '1;
|
||||||
|
end
|
||||||
|
field_combo.nmi.nmi.next = next_c;
|
||||||
|
field_combo.nmi.nmi.load_next = load_next_c;
|
||||||
|
end
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if(rst) begin
|
||||||
|
field_storage.nmi.nmi.value <= 16'h200;
|
||||||
|
end else begin
|
||||||
|
if(field_combo.nmi.nmi.load_next) begin
|
||||||
|
field_storage.nmi.nmi.value <= field_combo.nmi.nmi.next;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign hwif_out.nmi.nmi.value = field_storage.nmi.nmi.value;
|
||||||
// Field: verilog6502_io_regs.reset_brq.reset
|
// Field: verilog6502_io_regs.reset_brq.reset
|
||||||
always_comb begin
|
always_comb begin
|
||||||
automatic logic [15:0] next_c;
|
automatic logic [15:0] next_c;
|
||||||
@@ -247,6 +283,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'hff8) begin
|
||||||
|
readback_data_var[31:16] = field_storage.nmi.nmi.value;
|
||||||
|
end
|
||||||
if(rd_mux_addr == 12'hffc) begin
|
if(rd_mux_addr == 12'hffc) begin
|
||||||
readback_data_var[15:0] = field_storage.reset_brq.reset.value;
|
readback_data_var[15:0] = field_storage.reset_brq.reset.value;
|
||||||
readback_data_var[31:16] = field_storage.reset_brq.brk.value;
|
readback_data_var[31:16] = field_storage.reset_brq.brk.value;
|
||||||
|
|||||||
@@ -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 [15:0] value;
|
||||||
|
} verilog6502_io_regs__nmi__nmi__out_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
verilog6502_io_regs__nmi__nmi__out_t nmi;
|
||||||
|
} verilog6502_io_regs__nmi__out_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
logic [15:0] value;
|
logic [15:0] value;
|
||||||
} verilog6502_io_regs__reset_brq__reset__out_t;
|
} verilog6502_io_regs__reset_brq__reset__out_t;
|
||||||
@@ -30,6 +38,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__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;
|
||||||
endpackage
|
endpackage
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ module verilog6502_addr_decoder(
|
|||||||
input logic [7:0] i_cpu_data,
|
input logic [7:0] i_cpu_data,
|
||||||
output logic [7:0] o_cpu_data,
|
output logic [7:0] o_cpu_data,
|
||||||
input logic i_cpu_we,
|
input logic i_cpu_we,
|
||||||
/* verilator lint_off UNOPTFLAT */
|
input logic i_cpu_rdy,
|
||||||
output logic o_cpu_rdy,
|
output logic o_cpu_rdy,
|
||||||
/* verilator lint_on UNOPTFLAT */
|
|
||||||
|
|
||||||
|
|
||||||
output logic [15:0] o_mem_addr,
|
output logic [15:0] o_mem_addr,
|
||||||
@@ -95,28 +94,23 @@ always_comb begin
|
|||||||
o_mem_we = i_cpu_we & o_cpu_rdy;
|
o_mem_we = i_cpu_we & o_cpu_rdy;
|
||||||
o_mem_rd = ~i_cpu_we & o_cpu_rdy;
|
o_mem_rd = ~i_cpu_we & o_cpu_rdy;
|
||||||
prev_addr_next = MEM;
|
prev_addr_next = MEM;
|
||||||
// o_cpu_rdy = i_mem_rdy;
|
|
||||||
// o_cpu_data = i_mem_data;
|
|
||||||
end else if (i_cpu_addr < 16'hF000) begin
|
end else if (i_cpu_addr < 16'hF000) begin
|
||||||
o_external_addr = {4'b0, i_cpu_addr[11:0]};
|
o_external_addr = {4'b0, i_cpu_addr[11:0]};
|
||||||
o_external_data = i_cpu_data;
|
o_external_data = i_cpu_data;
|
||||||
o_external_we = i_cpu_we & o_cpu_rdy;
|
o_external_we = i_cpu_we & o_cpu_rdy;
|
||||||
o_external_rd = ~i_cpu_we & o_cpu_rdy;
|
o_external_rd = ~i_cpu_we & o_cpu_rdy;
|
||||||
prev_addr_next = EXT;
|
prev_addr_next = EXT;
|
||||||
// o_cpu_rdy = i_external_rdy;
|
|
||||||
// o_cpu_data = i_external_data;
|
|
||||||
end else begin
|
end else begin
|
||||||
o_io_addr = {4'b0, i_cpu_addr[11:0]};
|
o_io_addr = {4'b0, i_cpu_addr[11:0]};
|
||||||
o_io_data = i_cpu_data;
|
o_io_data = i_cpu_data;
|
||||||
o_io_we = i_cpu_we & o_cpu_rdy;
|
o_io_we = i_cpu_we & o_cpu_rdy;
|
||||||
o_io_rd = ~i_cpu_we & o_cpu_rdy;
|
o_io_rd = ~i_cpu_we & o_cpu_rdy;
|
||||||
prev_addr_next = IO;
|
prev_addr_next = IO;
|
||||||
// o_cpu_rdy = i_io_rdy;
|
|
||||||
// o_cpu_data = i_io_data;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (i_rst) begin
|
if (i_rst | ~i_cpu_rdy) begin
|
||||||
|
prev_addr_next = NONE;
|
||||||
o_mem_rd = 0;
|
o_mem_rd = 0;
|
||||||
o_mem_we = 0;
|
o_mem_we = 0;
|
||||||
o_external_rd = 0;
|
o_external_rd = 0;
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ logic [7:0] mem [4][14*1024];
|
|||||||
|
|
||||||
enum logic {CPU, EXT} sel, sel_next;
|
enum logic {CPU, EXT} sel, sel_next;
|
||||||
|
|
||||||
|
logic o_rdy_next;
|
||||||
|
|
||||||
logic [15:0] ram_addr;
|
logic [15:0] ram_addr;
|
||||||
logic [31:0] ram_wdata;
|
logic [31:0] ram_wdata;
|
||||||
logic [3:0] ram_wstrb;
|
logic [3:0] ram_wstrb;
|
||||||
@@ -87,12 +89,21 @@ logic ram_re;
|
|||||||
logic [31:0] ram_rdata;
|
logic [31:0] ram_rdata;
|
||||||
logic ram_rdata_valid;
|
logic ram_rdata_valid;
|
||||||
|
|
||||||
|
logic [1:0] latched_byte_select;
|
||||||
|
|
||||||
|
logic [15:0] pending_addr;
|
||||||
|
logic [7:0] pending_data;
|
||||||
|
logic pending_rd;
|
||||||
|
logic pending_we;
|
||||||
|
|
||||||
|
|
||||||
always_ff @(posedge i_clk) begin
|
always_ff @(posedge i_clk) begin
|
||||||
if (i_rst) begin
|
if (i_rst) begin
|
||||||
sel <= CPU;
|
sel <= CPU;
|
||||||
|
o_rdy <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
sel <= sel_next;
|
sel <= sel_next;
|
||||||
|
o_rdy <= o_rdy_next;
|
||||||
|
|
||||||
ram_rdata_valid <= '0;
|
ram_rdata_valid <= '0;
|
||||||
ram_rd_resp_last <= '0;
|
ram_rd_resp_last <= '0;
|
||||||
@@ -111,6 +122,26 @@ always_ff @(posedge i_clk) begin
|
|||||||
end
|
end
|
||||||
ram_rdata_valid <= '1;
|
ram_rdata_valid <= '1;
|
||||||
ram_rd_resp_last <= ram_cmd_last;
|
ram_rd_resp_last <= ram_cmd_last;
|
||||||
|
|
||||||
|
latched_byte_select <= ram_addr[1:0];
|
||||||
|
end
|
||||||
|
|
||||||
|
if (sel == EXT) begin
|
||||||
|
if (i_we) begin
|
||||||
|
pending_we <= '1;
|
||||||
|
pending_addr <= i_addr;
|
||||||
|
pending_data <= i_data;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (i_rd) begin
|
||||||
|
pending_rd <= '1;
|
||||||
|
pending_addr <= i_addr;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
pending_we <= '0;
|
||||||
|
pending_rd <= '0;
|
||||||
|
pending_addr <= '0;
|
||||||
|
pending_data <= '0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -129,12 +160,44 @@ always_comb begin
|
|||||||
ram_rd_resp_valid = '0;
|
ram_rd_resp_valid = '0;
|
||||||
ram_rd_resp_data = '0;
|
ram_rd_resp_data = '0;
|
||||||
|
|
||||||
|
o_rdy_next = '0;
|
||||||
|
o_data = '0;
|
||||||
|
|
||||||
case (sel)
|
case (sel)
|
||||||
CPU: begin
|
CPU: begin
|
||||||
// if there was no CPU op, then give external bus a chance
|
// if there was no CPU op, then give external bus a chance
|
||||||
if (~(i_rd | i_we)) begin
|
if (~(i_rd | i_we | pending_rd | pending_we)) begin
|
||||||
sel_next = EXT;
|
sel_next = EXT;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (i_we) begin
|
||||||
|
ram_addr = i_addr;
|
||||||
|
ram_wstrb = 4'b1 << i_addr[1:0];
|
||||||
|
ram_wdata = {24'b0, i_data} << (i_addr[1:0] * 8);
|
||||||
|
ram_we = '1;
|
||||||
|
o_rdy_next = '1;
|
||||||
|
end
|
||||||
|
if (pending_we) begin
|
||||||
|
ram_addr = pending_addr;
|
||||||
|
ram_wstrb = 4'b1 << pending_addr[1:0];
|
||||||
|
ram_wdata = {24'b0, pending_data} << (pending_addr[1:0] * 8);
|
||||||
|
ram_we = '1;
|
||||||
|
o_rdy_next = '1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (i_rd) begin
|
||||||
|
ram_addr = i_addr;
|
||||||
|
ram_re = '1;
|
||||||
|
o_rdy_next = '1;
|
||||||
|
end
|
||||||
|
if (pending_rd) begin
|
||||||
|
ram_addr = pending_addr;
|
||||||
|
ram_re = '1;
|
||||||
|
o_rdy_next = '1;
|
||||||
|
end
|
||||||
|
|
||||||
|
o_data = ram_rdata[8*latched_byte_select +: 8];
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
EXT: begin
|
EXT: begin
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ module verilog6502_wrapper(
|
|||||||
taxi_axi_if.wr_slv s_axi_wr,
|
taxi_axi_if.wr_slv s_axi_wr,
|
||||||
|
|
||||||
output logic o_irq_ext,
|
output logic o_irq_ext,
|
||||||
input logic i_irq_ext
|
input logic i_irq_ext,
|
||||||
|
input logic i_nmi_ext
|
||||||
);
|
);
|
||||||
|
|
||||||
taxi_apb_if internal_apb();
|
taxi_apb_if internal_apb();
|
||||||
@@ -66,12 +67,14 @@ logic cpu_we;
|
|||||||
logic cpu_irq;
|
logic cpu_irq;
|
||||||
logic cpu_nmi;
|
logic cpu_nmi;
|
||||||
logic cpu_rdy;
|
logic cpu_rdy;
|
||||||
|
logic cpu_rdy_o;
|
||||||
logic cpu_sync;
|
logic cpu_sync;
|
||||||
|
|
||||||
assign cpu_clk = clk;
|
assign cpu_clk = clk;
|
||||||
assign cpu_reset = hwif_out.core_ctrl.reset.value;
|
assign cpu_reset = hwif_out.core_ctrl.reset.value;
|
||||||
|
|
||||||
assign cpu_rdy = '1;
|
assign cpu_irq = i_irq_ext;
|
||||||
|
assign cpu_nmi = i_nmi_ext;
|
||||||
|
|
||||||
logic [15:0] mem_addr;
|
logic [15:0] mem_addr;
|
||||||
logic [7:0] mem_data_in;
|
logic [7:0] mem_data_in;
|
||||||
@@ -100,6 +103,7 @@ cpu_65c02 u_cpu_6502(
|
|||||||
.IRQ (cpu_irq),
|
.IRQ (cpu_irq),
|
||||||
.NMI (cpu_nmi),
|
.NMI (cpu_nmi),
|
||||||
.RDY (cpu_rdy),
|
.RDY (cpu_rdy),
|
||||||
|
.RDY_O (cpu_rdy_o),
|
||||||
.SYNC (cpu_sync)
|
.SYNC (cpu_sync)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -111,6 +115,7 @@ verilog6502_addr_decoder u_addr_decoder(
|
|||||||
.i_cpu_data (cpu_data_out),
|
.i_cpu_data (cpu_data_out),
|
||||||
.o_cpu_data (cpu_data_in),
|
.o_cpu_data (cpu_data_in),
|
||||||
.i_cpu_we (cpu_we),
|
.i_cpu_we (cpu_we),
|
||||||
|
.i_cpu_rdy (cpu_rdy_o),
|
||||||
.o_cpu_rdy (cpu_rdy),
|
.o_cpu_rdy (cpu_rdy),
|
||||||
|
|
||||||
.o_mem_addr (mem_addr),
|
.o_mem_addr (mem_addr),
|
||||||
|
|||||||
Submodule sub/verilog-6502 updated: ef2cc5ab45...8f19e45b40
Reference in New Issue
Block a user