01signal.com

源同步输入

简介

本页讨论源同步(source-synchronous)数据输入:这种技术是指,数据输入与外部组件随这些输入一同生成的一个时钟保持同步。

Source-synchronous clocking with inputs only

之所以常采用这种方法,仅仅是因为外部组件就是这样工作的。另一个充分理由是,数据源在物理上离 FPGA 很远。也可能在 FPGA 与对端之间有一条线缆和连接器,例如发送像素数据的数字相机。

源同步(source-synchronous)时钟的一个潜在困难是,它可能并非一直有效。时钟信号还可能受到悬空物理连接或过大噪声的影响。此外,时钟的周期可能不稳定,或者抖动(jitter)可能过高。当数据来源(因而也包括时钟)是一个微处理器的 I/O 外设时,这种情况经常发生。

请注意,本教程还有一个专门页面讨论时钟与数据之间的总体关系。

应对不稳定的时钟

关于源同步输入,最重要的一条准则是:时钟不应直接连接到 FPGA 内部的逻辑单元。相反,FPGA 内部使用的时钟应当是一个干净(clean)的时钟,由 FPGA 内部的 PLL 产生。

如果外部时钟直接连接到 FPGA 内部逻辑,就可能出现一些奇怪的故障:一个有问题的时钟会引发各种意想不到的行为,而这些行为看起来并不像是时钟问题。过大的抖动和毛刺(glitch)可能破坏保证设计可靠运行的时序要求。其后果是,几乎所有情况都可能发生,包括根据 Verilog 代码按理不可能出现的情形。因此,人们很容易误以为问题出在 FPGA 设计的 bug 上。

人们自然会(错误地)认为,时钟问题只会造成时钟周期丢失,并因此缺少一些数据。当一个有问题的时钟引发其他故障时,解决问题的尝试往往集中在逻辑设计中最“相关”的部分,这会浪费大量时间。

外部时钟可以直接用于逻辑结构的唯一情形,是这个时钟被保证稳定且干净。如果 FPGA 刚开始工作时该时钟尚不稳定,这个问题就需要处理:只要时钟不稳定,就必须对依赖该时钟的逻辑施加复位。

可行的策略

与外部时钟同步主要有四种可行策略。下面不按特定顺序逐一讨论。

策略 1:01 信号采样

这种策略(即 01 信号采样,01-signal sampling)是处理源同步输入最稳健的方法。当外部时钟行为异常时,01 信号采样明显优于任何其他方法。不过,只有在数据源时钟频率相对较低时,这种方法才有用武之地。

这种方法在一个专门的页面中另行讨论。

策略 2:使用 PLL

在这种策略下,外部时钟连接到 FPGA 上一个 PLL 的输入端。该 PLL 的输出时钟用于逻辑单元。当 PLL 尚未锁定时,会向这些逻辑单元施加复位信号。这种方案确保逻辑单元依赖稳定的时钟:当 PLL 的输出时钟不稳定时,逻辑单元会因复位而被禁用。

与直接连接外部时钟相比,PLL 也使满足时序约束(timing constraints)变得更容易:PLL 补偿了时钟引脚与 FPGA 内部时钟之间的延迟。

然而,请注意,外部时钟的不完美会导致 PLL 输出端出现过大的抖动。即使 PLL 产生的时钟噪声异常严重,PLL 的锁定检测器仍可能继续指示 PLL 工作正常。这种情况没有简单的解决办法。一个可行做法是更改依赖 PLL 输出的逻辑的时序约束。例如,将时序约束中时钟的抖动值增大到 PLL 很可能不会超过的程度(因为超过就会失锁)。

这种策略与系统同步时钟(system synchronous clocking)有相似之处:在两种场景中,外部时钟都连接到 PLL,PLL 的输出在 FPGA 内部使用。因此,时序约束的编写方式与系统同步时钟(system synchronous clock)相同。

请注意,PLL 通常会让其输出时钟与外部时钟对齐,这种对齐方式对系统同步时钟是最优的。而对源同步时钟的最优对齐方式可能会略有不同。在两种情况下,时钟都不是完美对齐的,而是在时钟边沿之间存在一个刻意引入的微小时间差。这个时间差使 I/O 寄存器更容易满足时序要求。某些 PLL 可以配置为按源同步时钟的最佳性能来对齐时钟。

与这里列出的其他策略相比,这种策略最容易实现。它适用于相对较高的时钟频率。但对于接近 I/O 能力上限的频率,这种策略很可能无法工作。

策略 3:移相

