01signal.com

Timing Closure的艺术

此页面属于关于 timing的一系列页面。前几页解释了一些基本主题 timing 计算和 clock period timing constraint背后的理论。还展示并解释了一些 timing reports 。现在该说说这些知识的一个重要用途了解决 timing 问题。

介绍

FPGA 工具最大的挑战是实现 timing constraints的要求。这很有希望成功,但有时会失败。当它失败时,是我们人类有责任找出它失败的原因并加以修复。这个任务有一个名字: 我们称之为Timing Closure 。这不是一件容易的事。

为什么 timing closure 难?问题是,这些工具有一个 place and route 算法,试图以最佳方式使用 FPGA的资源。通常,该算法首先会毫不费力地将 logic elements 放在 FPGA 上。然后一个迭代过程开始: 工具遍历所有的 paths,找出不满足 timing 要求的 paths 。为了纠正这些故障,对这些 paths采取了纠正措施。最值得注意的是, logic elements 移动到 FPGA的不同位置,并对 routing 进行了调整。至于更高级的纠正措施,每款 FPGA tool 都有自己的方法。

当所有的 paths 都满足 timing 的要求时, implementation 就被认为完成了。但 implementation 也可以结束,因为工具未能达到这个目标,因此放弃了尝试。在这种情况下,我们得到了停止工作时工具取得的成果。这个结果不一定是最优的: implementation 中可能有 paths 可以改进,但工具正忙于修复其他问题。当失败时,这些工具就放弃了,而没有尝试修复其他问题。就像工具在说: “如果 implementation 无论如何都会失败,那么浪费时间修复它是没有意义的”。

我们作为 FPGA designers 的任务是查看这个次优结果,并找出 timing constraints 的目标没有实现的原因。

随着时间的推移,算法会变得更好。当存在无法实现 timing constraints的常见原因时,下一版本的软件将针对该情况提供特定的解决方案。因此,当工具失败时,通常有充分的理由。

所以我们看看这些工具取得了什么成果,并问自己: 为什么工具会失败?我们要求的东西是不可能的吗?更重要的是,我们是否要求了一些不必要的东西?也许导致工具失败的障碍是我们甚至不需要的东西。或许,优化算法效果不佳?有时这只是运气不好的问题: logic elements 的初始位置可能非常糟糕,以至于后续提高性能的尝试注定要失败。

不管是什么问题,找到失败的原因都类似于侦探调查犯罪现场: 事实摆在眼前,但原因往往是隐藏的。这些事实中的大部分都可以在 timing reports中找到,但线索不会轻易泄露。人们必须经常问的问题是 timing report有什么问题、异常或异常。就像试图找到罪犯的侦探一样,目标是找到导致问题的细节。

但是为了发现什么是异常的,你必须知道什么是正常的: 比如普通的 delay 换 net 配某 fan-out是什么?为了实现某个 logic function,正常的 logic levels 有多少?这类问题的答案因 FPGA 而异。因此,即使一切都很好,也有必要通过阅读和理解 timing reports来获得经验。当一切正常时,您必须能够知道 timing report 的样子,以便找到 timing report 指示问题的地方。如果您想知道我为什么要在前几页中详细介绍,这就是原因之一。

Critical Path

当工具无法实现 timing constraints时,意味着至少有一个 path 具有负 slack。 slack 最负的 path 称为 Critical Path。这个名字反映了 timing closure的惯用策略: 专注于 Critical Path 通常是解决 timing 问题的方法。但我将在下面证明这种策略也可能是浪费时间。

实现 timing constraints 后, Critical Path 就是 path 加上最小的 slack。这个 path 通常并不有趣,因为这些工具不会尝试用积极的 slack来改进 paths 。因此,如果最差的 path 有一个正 slack,那么这个 path 竟然是最差的可能是巧合。

但如果 slack 为正且接近于零(例如,小于 0.2 ns),则表明很难使此 path 达到 timing 要求。这种 Critical paths 可以看作是警告,这些 paths 可能会在未来造成麻烦(特别是当 FPGA 变得充满更多 logic时,因此工具的工作转移到其他 paths)。

timing report 通常为每个 clock包含数量有限的 critical paths 。大多数 FPGA 工具的默认设置是显示一些 critical paths ,即使它们的 slack 为正数(即满足 timing 要求时)。这是推荐的设置。

