asynchronousverilogfpgadigitalasic

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


Solution

  • 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;