diff options
Diffstat (limited to 'fpga/usrp2/extram/extram_wb.v')
-rw-r--r-- | fpga/usrp2/extram/extram_wb.v | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/fpga/usrp2/extram/extram_wb.v b/fpga/usrp2/extram/extram_wb.v new file mode 100644 index 000000000..c8428783a --- /dev/null +++ b/fpga/usrp2/extram/extram_wb.v @@ -0,0 +1,146 @@ + +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 |