此页面属于关于 timing的一系列页面。前几页解释了 timing 计算背后的理论,展示了如何编写几个 timing constraints 并讨论了 timing closure的原理。上一页解释了有关 I/O timing constraints的一些基本原则。本页继续介绍本主题的实际方面。
介绍
I/O timing constraints 的目的是确保与外界的可靠接口: 它们保证来自外部世界的每个 signal 可靠地到达 FPGA上的相关 flip-flop 。同样,他们还确保从 FPGA 到外部世界的每个 signal 都可靠地到达外部组件上的 flip-flop 。
I/O timing constraints 是 timing constraints中最难的一种: timing 的一些参数取决于 PCB (Printed Circuit Board)上的外部电子元件。通常需要读取这些外部组件的 datasheets 以确定正确的 timing 要求。通常,需要纸笔计算才能获得正确的 timing constraint。
跳过这个复杂的任务并选择一个简单的替代方案很诱人: 反复试验。这个捷径包括让工具做他们想做的事,然后看看它是否有效。如果 input port有问题,请在接收 input signal的 flip-flop 上使用相反的 clock edge 。同样,如果 output 不能正常工作,请在 output flip-flop上使用相反的 clock edge 。这种方式通常可以让电子设备快速简单地工作。
这种方法的问题是 timing 的行为会随着温度的变化而变化。由于半导体元件的制造过程,也存在不确定性。这适用于 FPGA 以及外部电子设备。所以不正确的 timing constraints 会导致“ Black Magic 模式”。所有 timing constraints都是如此,但 I/O timing constraints更常见。
跳过纸笔计算的最糟糕的事情是有时因为 board design而无法保证 timing 的要求。如果在 board design的过程中发现了这样的情况,往往有一个简单的解决办法(换到 FPGA 的接线或者重新考虑 clocks的配线)。但是如果在 PCB 生产出来之后才发现这种缺陷,可能就没有办法修复了。换句话说,无法保证电子设备可靠地工作。
本页内容
此页面概述了 I/O ports的基本 timing constraints 。此处显示的语法是 SDC,由 Vivado 和 Quartus以及其他 FPGA 工具使用。
此页面以专用于 I/O的 timing constraints 开头: set_input_delay 和 set_output_delay。这些 constraints 的含义解释一下。接下来是对两个单独页面的引用,这些页面显示了 Vivado 和 Quartus的 timing reports 示例。
也可以用 set_max_delay 和 set_min_delay定义 timing constraints 。这些命令在某些场景下更适用。我们已经就 FPGA内部的 paths 与他们会面。它们作为 I/O timing constraints 的含义也在下面解释。
本页仅讨论有关这些 I/O timing constraints的技术方面。对于理论部分,请参考上一页,其中还展示了如何为 I/O ports定义 false paths 。
set_input_delay 和 set_output_delay的含义
当与外部组件的接口为system synchronous时,这两个命令适用。简而言之,
- set_input_delay -clock … -max … : input port + board的 trace delay外接元件最大 clock-to-output 。
- set_input_delay -clock … -min … : 连接到 input port的外部组件的最小 clock-to-output 。如果 datasheet 没有提供此信息,请选择零(以防万一此组件的未来版本将使用非常快的 process制造)。
- set_output_delay -clock … -max … : tsu 的 output signal + board的 trace delay外接组件。
- set_output_delay -clock … -min … : 接收 output signal的外部组件的 –thold 。注意减号。例如,如果 hold time 为 1 ns,则将此 constraint 设置为 -1 。
重要的是要注意,只有满足以下两个条件时,这些定义才是正确的:
- 接口是system synchronous 。
- 定义 clock 的 create_clock 命令是指带有 get_ports 命令的 clock signal (而不是依赖 FPGA 内部的另一个 signal ,例如 get_pins)。
这两个条件是确保 clock delays 计算正确所必需的。
另请注意,如果 -min 或 -max 均未使用,则该命令将被解释为两个命令: 一个命令使用 -min,第二个命令使用 -max。这可能不是您想要的。
这些命令的定义有点混乱: set_input_delay 定义何时允许 data signal 在 clock edge之后更改其值。但是 set_output_delay 定义了在 data signal 更改其值后何时允许 clock edge 。据推测,这些定义背后的基本原理是 datasheet 中的数字可以直接用于 timing constraints。
set_input_delay 和 set_output_delay 命令有几个选项,这里没有介绍。特别是,可以选择 falling clock edge 作为时间参考。有关详细信息,请参阅工具的文档。
始终同时使用 min 和 max
坚持为每个 timing constraint同时使用 -min 和 -max 似乎毫无意义。例如,如果外部组件的 tsetup 是 8 ns,这有什么问题?
set_output_delay -clock theclk 8 [get_ports test_out]
这正确定义了 setup time 。至于 hold time,无意中定义为 –8 ns。这允许 output port 在 clock之前更改其值 8 ns 。但谁在乎?那不可能发生,不是吗?
好吧,实际上它可以。我已经讨论了使用 PLL 生成内部 clock,基于来自 input pin 的 clock (即在 board上可见的 clock )。这允许 PLL 将 FPGA的内部 clock 与 input clock对齐。 PLL 通过稍微移动 (shifting) clock 来补偿 clock distribution network的 delay 来实现这一点。
实际上, FPGA 工具可能会随意将 clock 移动到比 board的 clock稍早的位置,以实现 timing constraint: 如果将 FPGA 内部的 clock 移动到外部 clock之前,则外部组件感知到的 clock-to-output 会变小。这是因为 FPGA 内部的 flip-flop 与内部的 clock是同步的,但是可见的 timing 是相对于外部的 clock而言的。
但是当 FPGA的内部 clock 早于 board上的 clock 时, FPGA的 output 可以在外部 clock的 clock edge 之前进行更改。这会导致接收这些 outputs的组件违反 hold time 。
如果 set_output_delay 命令定义 hold time 为 –8 ns,这并不意味着 output 将在 clock之前更改其值 8 ns 。但这允许工具以违反 thold 要求的方式移动内部 clock 。正确使用 set_output_delay 和 -min 可以防止这种情况发生。
由于 trace delay的调整
请务必记住,这些工具不会考虑 PCB的 trace delay 。这些工具没有此信息。因此,在对 set_input_delay 和 set_output_delay进行 timing 计算时,他们假设此 delay 为零。更正是将 trace delay 添加到 clock-to-output 和 tsu的 datasheet值中。
可能还需要考虑 clock skew : 在完美的 PCB上, clock 到达具有相同 delay的所有组件。在现实生活中, FPGA 和外部组件之间可能存在 clock skew 。在工具的 timing 计算中不考虑此类 clock skew 。
因此,如果 clock 比 FPGA 更早到达(相对于外部组件),则需要进行以下更正:
- 对于 set_input_delay -clock … -max … : 将 clock skew 添加到命令的 delay 值(这类似于外部组件的较大 clock-to-output )。
- 对于 set_output_delay -clock … -min … : 从命令的 delay 值减少 clock skew ,即使其更负(这类似于外部组件的更大 thold )。
同样,如果 clock 晚于 FPGA到货,则需要进行以下更正:
- 对于 set_input_delay -clock … -min … : 从命令的 delay 值减少 clock skew (这类似于外部组件的较小 clock-to-output )。如果外部组件的 datasheet中没有给出最小 clock-to-output 值,则使用 clock skew 的负值作为此命令的值。
- set_output_delay -clock … -max … : 将 clock skew 添加到命令的 delay 值(这类似于更大的 PCB trace delay)。
请注意,无论此处概述的调整如何, timing report 都可能显示不为零的 clock skew 。然而,出现在 timing report 中的 clock skew 与 FPGA内部的 clock delays 相关,而不是 PCB上的 clock delays 。
timing reports的例子
这些示例基于以下 Verilog 代码:
module top(
input test_clk,
input test_in,
output reg test_out
);
reg test_samp;
always @(posedge test_clk)
begin
test_samp <= test_in;
test_out <= test_samp;
end
endmodule
@test_clk 是 input clock, @test_in 是 input pin, @test_out 是 output pin。请注意,没有 PLL 用于将内部 clock 与 board的 clock对齐,因此有一个重要的 clock delay。
timing constraints 如下:
create_clock -name theclk -period 20 [get_ports test_clk] set_output_delay -clock theclk -max 8 [get_ports test_out] set_output_delay -clock theclk -min -3 [get_ports test_out] set_input_delay -clock theclk -max 4 [get_ports test_in] set_input_delay -clock theclk -min 2 [get_ports test_in]
由于 timing reports 比较长,它们在单独的页面上显示:
使用 set_max_delay 和 set_min_delay
当与外部组件的接口为source synchronous时,使用 set_input_delay 和 set_output_delay 就不太自然了。 set_max_delay 和 set_min_delay 比较适合这种情况。在上一页中,这两个命令仅作为对 clock period constraints的补充或调整 (timing exceptions) 提及。所有 paths 都是内部的: 他们以 sequential element开始和结束。当这些命令用作 I/O timing constraints时, path 的开头或结尾是 I/O port。 timing analysis 在这种情况下是怎么做到的?
事实是,深入研究这些命令的 timing analysis 通常毫无意义: 他们的目的通常是通过编写工具几乎无法实现的 timing constraints 来限制工具的行为。因此,这些 timing constraints 中的值是通过反复尝试使这些 constraints 更严格而找到的。使用这种方法, timing analysis 本身并不重要。
也就是说,了解 set_max_delay 和 set_min_delay背后的计算仍然是个好主意:
回想一下, timing analysis 有两个部分: 第一部分是 source path: 它计算从 clock edge (在外部 clock pin处)到第二个 flip-flop的 data input 处的更新有效值的时间。这部分是三个元素的总和:
- clock edge 到达第一个 flip-flop ( clock path)所需的时间
- 这个 flip-flop 更新它的值所花费的时间
- 这个新值达到第二个 flip-flop所用的时间
第二部分是 destination path,它仅包含 clock edge 到达第二个 flip-flop所需的时间。我们已经知道此 flip-flop的 input 何时更新(从 source path开始),因此可以根据需要将时间差与所需的 tsu 或 thold进行比较。
但两个 sequential elements确实如此。当一侧是 I/O port时会发生什么情况?为了 timing analysis, port 被视为虚拟的 flip-flop。 clock path delay 到此 flip-flop 为零。
让我们考虑通常的情况,其中 clock 是使用依赖于 get_ports 的 create_clock 命令定义的(如我几乎所有示例所示)。 clock path delay 为零意味着这个虚构的 flip-flop的 clock input 直接连接到 clock pin。因此,在 clock pin 和这个想象中的 flip-flop之间没有 delay 。
这个 flip-flop 的所有 timing 参数都为零: tsu、 thold 和 clock-to-output。这并不反映任何真实的电子元件,但它赋予 set_max_delay 和 set_min_delay 与 output port一起使用时的意义: port的 clock-to-output。例如:
set_max_delay -to [get_ports test_out] 7 set_min_delay -to [get_ports test_out] 0
这两款 timing constraints 要求 @test_out的 clock-to-output 介于 0 ns 和 7 ns之间。
让我们解释一下原因: 回想一下,对于特定的 flip-flops之间的 paths , set_max_delay 命令通常类似于 period constraint 。那么Destination Clock Path会发生什么?计算开始于第二个 clock edge,即 7 ns。但是 clock path delay 到第二个 flip-flop 是零,这个 flip-flop 的 tsu 也是零。所以 Destination Clock Path 的计算结果就是 7 ns。这是 Source Path允许的最大值,照常计算: Source Clock Path 加上 Data Path。综上所述,要求 data output 在第一个 clock edge之后是有效的 7 ns 。这正是 output port对 clock-to-output 的定义。如果相关 clock 的 create_clock 命令基于 get_ports,则此 clock-to-output 是相对于 PCB上的 clock 。
请参阅 timing reports和 Vivado的示例。
请注意, set_output_delay 与外部组件的 tsu 或 thold 相关。 set_max_delay 定义了 FPGA的 output port的 clock-to-output 。所以这两个选项之间的主要区别在于焦点在哪里。
关于一个 input port, set_max_delay 和 set_min_delay 是什么意思,没有直观的解释: Source Path 由接收 input signal的 flip-flop 的 input pin 和 data input 之间的 delay 组成。 Destination Clock Path 在 timing constraint 命令中指定的时间启动。这次加入了 clock path delay 。这些是毫无意义的计算(参见timing reports )。使用 set_input_delay比较自然,这与外部组件的 clock-to-output 有关。
请注意,代表 set_max_delay 和 set_min_delay 制作的 timing analysis 不依赖于 clock period。因此,如果 clock的频率发生变化,则在工具强制执行这些 constraints时会使用相同的数字。相比之下, set_input_delay 和 set_output_delay 的计算取决于 clock的频率。
I/O timing constraints 对 clock频率的依赖可能是优势,也可能是劣势,具体取决于具体情况。如果 timing constraints 是基于外部组件的 timing 参数编写的(并且接口是system synchronous ),那么依赖 set_input_delay 和 set_output_delay可能会更好: 即使 clock的频率发生变化,这些 constraints 也将保持正确。但是,当 timing constraints 的目的是强制工具做出某些选择(例如使用IOB registers )时, set_max_delay 和 set_min_delay 可能更适合。
使用 -datapath_only
timing constraint 的一个可能动机是确保 FPGA 工具尽一切努力实现最小可能的 delay 进出 I/O port。这通常意味着使用IOB register 。这也可能意味着避免在 input port 和 flip-flop 之间插入额外的 delay (这些工具可能会这样做,以便以更好的余量满足 thold 的要求)。
当 timing constraint 用于此目的时,没有特定的 delay 作为目标。这个想法是为了防止工具做任何其他事情,而不是获得最好的结果。如果 FPGA 工具支持 -datapath_only,最好使用带此选项的 set_max_delay 。这从计算中完全排除了 clock delay path ,因此只考虑 I/O port 和 flip-flop 之间的 delay 。这样, timing constraint的要求与其用途准确对应: 在 flip-flop 和 I/O pin之间控制 delay 。
这是 Vivado的一个简单示例:
set_max_delay -datapath_only -from [get_ports test_in] 2 set_max_delay -datapath_only -from [all_registers] \ -to [get_ports test_out] 3
但是“-from [all_registers]”部分的目的是什么?为什么需要“-from”?简短的回答是 Vivado 拒绝接受没有“-from”部分的命令。关于 input port的命令没有类似的要求。
timing reports 和 datapath_only 位于带有示例的页面底部。
概括
set_input_delay 和 set_output_delay 通常被认为是 I/O timing constraints的首选命令。实际上,当接口为system synchronous时,这通常是正确的选择。在其他情况下,可能值得考虑改用 set_max_delay 和 set_min_delay ,因为它们可能更好地反映 I/O port的 timing所需的限制。