我需要一些关于如何设计异步 FIFO 的建议。我了解将数据捕获到不同时钟域时的元稳定性问题,我的问题是使用两个触发器移位寄存器如何帮助同步写入指针和读取指针值以进行满标志和空标志计算。当寄存器捕获不同域的数据时,它有可能进入亚稳态并稳定到未知值,那么您如何有效地解决这个问题。
谢谢
我需要一些关于如何设计异步 FIFO 的建议。我了解将数据捕获到不同时钟域时的元稳定性问题,我的问题是使用两个触发器移位寄存器如何帮助同步写入指针和读取指针值以进行满标志和空标志计算。当寄存器捕获不同域的数据时,它有可能进入亚稳态并稳定到未知值,那么您如何有效地解决这个问题。
谢谢
当从一个时钟域传输到另一个时钟域时,您的读写指针需要使用灰色编码。如您所知,两个连续值之间只有一位灰色计数器不同。因此,亚稳态只能影响一个变化的位。重新同步后,传输的指针将是更新后的指针或其先前的值。
无论哪种情况,这都不是问题,只会导致您的 FIFO 出现悲观的标志/计数。
我使用常规计数器作为读/写指针,并使用以下函数将它们转换为格雷码。它们在 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 时序约束来约束同步器和源寄存器。