First-In-First-Out Buffer

  1. Introduction

    FIFO is an acronym for First In First Out, which describes how data is managed relative to time or priority. In this case, the first data that arrives will also be the first data to leave from a group of data. A FIFO Buffer is a read/write memory array that automatically keep track of the order in which data enters into the module and reads the data out in the same order. In hardware FIFO buffer is used for synchronization purposes. It is often implemented as a circular queue, and has two pointers:
    1. Read Pointer/Read Address Register
    2. Write Pointer/Write Address Register
    Read and write addresses are initially both at the first memory location and the FIFO queue is Empty. When the difference between the read address and write address of the FIFO buffer is equal to the size of the memory array then the FIFO queue is Full.

    FIFO can be classified as synchronous or asynchronous depending on whether same clock (synchronous) or different clocks (asynchronous) control the read and write operations.


    Synchronous FIFO

    A synchronous FIFO refers to a FIFO design where data values are written sequentially into a memory array using a clock signal, and the data values are read out sequentially from the memory array using the same clock signal. Figure 1 shows the flow of the operation of a typical FIFO.

    Figure 1. Operation of FIFO with the three data values

  2. Verilog Module

    Figure 2 presents the Verilog module of the FIFO Buffer. This FIFO Buffer can store eight 32-bit values. The FIFO Buffer module consists of a 32-bit data input line, dataIn and a 32-bit data output line, dataOut. The module is clocked using the 1-bit input clock line Clk. The module also has a 1-bit enable line, EN and a 1-bit active high reset line, Rst.

    The 1-bit RD line is used to signal a data read operation on the FIFO Buffer and the 1-bit WR line is used to signal a data write operation on the FIFO Buffer. Both the RD and WR lines are active high. The module also has two output lines FULL and EMPTY which are each 1-bit wide. The FULL line becomes high when the FIFO Buffer is or becomes full (internal counter becomes eight). The EMPTY line becomes high when the FIFO Buffer is or becomes empty (internal counter becomes zero).

    Figure 2. Verilog module of a FIFO Buffer

  3. Verilog Code for the FIFO Buffer (FIFObuffer.v)


    1. module FIFObuffer( Clk,
    2. dataIn,
    3. RD,
    4. WR,
    5. EN,
    6. dataOut,
    7. Rst,
    8. EMPTY,
    9. FULL
    10. );
    11. input Clk,
    12. RD,
    13. WR,
    14. EN,
    15. Rst;
    16. output EMPTY,
    17. FULL;
    18. input [31:0] dataIn;
    19. output reg [31:0] dataOut; // internal registers
    20. reg [2:0] Count = 0;
    21. reg [31:0] FIFO [0:7];
    22. reg [2:0] readCounter = 0,
    23. writeCounter = 0;
    24. assign EMPTY = (Count==0)? 1'b1:1'b0;
    25. assign FULL = (Count==8)? 1'b1:1'b0;
    26. always @ (posedge Clk)
    27. begin
    28. if (EN==0);
    29. else begin
    30. if (Rst) begin
    31. readCounter = 0;
    32. writeCounter = 0;
    33. end
    34. else if (RD ==1'b1 && Count!=0) begin
    35. dataOut = FIFO[readCounter];
    36. readCounter = readCounter+1;
    37. end
    38. else if (WR==1'b1 && Count<8) begin
    39. FIFO[writeCounter] = dataIn;
    40. writeCounter = writeCounter+1;
    41. end
    42. else;
    43. end
    44. if (writeCounter==8)
    45. writeCounter=0;
    46. else if (readCounter==8)
    47. readCounter=0;
    48. else;
    49. if (readCounter > writeCounter) begin
    50. Count=readCounter-writeCounter;
    51. end
    52. else if (writeCounter > readCounter)
    53. Count=writeCounter-readCounter;
    54. else;
    55. end
    56. endmodule
    Figure 3. Verilog code for FIFO Buffer

  4. Verilog Test Bench for FIFO Buffer (FIFObuffer_tb.v)


    1. `timescale 1ns / 1ps
    2. module FIFObuffer_tb;
    3. // Inputs
    4. reg Clk;
    5. reg [31:0] dataIn;
    6. reg RD;
    7. reg WR;
    8. reg EN;
    9. reg Rst;
    10. // Outputs
    11. wire [31:0] dataOut;
    12. wire EMPTY;
    13. wire FULL;
    14. // Instantiate the Unit Under Test (UUT)
    15. FIFObuffer uut (
    16. .Clk(Clk),
    17. .dataIn(dataIn),
    18. .RD(RD),
    19. .WR(WR),
    20. .EN(EN),
    21. .dataOut(dataOut),
    22. .Rst(Rst),
    23. .EMPTY(EMPTY),
    24. .FULL(FULL)
    25. );
    26. initial begin
    27. // Initialize Inputs
    28. Clk = 1'b0;
    29. dataIn = 32'h0;
    30. RD = 1'b0;
    31. WR = 1'b0;
    32. EN = 1'b0;
    33. Rst = 1'b1;
    34. // Wait 100 ns for global reset to finish
    35. #100;
    36. // Add stimulus here
    37. EN = 1'b1;
    38. Rst = 1'b1;
    39. #20;
    40. Rst = 1'b0;
    41. WR = 1'b1;
    42. dataIn = 32'h0;
    43. #20;
    44. dataIn = 32'h1;
    45. #20;
    46. dataIn = 32'h2;
    47. #20;
    48. dataIn = 32'h3;
    49. #20;
    50. dataIn = 32'h4;
    51. #20;
    52. WR = 1'b0;
    53. RD = 1'b1;
    54. end
    55. always #10 Clk = ~Clk;
    56. endmodule
    Figure 4. Verilog Test-bench for FIFO Buffer

  5. Timing Diagram

    Figure 6. Timing Diagram of FIFO Buffer