我需要一些关于如何设计异步FIFO的建议。我理解将数据捕获到不同时钟域时的元稳定性问题,我的问题是如何使用两个触发器移位寄存器协助写指针和读指针值的同步以进行完整和空标志计算。 当寄存器捕获不同域的数据时,它有可能进入亚稳状态并且可以稳定到未知值,因此如何有效地解决此问题。
由于
答案 0 :(得分:1)
当从一个时钟域传输到另一个时钟域时,您的读写指针需要使用灰色编码。如您所知,两个连续值之间只有1位灰色计数器不同。因此,亚稳态只能影响一个变化位。重新同步后,传输的指针将是更新的指针或其先前的值。
在任何一种情况下,这都不是问题,只会导致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;
答案 1 :(得分:0)
Jonathan解释得很好。 我想补充几点: 首先,除了2级同步器寄存器外,还必须有一个源寄存器。 您永远不能将组合逻辑中的信号馈送到您的2级同步器中,因为组合逻辑会产生毛刺。
您还必须意识到Verilog和VHDL没有内置的时钟域交叉和亚稳态支持。 即使你创建一个合适的2级同步器来传输灰色编码指针,也无法保证综合工具不会改变你的同步器,使其无法有效地保护亚稳态亚稳态。一些综合工具试图检测同步器并让它们独自存在。有些人没有。在任何一种情况下,你都不应该依赖它。 要获得完全正确的时钟域交叉,必须使用特定于供应商的属性和SDC时序约束来约束同步器和源寄存器。