01signal.com

logic design中 timing 的基础知识

此页面属于关于 timing的一系列页面

关于本页

如果不了解 logic design中的一些基本主题,就不可能正确完成 timing 。此页面解释了一些基本概念,这些概念是本系列页面其余部分的基础。

下面写的所有内容都是在有关 logic design的学术课程中教授的。然而,并不是所有使用 FPGAs 的人都上过这样的课程,即使上过这样的课程的人也不一定能记住所有的事情。此页面旨在填补缺失的部分(如果存在)。

随意跳过此页面上您已经知道的部分,但仍然建议通读所有内容,即使这种阅读是肤浅的。本页的最后几节对于理解本系列的后续页面特别重要。

简要回顾

在进入与 timing相关的概念之前,我将快速回顾一下 logic design中的一些相关术语。如果您还不知道这些术语中的任何一个,我建议您先熟悉一下,然后再继续浏览此页面。

首先, combinatorial logic。该术语用于描述 logic gates等元素: AND、 OR、 NOT等。这些 logic elements 因为没有内存所以被认为是 combinatorial logic 。换句话说,他们的行为不取决于过去发生的事情。这些 logic elements 的 output 处的值仅取决于 inputs处的值。

combinatorial logic 的一个重要类型是 look-up table (LUT)。这是一个多用途的 logic element,它实现了依赖于多个 inputs的任何 logic function 。 LUT 很重要,因为它用于 FPGA内的几乎所有 combinatorial logic 。 FPGA 中的 LUTs 实现为 asynchronous ROMs (即没有 clock的 ROMs ): inputs 作为地址线处理, output 通常有一个 bit 或两个 bits的宽度。

inputs 到这些 LUTs 的数量在市面上几乎所有的 FPGAs 中都是 4 或 6 ,所以每个 LUT 中的存储单元数量要么是 16 要么是 64。

下一个重要术语是 sequential logic。这包括 flip-flops、 synchronous RAMs和许多其他需要 clock 才能运行的构建块。作为对 clock特定变化的反应,所有这些 logic elements 都会变得活跃。在这些活动时刻之间, sequential elements 忽略它们的 inputs,保留它们的内部状态,并且不改变它们的 outputs。

例如,当 clock 从低电平变为高电平时, positive edge triggered logic elements 有效,即 rising clock edge。同样,当 clock 从高电平变为低电平时, negative edge triggered logic elements 处于活动状态,即 falling clock edge。也有 logic elements 在两个 clock edges上都处于活动状态,但是这样的 logic elements 几乎只用于对 I/O signals 进行采样或生产。

所有 sequential elements 都有某种内存。这是一个直接的结论,因为他们在 clock edge 到货之前不会更换 output 。有的 sequential elements 内存是最小的,正好是一个 bit 内存配一个 output。其他 sequential elements 具有更多内存,例如 shift registers 和 RAMs。

为了讨论 timing,只有两个重要事实: input 仅与 clock edge一起采样,而 output 几乎仅因 clock edge而发生变化。只有一个例外,就是有些 sequential elements 有一个 asynchronous reset input。当此 input 处于活动状态(高电平或低电平,取决于 logic element)时, sequential element 的内部状态立即更改为预定义值,而与 clock无关。结果,此元素的部分或全部 outputs 也立即更改为已知值。

在 FPGA中,一些 sequential elements 具有 asynchronous reset,而另一些则没有。 asynchronous reset 是 FPGA上几乎所有 sequential elements 中唯一可能的 asynchronous input 。即使 logic design 理论包括多个 elements 和多个 asynchronous inputs,例如 S-R flip-flop,也是如此。

下面我来说说 flip-flops

为了简单起见,我假设所有 sequential elements 都是 positive edge triggered flip-flops,即 flip-flops 对 clock的 rising edge 有反应。也就是说,所有的 sequential elements 都在这里用 flip-flops表示。只有当 clock 从低变高时,这些 flip-flops 才会响应它们的 inputs 并更新它们的 outputs 。

