0

I need some advice on how to design an asynchronous FIFO. I understand the meta stability issue when capturing data into a different clock domain, my question is how does using a two flip flop shift register assist in synchronization of write pointer and read pointer values for full and empty flag calculation. When register captures a data of a different domain there is a possibility it can enter a metastable state and can settle to a unknown value, so how do u effectively resolve this issue.

Thanks

Vamsi
  • 13
  • 4
  • For Altera FPGAs you can use [DCFIFO](https://www.altera.com/en_US/pdfs/literature/ug/ug_fifo.pdf) megafunction IP core. – Qiu Mar 23 '15 at 07:21
  • Take a look at [Asynchronous FIFO Design](http://www.rfwireless-world.com/downloads/Asynchronous-FIFO-Design.pdf) to write it yourself, except that empty and full indications should be generated with signals from only a single clock domain, and not from both as the initial figure indicates. – Morten Zilmer Mar 23 '15 at 07:23
  • 1
    Also see [Metastability and Synchronizers](http://webee.technion.ac.il/~ran/papers/Metastability%20and%20Synchronizers.posted.pdf) –  Mar 23 '15 at 13:29
  • 1
    Paired flip-flops only work with single signals. For groups of bits you must use a different scheme to ensure you don't capture bits at different times. Converting between Gray code works but imposes some overhead that increases the critical path (G-to-B conversion makes a long logic chain) and there are US patents on this use. Another option is to use a four-phase handshake to transfer the pointers. The handshake procedure ensures that pointers are safely moved between clock domains. A VHDL example is [available here](http://code.google.com/p/vhdl-extras/source/browse/rtl/extras/fifos.vhdl). – Kevin Thibedeau Mar 23 '15 at 20:41
  • Hi Kevin I agree with you,you would need a chain of Xor gates for binary to Grey conversions. But using a handshake protocol can it increase the latency of data transfer. – Vamsi Mar 23 '15 at 21:00

2 Answers2

1

Your read and write pointers need to use gray encoding when transferred from one clock domain to the other. As you should know, only 1 bit of a gray counter is different between two consecutive values. Thus, metastability can affect only the one changing bit. After re-synchronization, the transferred pointer will be either the updated pointer or its previous value.

In either case, this is not a problem and only lead to pessimistic flags/count for your FIFO.

I use regular counter for my read/write pointer, and use the following functions to convert them to gray code. They are in VHDL, but you should get the idea:

function bin_to_gray(a: unsigned) return unsigned is
begin
    return a xor ('0' & a(a'left downto 1));
end function bin_to_gray;

function gray_to_bin(a: unsigned) return unsigned is
    variable ret   : unsigned(a'range);
begin
    ret(a'left) := a(a'left);
    for i in a'left-1 downto 0 loop
        ret(i) := ret(i+1) xor a(i);
    end loop;
    return ret;
end function gray_to_bin;
Jonathan Drolet
  • 3,318
  • 1
  • 12
  • 23
  • 1
    With Verilog expression of the functions as modules: [Clock Domain Crossing (CDC) Design Verification Techniques Using SystemVerilog](http://www.sunburst-design.com/papers/CummingsSNUG2008Boston_CDC.pdf), (and a good reference no matter what HDL). –  Mar 23 '15 at 14:11
  • So after re synchronization of the pointers , the pointer will either move to the next state or stay in the present state. If it stays in the present state, can that result in lose of data(Maybe indicate incorrectly full or empty condition). – Vamsi Mar 23 '15 at 20:50
  • No. Since you will compare an up-to-date write pointer (for example) with a possibly outdated read pointer, you may find think that the FIFO is full when there is still room left, but never the other way around. There is no harm in asserting the full/empty flag, as long as the logic connected to the FIFO has to act accordingly, which really should anyways. This is the same behavior as major IP providers. – Jonathan Drolet Mar 23 '15 at 20:58
  • oh...i understand ,so it is acceptable to indicate a full condition but in reality it can be "nearly full" . I have also read that they employ 2-FF shift register synchronizers with very fast transistors so that they can settle from a meta stable state more quickly. How do they do that for an FPGA are they any specialized flip flops for that? – Vamsi Mar 24 '15 at 00:43
  • All flip-flops are the same AFAIK. Xilinx's Vivado has an async_reg design constraint that will try to place the registers close together to reduce delay and probability of metastability propagation. At FPGA speed, 2-registers are widely accepted for re-synchronizer, you can always have 3 or more if your application is critical. At the high speed of ASIC, I wouldn't know but what you suggest sounds logical. You can always ask a question on electronics; I don't have enough experience on that matter. – Jonathan Drolet Mar 24 '15 at 01:01
0

Jonathan explained it well. I would just like to add a few points: First, in addition to your 2-stage synchronizer registers you must also have a source register. You can never feed signals from combinational logic into your 2-stage synchronizer, since combinational logic produce glitches.

You must also be aware that Verilog and VHDL has no built-in support for clock domain crossings and metastability. Even if you create a proper 2-stage synchronizer to transfer the gray coded pointers, there is no guarantee that the synthesis tool does not change your synchronizers in a way which make it ineffective in protecting againsts metastability. Some synthesis tools try to detect synchronizers and leave them alone. Some don't. And in either case, you should not rely on it. For a completely proper clock domain crossing, you must constrain the synchronizer and the source register using vendor-specific attributes and SDC timing constraints.

Timmy Brolin
  • 1,101
  • 1
  • 8
  • 18
  • Hi Timmy, Thank you for your insight. Can you elaborate further on the Vendor- Specific attributes. Especially to emphasize the synthesizer on the clock domain crossing. – Vamsi Apr 12 '15 at 07:00
  • http://www10.edacafe.com/blogs/realintent/files/2014/07/Fig9.png At a minimum you need optimization preventing attributes on the signals called "Din" and "Sync Out" in the image above. On Xilinx I would use the attributes "KEEP" and "DONT_TOUCH" to prevent both synthesis and implementation optimizations. Altera ha a similar attribute called "SYN_KEEP". Creating a safe clock domain crossing FIFO is actually a rather difficult task, because there are surprisingly many pitfalls, and virtually none of them can be caught by simulation or testing. – Timmy Brolin Apr 12 '15 at 16:05
  • Xilinx now has an "async_reg" attribute you should use on both the metastable flop and the next one. It tells Vivado to put those flops physically close to each other, to not replicate them, and to not push logic across them. It also helps Vivado calculate MTBF. – Craig Sep 06 '22 at 16:41