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