这样更容易理解 timing ,关于 flip-flop 的讨论也很容易推广到任何其他 sequential element。

Setup 和 hold

为保证一个 flip-flop 正确可靠的工作,其 inputs 必须稳定(即不改变其值),满足 timing 的两个要求:

Timing diagram showing setup and hold times

上图显示了 tsu 和 thold的含义: D input 在黄色标记的时间段内不允许更改值。在本例中, D 随合法的 timing从高变为低,即在这个黄色时间段之外。

理解这两个 timing 参数的一种方法是这样的: 很明显,如果 input 到 flip-flop 与 clock edge完全一起变化,则不清楚 flip-flop 是否会将 input 视为高电平或低电平。它应该选择什么? clock edge 之前或之后的状态?

那么我们可以问一下, input 与 clock edge的变化“完全一致”是什么意思。这有多准确? timing 的两个参数 tsu 和 thold 定义了距离 clock edge 多远可以安全地更改 input的值。这些参数是为所有 sequential elements 定义的,含义相同。

需要注意的是,如果违反了这个 timing 要求,其后果可能比仅仅 clock edge 之后的 flip-flop 的 output 是随机的要糟糕得多。这是造成这种情况的两个主要原因:

Clock-to-output

为所有 sequential elements 定义的第三个 timing 参数是 clock-to-output 时间,它有几个常用的符号,例如 tcko、 tco、 tC_Q 等。这个参数不是 timing 的要求。相反,此参数表示 the sequential element 的 output (Q) 何时保证有效。更准确地说,在 clock edge 之后多少时间 output 有效(参见上面的 timing diagram )。

其实这件事有两个参数:

大多数时候,只有最大的 clock-to-output 是有趣的,所以当在 datasheet 中给出这个参数时,它几乎肯定是最大值。

请注意,如果违反 flip-flop的 timing 要求(tsu 和 thold),则无法保证 output 何时稳定。在这种情况下,最大 clock-to-output 参数没有意义,因为 flip-flop 可能会在短时间内保持未定义状态 (metastability)。

tsu 和 thold 可以是负的

尽管上图显示的 tsu 和 thold为正值,但这些参数中的一个或两个可能为负值。事实上, FPGAs 内部的 flip-flops 通常两个参数都是负数,尽管负数非常小。

例如,负的 tsu 意味着 clock edge 到货时 data 不必稳定。相反, data 必须在 clock edge之后略微达到其稳定值。但是 tsu 在 clock edge之后还是有限制的。

同样,负 thold 允许 data 在 clock edge之前改变。再一次,在允许多少之前仍然存在限制, thold反映了这一点。

因为 tsu 和 thold 都可以是负数,所以理论上可以定义无意义的 timing 要求。例如,如果 thold 允许 input 在 tsu 要求它稳定之前发生变化,那是没有任何意义的。对于任何真正的 timing 规范,这当然永远不会发生: 规范必须定义一定的时间段,在此期间要求 input 保持稳定。如果没有这样的时间段, flip-flop 什么时候对其 input进行采样?

clock-to-output 参数始终为正: flip-flop 在到达之前不可能对 clock edge 做出反应。

Propagation delay

Two flip-flops connected through a LUT

上图显示了两个 flip-flops 与中间的 LUT 之间的简单连接。为了简单起见,我们假设 LUT的 output 只依赖于 I1。例如,此 logic 可能是以下 Verilog 代码的结果,因此 LUT 实现了 NOT gate:

always @(posedge clk)
  begin
    foo_reg <= foo;   // FF1 = foo_reg
    bar <= !foo_reg;  // FF2 = bar
  end

请注意,两个 flip-flops 都连接到同一个 clock。这个 clock的最大频率是多少?

