Asynchronous FIFO


ASYNC FIFO is a frequency relationship agnostic bus synchronization technique and by that can be considered practically universal.

It is convenient to choose the write/read pointers of width by one bit bigger than needed by FIFO size. The msb then will play the role of “sign”. The pointers (bus) synchronization is performed with the help of Gray encoding. Gray code encoding is a popular technique to synchronize a bus because only one bit is changed at a time. This ensures we always sample or old or new value on the bus and never – inconsistent one. “g2b” and “b2g” is the logic to convert Gray code to binary and vice versa. It is out of the scope of this article to depict its design.



//write pointer
always @ (src_clk)
      if (!rst_n)
                  wr_ptr <= ‘d0;
      else if (push)
                  wr_ptr <= wr_ptr + 1’b1;
//read pointer
always @ (dst_clk)
      if (!rst_n)
                  rd_ptr <= ‘d0;
      else if (pop)
                  rd_ptr <= rd_ptr + 1’b1;
//full
assign full = (wr_ptr[log(FIFO_SIZE)] ^ rd_ptr_synch[log(FIFO_SIZE)]) &&
(wr_ptr[log(FIFO_SIZE)-1:0] == rd_ptr_synch[log(FIFO_SIZE)-1:0]);
//empty
assign empty = (wr_ptr_synch[log(FIFO_SIZE):0] == rd_ptr[log(FIFO_SIZE):0]);

The important thing to remember is the size of the FIFO has to be exactly power of two. This is because in any other case there will be multiple bit transitions even with Gray code encoding and thus bus synchronization with only one bit changed at a time is violated.


4 comments:

  1. What's up, after reading this amazing post i
    am too delighted to share my knowledge here with friends.

    ReplyDelete
    Replies
    1. Write to myblogvlsiuniverse@gmail.com.

      Delete
  2. You need handshaking on the pointers. Otherwise the slow clock may see two consecutive increments, which defeats the purpose of gray code.

    ReplyDelete
    Replies
    1. can you please elaborate what kind of handshaking you are talking about.

      Delete

Thanks for your valuable inputs/feedbacks. :-)