`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 12/01/2020 05:27:38 PM // Design Name: // Module Name: sram_controller // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module sram_controller( input clk, // 100MHz clock input reset, // resets the FSM input in_ready, // Tells this module to start an operation input sram_write, // FPGA says whether it wants to read(sram_write = 0) or write(sram_write = 1) to the SRAM input [35:0] data_to_write, // data to be written into the SRAM input [16:0] addr, // address you want to read or write at output reg [35:0] data_read, // the data outputted by the SRAM output reg out_ready = 1'b0, // Signals the main module the read/write is done output reg busy = 1'b0, // Tells the main module it is still preforming an operation output reg OE = 1'b0, // Connected to the OE pin of the SRAM output reg [2:0] CE = 3'b101, // 1,3 are active LOW, 2 is active HIGH, Connected to the CE pins of the SRAM output reg CEN = 1'b0, // Connected to the CEN pin of the SRAM output reg ZZ = 1'b0, // Connected to the ZZ pin of the SRAM output reg [3:0] BW = 4'b0000, // all inputs are active LOW, Connected to the BW[A:D] pins of the SRAM output reg mode = 1'b0, // Connected to the mode pin of the SRAM output reg WE = 1'b1, // Connected to the WE pin of the SRAM output reg ADV_LD = 1'b0, // Connected to the ADV/LD pin of the SRAM output sram_clk, // Connected to the CLK pin of the SRAM // SRAM IO inout [35:0] IO_bus, // Connected to the 36 data IO pins output reg [16:0] addr_bus // Connected to the 17 pin address bus of the SRAM ); reg [3:0] state_reg = 4'b0000; reg [35:0] data_bus = 35'b000000000000000000000000000000000000; assign IO_bus = (~OE) ? 36'bZ : data_bus;// If OE is LOW, then set the IO_bus to High Z so that the SRAM can control it, otherwise let the FPGA control it reg [2:0] writeCnt = 3'b000; reg [2:0] readCnt = 3'b000; parameter idle = 4'b0000; parameter write = 4'b0001; parameter read = 4'b0010; parameter finish = 4'b1000; //------------Desgin implementation------------ // State Machine always @(posedge sram_clk) begin if ( reset ) begin state_reg <= idle; end else case ( state_reg ) idle: begin if ( in_ready ) begin if ( sram_write ) state_reg <= write; else state_reg <= read; busy <= 1'b1; // Set FPGA to busy end out_ready <= 1'b0; // Set out_ready to False end write: begin if ( writeCnt == 0 ) begin CEN <= 1'b0;// Assert CEN CE <= 3'b010; // Select the device WE <= 1'b0; // Assert WE ADV_LD <= 1'b0; // Assert ADV/LD to set it into "load new address mode" addr_bus <= addr; // Write the address on the address bus end else if ( writeCnt == 1 ) begin OE <= 1'b1; // Deassert OE addr_bus <= 17'b11111111111111111; // Not sure if this is needed, but latch in an unused address CE <= 3'b101; // deselect the device end else if ( writeCnt == 2 ) begin data_bus <= data_to_write; // Write the data to the IO bus BW <= 4'b0000; // Assert all BW end else if ( writeCnt == 3 ) begin state_reg <= finish; writeCnt <= 0; end if ( writeCnt != 3 ) writeCnt <= writeCnt + 1; end read: begin if ( readCnt == 0 ) begin CEN <= 0; // Assert CEN CE <= 3'b010; // Select the device WE <= 1'b1; // Deassert WE ADV_LD <= 1'b0; // Assert ADV/LD to set it into "load new address mode" addr_bus <= addr; // Write the address on the address bus end else if ( readCnt == 1 ) begin OE <= 1'b0; // Asset OE data_read <= IO_bus; // Read data on the IO bus addr_bus <= 17'b11111111111111111; // Not sure if this is needed, but latch in an unused address CE <= 3'b101; // Deselect the device end else if ( readCnt == 2 ) begin state_reg <= finish; readCnt <= 0; end if ( readCnt != 2 ) readCnt <= readCnt + 1; end finish: begin out_ready <= 1'b1; // Set output ready signal to HIGH state_reg <= idle; busy <= 1'b0; // Set Busy to LOW end endcase end clk_wiz_0 clk_sram ( .clk_in1 (clk), // 100MHz clock .clk_out1 (sram_clk) // 100MHz clock ); endmodule