要回答这个问题,缺少一条信息: 从 FF1的 output 有稳定值到 FF2的 input 有稳定值需要多少时间?我们将时间标记为 tpd (propagation delay)。

请注意,术语 propagation delay 始终与 combinatorial logic的特定 segment 相关。明确定义它与哪个 segment 相关很重要。例如,也可以将 LUT的 I1 到同一个 LUT的 O (从 input 到 output)的时间定义为 propagation delay。这个 delay 很可能和之前定义的 tpd不一样。

特别是在 FPGA上, FF1 的 output 和 LUT的 input 之间有一个 routing delay 。所以在现实生活中, FF1的 Q 和 LUT的 I1不是同一个点, signal 在这两个点之间传播需要一定的时间。

由于这种歧义,很少在 datasheets 中看到 tpd 符号用于 FPGAs。而在这样的 datasheets中给出一个 propagation delay 的时候,这个参数的准确含义通常是写明的。

稍后我会回到 clock的最大频率。

path

很难给出 path的简洁定义,但我们已经看到了它的示例。上面我把 tpd 定义为介于 FF1的 Q 和 FF2的 D之间的 propagation delay 。这个 tpd 涉及到一个具体的场景: FF1 改变它的值,然后更新的值到达 LUT,之后 LUT 改变它的 output,最后更新的值到达 FF2。这一系列事件从仅改变一个 signal (FF1的 output)开始,到不同点的 signal (FF2的 input)稳定时结束。

所以 tpd 从 FF1的 Q 到 FF2的 D定义为 path 的 propagation delay 。或者简称为从 FF1 到 FF2的 path 。

path 包含从该序列的开头到结尾导致 delay 的所有元素。 path中有两种类型的元件:

path 的目的是计算其 propagation delay。接下来显示如何使用此计算结果。

通常一个 path 代表一个理论实验,其中一个 flip-flop的 output 发生变化,我们遵循特定的路线导致另一个 flip-flop的 input 。在这个理论实验中,假想的秒表在第一个 flip-flop 的 output 发生变化时启动。当第二个 flip-flop 的 input 发生变化时,此秒表停止。

这个理论实验有助于回答这个秒表显示的时间是否过长,这意味着违反了 tsu 的要求。第二个问题是这个时间是不是太短了,所以违反了 thold

请注意, path 的路由仅包括布线和 combinatorial logic。因此, signal 在目的地稳定所需的时间仅取决于 combinatorial logic 和 routing 以及 path的元素。不管这个理论实验什么时候做,结果总是一样的。

在一个真正的 FPGA design中,每个 flip-flop 通常有许多到达其 input的 paths ,以及许多从其 output开始的 paths 。事实上,一对 flip-flops 之间也可以有多个 path 。然而, timing 的计算始终假设只有一个 flip-flop 更改了其 output,而 FPGA的 logic 中发生的一切都是该更改的直接结果。在 FPGA design 中计算的 paths 的数量可能是巨大的,但这当然是由软件自动完成的。

一个简单的 static timing analysis

为了演示,我将用两个 flip-flops制作一个上面示例的简单 timing analysis 。 timing constraints 的话题后面再说,暂时先假设 @clk 的频率是 250 MHz (4 ns),直接接 logic (即没有 PLL,真 design不推荐这样) ,但这简化了 timing analysis)。 timing constraint ( SDC 风格)可能是这样的:

create_clock -period 4.000 -name clk [get_ports clk]

本系列的下一页显示了一个真实的 timing 分析示例,但该分析是准确的,因此包含许多难以理解的细节。所以这是一个简单的分析,只是演示原理。

分析执行上述理论实验: 一个假想的秒表与 @clk的 rising edge一起开始。这是事件链,以及每个事件所贡献的(虚构的) delay 。

Timing delay of path with a LUT between two flip-flops

