//////////////////////////////////////////////////////////////////////////////// // // Create Date: 09/20/08 // Module Name: base // Description: psramfifo.v - Using the external PSRAM for large FIFO // // // Revision: // Revision 0.01 - File Created // // File format: This file has been formated to use tabstop of 4 // // Development platform: Spartan-3 Nexys from Digilent // // Copyright (C) 2008, Rick Huang // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // //////////////////////////////////////////////////////////////////////////////// module PSRAM_FIFO (mclk, reset, RamAdv, RamCS, RamClk, RamCRE, // RAM interface RamLB, RamUB, RamWait, FlashRp, FlashCS, MemDB, MemOE, MemWR, MemAdr, FifoFull, FifoEmpty, FifoRead, FifoWrite, FifoReadAck, FifoWriteAck, FifoData_i, FifoData_o ); // Basic connections input mclk; input reset; // RAM connection output RamAdv; output RamCS; output RamClk; output RamCRE; output RamLB, RamUB; input RamWait; // ROM connection output FlashRp; output FlashCS; // Shared connection between RAM and ROM output MemOE; output MemWR; output [23:1] MemAdr; inout [15:0] MemDB; // Fifo Connection output FifoFull; // High = Fifo Full output FifoEmpty; // High = Fifo Empty input FifoRead; // High = Start a read cycle input FifoWrite; // High = Start a write cycle output FifoReadAck; // Goes high to ack a start of read cycle // goes low when data is ready in output register output FifoWriteAck; // Goes high to ack a start of write cycle, // goes low when data is written input [15:0] FifoData_i; // Data input output [15:0] FifoData_o; // ************************************************************************ // Adding some registers reg FifoReadAck; reg FifoWriteAck; reg [15:0] FifoData_o; reg FifoFull; reg FifoEmpty; // ************************************************************************ // Taking care of the connection to memory bus, tie off the ROM signals // Not using the ROM, disable it assign FlashRp = 0; // Deep power down assign FlashCS = 1; // Remap the RAM assign RamClk = 0; // Set in ASYNC mode first... assign RamAdv = 0; // Low = valid address, low to high - Hold address assign RamLB = 0; assign RamUB = 0; assign RamCRE = 0; // Split the memory bus into directional signals // Apply register to some of external signals reg [22:0] MemAddr_int; assign MemAdr[23:1] = MemAddr_int[22:0]; reg MemWR; reg MemOE; reg RamCS; wire [15:0] MemDB_i; assign MemDB = (MemWR == 0) ? FifoData_i : 16'hzzzz; assign MemDB_i = MemDB; // ************************************************************************ // Making a FIFO... parameter RAM_STATE_IDLE = 0; parameter RAM_STATE_WR0 = 1; parameter RAM_STATE_WR1 = 2; parameter RAM_STATE_WR2 = 3; parameter RAM_STATE_WR3 = 4; parameter RAM_STATE_RD0 = 5; parameter RAM_STATE_RD1 = 6; parameter RAM_STATE_RD2 = 7; parameter RAM_STATE_RD3 = 8; reg [3:0] ram_state; reg [22:0] ram_head; reg [22:0] ram_head_add1; reg [22:0] ram_tail; wire fifo_empty_int; wire fifo_full_int; assign fifo_empty_int = (ram_head == ram_tail); assign fifo_full_int = (ram_head_add1 == ram_tail); // Optimized for speed //assign fifo_full_int = ((ram_head + 1) == ram_tail); // Optimized for area always @ (posedge mclk) begin if(reset) begin ram_state <= RAM_STATE_IDLE; ram_head <= 0; ram_tail <= 0; FifoEmpty <= 1; FifoFull <= 0; RamCS <= 1; MemOE <= 1; MemWR <= 1; end else begin case (ram_state) RAM_STATE_IDLE: begin if(FifoWrite) begin MemAddr_int <= ram_head; MemOE <= 1; MemWR <= 0; RamCS <= 0; FifoWriteAck <= 1; ram_state <= RAM_STATE_WR0; end else if(FifoRead) begin MemAddr_int <= ram_tail; MemOE <= 0; MemWR <= 1; RamCS <= 0; FifoReadAck <= 1; ram_state <= RAM_STATE_RD0; end else begin RamCS <= 1; MemOE <= 1; MemWR <= 1; end end RAM_STATE_WR0: begin ram_state <= RAM_STATE_WR1; end RAM_STATE_WR1: begin ram_state <= RAM_STATE_WR2; ram_head <= ram_head + 1; ram_head_add1 <= ram_head + 2; // If not enough silicon, this can be removed end RAM_STATE_WR2: begin ram_state <= RAM_STATE_WR3; FifoFull <= fifo_full_int; FifoEmpty <= fifo_empty_int; end RAM_STATE_WR3: begin MemWR <= 1; RamCS <= 1; FifoWriteAck <= 0; ram_state <= RAM_STATE_IDLE; end RAM_STATE_RD0: begin ram_state <= RAM_STATE_RD1; end RAM_STATE_RD1: begin ram_state <= RAM_STATE_RD2; ram_tail <= ram_tail + 1; end RAM_STATE_RD2: begin ram_state <= RAM_STATE_RD3; FifoFull <= fifo_full_int; FifoEmpty <= fifo_empty_int; end RAM_STATE_RD3: begin FifoData_o <= MemDB_i; RamCS <= 1; FifoReadAck <= 0; ram_state <= RAM_STATE_IDLE; end endcase end end endmodule