Hi,
I have some problem detecting the full and empty conditions in an
asynchronous FIFO design. Hope any of you can help.
Assume wr_clk is slower than the rd_clk. The rd_ptr is
synchronized to the wr_clk domain to generate the full flag in wr_clk
(slow) domain while the wr_ptr is synchronized to the rd_clk domain to
generate the empty flag in rd_clk (fast) domain.
Say, on every 8th wr_clk, I generate a "wr_enable" signal. I write to
the FIFO and increment the write pointer whenever the "wr_enable" is
true. Assume the depth of the FIFO to be 4. I have written 3 FIFO
locations and my write pointer points to the last FIFO location at the
same time the 3rd location is written. Now when I write to the last
available (4th) FIFO location, full flag should be asserted. But now
when should it be deasserted?
1. Whenever the read and write pointers are equal (irrespective of
"wr_enable" signal) or
2. when the read and write pointers are equal and "wr_enable" is
true??
Please direct if any of you have any good information on
asynchronous FIFO design. Also is it possible to synchronize pointers
from a faster clk domain to slowr clk domain?
Thanks
Aditya
Asynchronous FIFO design question
Started by ●March 6, 2006
Reply by ●March 6, 20062006-03-06
It would be good to say what chip you are using since there are primitives in Xilinx for asynchonous FIFOs.
Reply by ●March 6, 20062006-03-06
EMPTY goes active as a result of reading, so the leading edge of EMPTY is inherently synchronous to the read clock. No problem there. The trailing edge of EMPTY is caused by writing, so it's inherently synchronous to the write clock and it must be moved over to the read clock domain. Moving between clock domains must accomodate potential metastability, which usually means sacrificing some clock periods. But that is usually not a problem. It just means the EMPTY signal stays longer than absolutely necessary. FULl is symmetrical, just exchange read for write etc. Metastability is the potential problem of any asynchronous interface. Peter Alfke, Xilinx Applications
Reply by ●March 6, 20062006-03-06
Thanks for the information. But the problem I have got is that the wr_clk is not free running. On my last wr_clk, I load the 4th location of the FIFO and assert FULL. Remember that my next wr_clk can be at any time which we never know. But in the mean time, if a read happens in the rd_clk domain the trailing edge of FULL needs to be synchronized to the wr_clk domain which is not possible till we see the next wr_clk. If this FULL flag has to be reflected in my status register (this works on rd_clk), what should my status bit be? Still high - as I have not yet synchronized the trailing edge of FULL to wr_clk or low - as in reality the FIFO is not full. P.S. This is to be used in a microcontroller. Thanks Aditya
Reply by ●March 6, 20062006-03-06
Hi, "Simulation and Synthesis Techniques for Asynchronous FIFO Design with Asynchronous Pointer Comparisons" by Clifford E. Cummings and Peter Alfke is very detailed in code and it teaches how to design a sophisticated asynchronous FIFO with thorough details. Clifford E. Cummings website address is: www.sunburst-design.com. You may download the paper from the website. Weng
Reply by ●March 6, 20062006-03-06
This is a tricky problem. That's why all my designs require free-running clocks. How deep is your FIFO, and how fast is your design ( clock-to-clock delay) and what FPGA device type or family are you targetting? Also remember, a properly-designed FIFO should never go FULL. When it is full, it has lost its fundamental function, to act as an elastic buffer, or shock absorber. A FIFO should always be deeper than necessary. If it ever goes FULL, you can perhaps treat that as an emergency situation. But it still requires some design finesse. Please give more information. Peter Alfke, Xilinx Applications (from home)
Reply by ●March 7, 20062006-03-07
Sorry if this newsgroup is only for discussions on FPGA. The FIFO I am trying to design is just a part of my Serial Peripheral Interface (SPI) design to be used in a 32-bit microcontroller (ASIC). I have two different FIFOs, one for transmit and one for receive. Here I am talking about the receive FIFO, where I receive data on my wr_clk (sent by an outside device and so is not free running. It actually sends the clock only when it has data to send to my SPI) but I read that data on rd_clk (this is internal to my design). In this case, the FIFO can actually go FULL and the next time I receive data when the FIFO is FULL, I set an overrun flag which is fine. The FIFO is 4 deep and the clock I receive from an external device (wr_clk) can be as high as 25 MHz. The same holds ture for my rd_clk. I have gone through your paper "Simulation and Synthesis Techniques for Asynchronous FIFO Design with Asynchronous Pointer Comparisons". But I have a question on pg.9 in "async_cmp.v" empty/full flag comparison module. Say, the wr_ptr is one quadrant behind the rd_ptr (in our case, assume rd_ptr = 11 (gray) and wr_ptr = 01). Now "dirset_n" will be active and on it's negative edge "direction" will be set meaning that the FIFO is going full. But when I load one more word into the FIFO and the rd/wr pointers become equal, what would "direction" be? From the code given, when there is no negative edge on "dirset_n" or "dirclr_n", "direction" would always be tied to Vdd. This looks ok for the full flag logic as per assign afull_n = ~((wr_ptr == rd_ptr) && direction); as the "direction" is still high even after the pointers became equal. But in case of empty logic, assign aempty_n = ~((wr_ptr == rd_ptr) && !direction); "direction" will be cleared only on the negative edge of "dirclr_n" which happens when the rd_ptr is one quadrant behind the wr_ptr. But when I read one more word from the FIFO, rd/wr pointers become equal and "direction" will now be set meaning that "aempty_n" is not active while it should have been as the FIFO is really empty now. Can you please explain this at your convenience? Sorry if I am wrong in my thought. Also please let me know what would be an effective way to code the intended behavior (basically an SR flop doing what we wanted). Thank You Aditya
Reply by ●March 7, 20062006-03-07
Aditya, "Sorry" that you are asking ASIC questions on a FPGA newsgroup? Don't be. Is it really that desparate? No one to talk to when you design an ASIC anymore? I don't mind the off topic question. It is instructive as it demonstrates just how hard it is to make an ASIC that actually works. And it gives all of the FPGA users a good feeling that they made the right decision, and did not even try to make an ASIC. Who needs those headaches. But I doubt that either Xilinx or Altera IC designers will offer to help you (much) with your ASIC design. We have enough work to do ourselves, and it is not in our interest to help ASIC designers design their ASICs. There are plenty of ASIC designers who are now FPGA users (as their bosses gave them a simple choice: design with FPGAs, or leave) that read this newsgroup. Perhaps they will help you. Austin Aditya wrote:> Sorry if this newsgroup is only for discussions on FPGA. > > The FIFO I am trying to design is just a part of my Serial Peripheral > Interface (SPI) design to be used in a 32-bit microcontroller (ASIC). I > have two different FIFOs, one for transmit and one for receive. Here I > am talking about the receive FIFO, where I receive data on my wr_clk > (sent by an outside device and so is not free running. It actually > sends the clock only when it has data to send to my SPI) but I read > that data on rd_clk (this is internal to my design). In this case, the > FIFO can actually go FULL and the next time I receive data when the > FIFO is FULL, I set an overrun flag which is fine. The FIFO is 4 deep > and the clock I receive from an external device (wr_clk) can be as high > as 25 MHz. The same holds ture for my rd_clk. > > I have gone through your paper "Simulation and Synthesis Techniques > for Asynchronous FIFO Design with Asynchronous Pointer Comparisons". > But I have a question on > pg.9 in "async_cmp.v" empty/full flag comparison module. > > Say, the wr_ptr is one quadrant behind the rd_ptr (in our case, assume > rd_ptr = 11 (gray) and wr_ptr = 01). Now "dirset_n" will be active and > on it's negative edge "direction" will be set meaning that the FIFO is > going full. But when I load one more word into the FIFO and the rd/wr > pointers become equal, what would "direction" be? From the code given, > when there is no negative edge on "dirset_n" or "dirclr_n", "direction" > would always be tied to Vdd. This looks ok for the full flag logic as > per > > assign afull_n = ~((wr_ptr == rd_ptr) && direction); > as the "direction" is still high even after the pointers became > equal. > > But in case of empty logic, > > assign aempty_n = ~((wr_ptr == rd_ptr) && > !direction); > > "direction" will be cleared only on the negative edge of "dirclr_n" > which happens when the rd_ptr is one quadrant behind the wr_ptr. But > when I read one more word from the FIFO, rd/wr pointers become equal > and "direction" will now be set meaning that "aempty_n" is not active > while it should have been as the FIFO is really empty now. > > Can you please explain this at your convenience? Sorry if I am > wrong in my thought. Also please let me know what would be an effective > way to code the intended behavior (basically an SR flop doing what we > wanted). > > Thank You > > Aditya >
Reply by ●March 7, 20062006-03-07
If your FIFO is only 4-deep and runs at only 25 MHz, there are lots of ways to implement the design "brute force". Contact your ASIC supplier or other friends. They can surely help you. Peter Alfke, Xilinx Applications
Reply by ●March 7, 20062006-03-07
Hi, Don't worry. I would like to discuss your problem with you, no matter it is for FPGA and for ASIC. They are the same. There are two flags for a full condition: 1. (Going full and write ptr = read ptr), not one. Going full means full only when write ptr = read ptr. The condition you described is just the full condition. And Going full can be used as almost full signal in the design at the 3/4 contents of AFIFO. It is very useful. 2. Same thing is with Empty. You have to really understand the paper, otherwise your ASIC design will become catastrophy! Based on the paper, I re-designed my own asynchornous logic, but it's never been used, because all my design is synchronous. Weng






