163 lines
3.9 KiB
Systemverilog
163 lines
3.9 KiB
Systemverilog
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][14*1024];
|
|
|
|
|
|
enum logic {CPU, EXT} sel, sel_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;
|
|
|
|
|
|
always_ff @(posedge i_clk) begin
|
|
if (i_rst) begin
|
|
sel <= CPU;
|
|
end else begin
|
|
sel <= sel_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;
|
|
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;
|
|
|
|
case (sel)
|
|
CPU: begin
|
|
// if there was no CPU op, then give external bus a chance
|
|
if (~(i_rd | i_we)) begin
|
|
sel_next = EXT;
|
|
end
|
|
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 |