0
votes

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

2
For Altera FPGAs you can use DCFIFO megafunction IP core.Qiu
Take a look at Asynchronous FIFO Design 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
Also see Metastability and Synchronizersuser1155120
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.Kevin Thibedeau
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

2 Answers

1
votes

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;
0
votes

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.