Vamsi
Vamsi

Reputation: 13

synthesizable asynchronous fifo design towards an FPGA

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

Upvotes: 0

Views: 1738

Answers (2)

Timmy Brolin
Timmy Brolin

Reputation: 1181

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.

Upvotes: 0

Jonathan Drolet
Jonathan Drolet

Reputation: 3388

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;

Upvotes: 1

Related Questions