面向 FPGA 的可综合异步 fifo 设计

synthesizable asynchronous fifo design towards an FPGA

我需要一些关于如何设计异步 FIFO 的建议。我了解将数据捕获到不同时钟域时的元稳定性问题,我的问题是使用两个触发器移位寄存器如何帮助同步写指针和读指针值以进行满标志和空标志计算。 当寄存器捕获不同域的数据时,它有可能进入亚稳态并稳定到未知值,那么如何有效解决这个问题。

谢谢

从一个时钟域传输到另一个时钟域时,您的读写指针需要使用格雷编码。如您所知,两个连续值之间只有灰度计数器的 1 位不同。因此,亚稳态只能影响一个变化的位。重新同步后,传输的指针将是更新后的指针或其先前的值。

无论哪种情况,这都不是问题,只会导致您的 FIFO 变得悲观 flags/count。

我对 read/write 指针使用常规计数器,并使用以下函数将它们转换为格雷码。它们是在 VHDL 中,但你应该明白了:

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;

乔纳森解释得很好。 我只想补充几点: 首先,除了 2 级同步器寄存器之外,您还必须有一个源寄存器。 您永远不能将来自组合逻辑的信号馈送到您的 2 级同步器中,因为组合逻辑会产生毛刺。

您还必须知道 Verilog 和 VHDL 没有对时钟域交叉和亚稳态的内置支持。 即使您创建了一个适当的 2 级同步器来传输格雷码指针,也不能保证综合工具不会以使其无法有效防止亚稳态的方式更改您的同步器。一些综合工具会尝试检测同步器并将其置之不理。有些人没有。在任何一种情况下,您都不应该依赖它。 对于完全正确的时钟域交叉,您必须使用特定于供应商的属性和 SDC 时序约束来约束同步器和源寄存器。