`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    16:26:44 06/19/2006 
// Design Name: 
// Module Name:    sram_iface 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

`include "defines.v"

module sram_iface(clk_i, reset_i, data_i, data_o, addr_i, Breq_i, WR_i, reqp_o, Brdy_o, mem_d, mem_addr, sram_bs, sram_cs, flash_cs, mem_we, mem_oe);
    input [31:0] data_i;
    output [31:0] data_o;
    input [31:0] addr_i;
    input Breq_i;
    input WR_i;
    output reqp_o;
	 output Brdy_o;
    input clk_i;
    input reset_i;
    inout [31:0] mem_d;
    output [21:0] mem_addr;
    output [3:0] sram_bs;
    output sram_cs;
    output flash_cs;
    output mem_we;
    output mem_oe;

	reg [1:0] bstate;
	reg [31:0] val;
	wire myreq;
	 
	 	 /* Writing to SRAM:
	 -All byte select signals to 1 SRAM_BS[3:0]
	 -SRAM_CS=1
	 -MEM_WE to 1
	 */

	 /* Reading from SRAM:
	 -All byte select signals to 1 SRAM_BS[3:0]
	 -SRAM_CS=1
	 -MEM_OE to 1
	 */

	parameter ba = `RAM_BASE_ADDR;

	// FSM states
	parameter bs_idle = 2'd0;
	parameter bs_wait = 2'd1;
	parameter bs_ack	= 2'd2;
	parameter bs_next = 2'd3;
	
	// SRAM signals
	assign myreq=Breq_i && addr_i[31:19] == ba[31:19];
	assign sram_bs=(bstate==bs_wait || bstate==bs_ack)?4'b0:4'b1111;
	assign sram_cs=bstate==bs_idle;
	assign flash_cs=1;
	assign mem_we=sram_cs || !WR_i;
	assign mem_oe=sram_cs || WR_i;
	assign reqp_o=(myreq || bstate==bs_wait)?1:bstate==bs_ack?0:1'bz;
	assign Brdy_o=(myreq || bstate==bs_wait)?0:bstate==bs_ack?1:1'bz;
	assign mem_addr[21:0]=addr_i[31:0]-ba;
	assign data_o=(!mem_oe)?val:32'hZ;
	assign mem_d=(!mem_we)?data_i[31:0]:32'hZ;
	
	
	always @(posedge clk_i or posedge reset_i) begin
		if (reset_i)
			bstate<=bs_idle;
		else
			case (bstate)
				bs_idle:
					if (myreq)
						bstate<=bs_wait;
				bs_wait: begin
					val <= mem_d[31:0];
					bstate<=bs_ack;
				end
				bs_ack:
					bstate<=bs_next;
				bs_next:
					bstate<=bs_idle;
			endcase
	end
endmodule
