module FIFO( input i_Clock, input i_writeDataReady_Flash, input [WIDTH_BITS-1:0] i_writeData, input [$clog2(DEPTH_WORDS)-1:0] i_almostFullLevel, output o_almostFull, output o_Full, input i_doRead_Flash, output reg o_readDataReady, output reg [WIDTH_BITS-1:0] o_readData, input [$clog2(DEPTH_WORDS)-1:0] i_almostEmptyLevel, output o_almostEmpty, output o_Empty, input i_Reset_Low ); parameter WIDTH_BITS = 8; parameter DEPTH_WORDS = 16; reg [WIDTH_BITS-1:0] r_RAM [DEPTH_WORDS-1:0]; reg [$clog2(DEPTH_WORDS)-1:0] r_writeAddress; reg [$clog2(DEPTH_WORDS)-1:0] r_readAddress; reg [$clog2(DEPTH_WORDS)-1:0] r_Count; always @(posedge i_Clock or negedge i_Reset_Low) begin if (~i_Reset_Low) begin r_writeAddress <= 0; r_readAddress <= 0; r_Count <= 0; end else begin if (i_writeDataReady_Flash) begin r_RAM[r_writeAddress] <= i_writeData; if (r_writeAddress == DEPTH_WORDS - 1) begin r_writeAddress <= 0; end else begin r_writeAddress <= r_writeAddress + 1; end end if (i_doRead_Flash) begin o_readData <= r_RAM[r_readAddress]; o_readDataReady <= i_doRead_Flash; if (r_readAddress == DEPTH_WORDS - 1) begin r_readAddress <= 0; end else begin r_readAddress <= r_readAddress + 1; end end if (i_doRead_Flash & ~i_writeDataReady_Flash) begin if (r_Count != 0) begin r_Count <= r_Count - 1; end end else if (i_writeDataReady_Flash & ~i_doRead_Flash) begin if (r_Count != DEPTH_WORDS) begin r_Count <= r_Count + 1; end end end end assign o_Full = ( r_Count == DEPTH_WORDS ) || ( r_Count == DEPTH_WORDS-1 && i_writeDataReady_Flash && !i_doRead_Flash ); assign o_Empty = (r_Count == 0); assign o_almostFull = (r_Count > DEPTH_WORDS - i_almostFullLevel); assign o_almostEmpty = (r_Count < i_almostEmptyLevel); endmodule module TestFIFO(); reg r_Clk = 0; always #1 r_Clk <= !r_Clk; reg r_Reset_Low = 0; reg r_writeDataReady_Flash = 0; reg [7:0] r_writeData = 50; reg [3:0] r_almostFullLevel = 4; wire w_almostFull; wire w_Full; reg r_doReadFlash = 0; wire w_readDataReady; wire [7:0] w_readData; reg [3:0] r_almostEmptyLevel = 4; wire w_almostEmpty; wire w_Empty; FIFO myFifo( .i_Clock(r_Clk), .i_Reset_Low(r_Reset_Low), .i_writeDataReady_Flash(r_writeDataReady_Flash), .i_writeData(r_writeData), .i_almostFullLevel(r_almostFullLevel), .o_almostFull(w_almostFull), .o_Full(w_Full), .i_doRead_Flash(r_doReadFlash), .o_readDataReady(w_readDataReady), .o_readData(w_readData), .i_almostEmptyLevel(r_almostEmptyLevel), .o_almostEmpty(w_almostEmpty), .o_Empty(w_Empty) ); initial begin $dumpfile("test.vcd"); $dumpvars; #2; r_Reset_Low <= 1; #2; r_writeDataReady_Flash <= 1; #2; r_writeDataReady_Flash <= 0; #2; r_writeData = 69; r_writeDataReady_Flash <= 1; #2; r_writeDataReady_Flash <= 0; #2; r_writeDataReady_Flash <= 1; #2; r_writeDataReady_Flash <= 0; #2; r_writeDataReady_Flash <= 1; #2; r_writeDataReady_Flash <= 0; #2; r_writeDataReady_Flash <= 1; #2; r_writeDataReady_Flash <= 0; #2; r_writeDataReady_Flash <= 1; #2; r_writeDataReady_Flash <= 0; #2; r_doReadFlash <= 1; #2; r_doReadFlash <= 0; #2; r_doReadFlash <= 1; #2; r_doReadFlash <= 0; #2; $finish; end endmodule