diff options
Diffstat (limited to 'design')
-rw-r--r-- | design/sram_slave.v | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/design/sram_slave.v b/design/sram_slave.v new file mode 100644 index 0000000..bcc2f1b --- /dev/null +++ b/design/sram_slave.v @@ -0,0 +1,106 @@ +`default_nettype none + +module sram_wb_slave + ( + /* Interface to memory */ + output wire [17:0] sram_addr, + inout wire [15:0] sram_io, + + output wire sram_cs_n, + output wire sram_oe_n, + output wire sram_we_n, + + /* Wishbone slave interface */ + output wire ACK_O, + input wire [17:0] ADR_I, + input wire CLK_I, + input wire [15:0] DAT_I, + output wire [15:0] DAT_O, + input wire RST_I, + input wire STB_I, + input wire WE_I, + output wire STALL_O + ); + + reg writing; + reg [15:0] write_data; + assign sram_io = sram_we_n ? 16'hZZZZ : write_data; + + reg sram_cs_not; + reg sram_oe_not; + reg sram_we_not; + assign sram_cs_n = sram_cs_not; + assign sram_oe_n = sram_oe_not; + assign sram_we_n = sram_we_not; + + reg [17:0] address; + assign sram_addr = address; + + reg ack; + assign ACK_O = ack; + + reg stall; + assign STALL_O = stall; + + reg [15:0] output_data; + assign DAT_O = output_data; + + reg [2:0] state; + + always @ (posedge CLK_I) begin + output_data <= sram_io; + + if (RST_I) begin + sram_cs_not <= 1; + sram_oe_not <= 1; + writing <= 0; + + ack <= 0; + stall <= 0; + + state <= 0; + end else begin + if (state == 0 || state == 2) begin /* possibly starting new job */ + if (STB_I) begin + address <= ADR_I; + + sram_cs_not <= 0; + sram_oe_not <= WE_I; + writing <= WE_I; + write_data <= DAT_I; + + state <= WE_I ? 1 : 2; + stall <= WE_I ? 1 : 0; + end else begin // if (STB_I) + sram_cs_not <= 1; + sram_oe_not <= 1; + writing <= 0; + + state <= 0; + end + end // if (state == 0 || state == 2) + + if (state == 1) begin /* performing write; it takes 2 CLK_I cycles */ + state <= 2; + stall <= 0; + end + + if (state == 2) begin /* finishing job */ + ack <= 1; + end else begin + ack <= 0; + end + end + end // always @ (posedge CLK_I) + + /* + * avoid bus congestion by only driving sram_io + * during the middle part of write cycle + */ + always @ (negedge CLK_I) begin + if (writing) + sram_we_not <= !sram_we_not; + else + sram_we_not <= 1; + end +endmodule // sram_wb_slave |