当数据速率接近 FPGA 所能支持的上限时,通常会选择这种策略。

在如此高的数据速率下,通常用来保证时序要求的方法不再奏效:你将无法满足时序约束。不过,仍然可以对数据信号进行可靠的采样(sampling)。

时序约束的问题在于通过计算来保证时序要求:这种计算包含若干不确定参数,例如 FPGA 制造过程中的差异。把这些参数考虑进去后,计算结果无法给出一个能确保可靠采样的时序方案。当数据速率非常高时,没有任何时序裕量可以浪费在这些不确定性上。

但对于某一颗具体的 FPGA 芯片而言,这些参数是固定的。因此解决办法是在 FPGA 运行时寻找正确的时序。在实践中,这意味着 FPGA 内部的一个状态机(state machine)会调整数据时钟与采样时刻之间的延迟。也就是说,用自适应机制而不是依靠计算来找到最佳时序。这种机制称为移相(phase shifting)。

这种策略常用于接收 DDR SDRAM 存储器发出的数据信号。在这种应用中,目标始终是尽可能提高数据速率,因此 I/O 端口的能力已被推到极限。相应地,移相是确保数据输入被可靠采样的唯一方法:DDR 存储器初始化后,先向存储器写入一段特殊的数据序列(送往存储器的数据信号属于源同步输出(source-synchronous outputs),因此时序上没有问题)。随后,FPGA 反复从 DDR 存储器的同一位置读取。状态机通过逐步改变采样延迟来寻找最佳时序。由于预期输入数据是已知的(就是先前写入的那段数据序列),状态机很容易评估数据的可靠性,并找到最佳延迟。

这个机制的一个有趣特点是,DDR 芯片提供的数据时钟可以被忽略:DDR 存储器与 FPGA 产生的时钟保持同步。这个时钟正是 DDR 存储器所接收的源同步输出(source-synchronous outputs)的一部分。因此可以保证,源同步输入的数据时钟与 FPGA 产生的时钟频率完全一致。于是,移相机制可以依赖内部时钟,而无需依赖随数据一起到达的时钟。这两个时钟之间存在一个未知延迟也无关紧要:状态机无论这个延迟是多少,都能找到最佳时序。

事实上,这就是 DDR 存储器通常实现这一机制的方式:尽管 DDR 存储器带有一个源同步时钟(称为数据选通脉冲,data strobe),但移相机制通常都会忽略该信号。理由是,确保数据信号可靠到达比与选通脉冲对齐更重要。

因此,使用移相可以免去对数据时钟的需求。如果内部时钟能保证其频率与数据速率完全相同,就可以转而依赖内部时钟。

采用这种策略时,时序约束的作用与普通 IOB 寄存器相同。

策略 4:直接使用时钟

这种策略显然最直截了当:将外部时钟直接连接到 FPGA 内部的触发器。就像这样:

module top (
   input data_clk,
   input [7:0] data
);

   reg [7:0] data_samp;

   always @(posedge data_clk)
     begin
       data_samp <= data;

      [ ... ]
     end

如前所述,这种策略通常不是一个好主意。主要原因是,如果 @data_clk 出现毛刺,所有依赖该时钟的逻辑都会变得不可预测

如果外部时钟被保证是干净且稳定的,那么这样使用它是合理的。但即便如此,由于时钟引脚与触发器之间存在延迟,仍然可能难以满足时序要求。有些 FPGA 拥有专门的时钟资源来减小这一延迟。这可能需要使用专用的时钟输入引脚,并将 I/O 端口限制在 FPGA 上的特定区域内。

直接使用时钟时,时序约束的编写方式与系统同步时钟相同。

上文建议的 PLL 方案是这种策略的直接替代方案。如果数据时钟不稳定,则应考虑 01 信号采样。

总结

01 信号采样在本页最先被提到,而且这种方法在专门的页面中单独讲述,这不是巧合:只要数据速率没有超过这种方法所能支撑的范围,它就是最值得推荐的方法。

如果考虑采用其他策略,就必须注意数据时钟的稳定性。如果时钟偏离其允许的行为(即时钟周期和最大抖动),可能导致相关逻辑发生永久性且不可恢复的故障。只有复位才能使逻辑恢复正常工作。

使用 PLL 来生成可靠时钟能大大改善这一状况:只要 PLL 的锁定检测器指示锁定,PLL 的输出就是可靠的。否则,就应对这些逻辑施加复位。

本页由机器从英文翻译而来。如有疑问,请参阅原文
Copyright © 2021-2026. All rights reserved. (dcc38493)