Move everything around
This commit is contained in:
1
src/embedded_wrapper/regs/gen_regs.sh
Executable file
1
src/embedded_wrapper/regs/gen_regs.sh
Executable file
@@ -0,0 +1 @@
|
||||
peakrdl regblock -o . --cpuif taxi-apb verilog6502_io_regs.rdl
|
||||
71
src/embedded_wrapper/regs/verilog6502_io_regs.rdl
Normal file
71
src/embedded_wrapper/regs/verilog6502_io_regs.rdl
Normal file
@@ -0,0 +1,71 @@
|
||||
addrmap verilog6502_io_regs {
|
||||
name = "";
|
||||
desc = "";
|
||||
|
||||
reg {
|
||||
name = "Core Control";
|
||||
desc = "";
|
||||
|
||||
field {
|
||||
name = "reset";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} reset[0:0] = 0x1;
|
||||
|
||||
field {
|
||||
name = "rdy";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} rdy[1:1] = 0x0;
|
||||
|
||||
} core_ctrl @ 0x0;
|
||||
|
||||
reg {
|
||||
name = "Core Status";
|
||||
desc = "";
|
||||
|
||||
field {
|
||||
name = "rdy_o";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = r;
|
||||
} rdy_o[0:0] = 0x0;
|
||||
|
||||
} core_status @ 0x4;
|
||||
|
||||
reg {
|
||||
name = "nmi";
|
||||
|
||||
field {
|
||||
name = "nmi";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} nmi[31:0] = 0x200;
|
||||
} nmi @ 0xff4;
|
||||
|
||||
reg {
|
||||
name = "reset";
|
||||
desc = "";
|
||||
|
||||
field {
|
||||
name = "reset";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} reset[31:0] = 0x200;
|
||||
} rst @ 0xff8;
|
||||
|
||||
reg {
|
||||
name = "brk";
|
||||
|
||||
field {
|
||||
name = "brq";
|
||||
desc = "";
|
||||
hw = r;
|
||||
sw = rw;
|
||||
} brk[31:0] = 0x200;
|
||||
} brk @ 0xffc;
|
||||
};
|
||||
346
src/embedded_wrapper/regs/verilog6502_io_regs.sv
Normal file
346
src/embedded_wrapper/regs/verilog6502_io_regs.sv
Normal file
@@ -0,0 +1,346 @@
|
||||
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
|
||||
// https://github.com/SystemRDL/PeakRDL-regblock
|
||||
|
||||
module verilog6502_io_regs (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
taxi_apb_if.slv s_apb,
|
||||
|
||||
output verilog6502_io_regs_pkg::verilog6502_io_regs__out_t hwif_out
|
||||
);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// CPU Bus interface logic
|
||||
//--------------------------------------------------------------------------
|
||||
logic cpuif_req;
|
||||
logic cpuif_req_is_wr;
|
||||
logic [11:0] cpuif_addr;
|
||||
logic [31:0] cpuif_wr_data;
|
||||
logic [31:0] cpuif_wr_biten;
|
||||
logic cpuif_req_stall_wr;
|
||||
logic cpuif_req_stall_rd;
|
||||
|
||||
logic cpuif_rd_ack;
|
||||
logic cpuif_rd_err;
|
||||
logic [31:0] cpuif_rd_data;
|
||||
|
||||
logic cpuif_wr_ack;
|
||||
logic cpuif_wr_err;
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
initial begin
|
||||
assert_bad_addr_width: assert($bits(s_apb.paddr) >= verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_MIN_ADDR_WIDTH)
|
||||
else $error("Interface address width of %0d is too small. Shall be at least %0d bits", $bits(s_apb.paddr), verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_MIN_ADDR_WIDTH);
|
||||
assert_bad_data_width: assert($bits(s_apb.pwdata) == verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_DATA_WIDTH)
|
||||
else $error("Interface data width of %0d is incorrect. Shall be %0d bits", $bits(s_apb.pwdata), verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_DATA_WIDTH);
|
||||
end
|
||||
`endif
|
||||
|
||||
// Request
|
||||
logic is_active;
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
is_active <= '0;
|
||||
cpuif_req <= '0;
|
||||
cpuif_req_is_wr <= '0;
|
||||
cpuif_addr <= '0;
|
||||
cpuif_wr_data <= '0;
|
||||
cpuif_wr_biten <= '0;
|
||||
end else begin
|
||||
if(~is_active) begin
|
||||
if(s_apb.psel) begin
|
||||
is_active <= '1;
|
||||
cpuif_req <= '1;
|
||||
cpuif_req_is_wr <= s_apb.pwrite;
|
||||
cpuif_addr <= {s_apb.paddr[11:2], 2'b0};
|
||||
cpuif_wr_data <= s_apb.pwdata;
|
||||
for(int i=0; i<4; i++) begin
|
||||
cpuif_wr_biten[i*8 +: 8] <= {8{s_apb.pstrb[i]}};
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
cpuif_req <= '0;
|
||||
if(cpuif_rd_ack || cpuif_wr_ack) begin
|
||||
is_active <= '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Response
|
||||
assign s_apb.pready = cpuif_rd_ack | cpuif_wr_ack;
|
||||
assign s_apb.prdata = cpuif_rd_data;
|
||||
assign s_apb.pslverr = cpuif_rd_err | cpuif_wr_err;
|
||||
|
||||
logic cpuif_req_masked;
|
||||
|
||||
// Read & write latencies are balanced. Stalls not required
|
||||
assign cpuif_req_stall_rd = '0;
|
||||
assign cpuif_req_stall_wr = '0;
|
||||
assign cpuif_req_masked = cpuif_req
|
||||
& !(!cpuif_req_is_wr & cpuif_req_stall_rd)
|
||||
& !(cpuif_req_is_wr & cpuif_req_stall_wr);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Address Decode
|
||||
//--------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
logic core_ctrl;
|
||||
logic core_status;
|
||||
logic nmi;
|
||||
logic rst;
|
||||
logic brk;
|
||||
} decoded_reg_strb_t;
|
||||
decoded_reg_strb_t decoded_reg_strb;
|
||||
logic decoded_err;
|
||||
logic [11:0] decoded_addr;
|
||||
logic decoded_req;
|
||||
logic decoded_req_is_wr;
|
||||
logic [31:0] decoded_wr_data;
|
||||
logic [31:0] decoded_wr_biten;
|
||||
|
||||
always_comb begin
|
||||
automatic logic is_valid_addr;
|
||||
automatic logic is_valid_rw;
|
||||
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.core_status = cpuif_req_masked & (cpuif_addr == 12'h4) & !cpuif_req_is_wr;
|
||||
decoded_reg_strb.nmi = cpuif_req_masked & (cpuif_addr == 12'hff4);
|
||||
decoded_reg_strb.rst = cpuif_req_masked & (cpuif_addr == 12'hff8);
|
||||
decoded_reg_strb.brk = cpuif_req_masked & (cpuif_addr == 12'hffc);
|
||||
decoded_err = '0;
|
||||
end
|
||||
|
||||
// Pass down signals to next stage
|
||||
assign decoded_addr = cpuif_addr;
|
||||
assign decoded_req = cpuif_req_masked;
|
||||
assign decoded_req_is_wr = cpuif_req_is_wr;
|
||||
assign decoded_wr_data = cpuif_wr_data;
|
||||
assign decoded_wr_biten = cpuif_wr_biten;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Field logic
|
||||
//--------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
struct {
|
||||
struct {
|
||||
logic next;
|
||||
logic load_next;
|
||||
} reset;
|
||||
struct {
|
||||
logic next;
|
||||
logic load_next;
|
||||
} rdy;
|
||||
} core_ctrl;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] next;
|
||||
logic load_next;
|
||||
} nmi;
|
||||
} nmi;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] next;
|
||||
logic load_next;
|
||||
} reset;
|
||||
} rst;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] next;
|
||||
logic load_next;
|
||||
} brk;
|
||||
} brk;
|
||||
} field_combo_t;
|
||||
field_combo_t field_combo;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
struct {
|
||||
logic value;
|
||||
} reset;
|
||||
struct {
|
||||
logic value;
|
||||
} rdy;
|
||||
} core_ctrl;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] value;
|
||||
} nmi;
|
||||
} nmi;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] value;
|
||||
} reset;
|
||||
} rst;
|
||||
struct {
|
||||
struct {
|
||||
logic [31:0] value;
|
||||
} brk;
|
||||
} brk;
|
||||
} field_storage_t;
|
||||
field_storage_t field_storage;
|
||||
|
||||
// Field: verilog6502_io_regs.core_ctrl.reset
|
||||
always_comb begin
|
||||
automatic logic [0:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.core_ctrl.reset.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.core_ctrl && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.core_ctrl.reset.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.core_ctrl.reset.next = next_c;
|
||||
field_combo.core_ctrl.reset.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.core_ctrl.reset.value <= 1'h1;
|
||||
end else begin
|
||||
if(field_combo.core_ctrl.reset.load_next) begin
|
||||
field_storage.core_ctrl.reset.value <= field_combo.core_ctrl.reset.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.core_ctrl.reset.value = field_storage.core_ctrl.reset.value;
|
||||
// Field: verilog6502_io_regs.core_ctrl.rdy
|
||||
always_comb begin
|
||||
automatic logic [0:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.core_ctrl.rdy.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.core_ctrl && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.core_ctrl.rdy.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.core_ctrl.rdy.next = next_c;
|
||||
field_combo.core_ctrl.rdy.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.core_ctrl.rdy.value <= 1'h0;
|
||||
end else begin
|
||||
if(field_combo.core_ctrl.rdy.load_next) begin
|
||||
field_storage.core_ctrl.rdy.value <= field_combo.core_ctrl.rdy.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.core_ctrl.rdy.value = field_storage.core_ctrl.rdy.value;
|
||||
assign hwif_out.core_status.rdy_o.value = 1'h0;
|
||||
// Field: verilog6502_io_regs.nmi.nmi
|
||||
always_comb begin
|
||||
automatic logic [31: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:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
|
||||
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 <= 32'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.rst.reset
|
||||
always_comb begin
|
||||
automatic logic [31:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.rst.reset.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.rst && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.rst.reset.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.rst.reset.next = next_c;
|
||||
field_combo.rst.reset.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.rst.reset.value <= 32'h200;
|
||||
end else begin
|
||||
if(field_combo.rst.reset.load_next) begin
|
||||
field_storage.rst.reset.value <= field_combo.rst.reset.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.rst.reset.value = field_storage.rst.reset.value;
|
||||
// Field: verilog6502_io_regs.brk.brk
|
||||
always_comb begin
|
||||
automatic logic [31:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.brk.brk.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.brk && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.brk.brk.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.brk.brk.next = next_c;
|
||||
field_combo.brk.brk.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.brk.brk.value <= 32'h200;
|
||||
end else begin
|
||||
if(field_combo.brk.brk.load_next) begin
|
||||
field_storage.brk.brk.value <= field_combo.brk.brk.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.brk.brk.value = field_storage.brk.brk.value;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Write response
|
||||
//--------------------------------------------------------------------------
|
||||
assign cpuif_wr_ack = decoded_req & decoded_req_is_wr;
|
||||
// Writes are always granted with no error response
|
||||
assign cpuif_wr_err = '0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Readback
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
logic [11:0] rd_mux_addr;
|
||||
assign rd_mux_addr = decoded_addr;
|
||||
|
||||
logic readback_err;
|
||||
logic readback_done;
|
||||
logic [31:0] readback_data;
|
||||
always_comb begin
|
||||
automatic logic [31:0] readback_data_var;
|
||||
readback_data_var = '0;
|
||||
if(rd_mux_addr == 12'h0) begin
|
||||
readback_data_var[0] = field_storage.core_ctrl.reset.value;
|
||||
readback_data_var[1] = field_storage.core_ctrl.rdy.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'h4) begin
|
||||
readback_data_var[0] = 1'h0;
|
||||
end
|
||||
if(rd_mux_addr == 12'hff4) begin
|
||||
readback_data_var[31:0] = field_storage.nmi.nmi.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'hff8) begin
|
||||
readback_data_var[31:0] = field_storage.rst.reset.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'hffc) begin
|
||||
readback_data_var[31:0] = field_storage.brk.brk.value;
|
||||
end
|
||||
readback_data = readback_data_var;
|
||||
readback_done = decoded_req & ~decoded_req_is_wr;
|
||||
readback_err = '0;
|
||||
end
|
||||
|
||||
assign cpuif_rd_ack = readback_done;
|
||||
assign cpuif_rd_data = readback_data;
|
||||
assign cpuif_rd_err = readback_err;
|
||||
endmodule
|
||||
62
src/embedded_wrapper/regs/verilog6502_io_regs_pkg.sv
Normal file
62
src/embedded_wrapper/regs/verilog6502_io_regs_pkg.sv
Normal file
@@ -0,0 +1,62 @@
|
||||
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
|
||||
// https://github.com/SystemRDL/PeakRDL-regblock
|
||||
|
||||
package verilog6502_io_regs_pkg;
|
||||
|
||||
localparam VERILOG6502_IO_REGS_DATA_WIDTH = 32;
|
||||
localparam VERILOG6502_IO_REGS_MIN_ADDR_WIDTH = 12;
|
||||
localparam VERILOG6502_IO_REGS_SIZE = 'h1000;
|
||||
|
||||
typedef struct {
|
||||
logic value;
|
||||
} verilog6502_io_regs__core_ctrl__reset__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic value;
|
||||
} verilog6502_io_regs__core_ctrl__rdy__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__core_ctrl__reset__out_t reset;
|
||||
verilog6502_io_regs__core_ctrl__rdy__out_t rdy;
|
||||
} verilog6502_io_regs__core_ctrl__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic value;
|
||||
} verilog6502_io_regs__core_status__rdy_o__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__core_status__rdy_o__out_t rdy_o;
|
||||
} verilog6502_io_regs__core_status__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic [31: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 {
|
||||
logic [31:0] value;
|
||||
} verilog6502_io_regs__rst__reset__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__rst__reset__out_t reset;
|
||||
} verilog6502_io_regs__rst__out_t;
|
||||
|
||||
typedef struct {
|
||||
logic [31:0] value;
|
||||
} verilog6502_io_regs__brk__brk__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__brk__brk__out_t brk;
|
||||
} verilog6502_io_regs__brk__out_t;
|
||||
|
||||
typedef struct {
|
||||
verilog6502_io_regs__core_ctrl__out_t core_ctrl;
|
||||
verilog6502_io_regs__core_status__out_t core_status;
|
||||
verilog6502_io_regs__nmi__out_t nmi;
|
||||
verilog6502_io_regs__rst__out_t rst;
|
||||
verilog6502_io_regs__brk__out_t brk;
|
||||
} verilog6502_io_regs__out_t;
|
||||
endpackage
|
||||
124
src/embedded_wrapper/verilog6502_addr_decoder.sv
Normal file
124
src/embedded_wrapper/verilog6502_addr_decoder.sv
Normal file
@@ -0,0 +1,124 @@
|
||||
module verilog6502_addr_decoder(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [31:0] i_cpu_addr,
|
||||
input logic [7:0] i_cpu_data,
|
||||
output logic [7:0] o_cpu_data,
|
||||
input logic i_cpu_we,
|
||||
input logic i_cpu_rdy,
|
||||
output logic o_cpu_rdy,
|
||||
|
||||
|
||||
output logic [15:0] o_mem_addr,
|
||||
output logic [7:0] o_mem_data,
|
||||
input logic [7:0] i_mem_data,
|
||||
output logic o_mem_rd,
|
||||
output logic o_mem_we,
|
||||
input logic i_mem_rdy,
|
||||
|
||||
output logic [31:0] o_external_addr,
|
||||
output logic [7:0] o_external_data,
|
||||
input logic [7:0] i_external_data,
|
||||
output logic o_external_rd,
|
||||
output logic o_external_we,
|
||||
input logic i_external_rdy,
|
||||
|
||||
output logic [11:0] o_io_addr,
|
||||
output logic [7:0] o_io_data,
|
||||
input logic [7:0] i_io_data,
|
||||
output logic o_io_rd,
|
||||
output logic o_io_we,
|
||||
input logic i_io_rdy
|
||||
);
|
||||
|
||||
enum logic [1:0] {NONE, MEM, EXT, IO} prev_addr, prev_addr_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
prev_addr <= NONE;
|
||||
end else begin
|
||||
prev_addr <= prev_addr_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
prev_addr_next = prev_addr;
|
||||
|
||||
o_mem_addr = '0;
|
||||
o_mem_data = '0;
|
||||
o_mem_rd = '0;
|
||||
o_mem_we = '0;
|
||||
|
||||
o_external_addr = '0;
|
||||
o_external_data = '0;
|
||||
o_external_rd = '0;
|
||||
o_external_we = '0;
|
||||
|
||||
o_io_addr = '0;
|
||||
o_io_data = '0;
|
||||
o_io_rd = '0;
|
||||
o_io_we = '0;
|
||||
|
||||
case (prev_addr)
|
||||
NONE: begin
|
||||
o_cpu_rdy = '1;
|
||||
o_cpu_data = '0;
|
||||
end
|
||||
|
||||
MEM: begin
|
||||
o_cpu_rdy = i_mem_rdy;
|
||||
o_cpu_data = i_mem_data;
|
||||
end
|
||||
|
||||
EXT: begin
|
||||
o_cpu_rdy = i_external_rdy;
|
||||
o_cpu_data = i_external_data;
|
||||
end
|
||||
|
||||
IO: begin
|
||||
o_cpu_rdy = i_io_rdy;
|
||||
o_cpu_data = i_io_data;
|
||||
end
|
||||
|
||||
default: begin
|
||||
o_cpu_rdy = '1;
|
||||
o_cpu_data = '0;
|
||||
end
|
||||
endcase
|
||||
|
||||
if (o_cpu_rdy) begin
|
||||
if (i_cpu_addr < 32'hFFFF) begin
|
||||
o_mem_addr = i_cpu_addr[15:0];
|
||||
o_mem_data = i_cpu_data;
|
||||
o_mem_we = i_cpu_we & o_cpu_rdy;
|
||||
o_mem_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = MEM;
|
||||
end else if (i_cpu_addr < 32'hFFFFEFFF) begin
|
||||
o_external_addr = i_cpu_addr;
|
||||
o_external_data = i_cpu_data;
|
||||
o_external_we = i_cpu_we & o_cpu_rdy;
|
||||
o_external_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = EXT;
|
||||
end else begin
|
||||
o_io_addr = i_cpu_addr[11:0];
|
||||
o_io_data = i_cpu_data;
|
||||
o_io_we = i_cpu_we & o_cpu_rdy;
|
||||
o_io_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = IO;
|
||||
end
|
||||
end
|
||||
|
||||
if (i_rst | ~i_cpu_rdy) begin
|
||||
prev_addr_next = NONE;
|
||||
o_mem_rd = 0;
|
||||
o_mem_we = 0;
|
||||
o_external_rd = 0;
|
||||
o_external_we = 0;
|
||||
o_io_rd = 0;
|
||||
o_io_we = 0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
120
src/embedded_wrapper/verilog6502_apb_adapter.sv
Normal file
120
src/embedded_wrapper/verilog6502_apb_adapter.sv
Normal file
@@ -0,0 +1,120 @@
|
||||
module verilog6502_apb_adapter #(
|
||||
parameter ADDR_WIDTH = 32
|
||||
)(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [ADDR_WIDTH-1: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,
|
||||
|
||||
taxi_apb_if.mst m_apb
|
||||
);
|
||||
|
||||
localparam APB_ADDR_WIDTH = m_apb.ADDR_W;
|
||||
|
||||
enum logic {IDLE, ENABLE} state, state_next;
|
||||
|
||||
logic [ADDR_WIDTH-1:0] latched_addr, latched_addr_next;
|
||||
logic [ADDR_WIDTH-1:0] second_addr, second_addr_next;
|
||||
logic second_we, second_rd, second_we_next, second_rd_next;
|
||||
logic [7:0] latched_data, latched_data_next;
|
||||
logic [7:0] second_data, second_data_next;
|
||||
logic latched_pwrite, latched_pwrite_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
state <= IDLE;
|
||||
latched_addr <= '0;
|
||||
second_addr <= '0;
|
||||
second_we <= '0;
|
||||
second_rd <= '0;
|
||||
latched_data <= '0;
|
||||
latched_pwrite <= '0;
|
||||
second_data <= '0;
|
||||
end else begin
|
||||
state <= state_next;
|
||||
latched_addr <= latched_addr_next;
|
||||
second_addr <= second_addr_next;
|
||||
second_we <= second_we_next;
|
||||
second_rd <= second_rd_next;
|
||||
latched_data <= latched_data_next;
|
||||
latched_pwrite <= latched_pwrite_next;
|
||||
second_data <= second_data_next;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always_comb begin
|
||||
|
||||
|
||||
case (state)
|
||||
IDLE: begin
|
||||
if (i_rd | i_we) begin
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = APB_ADDR_WIDTH'({i_addr[ADDR_WIDTH-1:2], 2'b0});
|
||||
m_apb.psel = '1;
|
||||
m_apb.pwrite = i_we;
|
||||
m_apb.pstrb = 4'h1 << i_addr[1:0]; // shift based on lower 2 bits
|
||||
m_apb.pwdata = {24'b0, i_data} << i_addr[1:0];
|
||||
o_rdy = '0;
|
||||
|
||||
m_apb.penable = '0;
|
||||
state_next = ENABLE;
|
||||
latched_addr_next = i_addr;
|
||||
latched_data_next = i_data;
|
||||
latched_pwrite_next = i_we;
|
||||
end else if (second_rd | second_we) begin
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = APB_ADDR_WIDTH'({second_addr[ADDR_WIDTH-1:2], 2'b0});
|
||||
m_apb.psel = '1;
|
||||
m_apb.pwrite = second_we;
|
||||
m_apb.pstrb = 4'h1 << second_addr[1:0]; // shift based on lower 2 bits
|
||||
m_apb.pwdata = {24'b0, second_data} << second_addr[1:0];
|
||||
o_rdy = '0;
|
||||
|
||||
m_apb.penable = '0;
|
||||
state_next = ENABLE;
|
||||
latched_addr_next = second_addr;
|
||||
latched_data_next = second_data;
|
||||
latched_pwrite_next = second_we;
|
||||
end else begin
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = '0;
|
||||
m_apb.psel = '0;
|
||||
m_apb.pwrite = '0;
|
||||
m_apb.pstrb = '0;
|
||||
m_apb.pwdata = '0;
|
||||
o_rdy = '0;
|
||||
end
|
||||
end
|
||||
|
||||
ENABLE: begin
|
||||
m_apb.penable = '1;
|
||||
|
||||
second_we_next = i_we;
|
||||
second_rd_next = i_rd;
|
||||
second_addr_next = i_addr;
|
||||
second_data_next = i_data;
|
||||
|
||||
m_apb.pprot = '0;
|
||||
m_apb.paddr = APB_ADDR_WIDTH'({latched_addr[ADDR_WIDTH-1:2], 2'b0});
|
||||
m_apb.psel = '1;
|
||||
m_apb.pwrite = latched_pwrite;
|
||||
m_apb.pstrb = 4'h1 << latched_addr[1:0]; // shift based on lower 2 bits
|
||||
m_apb.pwdata = {24'b0, latched_data} << latched_addr[1:0];
|
||||
|
||||
if (m_apb.pready) begin
|
||||
state_next = IDLE;
|
||||
o_data = m_apb.prdata[8 * latched_addr[1:0] +: 8];
|
||||
o_rdy = '1;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
59
src/embedded_wrapper/verilog6502_external_memory.sv
Normal file
59
src/embedded_wrapper/verilog6502_external_memory.sv
Normal file
@@ -0,0 +1,59 @@
|
||||
module verilog6502_external_memory (
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [31: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,
|
||||
|
||||
|
||||
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 = internal_apb.paddr;
|
||||
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
|
||||
226
src/embedded_wrapper/verilog6502_internal_memory.sv
Normal file
226
src/embedded_wrapper/verilog6502_internal_memory.sv
Normal file
@@ -0,0 +1,226 @@
|
||||
module verilog6502_internal_memory(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
taxi_axi_if.rd_slv s_axi_rd,
|
||||
taxi_axi_if.wr_slv s_axi_wr,
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
localparam ID_W = 8;
|
||||
localparam ADDR_W = 32;
|
||||
localparam AUSER_W = 1;
|
||||
localparam RUSER_W = 1;
|
||||
localparam WUSER_W = 1;
|
||||
localparam DATA_W = 32;
|
||||
localparam STRB_W = 4;
|
||||
|
||||
logic [ID_W-1:0] ram_cmd_id;
|
||||
logic [ADDR_W-1:0] ram_cmd_addr;
|
||||
logic [DATA_W-1:0] ram_cmd_wr_data;
|
||||
logic [STRB_W-1:0] ram_cmd_wr_strb;
|
||||
logic ram_cmd_wr_en;
|
||||
logic ram_cmd_rd_en;
|
||||
logic ram_cmd_last;
|
||||
logic ram_cmd_ready;
|
||||
logic [DATA_W-1:0] ram_rd_resp_data;
|
||||
logic ram_rd_resp_last;
|
||||
logic ram_rd_resp_valid;
|
||||
logic ram_rd_resp_ready;
|
||||
|
||||
taxi_axi_ram_if_rdwr #(
|
||||
.DATA_W(DATA_W),
|
||||
.ADDR_W(ADDR_W),
|
||||
.STRB_W(STRB_W),
|
||||
.ID_W(ID_W),
|
||||
.AUSER_W(AUSER_W),
|
||||
.WUSER_W(WUSER_W),
|
||||
.RUSER_W(RUSER_W)
|
||||
) axi_ram_if_rdwr (
|
||||
.clk (i_clk),
|
||||
.rst (i_rst),
|
||||
|
||||
.s_axi_wr (s_axi_wr),
|
||||
.s_axi_rd (s_axi_rd),
|
||||
|
||||
.ram_cmd_id (ram_cmd_id),
|
||||
.ram_cmd_addr (ram_cmd_addr),
|
||||
.ram_cmd_lock (),
|
||||
.ram_cmd_cache (),
|
||||
.ram_cmd_prot (),
|
||||
.ram_cmd_qos (),
|
||||
.ram_cmd_region (),
|
||||
.ram_cmd_auser (),
|
||||
.ram_cmd_wr_data (ram_cmd_wr_data),
|
||||
.ram_cmd_wr_strb (ram_cmd_wr_strb),
|
||||
.ram_cmd_wr_user (),
|
||||
.ram_cmd_wr_en (ram_cmd_wr_en),
|
||||
.ram_cmd_rd_en (ram_cmd_rd_en),
|
||||
.ram_cmd_last (ram_cmd_last),
|
||||
.ram_cmd_ready (ram_cmd_ready),
|
||||
.ram_rd_resp_id (),
|
||||
.ram_rd_resp_data (ram_rd_resp_data),
|
||||
.ram_rd_resp_last (ram_rd_resp_last),
|
||||
.ram_rd_resp_user (),
|
||||
.ram_rd_resp_valid (ram_rd_resp_valid),
|
||||
.ram_rd_resp_ready (ram_rd_resp_ready)
|
||||
);
|
||||
|
||||
|
||||
logic [7:0] mem [4][16*1024];
|
||||
|
||||
|
||||
enum logic {CPU, EXT} sel, sel_next;
|
||||
|
||||
logic o_rdy_next;
|
||||
|
||||
logic [15:0] ram_addr;
|
||||
logic [31:0] ram_wdata;
|
||||
logic [3:0] ram_wstrb;
|
||||
logic ram_we;
|
||||
|
||||
logic ram_re;
|
||||
logic [31:0] ram_rdata;
|
||||
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
|
||||
if (i_rst) begin
|
||||
sel <= CPU;
|
||||
o_rdy <= '0;
|
||||
end else begin
|
||||
sel <= sel_next;
|
||||
o_rdy <= o_rdy_next;
|
||||
|
||||
ram_rdata_valid <= '0;
|
||||
ram_rd_resp_last <= '0;
|
||||
|
||||
if (ram_we) begin
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
if (ram_wstrb[i]) begin
|
||||
mem[i][ram_addr[15:2]] <= ram_wdata[8*i +: 8];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (ram_re) begin
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
ram_rdata[8*i +: 8] <= mem[i][ram_addr[15:2]];
|
||||
end
|
||||
ram_rdata_valid <= '1;
|
||||
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
|
||||
|
||||
always_comb begin
|
||||
sel_next = sel;
|
||||
|
||||
ram_cmd_ready = '0;
|
||||
|
||||
ram_addr = '0;
|
||||
ram_we = '0;
|
||||
ram_wdata = '0;
|
||||
ram_we = '0;
|
||||
ram_re = '0;
|
||||
|
||||
ram_rd_resp_valid = '0;
|
||||
ram_rd_resp_data = '0;
|
||||
|
||||
o_rdy_next = '0;
|
||||
o_data = '0;
|
||||
|
||||
case (sel)
|
||||
CPU: begin
|
||||
// if there was no CPU op, then give external bus a chance
|
||||
if (~(i_rd | i_we | pending_rd | pending_we)) begin
|
||||
sel_next = EXT;
|
||||
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
|
||||
|
||||
EXT: begin
|
||||
ram_cmd_ready = '1;
|
||||
|
||||
if (ram_cmd_wr_en) begin
|
||||
ram_addr = ram_cmd_addr[15:0];
|
||||
ram_wdata = ram_cmd_wr_data;
|
||||
ram_wstrb = ram_cmd_wr_strb;
|
||||
ram_we = '1;
|
||||
end else if (ram_cmd_rd_en) begin
|
||||
ram_addr = ram_cmd_addr[15:0];
|
||||
ram_re = '1;
|
||||
|
||||
end else begin
|
||||
sel_next = CPU;
|
||||
end
|
||||
|
||||
ram_rd_resp_valid = ram_rdata_valid;
|
||||
ram_rd_resp_data = ram_rdata;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
205
src/embedded_wrapper/verilog6502_wrapper.sv
Normal file
205
src/embedded_wrapper/verilog6502_wrapper.sv
Normal file
@@ -0,0 +1,205 @@
|
||||
// Wrapper around verilog-6502
|
||||
|
||||
// memory map:
|
||||
// 0x00000000-0x000000FF Zero Page (Hard coded)
|
||||
// 0x00000100-0x000001FF Stack (Hard coded)
|
||||
// 0x00000200-0x0000FFFF Internal Memory
|
||||
// 0x00010000-0xFFFFEFFF External AXI
|
||||
// 0xFFFFF000-0xFFFFFFFF Processor IO
|
||||
|
||||
module verilog6502_wrapper(
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
taxi_apb_if.slv s_apb,
|
||||
|
||||
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,
|
||||
|
||||
output logic o_irq_ext,
|
||||
input logic i_irq_ext,
|
||||
input logic i_nmi_ext
|
||||
);
|
||||
|
||||
taxi_apb_if internal_apb();
|
||||
|
||||
taxi_apb_if s_apb_mux[2]();
|
||||
taxi_apb_if m_apb_mux[1]();
|
||||
taxi_apb_if m_apb();
|
||||
|
||||
taxi_apb_tie u_external_apb_tie(
|
||||
.s_apb(s_apb),
|
||||
.m_apb(s_apb_mux[0])
|
||||
);
|
||||
|
||||
taxi_apb_tie u_internal_apb_tie(
|
||||
.s_apb(internal_apb),
|
||||
.m_apb(s_apb_mux[1])
|
||||
);
|
||||
|
||||
taxi_apb_tie u_master_apb_tie(
|
||||
.s_apb(m_apb_mux[0]),
|
||||
.m_apb(m_apb)
|
||||
);
|
||||
|
||||
taxi_apb_interconnect #(
|
||||
.S_CNT(2),
|
||||
.M_CNT(1),
|
||||
.ADDR_W(32)
|
||||
) u_apb_interconnect (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
|
||||
.s_apb (s_apb_mux),
|
||||
.m_apb (m_apb_mux)
|
||||
);
|
||||
|
||||
|
||||
logic cpu_clk;
|
||||
logic cpu_reset;
|
||||
logic [31:0] cpu_addr;
|
||||
logic [7:0] cpu_data_in;
|
||||
logic [7:0] cpu_data_out;
|
||||
|
||||
logic cpu_we;
|
||||
logic cpu_irq;
|
||||
logic cpu_nmi;
|
||||
logic cpu_rdy;
|
||||
logic cpu_rdy_o;
|
||||
logic cpu_sync;
|
||||
|
||||
assign cpu_clk = clk;
|
||||
assign cpu_reset = hwif_out.core_ctrl.reset.value;
|
||||
|
||||
assign cpu_irq = i_irq_ext;
|
||||
assign cpu_nmi = i_nmi_ext;
|
||||
|
||||
logic [15:0] mem_addr;
|
||||
logic [7:0] mem_data_in;
|
||||
logic [7:0] mem_data_out;
|
||||
logic mem_rd;
|
||||
logic mem_we;
|
||||
logic mem_rdy;
|
||||
|
||||
logic [31: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 [11:0] io_addr;
|
||||
logic [7:0] io_data_in;
|
||||
logic [7:0] io_data_out;
|
||||
logic io_rd;
|
||||
logic io_we;
|
||||
logic io_rdy;
|
||||
|
||||
verilog6502_io_regs_pkg::verilog6502_io_regs__out_t hwif_out;
|
||||
|
||||
cpu_65c02 u_cpu_6502(
|
||||
.clk (cpu_clk),
|
||||
.reset (cpu_reset),
|
||||
|
||||
.AB (cpu_addr),
|
||||
.DI (cpu_data_in),
|
||||
.DO (cpu_data_out),
|
||||
.WE (cpu_we),
|
||||
.IRQ (cpu_irq),
|
||||
.NMI (cpu_nmi),
|
||||
.RDY (cpu_rdy),
|
||||
.RDY_O (cpu_rdy_o),
|
||||
.SYNC (cpu_sync)
|
||||
);
|
||||
|
||||
verilog6502_addr_decoder u_addr_decoder(
|
||||
.i_clk (cpu_clk),
|
||||
.i_rst (cpu_reset),
|
||||
|
||||
.i_cpu_addr (cpu_addr),
|
||||
.i_cpu_data (cpu_data_out),
|
||||
.o_cpu_data (cpu_data_in),
|
||||
.i_cpu_we (cpu_we),
|
||||
.i_cpu_rdy (cpu_rdy_o),
|
||||
.o_cpu_rdy (cpu_rdy),
|
||||
|
||||
.o_mem_addr (mem_addr),
|
||||
.o_mem_data (mem_data_in),
|
||||
.i_mem_data (mem_data_out),
|
||||
.o_mem_rd (mem_rd),
|
||||
.o_mem_we (mem_we),
|
||||
.i_mem_rdy (mem_rdy),
|
||||
|
||||
.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),
|
||||
.i_io_data (io_data_out),
|
||||
.o_io_rd (io_rd),
|
||||
.o_io_we (io_we),
|
||||
.i_io_rdy (io_rdy)
|
||||
);
|
||||
|
||||
verilog6502_internal_memory u_internal_memory(
|
||||
.i_clk (cpu_clk),
|
||||
.i_rst (rst),
|
||||
|
||||
.s_axi_rd (s_axi_rd),
|
||||
.s_axi_wr (s_axi_wr),
|
||||
|
||||
.i_addr (mem_addr),
|
||||
.i_data (mem_data_in),
|
||||
.o_data (mem_data_out),
|
||||
.i_rd (mem_rd),
|
||||
.i_we (mem_we),
|
||||
.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),
|
||||
|
||||
.m_axil_rd (m_axil_rd),
|
||||
.m_axil_wr (m_axil_wr)
|
||||
);
|
||||
|
||||
verilog6502_apb_adapter #(
|
||||
.ADDR_WIDTH(12)
|
||||
) u_io_apb_adapter(
|
||||
.i_clk (cpu_clk),
|
||||
.i_rst (rst),
|
||||
|
||||
.i_addr (io_addr),
|
||||
.i_data (io_data_in),
|
||||
.o_data (io_data_out),
|
||||
.i_rd (io_rd),
|
||||
.i_we (io_we),
|
||||
.o_rdy (io_rdy),
|
||||
|
||||
.m_apb (internal_apb)
|
||||
);
|
||||
|
||||
|
||||
verilog6502_io_regs u_io_regs (
|
||||
.clk (cpu_clk),
|
||||
.rst (rst),
|
||||
.s_apb (m_apb),
|
||||
|
||||
.hwif_out (hwif_out)
|
||||
);
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user