module extram_wb #(parameter PAGE_SIZE = 10, parameter ADDR_WIDTH = 16) (input clk, input rst, input wb_clk, input wb_rst, input cyc_i, input stb_i, input [ADDR_WIDTH-1:0] adr_i, input we_i, input [31:0] dat_i, output reg [31:0] dat_o, output reg ack_o, inout [17:0] RAM_D, output [PAGE_SIZE-2:0] RAM_A, output RAM_CE1n, output RAM_CENn, output RAM_CLK, output RAM_WEn, output RAM_OEn, output RAM_LDn ); wire read_acc = stb_i & cyc_i & ~we_i; wire write_acc = stb_i & cyc_i & we_i; wire acc = stb_i & cyc_i; assign RAM_CLK = ~wb_clk; // 50 MHz for now, eventually should be 200 MHz assign RAM_LDn = 0; // No burst for now assign RAM_CENn = 0; // Use CE1n as our main CE reg [PAGE_SIZE-2:1] RAM_addr_reg; always @(posedge wb_clk) if(acc) RAM_addr_reg[PAGE_SIZE-2:1] <= adr_i[PAGE_SIZE-1:2]; assign RAM_A[PAGE_SIZE-2:1] = RAM_addr_reg; reg [31:0] ram_out; always @(posedge wb_clk) if(write_acc) ram_out <= dat_i; // RAM access state machine localparam RAM_idle = 0; localparam RAM_read_1 = 1; localparam RAM_read_2 = 2; localparam RAM_read_3 = 3; localparam RAM_read_4 = 4; localparam RAM_write_1 = 6; localparam RAM_write_2 = 7; localparam RAM_write_3 = 8; localparam RAM_write_4 = 9; reg myOE = 0; reg RAM_OE = 0; reg RAM_WE = 0; reg RAM_EN = 0; reg RAM_A0_reg; reg [3:0] RAM_state; always @(posedge wb_clk) if(wb_rst) begin RAM_state <= RAM_idle; myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end else case(RAM_state) RAM_idle : if(read_acc & ~ack_o) begin RAM_state <= RAM_read_1; myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 0; end else if(write_acc & ~ack_o) begin RAM_state <= RAM_write_1; myOE <= 0; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 0; end else begin myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end RAM_read_1 : begin RAM_state <= RAM_read_2; myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 1; end RAM_read_2 : begin RAM_state <= RAM_read_3; myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end RAM_read_3 : begin RAM_state <= RAM_read_4; myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end RAM_read_4 : begin RAM_state <= RAM_idle; myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end RAM_write_1 : begin RAM_state <= RAM_write_2; myOE <= 1; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 1; end RAM_write_2 : begin RAM_state <= RAM_write_3; myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end RAM_write_3 : begin RAM_state <= RAM_write_4; myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end RAM_write_4 : begin RAM_state <= RAM_idle; myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0; end default : RAM_state <= RAM_idle; endcase // case(RAM_state) assign RAM_A[0] = RAM_A0_reg; assign RAM_WEn = ~RAM_WE; // ((RAM_state==RAM_write_1)||(RAM_state==RAM_write_2)); assign RAM_OEn = ~RAM_OE; assign RAM_CE1n = ~RAM_EN; // Active low (RAM_state != RAM_idle); assign RAM_D[17:16] = 2'bzz; assign RAM_D[15:0] = myOE ? ((RAM_state==RAM_write_2)?ram_out[15:0]:ram_out[31:16]) : 16'bzzzz_zzzz_zzzz_zzzz; always @(posedge wb_clk) if(RAM_state == RAM_read_3) dat_o[15:0] <= RAM_D[15:0]; else dat_o[31:16] <= RAM_D[15:0]; always @(posedge wb_clk) if(wb_rst) ack_o <= 0; else if((RAM_state == RAM_write_4)||(RAM_state == RAM_read_4)) ack_o <= 1; else ack_o <= 0; endmodule // extram_wb