Asynchronous FIFOs are used as buffers between two asynchronous clock domains to exchange data safely. Data is written into the FIFO from one clock domain and it is read from another clock domain. This requires a memory architecture wherein two ports of memory are available- one is for input (or write or push) operation and another is for output (or read or pop) operation. Generally FIFOs are used where write operation is faster than read operation. However, even with the different speed and access types the average rate of data transfer remains constant. FIFO pointers keep track of number of FIFO memory locations read and written and corresponding control logic circuit prevents FIFO from either under flowing or overflowing. FIFO architectures inherently have a challenge of synchronizing itself with the pointer logic of other clock domain and control the read and write operation of FIFO memory locations safely. A detailed and careful analysis of synchronizer circuit along with pointer logic is required to understand the synchronization of two FIFO pointer logic circuits which is responsible for accessing the FIFO read and write ports independently controlled by different clocks.
Why Synchronization?
It is very important to understand the signal stability in multi clock domains since for a traveling signal the new clock domain appears to be asynchronous. If the signal is not synchronized to new clock, the first storage element of the new clock domain may go to metastable state and the worst case is that resolution time can’t be predicted. It can traverse throughout the new clock domain resulting in failure of functionality. To prevent such failures setup time and hold time specification has to be obeyed in the design. Manufacturers provide statistics of probability of failure of flip-flops due to metastability characters in terms of MTBF (Mean Time Before Failure). Synchronizers are used to prevent the downstream logic from entering into the metastable state in multiclock domain with multibit data values.
Issues in Designing Asynchronous FIFO
It has been mentioned that designing of FIFO pointers for efficient working of FIFO is the key issue while designing FIFO architecture. Let us go deep into the FIFO read and write pointers. On reset both read and write pointers are pointing to the starting location of the FIFO. This location is also the first location where data has to be written at the same time this first location happens to be first read location. Therefore, in general we can say, read pointer always points to the word to be read and write pointer always points to the next location to which data has to be written.
Now let us examine data write operation. When both read and write pointers are pointing to first location of FIFO empty flag is asserted indicating the FIFO status as empty. Now data writing can be performed. Data will be written to the location where the write pointer is pointing and after the data write operation write pointer gets incremented pointing to the next location to be written. At the same time, empty flag is deasserted which indicates that FIFO is not empty, some data is available. One notable point regarding read pointer is with empty flag active the data pointed out by the read pointer is always invalid data. When first data written and empty flag status cleared (i.e. empty flag inactive) read pointer logic immediately drives the data from the location to which it was pointing to the read port of the dual port RAM, ready to be read by read logic. With this implementation of read logic the biggest advantage is that only one clock pulse is required to read from read port since previous clock cycle has already incremented read pointer and drives the data to read port. This will help in reducing latency in detecting empty and full pointer flag status. Empty status flag can be asserted in one more condition. After some n number of data write operations if same n number of read is performed then both pointers are again equal. Hence if both pointers “catch up” each other then empty flag is asserted.
Now let us examine about FIFO full status. When write pointer reaches the top of the FIFO, it is pointing towards the location, which can be written and is the last location to be written. No read operation is performed yet and read pointer is pointing to first location itself. This is one method is to generate FIFO full condition. When write pointer reaches the top of the FIFO, if full flag is asserted then it is not the actual FIFO full condition, this is only ‘almost full’ as there is one location which can be written. Similarly almost empty condition can exist in FIFO. Now a write operation causes the location to be written and increment of write pointer. Since the location was the last one write pointer wraps up to first location. Now both read and write pointers are equal and hence empty flag is asserted instead of full flag assertion, which is a fatal mistake. Hence wrap around condition of a full pointer may be a FIFO full condition.
After writing the data to FIFO (consider write pointer is in top of FIFO) some data has been read and read pointer is somewhere in between FIFO. One more write operation causes the write pointer to wrap. Note that even though write pointer is pointing to first location of FIFO this is NOT FIFO full condition, since read pointer has moved up from the first location. Further data writing pushes write pointer up. Imagine read pointer wraps around after some more read operation. Present condition is that both pointers have wrapped around but there is no FIFO full or FIFO empty condition. Data can be written to FIFO or read from the FIFO. This is being the situation how to identify and generate full and empty condition? How to synchronize and compare these two pointers to generate full and empty status? While synchronizing how to avoid possible metastable state and ‘pessimistic reporting’ (i.e. harmless wrong report; will be discussed later)? These are some key issues in designing an asynchronous FIFO.
Coming articles will discuss these issues. Also asynchronous FIFO designed using Verilog and Spartan 3 will be published. Interesting point of this design is it works as both synchronous and asynchronous FIFO !
References
[1]Clifford E.Cumings, Simulation and Synthesis techniques for Asynchronous FIFO Design, http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf (
[2] Clifford E.Cumings, Synthesis and Scripting Techniques for Designing Multi-Asynchronous Clock Designs, http://www.sunburst-design.com/papers/ (
[4] Mike Stein,Crossing the abyss:asynchronous signals in a synchronous world, http://www.edn.com/contents/images/310388.pdf (
Related Articles
It was a great information. Thanks for sharing.
ReplyDeleteDevOps Training
DevOps Online Training