这个 path 的 propagation delay (tpd) 是所有这些 delays的总和: 0.2 + 0.3 + 0.3 + 0.4 = 1.2 ns。为了示例,我们假设 FF2的 tsu 是 0.1 ns。这意味着 FF2的 input (D)在 @clk的下一个 rising edge 之前必须是稳定的 0.1 ns 。换句话说,允许的最大 tpd 是 4 - 0.1 = 3.9 ns。

但是 tpd 只是 1.2 ns,所以按照这个计算, path 以较大的优势实现了 timing constraint 。此边距称为 slack,在本例中为 3.9 - 1.2 = 2.7 ns。当此数字出现在软件的 timing 计算中时,表明工具是否难以实现 timing constraints : 如果 slack 接近于零,通常表示软件必须努力工作才能使 path 达到 timing。

propagation delay 还允许我们计算 path 可以达到 timing 的 @clk 的最大频率。 tpd 就是 1.2 ns, tsu 的要求就是下一个 rising edge 可以晚点到 0.1 ns 。也就是说, rising edges之间至少要有 1.3 ns 。这意味着大约 769 MHz的频率。这是一个非常高的频率,但这是一个现实的结果,因为 path 只包含一个 LUT。现实生活中的 logic 通常比这更复杂,这就是为什么现实生活中的频率通常要低得多。

真正的 static timing analysis 可以准确地进行此计算,但这只是故事的一部分。这里计算出的 path 在实际计算中称为data path。然而,真正的 static timing analysis 还考虑到 clock edge 不会同时到达两个 flip-flops 。这是因为从 clock buffer 到 flip-flops 中的每一个 delay 都略有不同。这些 delays 之间的差异称为clock skew 。此外,由于 clock jitter,每个 clock edge 之间的时间也不完全相同。 clock 的这些问题使精确计算更加复杂,如下一页所示。

Recovery 和 Removal

如果 flip-flop 有 asynchronous reset input (您确定要那个吗?),则此 input 何时变为非活动状态有要求。请注意, reset 何时激活并不重要,因为 flip-flop 无论如何都会更改为已知状态。

但是当 reset 变为非活动状态时, flip-flop 开始对 clock敏感。如果 reset 的停用发生在靠近 clock edge的地方,则不清楚 flip-flop 是否应该对此做出响应。就像 tsetup 和 thold一样, reset 必须在 clock edge前后的一段时间内保持稳定。或者,更具体地说:

这些定义类似于 tsetup 和 thold的定义。这不是巧合: recovery time 是一种特殊的 setup time。 timing analysis 以相同的方式完成。唯一的区别是无论 data signal的值如何, setup time 都是相关的。相比之下,当 asynchronous reset signal 更改为活动时,不会强制执行 recovery time 。 removal time 和 hold time 之间的关系是一样的。

由于这种相似性, Recovery 和 Removal 将不再讨论。另请注意,上述内容适用于所有 asynchronous inputs,而不仅仅是 asynchronous reset。

RTL paradigm 和 timing

上面显示的带有两个 flip-flops 的示例很简单,但它代表了使用 RTL paradigm创建的所有 logic : 每个 path 都从 flip-flop 开始,到 flip-flop 结束,并具有相同的 clock (或 related clock)。 path 本身由 combinatorial logic 和 routing组成。在这个例子中, combinatorial logic 只是一个 LUT,但这和 path中的几个 logic elements 没有本质区别。结构是一样的。

RTL paradigm 之所以如此重要,是因为当使用这种方法时,几乎所有的 data paths 都具有相同的简单结构。由于 logic design 中的 paths 数量通常很大,因此 timing analysis 的简单性有助于防止错误。其中, timing analysis 具有特定模式这一事实使得读取 timing report 并询问它是否有意义成为可能。

所以在可能的范围内,一切都应该以 sequential element 开始,以 sequential element结束。在编写 Verilog 代码以及总体规划 logic的结构时,这是一个有用的指南。


timing constraints背后的理论简介到此结束。 clock period constraint 和相关的 timing reports 将在下一页进行说明。

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