critical path的一个例子

我将从 Critical Path的分析示例开始。本例 Verilog 代码如下:

reg [24:0] calc, result;
   reg [11:0] x, y, z;

   always @(posedge clk)
     begin
	calc <= x * y + z;
	result <= calc;
     end

本例中 @clk的频率为 250 MHz,没有使用 PLL 来生成这个 clock。还假设 @x、 @y 和 @z 是与 @clk同步的 registers 。没有显示为这些 registers 赋值的 Verilog 代码,因为它不相关。

在 Vivado上尝试此代码时未实现 timing constraints 。在 timing report 中,这是 Critical Path:

Slack (VIOLATED) :        -0.239ns  (required time - arrival time)
  Source:                 x_reg[1]__0_replica_2/C
                            (rising edge-triggered cell FDRE clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Destination:            calc_reg[23]/D
                            (rising edge-triggered cell FDRE clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Path Group:             clk
  Path Type:              Setup (Max at Slow Process Corner)
  Requirement:            4.000ns  (clk rise@4.000ns - clk rise@0.000ns)
  Data Path Delay:        4.180ns  (logic 1.642ns (39.282%)  route 2.538ns (60.718%))
  Logic Levels:           7  (CARRY8=4 LUT3=1 LUT4=1 LUT6=1)
  Clock Path Skew:        -0.087ns (DCD - SCD + CPR)
    Destination Clock Delay (DCD):    3.176ns = ( 7.176 - 4.000 )
    Source Clock Delay      (SCD):    3.864ns
    Clock Pessimism Removal (CPR):    0.601ns
  Clock Uncertainty:      0.035ns  ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
    Total System Jitter     (TSJ):    0.071ns
    Total Input Jitter      (TIJ):    0.000ns
    Discrete Jitter          (DJ):    0.000ns
    Phase Error              (PE):    0.000ns
  Clock Net Delay (Source):      2.032ns (routing 0.396ns, distribution 1.636ns)
  Clock Net Delay (Destination): 1.748ns (routing 0.365ns, distribution 1.383ns)

    Location             Delay type                Incr(ns)  Path(ns)    Netlist Resource(s)
  -------------------------------------------------------------------    -------------------
                         (clock clk rise edge)        0.000     0.000 r
    AG12                                              0.000     0.000 r  clk (IN)
                         net (fo=0)                   0.000     0.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.738     0.738 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.105     0.843    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.049     0.892 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.839     1.731    clk_IBUF
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.101     1.832 r  clk_IBUF_BUFG_inst/O
    X2Y0 (CLOCK_ROOT)    net (fo=106, routed)         2.032     3.864    clk_IBUF_BUFG
    SLICE_X54Y54         FDRE                                         r  x_reg[1]__0_replica_2/C
  -------------------------------------------------------------------    -------------------
    SLICE_X54Y54         FDRE (Prop_HFF2_SLICEL_C_Q)
                                                      0.137     4.001 r  x_reg[1]__0_replica_2/Q
                         net (fo=21, routed)          0.371     4.372    x[1]_repN_2
    SLICE_X56Y53         LUT6 (Prop_E6LUT_SLICEL_I1_O)
                                                      0.219     4.591 r  calc[23]_i_101/O
                         net (fo=2, routed)           0.550     5.141    calc[23]_i_101_n_0
    SLICE_X54Y57         CARRY8 (Prop_CARRY8_SLICEL_DI[5]_CO[7])
                                                      0.228     5.369 r  calc_reg[23]_i_30/CO[7]
                         net (fo=1, routed)           0.030     5.399    calc_reg[23]_i_30_n_0
    SLICE_X54Y58         CARRY8 (Prop_CARRY8_SLICEL_CI_O[1])
                                                      0.163     5.562 r  calc_reg[23]_i_22/O[1]
                         net (fo=3, routed)           0.351     5.913    calc_reg[23]_i_22_n_14
    SLICE_X56Y57         LUT3 (Prop_C6LUT_SLICEL_I1_O)
                                                      0.146     6.059 r  calc[23]_i_26/O
                         net (fo=3, routed)           0.240     6.299    calc[23]_i_26_n_0
    SLICE_X55Y58         LUT4 (Prop_A6LUT_SLICEM_I0_O)
                                                      0.089     6.388 r  calc[23]_i_7/O
                         net (fo=1, routed)           0.407     6.795    calc[23]_i_7_n_0
    SLICE_X53Y57         CARRY8 (Prop_CARRY8_SLICEM_DI[2]_O[4])
                                                      0.308     7.103 r  calc_reg[23]_i_2/O[4]
                         net (fo=1, routed)           0.538     7.641    P[20]
    SLICE_X54Y56         CARRY8 (Prop_CARRY8_SLICEL_S[4]_O[7])
                                                      0.352     7.993 r  calc_reg[23]_i_1/O[7]
                         net (fo=1, routed)           0.051     8.044    P0_out[23]
    SLICE_X54Y56         FDRE                                         r  calc_reg[23]/D
  -------------------------------------------------------------------    -------------------

                         (clock clk rise edge)        4.000     4.000 r
    AG12                                              0.000     4.000 r  clk (IN)
                         net (fo=0)                   0.000     4.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.515     4.515 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.066     4.581    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.034     4.615 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.722     5.337    clk_IBUF
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.091     5.428 r  clk_IBUF_BUFG_inst/O
    X2Y0 (CLOCK_ROOT)    net (fo=106, routed)         1.748     7.176    clk_IBUF_BUFG
    SLICE_X54Y56         FDRE                                         r  calc_reg[23]/C
                         clock pessimism              0.601     7.777
                         clock uncertainty           -0.035     7.741
    SLICE_X54Y56         FDRE (Setup_HFF_SLICEL_C_D)
                                                      0.063     7.804    calc_reg[23]
  -------------------------------------------------------------------
                         required time                          7.804
                         arrival time                          -8.044
  -------------------------------------------------------------------
                         slack                                 -0.239

这个 path 的 slack 是 –0.239 ns,所以有点不符合 timing 的要求。首先要检查的是这个 path的开头和结尾: 我们查看报告的 header中的“Source”和“Destination”,找到 x_reg 和 calc_reg。所以问题的根源显然是这部分:

calc <= x * y + z;

这应该不足为奇,因为它是 Verilog 代码中唯一有意义的操作。在现实生活中, logic 的哪个部分导致问题并不那么明显。

从 timing report 也可以明显看出 logic levels的数量很大: 7。 combinatorial path 太长了。换句话说, @clk的两个 clock edges 之间要做的事情太多了。

但失败的真正原因是什么?也许 routing 负责 delay的 61% ?回想一下,根据经验, routing delay 通常是总 delay中的 40% 。那么也许尝试使用 FPGA 工具来获得更好的性能?然而,这不太可能是一个成功的解决方案,因为这些工具通常会在放弃尝试实现 path的 timing 要求之前努力工作。

尝试在 @x 和 @calc 之间更改 logic function 同样是徒劳的: 乘法是必不可少的,所以没有办法用更简单的东西代替。

我将在下一页介绍解决此类问题的其他可能方法。但是在这种情况下,浏览一系列技术将无济于事。这个简单的例子表明,有时我们需要像侦探一样思考。

你的大脑无可替代

阅读 timing report 时要问的第一个问题是它有什么异常。在此示例中,答案是 combinatorial path 仅由 slices组成: 几乎所有 FPGAs 都有指定的算术单元(DSPs、 ALUs,名称各不相同),它们在请求乘法时使用。实际上, multiply and add 是此类指定 logic中最常见的功能。所以大多数情况下最简单的解决办法就是让工具使用指定的运算单元。此解决方案的 timing report 显示在本页底部。

但我们真正应该问的问题是,为什么使用 slices 而不是指定的运算单元。最常见的原因是 FPGA的所有可用运算单元已被 design的其他部分使用。在这种情况下,必要的更改可能与 critical path 根本无关: 也许需要通过从 design中移除一些 logic 来释放一些运算单元。另一种可能性是指示工具在 design的不同部分之间以不同方式分配这些算术单元。

在此示例中,使用 slices 代替算术单元,因为我希望发生这种情况: 我特意关掉了运算单元的使用( Vivado的 synthesizer有一个参数: 我将 max_dsp 设置为零)。但这并不能使这个例子是人为的。 FPGA tools有时使用不正确的参数,导致这种情况。事实上,有时故意不使用运算单元是正确的,因为 design的其他地方更需要它们。

因此,简单的解决方案是使用指定的算术单元。但是,如果我们必须使用 slices怎么办?同样,解决方案是间接的。回想一下,有问题的部分是:

calc <= x * y + z;

但请注意,这是紧随其后的:

result <= calc;

如果 @calc 仅用于此行,而不用于其他任何地方,则可以将计算分为两个阶段。这种技术通常称为 pipelining。所以 Verilog 代码更改为:

reg [24:0] calc, result;
   reg [11:0] x, y, z, z_d;

   always @(posedge clk)
     begin
	z_d <= z;

	calc <= x * y;
	result <= calc + z_d;
     end

在此解决方案中, @calc 仅给出乘法结果。 @z 的值仅在下一阶段添加到 @calc 。更准确地说,加操作是在 @calc 和 @z_d之间,因为这个操作发生在一个 clock cycle 之后。所以 @result 的值和之前完全一样。

这样解决问题很容易,因为 @result 只是原始 Verilog 代码中 @calc 的延迟副本。在现实生活中,我们通常没有这么幸运。

请注意, critical path 仅涉及 @calc 和 @x。 path中甚至没有提到 @z 。所以这种操作的目的是为了减轻算术运算的负担。或者更准确地说,减少 logic levels的数量。

回想一下, critical path 是执行优化算法后最差的 path 。该算法不询问问题的原因。相反,它试图改进具有负 slack的 paths 。因此,即使问题的解决方案需要对 @z进行操作,与 @z 相关的 path 也不是 critical path。这只是一个巧合,但这种情况经常发生。

此解决方案的 timing report 和 critical path 也显示在本页底部。表明 logic levels 的数量从 7 减少到 6。结果, data path delay 减少了 0.715 ns,满足 timing 的要求绰绰有余。

从这个例子中吸取的教训是, critical path 并不总是问题的直接原因。问为什么这个 path 失败仍然是正确的,但解决方案可以在其他地方。请记住,每个 FPGA 工具都有自己的实用程序,这些实用程序提供的信息可以帮助找到问题的根本原因。花时间探索这些实用程序并阅读它们的文档是值得的。

尽早避免问题而不是稍后解决问题

如果从一开始就正确地完成 logic design ,那么 timing closure 上的大部分工作都可以避免。这需要持续意识到 logic design 不是软件这一事实。 Verilog 代码的目的不是在 simulation期间产生正确的结果。真正重要的是 synthesizer 从 Verilog 代码生成的输出。

一个好的 logic design 首先要考虑 logic 应该如何最好地实现其目的。这包括识别与 timing相关的潜在障碍。

经验不足的 FPGA designers 经常通过反复试验开发 Verilog 代码。用 simulation 看 logic 是否按预期工作,逐步修正,直到 simulation 输出正确。结果可能是无法在硬件上使用的 logic : 为了实现 timing constraints,必须完全重写 Verilog 代码。

提前考虑 Verilog 代码生成的 combinatorial paths 很重要。这个想法是查看每个 register,并跟踪 combinatorial path 到底。回想一下, combinatorial path 始终以 register 开始并以 register结束。

让我们看一下这个例子:

reg [15:0] a, b;
wire [16:0] x, y;
reg [33:0] z;

assign x = a + 2;
assign y = b + 3;

always @(posedge clk)
  z <= x * y;

关于 @a: 当这个 register 变化时, combinatorial path 到达 @x 作为第一阶段。但是 @x 不是 register。 @x 凭借 continuous assignment进行更新。因此 path 继续 @z。所以这个 combinatorial path中有两个显着的 logic operations : 算术加法和算术乘法。这太多了吗?是否需要借助 pipelining将其拆分为两个 clock cycles?这取决于 clock frequency 和使用的 FPGA 。

另一个重要因素是将 combinatorial paths 变短的难度。有时长 combinatorial path 是不可避免的。但是当改进 path的 timing 很容易时,即使 design中有更差的 paths ,也要这样做: 如果一个 design中有几个有问题的 paths ,工具往往可以集中精力在这些 paths上实现 timing constraints 。当很容易满足另一个 paths的 timing 要求时,它有很大帮助。

因此,为了获得实现 timing constraints的 design ,没有允许或不允许的规则。它需要 FPGA design 的经验才能在该领域做出正确的决定。使用特定 FPGA 工具的经验也很重要。唯一永远正确的规则是: 如果可以通过简单更改 Verilog 代码来改进 timing ,那就去做吧。不要偷懒,从一开始就做出改变。始终牢记 timing 。

快速编写 logic

如前所述,目标是在 registers之间实现短 combinatorial paths : 计算 registers 的下一个值的 logic functions 应该很简单。换句话说,应该需要少量的 logic levels 来实现这些 logic functions。

作为 FPGA designers ,我们的任务是查看 Verilog 代码并评估 logic functions 的复杂程度。这需要了解 synthesizer 如何将 Verilog 转换为 logic elements (LUTs 和其他 logic primitives)。这些知识是通过经验获得的,部分是通过分析 timing reports获得的。使事情变得更加困难的是,这种翻译从一个 FPGA 到另一个 FPGA 是不同的。因此,编写可产生快速 logic的 Verilog 代码并非易事。

如果你是 FPGA 的新手,建议花点时间看看 implementation 的成绩,以求学习。 timing report 显示了如何将 logic design 分解为简单的 logic elements的示例。 FPGA 工具还提供其他用于查看低级 logic elements的实用程序。

此外,还有一些简单的规则可以提供帮助:

两个额外的 timing reports

我在上面的“你的大脑无可替代”一节中承诺了两个 timing reports 。我把它们放在这里,而不是在提到它们的地方,因为它们很长而且不完全相关。

请注意,这两个 timing reports 中的每一个都是相关场景的 critical path 。因此, path 与上面显示的 path 不在同一 registers 处开始和结束。

第一个 timing report 与第一个 Verilog 代码示例相关。与上面的 timing report 不同,这些工具可以使用指定的运算单元。结果是轻松实现了 timing constraints 。

此 timing report 是为 Kintex Ultrascale FPGA生成的。在 FPGAs这个家族中,一个指定的运算单元被称为 DSP48E2。请注意, path 在同一个 DSP48E2 单元上开始和结束。因此 logic delay 是 100%。

Slack (MET) :             1.406ns  (required time - arrival time)
  Source:                 calc_reg/DSP_A_B_DATA_INST/CLK
                            (rising edge-triggered cell DSP_A_B_DATA clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Destination:            calc_reg/DSP_OUTPUT_INST/ALU_OUT[10]
                            (rising edge-triggered cell DSP_OUTPUT clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Path Group:             clk
  Path Type:              Setup (Max at Slow Process Corner)
  Requirement:            4.000ns  (clk rise@4.000ns - clk rise@0.000ns)
  Data Path Delay:        2.445ns  (logic 2.445ns (100.000%)  route 0.000ns (0.000%))
  Logic Levels:           4  (DSP_ALU=1 DSP_M_DATA=1 DSP_MULTIPLIER=1 DSP_PREADD_DATA=1)
  Clock Path Skew:        -0.010ns (DCD - SCD + CPR)
    Destination Clock Delay (DCD):    3.392ns = ( 7.392 - 4.000 )
    Source Clock Delay      (SCD):    4.096ns
    Clock Pessimism Removal (CPR):    0.694ns
  Clock Uncertainty:      0.035ns  ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
    Total System Jitter     (TSJ):    0.071ns
    Total Input Jitter      (TIJ):    0.000ns
    Discrete Jitter          (DJ):    0.000ns
    Phase Error              (PE):    0.000ns
  Clock Net Delay (Source):      2.264ns (routing 0.756ns, distribution 1.508ns)
  Clock Net Delay (Destination): 1.964ns (routing 0.696ns, distribution 1.268ns)

    Location             Delay type                Incr(ns)  Path(ns)    Netlist Resource(s)
  -------------------------------------------------------------------    -------------------
                         (clock clk rise edge)        0.000     0.000 r
    AG12                                              0.000     0.000 r  clk (IN)
                         net (fo=0)                   0.000     0.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.738     0.738 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.105     0.843    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.049     0.892 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.839     1.731    clk_IBUF
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.101     1.832 r  clk_IBUF_BUFG_inst/O
    X2Y1 (CLOCK_ROOT)    net (fo=80, routed)          2.264     4.096    calc_reg/CLK
    DSP48E2_X11Y34       DSP_A_B_DATA                                 r  calc_reg/DSP_A_B_DATA_INST/CLK
  -------------------------------------------------------------------    -------------------
    DSP48E2_X11Y34       DSP_A_B_DATA (Prop_DSP_A_B_DATA_DSP48E2_CLK_A2_DATA[9])
                                                      0.302     4.398 r  calc_reg/DSP_A_B_DATA_INST/A2_DATA[9]
                         net (fo=1, routed)           0.000     4.398    calc_reg/DSP_A_B_DATA.A2_DATA<9>
    DSP48E2_X11Y34       DSP_PREADD_DATA (Prop_DSP_PREADD_DATA_DSP48E2_A2_DATA[9]_A2A1[9])
                                                      0.182     4.580 r  calc_reg/DSP_PREADD_DATA_INST/A2A1[9]
                         net (fo=1, routed)           0.000     4.580    calc_reg/DSP_PREADD_DATA.A2A1<9>
    DSP48E2_X11Y34       DSP_MULTIPLIER (Prop_DSP_MULTIPLIER_DSP48E2_A2A1[9]_U[10])
                                                      0.994     5.574 f  calc_reg/DSP_MULTIPLIER_INST/U[10]
                         net (fo=1, routed)           0.000     5.574    calc_reg/DSP_MULTIPLIER.U<10>
    DSP48E2_X11Y34       DSP_M_DATA (Prop_DSP_M_DATA_DSP48E2_U[10]_U_DATA[10])
                                                      0.164     5.738 r  calc_reg/DSP_M_DATA_INST/U_DATA[10]
                         net (fo=1, routed)           0.000     5.738    calc_reg/DSP_M_DATA.U_DATA<10>
    DSP48E2_X11Y34       DSP_ALU (Prop_DSP_ALU_DSP48E2_U_DATA[10]_ALU_OUT[10])
                                                      0.803     6.541 r  calc_reg/DSP_ALU_INST/ALU_OUT[10]
                         net (fo=1, routed)           0.000     6.541    calc_reg/DSP_ALU.ALU_OUT<10>
    DSP48E2_X11Y34       DSP_OUTPUT                                   r  calc_reg/DSP_OUTPUT_INST/ALU_OUT[10]
  -------------------------------------------------------------------    -------------------

                         (clock clk rise edge)        4.000     4.000 r
    AG12                                              0.000     4.000 r  clk (IN)
                         net (fo=0)                   0.000     4.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.515     4.515 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.066     4.581    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.034     4.615 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.722     5.337    clk_IBUF
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.091     5.428 r  clk_IBUF_BUFG_inst/O
    X2Y1 (CLOCK_ROOT)    net (fo=80, routed)          1.964     7.392    calc_reg/CLK
    DSP48E2_X11Y34       DSP_OUTPUT                                   r  calc_reg/DSP_OUTPUT_INST/CLK
                         clock pessimism              0.694     8.086
                         clock uncertainty           -0.035     8.050
    DSP48E2_X11Y34       DSP_OUTPUT (Setup_DSP_OUTPUT_DSP48E2_CLK_ALU_OUT[10])
                                                     -0.104     7.946    calc_reg/DSP_OUTPUT_INST
  -------------------------------------------------------------------
                         required time                          7.946
                         arrival time                          -6.541
  -------------------------------------------------------------------
                         slack                                  1.406

第二个 timing report 与 Verilog 代码的第二个示例相关。在本例中,借助 pipelining,情况得到了改善:

Slack (MET) :             0.433ns  (required time - arrival time)
  Source:                 y_reg[1]__0/C
                            (rising edge-triggered cell FDRE clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Destination:            calc_reg[23]/D
                            (rising edge-triggered cell FDRE clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Path Group:             clk
  Path Type:              Setup (Max at Slow Process Corner)
  Requirement:            4.000ns  (clk rise@4.000ns - clk rise@0.000ns)
  Data Path Delay:        3.465ns  (logic 1.653ns (47.706%)  route 1.812ns (52.294%))
  Logic Levels:           6  (CARRY8=4 LUT4=2)
  Clock Path Skew:        -0.129ns (DCD - SCD + CPR)
    Destination Clock Delay (DCD):    3.373ns = ( 7.373 - 4.000 )
    Source Clock Delay      (SCD):    4.040ns
    Clock Pessimism Removal (CPR):    0.538ns
  Clock Uncertainty:      0.035ns  ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
    Total System Jitter     (TSJ):    0.071ns
    Total Input Jitter      (TIJ):    0.000ns
    Discrete Jitter          (DJ):    0.000ns
    Phase Error              (PE):    0.000ns
  Clock Net Delay (Source):      2.208ns (routing 0.756ns, distribution 1.452ns)
  Clock Net Delay (Destination): 1.945ns (routing 0.696ns, distribution 1.249ns)

    Location             Delay type                Incr(ns)  Path(ns)    Netlist Resource(s)
  -------------------------------------------------------------------    -------------------
                         (clock clk rise edge)        0.000     0.000 r
    AG12                                              0.000     0.000 r  clk (IN)
                         net (fo=0)                   0.000     0.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.738     0.738 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.105     0.843    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.049     0.892 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.839     1.731    clk_IBUF
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.101     1.832 r  clk_IBUF_BUFG_inst/O
    X2Y1 (CLOCK_ROOT)    net (fo=121, routed)         2.208     4.040    clk_IBUF_BUFG
    SLICE_X54Y88         FDRE                                         r  y_reg[1]__0/C
  -------------------------------------------------------------------    -------------------
    SLICE_X54Y88         FDRE (Prop_EFF2_SLICEL_C_Q)
                                                      0.138     4.178 r  y_reg[1]__0/Q
                         net (fo=25, routed)          0.505     4.683    y[1]
    SLICE_X53Y91         LUT4 (Prop_B6LUT_SLICEM_I0_O)
                                                      0.150     4.833 r  calc[7]_i_28/O
                         net (fo=1, routed)           0.344     5.177    calc[7]_i_28_n_0
    SLICE_X53Y89         CARRY8 (Prop_CARRY8_SLICEM_DI[2]_CO[7])
                                                      0.424     5.601 r  calc_reg[7]_i_9/CO[7]
                         net (fo=1, routed)           0.043     5.644    calc_reg[7]_i_9_n_0
    SLICE_X53Y90         CARRY8 (Prop_CARRY8_SLICEM_CI_O[0])
                                                      0.122     5.766 r  calc_reg[23]_i_30/O[0]
                         net (fo=3, routed)           0.402     6.168    calc_reg[23]_i_30_n_15
    SLICE_X51Y88         LUT4 (Prop_C5LUT_SLICEL_I0_O)
                                                      0.169     6.337 r  calc[15]_i_8/O
                         net (fo=1, routed)           0.437     6.774    calc[15]_i_8_n_0
    SLICE_X51Y92         CARRY8 (Prop_CARRY8_SLICEL_DI[1]_CO[7])
                                                      0.422     7.196 r  calc_reg[15]_i_1/CO[7]
                         net (fo=1, routed)           0.030     7.226    calc_reg[15]_i_1_n_0
    SLICE_X51Y93         CARRY8 (Prop_CARRY8_SLICEL_CI_O[7])
                                                      0.228     7.454 r  calc_reg[23]_i_1/O[7]
                         net (fo=1, routed)           0.051     7.505    calc_reg[23]_i_1_n_8
    SLICE_X51Y93         FDRE                                         r  calc_reg[23]/D
  -------------------------------------------------------------------    -------------------

                         (clock clk rise edge)        4.000     4.000 r
    AG12                                              0.000     4.000 r  clk (IN)
                         net (fo=0)                   0.000     4.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.515     4.515 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.066     4.581    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.034     4.615 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.722     5.337    clk_IBUF
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.091     5.428 r  clk_IBUF_BUFG_inst/O
    X2Y1 (CLOCK_ROOT)    net (fo=121, routed)         1.945     7.373    clk_IBUF_BUFG
    SLICE_X51Y93         FDRE                                         r  calc_reg[23]/C
                         clock pessimism              0.538     7.910
                         clock uncertainty           -0.035     7.875
    SLICE_X51Y93         FDRE (Setup_HFF_SLICEL_C_D)
                                                      0.063     7.938    calc_reg[23]
  -------------------------------------------------------------------
                         required time                          7.938
                         arrival time                          -7.505
  -------------------------------------------------------------------
                         slack                                  0.433

差异并不像使用指定算术单元时那么显着。但它仍然足以实现 timing constraint。


关于 timing closure的一般性讨论到此结束。下一页就此主题提出了几种实用策略。

此页面由英文自动翻译。 如果有不清楚的地方,请参考原始页面
Copyright © 2021-2024. All rights reserved. (6f913017)