【问题标题】:synthesizable asynchronous fifo design towards an FPGA面向 FPGA 的可综合异步 fifo 设计
【发布时间】:2015-03-23 07:06:11
【问题描述】:

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

谢谢

【问题讨论】:

  • 对于 Altera FPGA,您可以使用 DCFIFO 宏功能 IP 内核。
  • 看看Asynchronous FIFO Design自己写,除了空和满的指示应该只使用来自单个时钟域的信号生成,而不是像初始图所示的那样来自两者。跨度>
  • 成对触发器仅适用于单个信号。对于位组,您必须使用不同的方案以确保您不会在不同时间捕获位。格雷码之间的转换是可行的,但会增加一些开销,从而增加关键路径(G 到 B 转换会产生很长的逻辑链),并且在这种用途上有美国专利。另一种选择是使用四阶段握手来传输指针。握手过程确保指针在时钟域之间安全移动。 VHDL 示例是available here
  • 嗨 Kevin 我同意你的观点,你需要一个 Xor 门链来进行二进制到灰色的转换。但是使用握手协议会增加数据传输的延迟。

标签: asynchronous verilog fpga digital asic


【解决方案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;

【讨论】:

  • 将函数的 Verilog 表达式作为模块:Clock Domain Crossing (CDC) Design Verification Techniques Using SystemVerilog,(无论是什么 HDL,都是一个很好的参考)。
  • 所以指针重新同步后,指针要么移动到下一个状态,要么停留在当前状态。如果它保持在当前状态,是否会导致数据丢失(可能指示不正确的满或空状态)。
  • 没有。由于您会将最新的写入指针(例如)与可能已过时的读取指针进行比较,您可能会发现当仍有空间时认为 FIFO 已满,但绝不会反过来。只要连接到 FIFO 的逻辑必须相应地采取行动,就断言满/空标志没有害处,无论如何这确实应该如此。这与主要 IP 提供商的行为相同。
  • 哦...我明白了,所以表示已满是可以接受的,但实际上它可能是“几乎满了”。我还读到他们使用 2-FF 移位寄存器同步器和非常快的晶体管,以便它们可以更快地从亚稳定状态稳定下来。他们如何为 FPGA 做到这一点?他们有专门的触发器吗?
  • 所有的人字拖都是同一个 AFAIK。 Xilinx 的 Vivado 有一个 async_reg 设计约束,它将尝试将寄存器放置在一起以减少延迟和亚稳态传播的可能性。在 FPGA 速度下,2 个寄存器被广泛接受用于重新同步器,如果您的应用程序很关键,您总是可以有 3 个或更多。在 ASIC 的高速下,我不知道,但你的建议听起来合乎逻辑。您可以随时提出有关电子产品的问题;我在这方面没有足够的经验。
【解决方案2】:

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

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

【讨论】:

  • 嗨蒂米,感谢您的洞察力。您能否进一步详细说明供应商特定属性。尤其要强调时钟域交叉上的合成器。
  • www10.edacafe.com/blogs/realintent/files/2014/07/Fig9.png 至少需要优化防止上图中称为“Din”和“Sync Out”的信号的属性。在 Xilinx 上,我会使用属性“KEEP”和“DONT_TOUCH”来防止综合和实现优化。 Altera 有一个类似的属性叫做“SYN_KEEP”。创建一个跨越 FIFO 的安全时钟域实际上是一项相当困难的任务,因为其中有很多令人惊讶的陷阱,而且几乎没有一个可以通过模拟或测试来发现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多