绪论

众所周知,静态时序分析是IC工程师必备知识点,也是秋招中笔试面试的高频考点。
网上不乏优秀视频课,如V3学院尤老师、小梅哥、IC创新学院邸志雄老师的课。
《Static Timing Analysis for Nanometer Designs:A Practical Approach》,可堪称静态时序分析的“圣经”吧!
由于网上找不到此书的翻译,因此笔者决定开坑进行对“圣经”的翻译~!希望可以在加深对静态时序分析的学习同时,完成这一本书的翻译方便大家以后更好地从中学习吧。


本章节概述了纳米级(nanometer)设计下的静态时序仿真过程
本章节解决了如下问题:

  • 什么是静态时序分析(static timing analysis)?
  • 噪声(noise)与串扰(crosstalk)会带来什么影响 ?
  • 如何使用静态时序分析?
  • 在整个设计流程中的哪个阶段会应用静态时序分析?

纳米设计

​ 在半导体器件中,金属互连走线通常用于在电路的各个部分之间建立连接以实现设计。众所周知,随着工艺技术的缩小,这些互连走线会影响设计的性能。对于深亚微米或纳米工艺技术,互连中的耦合会引起噪声和串扰——这两种情况都会限制设计的运行速度。虽然噪声和耦合效应在老一代技术中可以忽略不计,但它们在纳米技术中发挥着重要作用。因此,物理设计应考虑串扰和噪声的影响,然后设计验证应包括串扰和噪声的影响。

什么是静态时序分析?

​ 静态时序分析(也称为 STA)是可用于验证数字设计时序的众多技术之一。用于验证时序的另一种方法是时序仿真,它可以验证设计的功能和时序。术语时序分析用于指代这两种方法之一 - 静态时序分析或时序仿真。因此,时序分析只是指对时序问题的设计进行分析。

​ STA 是静态的,因为设计分析是静态执行的,不依赖于施加到输入引脚的数据值。这与基于仿真的时序分析形成对比,在基于仿真的时序分析中,对输入信号应用刺激,观察并验证结果行为,然后随着新输入刺激的应用而推进时间,并观察和验证新行为,依此类推。

​ 给定一个设计以及一组输入时钟定义和设计外部环境的定义,静态时序分析的目的是验证设计是否可以以额定速度运行。也就是说,设计可以在指定的时钟频率下安全运行,而不会出现任何时序违规。图 1-1 展示了静态时序分析的基本功能 。DUA 是被分析的设计。一些时序检查的例子是建立和保持检查。建立检查确保数据可以在给定的时钟周期内到达触发器。保持检查确保数据至少保持最短时间,从而不会出现意外的数据通过触发器:也就是说,它确保触发器正确捕获预期数据。这些检查确保正确的数据已准备就绪并可用于捕获并锁定新状态。

img

​ 静态时序分析更重要的方面是对整个设计进行一次分析,并对设计的所有可能路径和场景执行所需的时序检查。因此,STA 是一种用于验证设计时序的完整而详尽的方法。

​ 分析中的设计通常使用指定的硬件描述语言(例如 VHDL 或 Verilog HDL)。外部环境(包括时钟定义)通常使用 SDC或等效格式指定。 SDC 是一种时序约束规范语言。时序报告采用 ASCII 格式,通常有多列,每一列显示路径延迟的一个属性。

为什么使用静态时序分析?

​ 静态时序分析是对设计的所有时序检查的完整而详尽的验证。其他时序分析方法(例如仿真)只能验证设计中受激励影响的部分。通过时序仿真进行验证与所使用的测试向量一样详尽。模拟和验证具有 10-1亿个门的设计的所有时序条件非常缓慢,并且无法完全验证时序。因此,很难通过模拟进行详尽的验证。

​ 另一方面,静态时序分析提供了一种更快、更简单的方法来检查和分析设计中的所有时序路径是否存在任何时序违规。考虑到当今 ASIC 的复杂性,其中可能包含 10 到 1 亿个门,静态时序分析已成为详尽验证设计时序的必要条件。

串扰和噪声(Crosstalk and Noise)

​ 设计功能及其性能可能会受到噪声的限制。噪声是由于与其他信号的串扰或主输入或电源上的噪声而产生的。噪声影响可以限制设计运作频率,并且也可能导致功能故障。因此,一个设计实现必须经过验证证明它的稳健性,这意味着它可以在不影响设计的额定性能情况下承受噪声。

​ 基于逻辑仿真的验证无法处理串扰、噪声和片上变化的影响。

​ 本书中描述的分析方法不仅涵盖了传统的时序分析技术,还涵盖了噪声分析,以验证包括噪声影响在内的设计。

设计流程

​ 本节主要描述本书其余部分使用的上下文中的 CMOS数字设计流程。还简要描述了它对 FPGA 和异步设计的适用性。

CMOS数字设计

​ 在 CMOS 数字设计流程中,静态时序分析可以在实现的许多不同阶段执行。图 1-2 显示了一个典型的流程。

img

​ STA 很少在 RTL 级别完成,因为此时验证设计的功能性比验证时序更为重要。也不是所有的时序信息都可用,因为块的描述在行为级。一旦 RTL 级的设计被综合到门级,STA 用于验证设计的时序。STA 也可以在执行逻辑优化之前运行 - 目标是识别最差或关键的时序路径。 STA可以在逻辑优化后重新运行来查看是否仍有需要优化的失败路径,或确定关键路径。

​ 在物理设计开始时,时钟树被认为是理想的,即它们具有零延迟。一旦物理设计开始并且在时钟树构建之后,就可以执行 STA 来再次检查时序。实际上,在物理设计期间,可以在每一步执行 STA 以识别最差路径。

​ 在物理实现中,逻辑单元通过互连金属走线连接。金属走线的寄生 RC(电阻和电容)会影响通过这些走线的信号路径延迟。在典型的纳米设计中,互连的寄生效应可以解释设计中的大部分延迟和功耗。因此,任何设计分析都应评估互连对性能特征(速度、功率等)的影响。如前所述,信号走线之间的耦合会产生噪声,设计验证必须包括噪声对性能的影响。

​ 在逻辑设计阶段,由于没有与布局相关的物理信息,因此可以假设为理想互连;可能更有兴趣查看导致最坏路径的逻辑。此阶段使用的另一种技术是使用线载模型估算互连的长度。线载模型根据单元的扇出提供估计的 RC。

​ 在最终确定走线的布线( routing)之前,实施工具使用布线距离的估计来获得布线的 RC 寄生效应。由于布线还没有最终确定,所以这个阶段称为全局布线阶段(global route),以区别于最终布线阶段(final route)。在物理设计的全局布线阶段,简化布线用于估计布线长度,布线估计用于确定计算布线延迟所需的电阻和电容。在这个阶段,不能包括耦合的影响。详细布线完成后,使用提取工具得到的实际 RC 值,可以分析耦合的影响。但是,物理设计工具可能仍会使用近似值来帮助改善计算 RC 值的运行时间。

​ 提取工具用于从布线设计中提取详细的寄生参数(RC 值)。这样的提取工具可以选择在迭代优化期间以较小的运行时间和较不精确的RC值获得寄生参数,也可以选择在最终验证过程中以较大的运行时间提取非常精确的RC值。

​ 总而言之,静态时序分析可以在门级网表上执行,具体取决于:

  1. 互连(interconnect)是怎么建模 的-——理想互连、线载模型、具有近似 RC 的全局布线或具有准确 RC 的真实布线。
  2. 时钟是怎么建模 的-——时钟是理想的(零延迟)还是传播的(实际延迟)。
  3. 是否包括信号之间的耦合——是否分析了任何串扰噪声。

​ 图 1-2 似乎暗示 STA 是在实现步骤之外完成的,也就是说,STA 是在每个综合、逻辑优化和物理设计步骤之后完成的。实际上,这些步骤中的每一个都在其功能范围内执行集成(和增量)STA。例如,逻辑优化步骤中的时序分析引擎,它是用于识别优化器需要处理的关键路径。同样,布局工具中的集成时序分析引擎用于在布局逐步进行时保持设计的时序。

FPGA设计

​ STA 的基本流程在 FPGA 中仍然有效。尽管 FPGA 中的布线受限于通道,但提取寄生效应和执行 STA 的机制与 CMOS 数字设计流程相同。例如,STA执行时,可以假设互联是理想的,或者使用线载模型,假设时钟树是理想的或真实的,假设全局布线,或者使用真实布线进行寄生。

异步设计

​ STA 的原理也适用于异步设计。人们可能对从设计中的一个信号到另一个信号的时序更感兴趣,而不是对可能不存在的情况进行建立和保持检查。因此,大多数检查可能是点对点时序检查,或偏斜 STA 检查。用于分析耦合引起的毛刺的噪声分析适用于任何设计——异步或同步。此外,噪声分析对时序的影响,包括耦合的影响,也适用于异步设计。

不同设计阶段的STA

​ 在逻辑级(门级,还没有物理设计),STA可以使用:

  1. 理想互连或基于线载模型的互连。
  2. 具有延迟和抖动估计值的理想时钟。

​ 在物理设计阶段,除了上述模式外,STA 还可以使用:

  1. 互连 -——范围可以从全局布线估计、具有近似提取的真实布线或具有准确signoff提取的真实路由。
  2. 时钟树 -——真正的时钟树。
  3. 包括和不包括串扰的影响

静态时序分析的局限性

​ 虽然时序和噪声分析在分析所有可能情况下的时序问题方面做得非常出色,但最先进的技术仍然不允许 STA 完全取代仿真。 这是因为在时序验证的一些方面不能被STA 完全捕获和验证。

​ STA的一些局限性:

  1. 复位顺序:检查在异步或同步复位后,所有触发器是否复位到其所需的逻辑值。这是无法使用静态计时分析进行检查的。芯片可能无法复位。这是因为某些声明(如信号的初始值)不会被合成,只能在模拟过程中进行验证。
  2. X处理:STA技术只处理逻辑0和逻辑1(或者高和低)、上升和下降的逻辑域。设计中的未知值X会导致不确定值在设计中传播,这无法通过STA进行检查。尽管STA中的噪声分析可以通过设计分析和传播 glitches,但 glitches分析和传播的范围与作为基于模拟的纳米设计时序验证一部分的X处理非常不同。
  3. PLL设置:PLL配置可能未正确加载或设置。
  4. 异步时钟域交叉:STA不检查是否使用了正确的时钟同步器。需要其他工具来确保在存在异步时钟域交叉的地方存在正确的时钟同步器。
  5. IO接口时序:可能无法仅根据STA约束指定IO接口要求。例如,设计者可以使用SDRAM仿真模型为双数据速率(Double Data Rate,DDR)接口选择详细的电路级仿真。模拟的目的是确保可以以足够的余量读取和写入存储器,而且,如果有延迟锁相环(Delay Locked Loop,DLL),可以控制DLL以便在必要时对齐信号。
  6. 模拟和数字块之间的接口:由于STA不处理模拟块,验证方法需要确保这两种块之间的连接正确。
  7. 错误路径(False paths):静态时序分析验证通过逻辑路径的时序是否满足所有约束,如果通过逻辑路径的时序不符合要求的规范,则标记违规。在许多情况下,STA 可能会将逻辑路径标记为失败路径,即使逻辑可能永远无法通过该路径传播。当系统应用程序从不使用这样的路径或者在故障路径的敏感化期间使用相互矛盾的条件时,就会发生这种情况。这种时序路径被称为虚假路径,因为它们永远无法实现。在设计中指定适当的时序约束(包括错误路径和多周期路径约束)时,STA 结果的质量会更好。在大多数情况下,设计人员可以利用设计的固有知识并指定约束条件,以便在 STA 期间消除错误路径。
  8. FIFO 指针不同步:当两个期望同步的有限状态机实际上不同步时,STA 无法检测到问题。在功能仿真期间,两个有限状态机可能始终同步并同步变化。然而,在考虑延迟之后,有限状态机中的一个可能与另一个不同步,很可能是因为一个有限状态机比另一个更早退出复位。这种情况是STA无法检测到的。
  9. 时钟同步逻辑:STA无法检测时钟生成逻辑与时钟定义不匹配的问题。 STA 假设时钟发生器将提供时钟定义中指定的波形。可能对时钟发生器逻辑执行了错误的优化,例如导致在其中一条可能没有受到适当的约束路径上插入大延迟。或者,添加的逻辑可能会改变时钟的占空比。 STA 无法检测到这些潜在条件中的任何一个。
  10. 跨时钟周期的功能行为:静态时序分析无法建模或模拟跨时钟周期变化的功能行为。

​ 尽管存在这些问题,STA 被广泛用于验证设计的时序,并且带有时序或带有单位延迟的仿真用于检查极端情况的备份,更简单地用于验证设计的正常功能模式。

功率考虑

​ 功耗是设计实施中的一个重要考虑因素。大多数设计需要在电路板和系统的功率预算内运行。由于符合标准和/或由于芯片必须在其中运行的电路板或系统上的热预算,也可能引起功率考虑。总功率和待机功率通常有单独的限制。待机功率限制通常适用于手持设备或电池供电设备。

​ 在大多数实际设计中,功率和时序通常是齐头并进的。设计人员希望使用更快(或更高速度)的单元来满足速度考虑,但可能会遇到可用功耗的限制。在为设计选择工艺技术和单元库时,功耗是一个重要的考虑因素。

可靠性考虑

​ 设计实现必须满足可靠性要求。如第 1.4.1 节所述,金属互连走线具有限制设计性能的寄生 RC。除了寄生效应之外,还需要设计金属走线宽度,同时考虑可靠性因素。例如,高速时钟信号需要足够宽才能满足可靠性考虑,例如电迁移。

书的大纲

​ 虽然静态时序分析从表面上看可能是一个非常简单的概念,但这种分析背后有很多背景知识。基本概念范围从单元延迟的准确表示到以最小的悲观计算最坏的路径延迟。计算单元延迟、组合块计时、时钟关系、多个时钟域和门控时钟的概念构成了静态时序分析的重要基础。为设计编写正确的 SDC 确实是一个挑战。

​ 这本书是按照自下而上的顺序编写的——首先介绍简单的概念,然后在后面的章节中介绍更高级的主题。本书首先介绍了准确的单元延迟(第 3 章)。以有效的方式估计或计算精确的互连延迟及其表示是第 4 章的主题。计算由单元和互连组成的路径的延迟是第 5 章的主题。信号完整性,即信号切换对相邻网络的影响以及它如何影响沿路径的延迟,是第 6 章的主题。准确地表示具有时钟定义和路径异常的 DUA 环境是第 7 章的主题。STA 中执行的时序检查的详细信息在第 6 章中描述8. 跨各种接口的 IO 时序建模是第 9 章的主题。最后,第 10 章详细介绍高级时序检查,例如片上变化、时钟门控检查、电源管理和统计时序分析。附录提供了 SDC(用于表示时序约束)、SDF(用于表示单元和网络的延迟)和 SPEF(用于表示寄生)的详细描述。

​ 第 7 章到第 10 章提供了 STA 验证的核心。前面的章节为更好地理解STA所需的nuts
and bolts 知识提供了坚实的基础和详细描述。

STA概念

介绍 CMOS 逻辑的基础知识以及与静态时序分析相关的时序术语。

CMOS 逻辑设计

MOS基本结构

​ 图2.1描述了MOS晶体管(NMOS和PMOS)的物理实现。源区和漏区之间的距离是MOS晶体管的沟道长度。用于构建 MOS 晶体管的最小沟道长度通常是 CMOS 技术工艺的最小特征尺寸。例如,0.25mm 技术允许制造沟道长度为 0.25mm 或更大的 MOS 晶体管。通过缩小通道几何形状,晶体管尺寸变得更小,随后在给定区域中可以封装更多晶体管。正如我们将在本章后面看到的,这也允许设计以更快的速度运行。

img

CMOS 逻辑门

​ CMOS 逻辑门是使用 NMOS 和 PMOS 晶体管构建的。图 2-2 显示了 CMOS 反相器的示例。根据输入的状态,CMOS 反相器有两种稳定状态。当输入 A 为低电平(Vss 或逻辑 0)时,NMOS 晶体管关闭,PMOS 晶体管开启,导致输出 Z 被拉至 Vdd,即逻辑 1。当输入 A 为高电平(Vdd 或逻辑 1)时,NMOS 晶体管导通,PMOS 晶体管关闭,导致输出 Z 被拉至 Vss,即逻辑 0。在上述两种状态中的任何一种状态下,CMOS 反相器都是稳定的,并且不会从输入 A 或电源 Vdd 汲取任何电流。

img

​ CMOS 反相器的特性可以扩展到任何 CMOS 逻辑门。在 CMOS 逻辑门中,输出节点通过上拉结构(由 PMOS 晶体管组成)连接到 Vdd,通过下拉结构(由 NMOS 晶体管组成)连接到 Vss。例如,图 2-3 显示了一个两输入 CMOS 与非门。在本例中,上拉结构由两个并联的 PMOS 晶体管组成,下拉结构由两个串联的 NMOS 晶体管组成。

​ 对于任何 CMOS 逻辑门,上拉和下拉结构都是互补的。对于逻辑 0 或逻辑 1 的输入,这意味着如果上拉级打开,下拉级将关闭,同样如果上拉级关闭,下拉级将被关闭在。下拉和上拉结构由 CMOS 门实现的逻辑功能控制。例如,在CMOS与非门中,控制下拉结构的功能是“A和B”,即在A和B都为逻辑1时开启下拉。同理,控制上拉结构的函数是“not A or not B”,即在A或B逻辑-0时开启上拉。这些特性确保基于控制上拉结构的功能将输出节点逻辑拉至 Vdd。由于下拉结构是由一个互补功能控制。

​ 对于逻辑 0 或逻辑 1 的输入,CMOS 逻辑门在稳定状态下不会从输入或电源汲取任何电流,因为上拉和下拉结构不能同时打开 1。 CMOS 逻辑的另一个重要方面是输入仅对前一级构成容性负载。

​ CMOS逻辑门是一个反相门,意思是单个开关输入(上升或下降)只能引起输出反方向开关,即输出不能与开关输入同方向开关。然而,CMOS 逻辑门可以级联以组合更复杂的逻辑功能 - 反相和非反相。

img

标准单元

​ 芯片中的大多数复杂功能通常使用基本构建块设计,这些构建块实现简单的逻辑功能,例如和、或、与非、与或反转、或与反转和触发器。这些基本构建块是预先设计的,被称为标准单元(standard cells)。标准单元的功能和时序是预先表征的,可供设计人员使用。然后,设计人员可以使用标准单元作为构建块来实现所需的功能。

​ 前一小节中描述的 CMOS 逻辑门的关键特性适用于所有 CMOS 数字设计。所有数字 CMOS 单元都设计为在输入处于稳定逻辑状态时没有从电源汲取电流(泄漏除外)。因此,大部分功耗与设计中的活动有关,并且是由设计中 CMOS 单元输入的充电和放电引起的。

​ 什么是逻辑 1 或逻辑 0?在 CMOS 单元中,两个值 VIHmin 和 VILmax 定义了限值。也就是说,任何高于 VIHmin 的电压值都被视为逻辑 1,而任何低于 VILmax 的电压值都被视为逻辑 0。参见图 2-4。具有 1.2V Vdd 电源的 CMOS 0.13mm 反相器单元的典型值为 VILmax 的 0.465V 和 VIHmin 的 0.625V。 VIHmin 和 VILmax 值源自电池的直流传输特性。直流传输特性在第 6.2.3 节中有更详细的描述。

img

​ 有关 CMOS 技术的更多详细信息,请参阅参考书目中列出的相关文本之一。

CMOS 单元的建模

​ 如果一个单元输出引脚驱动多个扇出单元,则单元输出引脚上的总电容是它所驱动的单元的所有输入电容之和加上构成网络的所有线段的电容之和加上驱动单元的输出电容。请注意,在 CMOS 单元中,单元的输入仅呈现电容性负载。

img

​ 图 2-5 显示了一个单元格 G1 驱动其他三个单元格 G2、G3 和 G4 的示例。 Cs1、Cs2、Cs3 和 Cs4 是构成网络的线段的电容值。因此:

1
2
3
4
Total cap (Output G1) = Cout(G1) + Cin(G2) + Cin(G3) +
Cin(G4) + Cs1 + Cs2 + Cs3 + Cs4
#Cout 是单元的输出引脚电容。
#Cin 是单元的输入引脚电容。

​ 这是当单元 G1 切换时需要充电或放电的电容,因此该总电容值会影响单元 G1 的时序。

​ 从时序的角度来看,我们需要对 CMOS 单元进行建模,以帮助我们分析通过单元的时序。对于每个输入引脚指定输入引脚电容。虽然大多数 CMOS 逻辑单元不包括输出引脚的引脚电容,但也可能存在输出引脚电容。

​ 当输出为逻辑 1 时,输出级的上拉结构开启,并提供从输出到 Vdd 的路径。类似地,当输出为逻辑 0 时,输出级的下拉结构提供了从输出到 Vss 的路径。当 CMOS 单元切换状态时,切换速度取决于输出网络上的电容充电或放电的速度。输出网络上的电容(图 2-5)分别通过上拉和下拉结构充电和放电。请注意,上拉和下拉结构中的通道对输出充电和放电路径构成电阻。充电和放电路径电阻是决定 CMOS 单元速度的主要因素。上拉电阻的倒数称为电池的输出高驱动。输出上拉结构越大,上拉电阻越小,单元的输出高驱动越大。更大的输出结构也意味着单元的面积更大。输出上拉结构越小,单元面积越小,其输出高驱动也越小。上拉结构的相同概念可以应用于决定下拉路径电阻和输出低电平驱动的下拉结构。通常,单元被设计为具有相似的驱动强度(大或小)用于上拉和下拉结构。

​ 输出驱动决定了可以驱动的最大容性负载。最大容性负载决定了扇出的最大数量,即它可以驱动多少个其他单元。较高的输出驱动对应于较低的输出上拉和下拉电阻,这允许电池在输出引脚上对较高的负载进行充电和放电。

​ 图 2-6 显示了 CMOS 单元的等效抽象模型。该模型的目标是抽象单元的时序行为,因此仅对输入和输出阶段进行建模。该模型不捕获单元固有延迟或电气行为。

img

​ CpinA 是输入 A 上单元的输入引脚电容。 Rdh 和 Rdl 是单元的输出驱动电阻,并根据单元驱动的负载确定输出引脚 Z 的上升和下降时间。该驱动器还决定了单元的最大扇出限制。

​ 图 2-7 显示了与图 2-5 相同的网络,但具有等效的单元模型。

img

1
2
3
Cwire = Cs1 + Cs2 + Cs3 + Cs4
Output charging delay (for high or low) =
Rout * (Cwire + Cin2 +Cin3 + Cin4)

​ 在上面的表达式中,Rout 是 Rdh 或 Rdl 之一,其中 Rdh 是上拉的输出驱动电阻,Rdl 是下拉的输出驱动电阻。

开关波形

​ 当通过激活 SW0 开关将电压施加到 RC 网络时,如图 2-8(a) 所示,输出变为逻辑 1。假设 SW0 激活时输出为 0V,输出端的电压转换由以下等式描述:

​ 这种上升的电压波形如图 2-8(b) 所示。乘积 (Rdh * Cload) 称为 RC 时间常数 - 通常这也与输出的转换时间有关。

​ 当输出从逻辑 1 变为逻辑 0 时,由于输入变化导致 SW0 断开连接并激活 SW1,输出转换如图 2-8(c) 所示。输出电容通过打开的 SW1 开关放电。这种情况下的电压转换由以下等式描述:

img

​ 在 CMOS 单元中,输出端充电和放电波形与图 2-8 中的 RC 充电和放电波形不同,因为 PMOS 上拉和 NMOS 下拉晶体管在短时间内同时导通。图 2-9 显示了 CMOS 反相器单元内输出从逻辑 1 切换到逻辑 0 的各个阶段的电流路径。图 2-9(a) 显示了上拉和下拉结构都打开时的电流。 之后,上拉结构关闭,电流如图 2-9(b) 所示。输出达到最终状态后,由于电容 Cload 已完全放电,因此没有电流流动。

img

​ 图 2-10(a) 显示了 CMOS 单元输出端的代表性波形。请注意过渡波形如何逐渐向 Vss 轨道和 Vdd 轨道弯曲,波形的线性部分位于中间。

​ 在本文中,我们将使用如图 2-10(b) 所示的简单绘图来描绘一些波形。它显示了具有一些转换时间的波形,即从一种逻辑状态转换到另一种逻辑状态所需的时间。图2-10(c)示出了使用0跃迁时间的相同波形,即理想波形。我们将在本文中交替使用这两种形式来解释这些概念,但实际上,每个波形都有其真实的边缘特征,如图 2-10(a) 所示。

img

传播延迟(Propagation Delay)

​ 考虑一个 CMOS 反相器单元及其输入和输出波形。单元的传播延迟是根据开关波形上的一些测量点定义的。这些点是使用以下四个变量定义的:

1
2
3
4
5
6
7
8
# 输入下降沿的阈值点:
input_threshold_pct_fall : 50.0;
# 输入上升沿的阈值点:
input_threshold_pct_rise : 50.0;
# 输出下降沿的阈值点:
output_threshold_pct_fall : 50.0;
# 输出上升沿的阈值点:
output_threshold_pct_rise : 50.0;

​ 这些变量是用于描述单元库的命令集的一部分(该命令集在 Liberty中进行了描述)。这些阈值规格以 Vdd 或电源的百分比表示。大多数标准单元库的延迟测量通常使用 50% 阈值。

​ 上升沿是从逻辑 0 到逻辑 1 的过渡。下降沿是从逻辑 1 到逻辑 0 的转变。

img

​ 以图 2-11 逆变器单元及其引脚处的波形示例。传播延迟表示为:

  1. 输出下降延迟 (Tf)
  2. 输出上升延迟 (Tr)

​ 一般来说,这两个值是不同的。图 2-11 显示了如何测量这两个传播延迟。

​ 如果我们查看理想波形,传播延迟就是两个边沿之间的延迟。如图 2-12 所示。

img

波形转换(Slew of a Waveform)

​ 转换速率( slew rate )被定义为变化速率。在静态时序分析中,根据过渡(transition)是慢还是快来测量上升或下降的波形。转换(slew)通常用转换时间(transition time)来衡量,即信号在两个特定电平之间转换所花费的时间。请注意,转换时间实际上与转换速率成反比——转换时间越大,转换速度越慢,反之亦然。图2-10显示了CMOS单元输出的典型波形。在两端的波形是渐近的,很难确定准确的开始和结束的过渡点。因此,转换时间是根据特定的阈值水平来定义的。例如, 转换阈值设置可以是:

1
2
3
4
5
6
7
# Falling edge thresholds:
slew_lower_threshold_pct_fall : 30.0;
slew_upper_threshold_pct_fall : 70.0;

# Rising edge thresholds:
slew_lower_threshold_pct_rise : 30.0;
slew_upper_threshold_pct_rise : 70.0;

​ 这些值被指定为Vdd的百分比。阈值设置(threshold settings)指定下降的反转为下降沿达到Vdd的70%和30%的时间差。同样地,上升设置指定上升幅度是上升边达到Vdd的30%和70%的时间差。如图2-13所示。

img

​ 一个例子如图2-14显示,下降边的转换(slew)测量为20-80(80%到20%),上升边测量为10-90(10%到90%)。这里是本例的阈值设置。

img

1
2
3
4
5
6
7
# Falling edge thresholds:
slew_lower_threshold_pct_fall : 20.0;
slew_upper_threshold_pct_fall : 80.0;

# Rising edge thresholds:
slew_lower_threshold_pct_rise : 10.0;
slew_upper_threshold_pct_rise : 90.0;

信号之间的偏差(Skew between Signals)

偏差(skew)是两个或多个信号(可能是数据、时钟或两者)之间的时间差。例如,如果一个时钟树有500个端点,偏移量为50ps,则表示最长路径和最短时钟路径之间的延迟差为50ps。图2-15显示了时钟树的示例。时钟树的起点通常是定义时钟的节点。时钟树的端点通常是同步元件(如触发器 flip-flops)的时钟引脚。时钟延迟( Clock latency)是从时钟源到终点所花费的总时间。时钟偏移(Clock skew)是时钟树端点处到达时间的差异。

img

​ 一个理想的时钟树是一个假设时钟源具有无限驱动的树,也就是说,时钟可以无延迟地驱动无限源。此外,假设时钟树中存在的任何单元具有零延迟。

​ 在逻辑设计的早期阶段,STA通常使用理想的时钟树执行,因此分析的重点是数据路径。在理想的时钟树中,时钟偏移默认为0ps。可以使用set_clock_Latency命令显式指定时钟树的延迟。以下示例对时钟树的延迟进行建模:

1
2
3
4
5
set_clock_latency 2.2 [get_clocks BZCLK]

# Both rise and fall latency is 2.2ns.

# Use options -rise and -fall if different.

​ 时钟树的时钟偏移也可以通过使用set_Clock_INDUCTION命令显式指定其值来表示:

1
2
3
set_clock_uncertainty 0.250 -setup [get_clocks BZCLK]

set_clock_uncertainty 0.100 -hold [get_clocks BZCLK]

set_clock_uncertainty指定一个窗口,在该窗口内可以出现时钟边沿。时钟边沿时序的不确定性,是为了考虑几个因素,例如时钟周期抖动( clock period jitter )和用于时序验证的附加裕度(additional margins)。每一个真实的时钟源都有一个有限的抖动——一个时钟边沿可以出现的窗口。clock period jitter由所使用的时钟发生器的类型决定。实际上,没有理想的时钟,也就是说,所有时钟都有有限的抖动,在指定时钟不确定性时,应包括时钟周期抖动。

​ 在实现时钟树之前,时钟不确定性还必须包括实现的预期时钟偏差。

​ 可以为建立检查( setup checks )和保持检查(hold checks)指定不同的时钟不确定性。保持检查不需要将时钟抖动包含在不确定性中,因此通常为hold指定较小的时钟不确定性值。

​ 图 2-16 显示了设置不确定性为 250ps 的时钟示例。图 2-16(b) 显示在传播到下一个触发器阶段的逻辑的时间中,如何去除不确定性。这相当于验证设计以更高的频率运行。

img

​ 如上所述,set_clock_uncertainty 还可用于对任何附加裕度(additional margins)进行建模。例如,设计人员可能会在设计过程中使用 50ps 的时序余量作为额外坏情况的考虑(additional pessimism)。该组件可以添加并包含在 set_clock_uncertainty 命令中。通常,在实现时钟树之前,set_clock_uncertainty 命令用于指定一个值,该值包括时钟抖动加上估计的时钟偏斜加上额外坏情况的考虑(additional pessimism)。

1
2
3
4
5
6
7
set_clock_latency 2.0 [get_clocks USBCLK]

set_clock_uncertainty 0.2 [get_clocks USBCLK]

# The 200ps may be composed of 50ps clock jitter,

# 100ps clock skew and 50ps additional pessimism.

​ 稍后我们将看到 set_clock_uncertainty 如何影响建立和保持检查。最好将时钟不确定性视为最终偏斜(slack)计算的偏移量。

时序弧(Timing Arcs and Unateness)

​ 每个cell都有多个时序弧。例如,组合逻辑单元(如and、or、nand、nor 、adder单元)从单元的每个输入到每个输出具有时序弧。顺序单元(如触发器flip-flops )具有从时钟到输出的时序弧,和关于时钟的数据管脚的时序约束。每个时序弧都有一个时序感测(timing sense),即输入上不同类型的转换如何改变输出。如果输入上的上升过渡导致输出上升(或不改变),而输入上的下降过渡导致输出下降(或不改变),则为正时序弧(positive unate)。例如,and和or类型单元格的计时弧为正。见图2-17(a)。

负时序弧(negative unate)是指,输入上的上升过渡导致输出有下降过渡(或不改变)和在输入上的下降过渡,使输出具有上升过渡(或不改变)。例如,nand和nor类型单元的时序弧为负。见图2-17(b)。

​ 在non-unate时序弧中,输出转换不能仅从输入的变化方向确定,还取决于其他输入的状态。例如,异或(xor)单元(异或)中的时序弧是non-unate的。1见图2-17(c)。

img

Unateness 对于时序非常重要,因为它指定了边沿(过渡transitions)如何在单元格中传播以及它们如何在单元格的输出中显示。

​ 人们可以利用时序弧的non-unateness性,例如当使用异或(xor )单元时,翻转时钟的极性。参见图2-18中的示例。如果输入POLCTRL为逻辑-0,则单元UXOR0输出上的时钟DDRCLK与输入时钟MEMCLK具有相同的极性。如果POLCTRL是逻辑1,则单元UXOR0输出上的时钟与输入时钟MEMCLK的极性相反。

img

最小和最大时序路径(Min and Max Timing Paths)

​ 逻辑通过逻辑路径传播的总延迟称为路径延迟(path delay)。这相当于通过路径上各种逻辑单元和网络的延迟之和。通常,逻辑可以通过多条路径传播到所需的目标点。实际路径取决于逻辑路径上其他输入的状态。如图 2-19 示例。由于到达目的地的路径有多条,因此可以得到到达目的点的最大时间和最小时间。最大时间和最小时间对应的路径分别称为最大路径和最小路径。两个端点之间的最大路径是具有最大延迟的路径(也称为最长路径)。同样地,最小路径是延迟最小的路径(也称为最短路径)。

​ 数据路径示例如图2-19所示。UFF1和UFF3之间的最大路径假定是通过UNAND0、UBUF2、UOR2和UNAND6单元的路径。UFF1和UFF3之间的最小路径被认为是通过UOR4和UNAND6单元的路径。注意,在这个例子中,最大值和最小值是与目的点(即触发器UFF3的D引脚)相关的。

​ 最大路径通常被称为late path,而最小路径通常被称为early path

​ 当考虑从UFF1到UFF3等触发器到触发器路径时,其中一个触发器启动数据,另一个触发器捕获数据。在本例中,由于UFF1启动数据,因此UFF1被称为启动触发器。因为UFF3捕获数据,所以UFF3被称为捕获触发器。请注意,启动和捕获术语总是与触发器到触发器路径有关。例如,UFF3将成为通往捕获UFF3产生的数据的触发器路径的启动触发器。

img

时钟域(Clock Domains)

​ 在同步逻辑设计中,一个周期时钟信号锁存计算到触发器中的新数据。新的数据输入是基于前一个时钟周期的触发器值。因此,锁存数据用于计算下一个时钟周期的数据。

​ 一个时钟通常为多个触发器服务。由一个时钟服务的一组触发器称为其时钟域。在典型设计中,可能存在多个时钟域。例如,200个触发器可以由USBCLK计时,1000个触发器可以由时钟MEMCLK馈送。图2-20描述了触发器和时钟。在本例中,我们说有两个时钟域。

img

​ 一个令人感兴趣的问题是时钟域是彼此相关还是相互独立。答案取决于是否存在从一个时钟域开始并在另一个时钟域结束的任何数据路径。如果没有这样的路径,我们可以安全地说这两个时钟域是彼此独立的。这意味着没有从一个时钟域开始并在另一个时钟域结束的定时路径。

​ 如果确实存在跨越时钟域的数据路径(参见图2-21),则必须决定这些路径是否是真实的。真实路径的一个例子是,具有2倍速度时钟的触发器驱动到具有1倍速度时钟的触发器中。错误路径的一个例子是,设计者明确地将时钟同步器逻辑放置在两个时钟域之间。在这种情况下,即使看起来存在从一个时钟域到下一个时钟域的时序路径,它也不是真正的时序路径,因为数据不受限制在一个时钟周期内通过同步器逻辑传播。这样的路径被称为假路径(不是真实路径),因为时钟同步器确保数据正确地从一个域传递到下一个域。可以使用set_false_path规范指定时钟域之间的假路径,例如:

1
2
3
4
5
set_false_path -from [get_clocks USBCLK]

-to [get_clocks MEMCLK]

# This specification is explained in more detail in Chapter 8.

​ 即使未在图2-21中描述,时钟域交叉也可能以两种方式发生,即从USBCLK时钟域到MEMCLK时钟域,以及从MEMCLK时钟域到USBCLK时钟域。这两种情况都需要在STA中正确理解和处理。

img

​ 讨论时钟域之间路径的原因是什么?通常,一种设计具有大量时钟,并且在时钟域之间可以有无数条路径。识别哪些时钟域交叉是真实的,哪些时钟交叉不是真实的是时序验证工作的一个重要部分。这使设计人员能够专注于仅验证真正时序路径。

​ 图2-22显示了时钟域的另一个示例。多路复用器选择一个时钟源——它是一个或另一个,取决于设计的操作模式。只有一个时钟域,但有两个时钟,这两个时钟被认为是互斥的,因为一次只有一个时钟是活动的。因此,在该示例中,重要的是要注意,USBCLK和USBCLKx2的两个时钟域之间永远不可能存在路径(假设多路复用器控制是静态的,并且这种路径在设计中的其他地方不存在)。

img

操作条件(Operating Conditions)

​ 静态定时分析通常在特定操作条件下执行*****。操作条件定义为工艺、电压和温度(Process, Voltage and Temperature PVT)的组合。单元延迟和互连延迟是根据指定的操作条件计算的。

******STA 可以在具有不同电压的单元的设计上执行。稍后我们将看到这些是如何处理的。 STA 也可以统计执行,这在第 10 章中描述。*

​ 半导体代工厂为数字设计提供了三种制造工艺模型:慢工艺模型、典型工艺模型和快速工艺模型。慢速和快速工艺模型代表了铸造厂制造过程的极端角落。对于稳健设计,该设计在制造过程的极端角落以及温度和电源的极端环境中得到验证。图 2-23(a) 显示了cell delays如何随工艺角变化。图 2-23(b) 显示cell delays如何随电源电压变化,图 2-23(c) 显示cell delays如何随温度变化。因此,决定用于各种静态时序分析的工作条件非常重要。

img

​ STA 使用何种操作条件的选择还取决于单元库可用的操作条件。三个标准操作条件是:

  1. WCS(Worst-Case Slow):过程(process)缓慢,温度(temperature)最高(比如 125C),电压(voltage)最低(比如标称 1.2V 减 10%)。对于使用低电源的纳米技术,可能还有另一个最坏情况的慢角,对应于慢工艺、最低电源和最低温度。低温下的延迟并不总是小于高温下的延时 。这是因为纳米技术降低了与电源相关的设备阈值电压(Vt)裕度。在这种情况下,在低电源条件下,轻负载电池在低温下的延迟高于高温下的延迟。对于高Vt(更高的阈值,更大的延迟)或甚至是标准Vt(常规阈值,更低的延迟)小区来说尤其如此。这种延迟在较低温度下增加的反常行为称为温度反转。见图2-23(c)。
  2. TYP (Typical):过程(process)是典型的,温度(temperature)是标称的(比如25C),电压(voltage)是标称的(比如1.2V)。
  3. BCF(Best-Case Fast):过程(process)快速,温度(temperature)最低(比如-40℃),电压(voltage)最高(比如标称1.2V加10%)。

​ 功率分析的环境条件通常与静态定时分析的环境条件不同。对于功率分析,工作条件可能为:

  1. ML (Maximal Leakage):过程很快,温度最高(比如125C),电压也最高(比如1.2V加10%)。该角对应于最大泄漏功率。对于大多数设计,此角也对应于最大有功功率。
  2. TL (Typical Leakage):过程是典型的,温度最高(比如125C),电压为标称值(比如1.2V)。这是指大多数设计中泄漏具有代表性的情况,因为在正常操作中,由于功率损耗,芯片温度会更高。

​ 静态定时分析基于为STA加载和链接的库。可以使用set_operating_conditions命令明确指定设计的操作条件。

1
2
3
4
5
set_operating_conditions “WCCOM” -library mychip

# Use the operating condition called WCCOM defined in the

# cell library mychip.

​ 单元库在各种操作条件下可用,选择用于分析的操作条件取决于为STA加载的内容。

标准单元库(Standard Cell Library)

​ 描述了常用库单元描述中的时序相关信息。本章仅关注与时序、串扰和功率分析相关的属性,尽管库单元包含多个属性。纳米技术中对时序的主要影响是互连。

​ 除了时序信息外,库单元描述还包含几个属性(attributes),如单元面积和功能,这些属性与时序无关,但在RTL合成过程中相关。在本章中,我们只关注与时序和功率计算相关的属性(attributes)。

​ 可以使用各种标准格式来描述库单元。虽然各种格式的内容基本相似,但我们已经使用Liberty语法描述了库单元示例。

​ 本章的开始部分描述了线性和非线性时序模型(linear and the non-linear timing models ),然后是第3.7节描述的纳米技术的高级时序模型。

引脚电容(Pin Capacitance)

​ 单元的每个输入和输出都可以指定引脚处的电容。在大多数情况下,电容仅针对单元输入而不是输出指定,即大多数单元库中的输出引脚电容为 0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pin (INP1) {

capacitance: 0.5;

rise_capacitance: 0.5;

rise_capacitance_range: (0.48, 0.52);

fall_capacitance: 0.45;

fall_capacitance_range: (0.435, 0.46);

. . .

}

​ 上面的示例显示了输入 INP1 的引脚电容值的一般规范。在最基本的形式中,引脚电容被指定为单个值(在上例中为 0.5 个单位)。 (电容单位通常是皮法,并在库文件的开头指定)。单元描述还可以为rise_capacitance(0.5 个单位)和fall_capacitance(0.45 个单位)指定单独的值,它们指的是用于引脚INP1 上的上升和下降转换的值。也可以将rise_capacitancefall_capacitance 值指定为一个范围,并在说明中指定下限和上限值。

时序建模(Timing Modeling)

​ 单元时序模型旨在为设计环境中单元的各种实例提供准确的时序。时序模型通常是从单元的详细电路模拟中获得,以模拟单元运行的实际场景。为单元的每个时序弧指定时序模型。

img

​ 让我们首先考虑一个简单的逆变器逻辑单元的时序弧,如图3-1所示,因为它是一个逆变器,在输入端的上升(下降)转变导致输出处的下降(上升)转变。单元的两种延迟特性是:

  1. Tr:输出上升延迟
  2. Tf:输出下降延迟

​ 请注意,延迟是基于单元库中定义的阈值点来测量的(参见第2.4节),通常为50%Vdd。因此,从输入超过其阈值点到输出超过其阈值点,测量延迟。

​ 通过逆变器单元的时序电弧延迟取决于两个因素:

  1. 输出负载(output load),即逆变器输出引脚的电容负载。
  2. 输入端信号的转换时间(transition time)。

​ 延迟值与负载电容直接相关——负载电容越大,延迟越大。在大多数情况下,延迟随着输入转换时间的增加而增加。在某些情况下,输入阈值(用于测量延迟)与单元的内部开关点有显着差异。在这种情况下,通过单元的延迟可能会表现出相对于输入转换时间的非单调行为 - 较大的输入转换时间可能会产生较小的延迟,尤其是在输出负载较轻的情况下。

​ 单元输出的转换(slew)主要取决于输出电容——输出转换时间随着输出负载的增加而增加。因此,根据单元类型及其输出负载,输入处的大转换(大转换时间)可以改善输出处。图 3-2 显示了单元输出的转换时间可以根据单元输出的负载而改善或恶化的情况。

img

线性时序模型(Linear Timing Model)

​ 一个简单的时序模型是线性延迟模型,其中单元的延迟和输出转换时间表示为两个参数的线性函数:输入转换时间和输出负载电容。通过单元的延迟 D 的线性模型的一般形式如下所示。

​ 其中 D0、D1、D2 是常数,S 是输入转换时间,C 是输出负载电容。线性延迟模型在亚微米技术的输入转换时间和输出电容范围内不准确因此,大多数单元库目前使用更复杂的模型,例如非线性延迟模型。

非线性延迟模型(Non-Linear Delay Model)

​ 大多数单元库都包含表(table)模型,用于指定单元的各种时序弧的延迟和时序检查。一些用于纳米技术的较新的时序库还提供了基于电流源的高级时序模型(例如 CCS、ECSM 等),本章稍后将对其进行介绍。table型称为 NLDM(非线性延迟模型),用于延迟、输出转换或其他时序检查。

​ table模型捕获了通过单元输入引脚的输入转换时间和单元输出的总输出电容的各种组合的延迟。

​ 延迟的 NLDM 模型以二维形式呈现,两个独立变量是输入转换时间(nput transition time 输出负载电容(output load capacitance),table中的条目表示延迟。以下是典型逆变器单元的此类table示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
pin (OUT) {

max_transition : 1.0;

timing() {

related_pin : "INP1";

timing_sense : negative_unate;

cell_rise(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7"); /* Input transition */

index_2 ("0.16, 0.35, 1.43"); /* Output capacitance */

values ( /* 0.16 0.35 1.43 */ \

/* 0.1 */ "0.0513, 0.1537, 0.5280", \

/* 0.3 */ "0.1018, 0.2327, 0.6476", \

/* 0.7 */ "0.1334, 0.2973, 0.7252");

}

cell_fall(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7"); /* Input transition */

index_2 ("0.16, 0.35, 1.43"); /* Output capacitance */

values ( /* 0.16 0.35 1.43 */ \

/* 0.1 */ "0.0617, 0.1537, 0.5280", \

/* 0.3 */ "0.0918, 0.2027, 0.5676", \

/* 0.7 */ "0.1034, 0.2273, 0.6452");

}

​ 在上面的示例中,描述了输出引脚 OUT 的延迟。单元描述的这一部分包含从引脚 INP1 到引脚 OUT 的时序弧的上升和下降延迟模型,以及引脚 OUT 上的 max_transition 允许时间。上升和下降延迟(对于输出引脚)有单独的模型,它们分别标记为 cell_risecell_fall。索引的类型和表查找索引的顺序在查找表模板 delay_template_3x3 中描述。

1
2
3
4
5
6
7
8
9
10
11
12
13
lu_table_template(delay_template_3x3) {

variable_1 : input_net_transition;

variable_2 : total_output_net_capacitance;

index_1 ("1000, 1001, 1002");

index_2 ("1000, 1001, 1002");

}

/* 输入转换和输出电容可以是任意顺序,即variable_1可以是输出电容。但是,这些名称在库中的所有模板中通常是一致的。 */

​ 此查找表模板指定表中的第一个变量是输入转换时间,第二个变量是输出电容。表值像嵌套循环一样指定,其中第一个索引 (index_1) 是外部(或变化最小)变量,第二个索引 (index_2) 是内部(或变化最大)变量,依此类推。每个变量有三个条目,因此它对应于一个 3×3 表。在大多数情况下,表的条目也像表一样格式化,然后可以将第一个索引 (index_1) 视为行索引,而第二个索引 (index_2) 变得等效于列索引。索引值(例如 1000)是虚拟占位符,它们被 cell_fallcell_rise 延迟表中的实际索引值覆盖。指定索引值的另一种方法是在模板定义中指定索引值,而不是在 cell_risecell_fall 表中指定它们。这样的模板看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
lu_table_template(delay_template_3x3) {

variable_1 : input_net_transition;

variable_2 : total_output_net_capacitance;

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

}

​ 根据延迟表,0.3ns 的输入下降转换时间和 0.16pf 的输出负载将对应于 0.1018ns 的反相器上升延迟。由于输入端的下降跃迁导致逆变器输出上升,上升延迟的表查找涉及反相器输入处的下降转换。

​ 这种在表格中将延迟表示为两个变量(转换时间和电容)的函数的形式称为非线性延迟模型,因为延迟随输入转换时间和负载电容的非线性变化在此类表中表示。

​ 表模型也可以是 3 维的——一个例子是具有互补输出 Q 和 QN 的触发器,这在第 3.8 节中进行了描述。

​ NLDM 模型不仅用于延迟,还用于单元输出的转换时间,其特征在于输入转换时间和输出负载。因此,有单独的二维表用于计算单元的输出上升和下降转换时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
pin (OUT) {

max_transition : 1.0;

timing() {

related_pin : "INP";

timing_sense : negative_unate;

rise_transition(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7"); /* Input transition */

index_2 ("0.16, 0.35, 1.43"); /* Output capacitance */

values ( /* 0.16 0.35 1.43 */ \

/* 0.1 */ "0.0417, 0.1337, 0.4680", \

/* 0.3 */ "0.0718, 0.1827, 0.5676", \

/* 0.7 */ "0.1034, 0.2173, 0.6452");

}

fall_transition(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7"); /* Input transition */

index_2 ("0.16, 0.35, 1.43"); /* Output capacitance */

values ( /* 0.16 0.35 1.43 */ \

/* 0.1 */ "0.0817, 0.1937, 0.7280", \

/* 0.3 */ "0.1018, 0.2327, 0.7676", \

/* 0.7 */ "0.1334, 0.2973, 0.8452");

}

. . .

}

. . .

}

​ 有两个这样的过渡时间表:rise_transition 和fall_transition。如第 2 章所述,转换时间是根据特定的转换阈值测量的,通常是电源的 10%-90%。

​ 如上所示,具有 NLDM 模型的逆变器单元具有下表:

  • Rise delay
  • Fall delay
  • Rise transition
  • Fall transition

​ 给定这种单元的输入转换时间和输出电容,如图 3-3 所示,从 cell_rise 表中获得 15ps 输入转换时间(下降)和 10fF 负载的上升延迟,从20ps 输入转换时间(上升)和 10fF 负载的 cell_fall 表。

img

​ 指定单元正在反转的信息在哪里?该信息被指定为时序弧的timing_sense 字段的一部分。在某些情况下,此字段未指定,但应从引脚功能派生。

​ 对于示例反相器单元,时序弧为negative_unate,这意味着输出引脚转换方向与输入引脚转换方向相反(负)。因此,cell_rise 表查找对应于输入引脚的下降转换时间。

非线性延迟模型查找示例(Example of Non-Linear Delay Model Lookup)

​ 本节通过示例说明表模型的查找。如果输入转换时间和输出电容对应于表条目,则表查找是微不足道的,因为时序值直接对应于表中的值。下面的示例对应于查找不对应于表中任何可用条目的一般情况。在这种情况下,使用二维内插来提供结果时序值。为表插值选择每个维度中两个最近的表索引。考虑输入转换时间为 0.15ns 和输出电容为 1.16pF 的下降转换表(上面指定的示例表)。下面再现了与二维插值相关的下降过渡表的相应部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
fall_transition(delay_template_3x3) {

index_1 ("0.1, 0.3 . . .");

index_2 (". . . 0.35, 1.43");

values ( \

". . . 0.1937, 0.7280", \

". . . 0.2327, 0.7676"

. . .

​ 在下面的公式中,两个 index_1 值表示为 x1 和 x2;两个index_2值分别记为y1和y2,对应的表值分别记为T11、T12、T21和T22。

如果 (x0, y0) 需要查表,则通过插值获得查找值 T00,由下式给出:

这里

x01= (x0- x1) / (x2- x1)
x20= (x2- x0) / (x2- x1)
y01= (y0- y1) / (y2- y1)
y20= (y2- y0) / (y2- y1)

​ 用 0.15 代替 index_1 和 1.16 代替 index_2 导致 fall_transition 值:

T00= 0.75 * 0.25 * 0.1937 + 0.75 * 0.75 * 0.7280 +
0.25 * 0.25 * 0.2327 + 0.25 * 0.75 * 0.7676 = 0.6043

​ 请注意,上述等式对于内插和外推均有效 - 即当指数 (x0, y0) 位于指数的特征范围之外时。例如,对于 index_1 为 0.05 和 index_2 为 1.7 的表查找,获得下降过渡值如下:

T00= 1.25 * (-0.25) * 0.1937 + 1.25 * 1.25 * 0.7280 +
(-0.25) * (-0.25) * 0.2327 + (-0.25) * 1.25 * 0.7676
= 0.8516

阈值规格和转换时间降额(Threshold Specifications and Slew Derating)

slew(即transition time)值基于库中指定的测量阈值。大多数上一代库(0.25 毫米或更早)使用 10% 和 90% 作为压摆或转换时间的测量阈值。

​ 选择转换阈值以对应于波形的线性部分。随着技术变得越来越精细,实际波形最线性的部分通常在 30% 到 70% 之间。因此,大多数新一代时序库将转换测量点指定为 Vdd 的 30% 和 70%。但是,由于之前测量的转换时间在 10% 到 90% 之间,因此在填充库时测量的转换时间通常在 30% 到 70% 之间加倍。这由通常指定为 0.5 的转换降额系数指定。 30% 和 70% 的转换阈值(转换降额为 0.5)导致等效的测量点为 10% 和 90%。阈值设置示例如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* Threshold definitions */

slew_lower_threshold_pct_fall : 30.0;

slew_upper_threshold_pct_fall : 70.0;

slew_lower_threshold_pct_rise : 30.0;

slew_upper_threshold_pct_rise : 70.0;

input_threshold_pct_fall : 50.0;

input_threshold_pct_rise : 50.0;

output_threshold_pct_fall : 50.0;

output_threshold_pct_rise : 50.0;

slew_derate_from_library : 0.5;

​ 上述设置指定库表中的转换时间必须乘以 0.5 才能获得与转换阈值 (30-70) 设置相对应的转换时间。这意味着转换表中的值(以及相应的索引值)实际上是 10-90 个值。在表征过程中,转换是在 30-70 处测量的,库中的转换数据对应于将测量值外推到 10% 到 90% ((70 - 30)/(90 - 10) = 0.5)。

​ 具有一组不同转换阈值设置的另一个示例可能包含:

1
2
3
4
5
6
7
8
9
10
11
/* Threshold definitions 20/80/1 */

slew_lower_threshold_pct_fall : 20.0;

slew_upper_threshold_pct_fall : 80.0;

slew_lower_threshold_pct_rise : 20.0;

slew_upper_threshold_pct_rise : 80.0;

/* slew_derate_from_library not specified */

​ 在这个 20-80 转换率阈值设置的示例中,没有指定 slew_derate_from_library(暗示默认值为 1.0),这意味着库中的转换时间数据没有降额。转换表中的值直接对应于 20-80 表征的转换值。见图 3-4 。

img

​ 这是单元库中转换阈值设置的另一个示例。

1
2
3
4
5
6
7
8
9
slew_lower_threshold_pct_rise : 20.00;

slew_upper_threshold_pct_rise : 80.00;

slew_lower_threshold_pct_fall : 20.00;

slew_upper_threshold_pct_fall : 80.00;

slew_derate_from_library : 0.6;

​ 在这种情况下,slew_derate_from_library 设置为 0.6,并且将特征转换跳变点指定为 20% 和 80%。这意味着库中的转换表数据对应于 0% 到 100% ((80 - 20)/(100 - 0) = 0.6) 外推值。如图 3-5 所示。

img

​ 指定slew降额时,延迟计算期间内部使用的slew值为:

1
library_transition_time_value * slew_derate

​ 这是延迟计算工具内部使用的转换,对应于特征转换阈值测量点。

时序模型——组合单元(Timing Models - Combinational Cells)

​ 让我们考虑两个输入和单元格的时序弧。该单元格的两个时序弧都是positive_unate;因此,输入引脚上升对应于输出上升,反之亦然。

img

​ 对于二输入and单元,有四种延迟:

  • A -> Z: Output rise
  • A -> Z: Output fall
  • B -> Z: Output rise
  • B -> Z: Output fall

​ 这意味着对于 NLDM 模型,将有四个表模型用于指定延迟。类似地,也将有四个这样的表模型用于指定输出转换时间。

延迟和转换模型(Delay and Slew Models)

​ 一个三输入 nand 单元的输入 INP1 到输出 OUT 的时序模型示例如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
pin (OUT) {

max_transition : 1.0;

timing() {

related_pin : "INP1";

timing_sense : negative_unate;

cell_rise(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0513, 0.1537, 0.5280", \

"0.1018, 0.2327, 0.6476", \

"0.1334, 0.2973, 0.7252");

}

rise_transition(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0417, 0.1337, 0.4680", \

"0.0718, 0.1827, 0.5676", \

"0.1034, 0.2173, 0.6452");

}

cell_fall(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0617, 0.1537, 0.5280", \

"0.0918, 0.2027, 0.5676", \

"0.1034, 0.2273, 0.6452");

}

fall_transition(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0817, 0.1937, 0.7280", \

"0.1018, 0.2327, 0.7676", \

"0.1334, 0.2973, 0.8452");

}

. . .

}

. . .

}

​ 在此示例中,使用两个单元延迟表 cell_risecell_fall 以及两个转换表rise_transitionfall_transition 来描述从 INP1OUT 的时序弧的特性。输出 max_transition 值也包含在上面的示例中。

Positive or Negative Unate

​ 如第 2.7 节所述,nand 单元示例中的时序弧为negative unate,这意味着输出引脚转换方向与输入引脚转换方向相反(负)。因此,cell_rise 表查找对应于输入引脚的下降转换时间。另一方面,通过and单元格或or单元格的时序弧是positive unate,因为输出转换与输入转换的方向相同。

通用组合块(General Combinational Block)

​ 考虑具有三个输入和两个输出的组合块。

img

​ 像这样的块可以有许多时序弧。通常,时序弧可以从块的每个输入到每个输出。如果从输入到输出的逻辑路径是non-inverting 或 positive unate,则输出具有与输入相同的极性。如果是反相逻辑路径是negative unate,则输出与输入极性相反;因此,当输入上升时,输出下降。这些时序弧表示通过块的传播延迟。

​ 一些通过组合单元格的时序弧可以是positive unate 也可以是negative unatee。一个例子是通过两输入异或单元的时序弧。两输入异或( xor )单元的输入处的转换 可导致输出转换沿相同或相反的转换方向,具体取决于单元的另一个输入的逻辑状态。这些时序弧可以被描述为non-unate或两组不同的 positive unate 和 negative unate 时序模型,它们依赖于状态。此类依赖于状态的表在第 3.5 节中有更详细的描述。

时序模型——顺序单元(Timing Models - Sequential Cells)

​ 考虑图 3-8 中所示的顺序单元的时序弧。

img

​ 对于同步输入(synchronous inputs),例如引脚 D(或 SI、SE),有以下时序弧:

  • Setup check arc (rising and falling)
  • Hold check arc (rising and falling)

​ 对于异步输入(asynchronous inputs),例如 pin CDN,有以下时序弧:

  • Recovery check arc
  • Removal check arc

​ 对于触发器的同步输出,例如引脚 Q 或 QN,有以下时序弧:

  • CK-to-output propagation delay arc (rising and falling)

​ 所有同步时序弧都与时钟的有效边沿有关,时钟的边沿使顺序单元捕获数据。此外,时钟引脚和异步引脚等清零,可以进行脉宽定时检查。图 3-9 显示了使用各种信号波形的时序检查。

img

同步检查:建立和保持(Synchronous Checks: Setup and Hold)

​ 需要建立和保持同步时序检查,以便通过时序单元正确传递数据。这些检查验证数据输入在时钟的有效边沿是明确的,并且正确的数据在有效边沿被锁存。这些时序检查验证数据输入在活动时钟边沿附近是否稳定。当数据输入必须保持稳定时,激活时钟之前的最短时间称为建立时间(setup time)。从超过阈值的最新数据信号(通常为Vdd的50%)到超过其阈值的活动时钟边缘(通常为Vdd的50%)的时间间隔是setup time。类似地,保持时间(hold time)是数据输入必须在时钟活动边缘之后保持稳定的最短时间。从超过其阈值的活动时钟边缘到超过其阈值的最早数据信号的时间间隔是hold time。如前所述,时序单元时钟的有效边沿是导致时序单元捕获数据的上升沿或下降沿。

建立和保持检查示例(Example of Setup and Hold Checks)

​ 顺序单元的同步管脚的setup 和hold constraints通常以二维表格的形式描述,如下所示。下面的示例显示触发器数据引脚的setup 和hold时序信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
pin (D) {

direction : input;

. . .

timing () {

related_pin : "CK";

timing_type : "setup_rising";

rise_constraint ("setuphold_template_3x3") {

index_1("0.4, 0.57, 0.84"); /* Data transition */

index_2("0.4, 0.57, 0.84"); /* Clock transition */

values( /* 0.4 0.57 0.84 */ \

/* 0.4 */ "0.063, 0.093, 0.112", \

/* 0.57 */ "0.526, 0.644, 0.824", \

/* 0.84 */ "0.720, 0.839, 0.930");

}

fall_constraint ("setuphold_template_3x3") {

index_1("0.4, 0.57, 0.84"); /* Data transition */

index_2("0.4, 0.57, 0.84"); /* Clock transition */

values( /* 0.4 0.57 0.84 */ \

/* 0.4 */ "0.762, 0.895, 0.969", \

/* 0.57 */ "0.804, 0.952, 0.166", \

/* 0.84 */ "0.159, 0.170, 0.245");

}

}

}



timing () {

related_pin : "CK";

timing_type : "hold_rising";

rise_constraint ("setuphold_template_3x3") {

index_1("0.4, 0.57, 0.84"); /* Data transition */

index_2("0.4, 0.57, 0.84"); /* Clock transition */

values( /* 0.4 0.57 0.84 */ \

/* 0.4 */ "-0.220, -0.339, -0.584", \

/* 0.57 */ "-0.247, -0.381, -0.729", \

/* 0.84 */ "-0.398, -0.516, -0.864");

}

fall_constraint ("setuphold_template_3x3") {

index_1("0.4, 0.57, 0.84"); /* Data transition */

index_2("0.4, 0.57, 0.84");/* Clock transition */

values( /* 0.4 0.57 0.84 */ \

/* 0.4 */ "-0.028, -0.397, -0.489", \

/* 0.57 */ "-0.408, -0.527, -0.649", \

/* 0.84 */ "-0.705, -0.839, -0.580");

}

}

​ 上面的示例显示了输入管脚D上相对于顺序单元的时钟CK的上升沿的设setup 和hold constraints。二维模型是根据受约束的_-pin(D)和相关的_-pin(CK)处的过渡时间建立的。 二维查找表基于库中描述的模板setuphold_template_3x3。对于上述示例,查找表模板setuphold_template_3x3描述为:

1
2
3
4
5
6
7
8
9
10
11
12
13
lu_table_template(setuphold_template_3x3) {

variable_1 : constrained_pin_transition;

variable_2 : related_pin_transition;

index_1 ("1000, 1001, 1002");

index_2 ("1000, 1001, 1002");

}

/*受约束管脚和相关管脚可以是任意顺序,即variable_1可以是相关管脚转换。但是,这些名称通常在库中的所有模板中都是一致的*/

​ 与前面的示例一样,表中的设置值被指定为一个嵌套循环,第一个索引index_1是外部(或变化最小)变量,第二个索引index_2是内部(或变化最大)变量,依此类推。因此,当D引脚上升过渡时间为0.4ns,CK引脚上升过渡时间为0.84ns时,D引脚上升沿的设置约束为0.112ns—该值从rise_constraint 表中读取。对于D引脚的下降沿,setup constraint将检查设置表的fall_constraint表。对于过渡时间与索引值不对应的setup and hold constraint表的查找,第3.2节中描述的non-linear model查找的一般程序适用。

​ 请注意,setup constraint的rise_constraint和fall_constraint表指的是constrained_pin。使用的时钟转换由timing_type 确定,该类型指定单元是上升沿触发还是下降沿触发。

建立和保持检查中的负值(Negative Values in Setup and Hold Checks)

​ 请注意,上面示例中的一些hold值为负值。这是可以接受的,并且通常发生在从触发器引脚到数据内部锁存点的路径长于相应的时钟的路径时。

​ 因此,负 hold check意味着触发器的数据管脚可以在时钟管脚之前改变,并且仍然满足hold time check。

​ 触发器的setup值也可以为负值。这意味着在触发器的引脚上,数据可以在时钟引脚之后更改,并且仍然满足setup time check。

​ setup和hold都可以是负数吗?不。为使setup和hold检查一致,setup和hold值之和应为正值。因此,如果setup(或hold)检查包含负值,则相应的hold(或setup)应为正值,以便setup加上hold值为正值。有关负hold值的示例,请参见图3-10。由于setup必须在hold之前进行,因此setup加hold是一个正数。setup加hold time是要求数据信号稳定的区域宽度。

img

​ 对于触发器,在扫描数据输入引脚上有一个负的hold时间是有帮助的。这在时钟偏移(clock skew)方面提供了灵活性,并且可以消除几乎所有缓冲器插入的需要,以便在scan mode中修复hold冲突(scan mode是触发器串行连接形成扫描链的模式-触发器的输出通常串行连接到下一个触发器的扫描数据输入引脚;这些连接用于测试性)。

​ 与同步数据输入上的setup 或 hold check类似,有约束检查控制异步管脚。下面将描述这些。

异步检查(Asynchronous Checks)

恢复和去除检查(Recovery and Removal Checks)

​ 异步引脚(如Asynchronous clear或Asynchronous set)覆盖单元格的任何同步行为。当异步引脚激活时,输出由异步引脚控制,而不是由数据输入中的时钟锁存控制。但是,当异步引脚变为非活动时,时钟的活动边缘开始在数据输入中锁定。异步恢复和删除约束检查验证异步引脚在下一个活动时钟边缘已明确返回到非活动状态。

恢复时间(recovery time)是异步输入在下一个有效时钟沿之前被取消置位后稳定的最短时间。

​ 类似地,移除时间(removal time)是有效时钟边沿之后异步引脚必须保持有效状态才能取消置位的最短时间。

​ 异步删除和恢复检查分别在第 8.6 节和第 8.7 节中描述。

脉冲宽度检查(Pulse Width Checks)

​ 除了同步和异步时序检查之外,还有一项检查可确保单元输入引脚的脉冲宽度满足最低要求。例如,如果时钟引脚的脉冲宽度小于指定的最小值,则时钟可能无法正确锁存数据。也可以为相关的同步和异步引脚指定脉冲宽度检查。可以为高脉冲和低脉冲指定最小脉冲宽度检查。

恢复、去除和脉冲宽度检查示例(Example of Recovery, Removal and Pulse Width Checks)

​ 下面给出了触发器异步清除引脚 CDN 的恢复时间、移除时间和脉冲宽度检查的示例。恢复和移除检查是针对时钟引脚 CK 的。由于恢复和移除检查是为置位的异步引脚定义的,因此下面的示例中仅存在上升约束。引脚 CDN 的最小脉冲宽度检查是针对低脉冲。由于 CDN 引脚为低电平有效,因此该引脚上的高脉冲宽度没有限制,因此未指定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
pin(CDN) {

direction : input;

capacitance : 0.002236;

. . .

timing() {

related_pin : "CDN";

timing_type : min_pulse_width;

fall_constraint(width_template_3x1) { /*low pulse check*/

index_1 ("0.032, 0.504, 0.788"); /* Input transition */

values ( /* 0.032 0.504 0.788 */ \

"0.034, 0.060, 0.377");

}

}

timing() {

related_pin : "CK";

timing_type : recovery_rising;

rise_constraint(recovery_template_3x3) { /* CDN rising */

index_1 ("0.032, 0.504, 0.788"); /* Data transition */

index_2 ("0.032, 0.504, 0.788"); /* Clock transition */

values( /* 0.032 0.504 0.788 */ \

/* 0.032 */ "-0.198, -0.122, 0.187", \

/* 0.504 */ "-0.268, -0.157, 0.124", \

/* 0.788 */ "-0.490, -0.219, -0.069");

}

}

timing() {

related_pin : "CP";

timing_type : removal_rising;

rise_constraint(removal_template_3x3) { /* CDN rising */

index_1 ("0.032, 0.504, 0.788"); /* Data transition */

index_2 ("0.032, 0.504, 0.788"); /* Clock transition */

values( /* 0.032 0.504 0.788 */ \

/* 0.032 */ "0.106, 0.167, 0.548", \

/* 0.504 */ "0.221, 0.381, 0.662", \

/* 0.788 */ "0.381, 0.456, 0.778");

}

}

}

传播延迟(Propagation Delay)

​ 顺序单元的传播延迟是从时钟的有效边沿到输出的上升沿或下降沿。这是负边沿触发的触发器的传播延迟弧示例,从时钟引脚 CKN 到输出 Q。这是一个非同步的时序弧,因为时钟的有效边沿可能导致上升或下降输出 Q 上的边缘。这是延迟表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
timing() {

related_pin : "CKN";

timing_type : falling_edge;

timing_sense : non_unate;

cell_rise(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7"); /* Clock transition */

index_2 ("0.16, 0.35, 1.43"); /* Output capacitance */

values ( /* 0.16 0.35 1.43 */ \

/* 0.1 */ "0.0513, 0.1537, 0.5280", \

/* 0.3 */ "0.1018, 0.2327, 0.6476", \

/* 0.7 */ "0.1334, 0.2973, 0.7252");

}

rise_transition(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0417, 0.1337, 0.4680", \

"0.0718, 0.1827, 0.5676", \

"0.1034, 0.2173, 0.6452");

}

cell_fall(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0617, 0.1537, 0.5280", \

"0.0918, 0.2027, 0.5676", \

"0.1034, 0.2273, 0.6452");

}

fall_transition(delay_template_3x3) {

index_1 ("0.1, 0.3, 0.7");

index_2 ("0.16, 0.35, 1.43");

values ( \

"0.0817, 0.1937, 0.7280", \

"0.1018, 0.2327, 0.7676", \

"0.1334, 0.2973, 0.8452");

}

}

​ 与前面的示例一样,输出延迟以输入转换时间和输出引脚电容的二维表表示。然而,在本例中,要使用的输入转换时间是 CKN 引脚的下降转换时间,因为这是一个下降沿触发的触发器。这由上面示例中的构造timing_type 指示。上升沿触发触发器将指定rising_edge 作为其timing_type。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
timing() {

related_pin : "CKP";

timing_type : rising_edge;

timing_sense : non_unate;

cell_rise(delay_template_3x3) {

. . .

}

. . .

}

状态相关模型(State-Dependent Models)

​ 在许多组合块中,输入和输出之间的时序弧取决于块中其他引脚的状态。输入和输出引脚之间的这些时序弧可以是positive unate, negative unat,或者都是positive unate弧,都是negative unat 弧。一个例子是 xor 或 xnor 单元,其中输出的时序可以是positive unate 或negative unat。在这种情况下,时序行为可能会因模块其他输入的状态而异。通常,描述了取决于引脚状态的多个时序模型。这种模型被称为状态相关模型(state-dependent models)

XOR、XNOR 和顺序单元(XOR, XNOR and Sequential Cells)

考虑一个两输入异或单元的例子。当另一个输入 A2 为逻辑 0 时,从输入 A1 到输出 Z 的时序路径为正值。当输入 A2 为逻辑 1 时,从 A1 到 Z 的路径为负 unate。这两个时序模型是使用状态相关模型指定的。当 A2 为逻辑 0 时,从 A1 到 Z 的时序模型指定如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
pin (Z) {

direction : output;

max_capacitance : 0.0842;

function : "(A1Â2)";

timing() {

related_pin : "A1";

when : "!A2";

sdf_cond : "A2 == 1'b0";

timing_sense : positive_unate;

cell_rise(delay_template_3x3) {

index_1 ("0.0272, 0.0576, 0.1184"); /* Input slew */

index_2 ("0.0102, 0.0208, 0.0419"); /* Output load */

values( \

"0.0581, 0.0898, 0.2791", \

"0.0913, 0.1545, 0.2806", \

"0.0461, 0.0626, 0.2838");

}

. . .

}

​ 使用 when 条件指定依赖于状态的条件。虽然单元模型摘录仅说明了 cell_rise 延迟,但其他时序模型(cell_fall、rise_transition 和 fall_transition 表)也指定了相同的 when 条件。为另一个 when 条件指定单独的时序模型 - 对于 A2 为逻辑 1 的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
timing() {

related_pin : "A1";

when : "A2";

sdf_cond : "A2 == 1'b1";

timing_sense : negative_unate;

cell_fall(delay_template_3x3) {

index_1 ("0.0272, 0.0576, 0.1184");

index_2 ("0.0102, 0.0208, 0.0419");

values( \

"0.0784, 0.1019, 0.2269", \

"0.0943, 0.1177, 0.2428", \

"0.0997, 0.1796, 0.2620");

}

. . .

}

​ sdf_cond 用于指定生成 SDF 时要使用的计时弧的条件 - 请参阅第 3.9 节中的示例和附录 B 中描述的 COND 构造。

​ 状态相关模型用于各种类型的时序弧。许多时序单元使用状态相关模型指定建立或保持时序约束。接下来指定使用状态相关模型进行保持约束的扫描触发器的示例。在这种情况下,指定了两组模型 - 一组在扫描启用引脚 SE 处于活动状态时,另一组在扫描启用引脚处于非活动状态时。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
pin (D) {

. . .

timing() {

related_pin : "CK";

timing_type : hold_rising;

when : "!SE";

fall_constraint(hold_template_3x3) {

index_1("0.08573, 0.2057, 0.3926");

index_2("0.08573, 0.2057, 0.3926");

values("-0.05018, -0.02966, -0.00919",\

"-0.0703, -0.05008, -0.0091",\

"-0.1407, -0.1206, -0.1096");

}

. . .

}

}

​ 当 SE 引脚为逻辑 0 时使用上述模型。一个类似的模型用 when 条件 SE 指定为 logic-1。

​ 一些时序关系是使用状态相关和非状态相关模型指定的。在这种情况下,如果单元的状态已知并且包含在状态相关模型之一中,则时序分析将使用状态相关模型。如果状态相关模型不涵盖单元格的条件,则使用来自非状态相关模型的时序。考虑一种情况,其中hold constraint仅由逻辑 0 处的 SE 的一个 when 条件指定,并且没有为逻辑 1 处的 SE 指定单独的状态相关模型。在这种情况下,如果 SE 设置为逻辑 1,则使用来自非状态相关模型的保持约束。如果保持约束没有非状态依赖模型,则不会有任何 active hold constraint!

​ 可以为时序库中的任何属性指定状态相关模型。因此,对于power,leakage power, transition time, rise and fall delays, timing constraints等,可能存在状态相关的规范。下面给出了状态相关leakage power规范的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
leakage_power() {

when : "A1 !A2";

value : 259.8;

}

leakage_power() {

when : "A1 A2";

value : 282.7;

}

黑匣子的接口时序模型

​ 本节介绍黑匣子(任意模块或块)的 IO 接口的时序弧。时序模型捕获黑盒 IO 接口的时序。黑盒接口模型可以具有组合以及顺序时序弧。一般来说,这些弧也可以是状态相关的。

img

​ 对于图 3-11 所示的示例,时序弧可以放置在以下类别下:

  • 输入到输出组合弧(Input to output combinational arc:):这对应于从输入到输出的直接组合路径,例如从输入端口 FIN 到输出端口 FOUT。
  • 输入顺序弧(Input sequential arc):这被描述为连接到触发器 D 引脚的输入的建立或保持时间。通常,在连接到触发器的 D 引脚之前,模块的输入可能存在组合逻辑。这方面的一个例子是在端口 DIN 上相对于时钟 ACLK 的设置检查。
  • 异步输入弧(Asynchronous input arc):这类似于触发器的输入异步引脚的恢复或移除时序约束。一个例子是触发器 UFF0 的异步清除引脚的输入 ARST。
  • 输出顺序弧(Output sequential arc):这类似于时钟输出连接到触发器Q 的输出传播时序。一般来说,触发器输出和模块输出之间可以有组合逻辑。一个例子是从时钟 BCLK 到触发器 UFF1 输出到输出端口 DOUT 的路径。

​ 除了上面的时序弧,还可以对黑匣子的外部时钟引脚进行脉宽检查。也可以定义内部节点并在这些内部节点上定义生成的时钟以及指定进出这些节点的定时弧。总之,黑盒模型可以具有以下时序弧:

  • 组合逻辑路径的输入输出时序弧。
  • 从同步输入到相关时钟引脚的建立和保持时序弧。
  • 相关时钟引脚的异步输入的恢复和移除时序弧。
  • 从时钟引脚到输出引脚的输出传播延迟。

高级时序建模(Advanced Timing Modeling)

​ 时序模型(例如 NLDM)表示通过基于输出负载电容和输入转换时间的时序弧的延迟。实际上,电池输出看到的负载由电容和互连电阻组成。由于 NLDM 方法假设输出负载是纯电容性的,因此互连电阻成为一个问题。即使互连电阻不为零,当互连电阻的影响很小时,也可以使用这些 NLDM 模型。在存在电阻互连的情况下,延迟计算方法通过获得单元输出处的等效有效电容来改进 NLDM 模型。延迟计算工具中使用的“有效”电容方法获得等效电容,该电容在单元的输出端具有与具有 RC 互连的单元相同的延迟。有效电容方法在第 5.2 节中作为延迟计算的一部分进行了描述。

​ 随着特征尺寸的缩小,由于波形变得高度非线性,互连电阻的影响会导致很大的不准确性。各种建模方法为单元输出驱动器提供了额外的精度。从广义上讲,这些方法通过等价电流源驱动的输出状态建模获得更高的精度。

这些方法的示例是 - CCS(Composite Current Source复合电流源)或 ECSM(Effective
Current Source Model有效电流源模型)。例如,CCS 时序模型通过使用随时间变化和电压相关的电流源为单元输出驱动器建模提供了额外的精度。通过指定不同场景下接收器引脚电容1和输出充电电流的详细模型来提供时序信息。接下来描述 CCS 模型的细节。

接收器引脚电容(Receiver Pin Capacitance)

​ 接收器引脚电容对应于为 NLDM 模型指定的输入引脚电容。与 NLDM 模型的引脚电容不同,CCS 模型允许在转换波形的不同部分分别指定接收器电容。由于互连 RC 和等效输入非线性电容(由于来自单元内输入设备的米勒效应),接收器电容值在转换波形上的不同点发生变化。因此,该电容在波形的初始(或前导)部分与波形的尾随部分被不同地建模。

​ 接收器引脚电容可以在引脚级别指定(如在 NLDM 模型中),其中通过该引脚的所有时序弧都使用该电容值。或者,接收器电容可以在定时弧级指定,在这种情况下,可以为不同的定时弧指定不同的电容模型。下面描述这两种指定接收器引脚电容的方法。

在引脚级别指定电容

当在引脚级别指定时,接下来给出接收器引脚电容的一维表规范示例。

1
2
3
4
5
6
7
8
9
10
11
pin (IN) {

. . .

receiver_capacitance1_rise ("Lookup_table_4") {

index_1: ("0.1, 0.2, 0.3, 0.4"); /* Input transition */

values("0.001040, 0.001072, 0.001074, 0.001085");

}

​ index_1 指定该引脚输入转换时间的索引。一维表中的value指定了波形前导部分输入引脚处上升波形的接收器电容。

​ 上面显示的receiver_capacitance1_rise 类似,receiver_capacitance2_rise 指定输入上升波形尾部的上升电容。下降电容(下降输入波形的引脚电容)分别由属性receiver_capacitance1_fall 和receiver_capacitance2_fall 指定。

在定时电弧级别指定电容

​ 接收器引脚电容也可以用时序弧指定为输入转换时间和输出负载的二维表。下面给出了时序弧级别的规范示例。此示例指定了引脚 IN 波形前导部分的接收器引脚上升电容,作为输入引脚 IN 的转换时间和输出引脚 OUT 的负载的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
pin (OUT) {

. . .

timing () {

related_pin : "IN" ;

. . .

receiver_capacitance1_rise ("Lookup_table_4x4") {

index_1("0.1, 0.2, 0.3, 0.4"); /* Input transition */

index_2("0.01, 0.2, 0.4, 0.8"); /* Output capacitance */

values("0.001040 , 0.001072 , 0.001074 , 0.001075", \

"0.001148 , 0.001150 , 0.001152 , 0.001153", \

"0.001174 , 0.001172 , 0.001172 , 0.001172", \

"0.001174 , 0.001171 , 0.001177 , 0.001174");

}

. . .

}

. . .

}

​ 上面的例子指定receiver_capacitance1_rise 的模型。该库包括receiver_capacitance2_rise、receiver_capacitance1_fall 和receiver_capacitance2_fall 规范的类似定义。

上面的例子指定了receiver_capacitance1_rise 的模型。该库包括receiver_capacitance2_rise、receiver_capacitance1_fall 和receiver_capacitance2_fall 规范的类似定义。

img

输出电流

​ 在 CCS 模型中,非线性时序用输出电流表示。输出电流信息被指定为依赖于输入转换时间和输出负载的查找表。

​ 输出电流针对输入转换时间和输出电容的不同组合而指定。对于这些组合中的每一个,都指定输出电流波形。本质上,这里的波形是指指定为时间函数的输出电流值。使用output_current_fall 指定的下降输出波形的输出电流示例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pin (OUT) {

. . .

timing () {

related_pin : "IN" ;

. . .

output_current_fall () {

vector ("LOOKUP_TABLE_1x1x5") {

reference_time : 5.06; /* Time of input crossing

threshold */

index_1("0.040"); /* Input transition */

index_2("0.900"); /* Output capacitance */

index_3("5.079e+00, 5.093e+00, 5.152e+00,

5.170e+00, 5.352e+00");/* Time values */

/* Output charging current: */

values("-5.784e-02, -5.980e-02, -5.417e-02,

-4.257e-02, -2.184e-03");

}

. . .

}

. . .

}

. . .

}

​ reference_time 属性是指输入波形越过延迟阈值的时间。 index_1 和 index_2 是指输入转换时间和使用的输出负载,index_3 是时间。 index_1 和 index_2(输入转换时间和输出电容)只能有一个值。 index_3 是指时间值,表值是指相应的输出电流。因此,对于给定的输入转换时间和输出负载,可以使用作为时间函数的输出电流波形。还指定了其他输入转换时间和输出电容组合的附加查找表。

​ 使用 output_current_rise 指定的上升输出波形的输出电流的描述类似。

模型串扰噪声分析(Models for Crosstalk Noise Analysis)

​ 本节介绍用于串扰噪声(或毛刺glitch)分析的 CCS 模型。这些被描述为 CCSN(CCS noise)模型。 CCS noise模型是结构模型,代表单元内不同的 CCB(Channel Connected Blocks通道连接块)。

​ 什么是CCB? CCB是指单元的源漏通道连接部分。例如,单级单元(如反相器、与非单元和非单元)仅包含一个 CCB——整个单元通过使用一个通道连接区域连接。多级单元,例如和单元,或或单元,包含多个 CCB。

​ CCSN 模型通常指定为由单元输入驱动的第一个 CCB,以及驱动单元输出的最后一个 CCB。这些是使用稳态电流、输出电压和传播噪声模型指定的。

​ 对于单级组合单元,如 nand 和 nor 单元,CCS 噪声模型是为每个时序弧指定的。这些单元只有一个 CCB,因此模型是从单元的输入引脚到输出引脚。

​ 下面描述了一个 nand 单元的示例模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
pin (OUT) {

. . .

timing () {

related_pin : "IN1";

. . .

ccsn_first_stage() { /* First stage CCB */

is_needed : true;

stage_type : both; /*CCB contains pull-up and pull-down*/

is_inverting : true;

miller_cap_rise : 0.8;

miller_cap_fall : 0.5;

dc_current (ccsn_dc) {

index_1 ("-0.9, 0, 0.5, 1.35, 1.8"); /* Input voltage */

index_2 ("-0.9, 0, 0.5, 1.35, 1.8"); /* Output voltage*/

values ( \

"1.56, 0.42, . . ."); /* Current at output pin */

}

. . .

output_voltage_rise () {

vector (ccsn_ovrf) {

index_1 ("0.01"); /* Rail-to-rail input transition */

index_2 ("0.001"); /* Output net capacitance */

index_3 ("0.3, 0.5, 0.8"); /* Time */

values ("0.27, 0.63, 0.81");

}

. . .

}

output_voltage_fall () {

vector (ccsn_ovrf) {

index_1 ("0.01"); /* Rail-to-rail input transition */

index_2 ("0.001"); /* Output net capacitance */

index_3 ("0.2, 0.4, 0.6"); /* Time */

values ("0.81, 0.63, 0.27");

}

. . .

}

propagated_noise_low () {

vector (ccsn_pnlh) {

index_1 ("0.5"); /* Input glitch height */

index_2 ("0.6"); /* Input glitch width */

index_3 ("0.05"); /* Output net capacitance */

index_4 ("0.3, 0.4, 0.5, 0.7"); /* Time */

values ("0.19, 0.23, 0.19, 0.11");

}

propagated_noise_high () {

. . .

}

}

}

​ 我们现在描述 CCS noise模型的属性。属性 ccsn_first_stage 表示该模型用于 nand 单元的第一阶段 CCB。如前所述,nand cell只有一个CCB。属性 is_needed 几乎总是正确的,但对于非功能性单元(例如称重单元和天线单元)的除外。值为 both 的 stage_type 指定此阶段具有上拉和下拉结构。 miller_cap_rise 和 miller_cap_fall 分别代表上升和下降输出转换的米勒电容

由于输入和输出端子之间的电容放大,米勒电容解释了反相级等效输入电容的增加。

直流电流(DC Current)

​ dc_current 表代表输入和输出引脚电压的不同组合的输出引脚上的直流电流。 index_1 指定输入电压,index_2 指定输出电压。二维表中的值指定了 CCB 输出端的直流电流。输入电压和输出电流均以库单位指定(通常为Volt 和 mA)。对于从输入 IN1 到 nand 单元的 OUT 的示例 CCS 噪声模型,-0.9V 的输入电压和 0V 的输出电压导致输出端的直流电流为 0.42mA。

输出电压(Output Voltage)

​ output_voltage_rise 和 output_voltage_fall 结构分别包含 CCB 输出上升和下降的时序信息。这些被指定为 CCB 输出节点的多维表。多维表被组织成多个表,指定不同input transition time和output net capacitances的上升和下降输出电压。每个表都有 index_1 指定rail-to-rail 输入转换时间速率,index_2 指定输出净电容。 index_3 指定输出电压跨越特定阈值点的次数(在本例中为 0.9V 的 Vdd 电源的 30%、70% 和 90%)。在每个多维表中,电压交叉点是固定的,在index_3中指定了CCB输出节点与电压交叉时的时间值。

传播噪声(Propagated Noise)

​ 传播噪声高和传播噪声低模型指定多维表,这些表通过 CCB 提供噪声传播信息。这些模型表征从 CCB 输入到输出的串扰毛刺(或噪声)传播。表征在输入端使用对称三角波。传播噪声的多维表被组织成多个表,指定 CCB 输出端的毛刺波形。这些多维表包含:

  • input glitch magnitude (in index_1),
  • input glitch width (in index_2),
  • CCB output net capacitance (in index_3), and
  • time (in index_4).

​ CCB 输出电压(或通过 CCB 传播的噪声)在表中指定。

两级单元的噪声模型(Noise Models for Two-Stage Cells)

​ 就像单级单元一样,两级单元(例如and cells 和 or cells)的 CCS 噪声模型通常被描述为时序弧的一部分。由于这些单元包含两个单独的 CCB,噪声模型分别为 ccsn_first_stage 和另一个为 ccsn_last_stage 指定。例如,对于双输入and单元,CCS 噪声模型由第一阶段和最后阶段的单独模型组成。这在接下来说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
pin (OUT) {

. . .

timing () {

related_pin : "IN1";

. . .

ccsn_first_stage() {

/* IN1 to internal node between stages */

. . .

}

ccsn_last_stage() { /* Internal node to output */

. . .

}

. . .

}

timing () {

related_pin : "IN2";

. . .

ccsn_first_stage() {

/* IN2 to internal node between stages */

. . .

}

ccsn_last_stage() {

/* Internal node to output */

/* Same as from IN1 */

. . .

}

}

. . .

}

. . .

为 IN2 指定的 ccsn_last_stage 中的模型与为 IN1 描述的 ccsn_last_stage 中的模型相同。

多级和顺序单元的噪声模型(Noise Models for Multi-stage and Sequential Cells)

​ 复杂组合或顺序单元的 CCS 噪声模型通常作为引脚规范的一部分进行描述。这不同于单级或两级单元,如 nand、nor 和,或者 CCS 噪声模型通常在引脚对基础上指定为时序弧的一部分。复杂的多级和顺序单元通常由所有输入引脚的 ccsn_first_stage 模型和输出引脚的另一个 ccsn_last_stage 模型描述。这些单元的 CCS 噪声模型不是时序弧的一部分,但通常是为引脚指定的。

​ 如果输入和输出之间的内部路径多达两个 CCB 级,噪声模型也可以表示为引脚对时序弧的一部分。通常,多级单元描述可以将一些 CCS 噪声模型指定为引脚对时序弧的一部分,而其他一些噪声模型可以通过引脚描述指定。

​ 下面的示例具有使用引脚描述以及部分时序弧指定的 CCS 噪声模型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
pin (CDN) {

. . .

}

pin (CP) {

. . .

ccsn_first_stage() {

. . .

}

}

pin (D) {

. . .

ccsn_first_stage() {

. . .

}

}

pin (Q) {

. . .

timing() {

related_pin : "CDN";

. . .

ccsn_first_stage() {

. . .

}

ccsn_last_stage() {

. . .

}

}

}

pin (QN) {

. . .

ccsn_last_stage() {

. . .

}

}

​ 请注意,上面触发器单元的一些 CCS 模型是用引脚定义的。那些在输入引脚上定义的引脚规范被指定为 ccsn_first_stage,输出引脚 QN 的 CCS 模型被指定为 ccsn_last_stage。此外,两级 CCS 噪声模型被描述为 CDN 到 Q 的时序弧的一部分。因此,此示例表明单元可以将 CCS 模型指定为引脚规范的一部分和时序组的一部分。

其他噪声模型

​ 除了上述 CCS noise模型外,一些单元库还可以提供其他模型来表征噪声。其中一些模型在 CCS noise模型出现之前就在使用了。如果 CCS noise模型可用,则不需要这些附加模型。为了完整性,我们在下面描述了一些早期的噪声模型。

​ DC 裕度模型(Models for DC margin):DC 裕度是指单元输入引脚允许的最大 DC 变化,它可以使单元保持稳定状态,即不会在输出端引起毛刺。例如,输入低电平的直流裕度是指输入引脚处的最大直流电压值,而不会在输出端引起任何转换。

​ 抗噪模型(Models for noise immunity):抗噪模型指定输入引脚允许的毛刺幅度。这些通常根据以毛刺宽度和输出电容作为两个指标的二维表来描述。表中的值对应于输入引脚允许的毛刺幅度。这意味着任何小于指定幅度和宽度的毛刺都不会通过单元传播。可以指定抗噪模型的不同变体,例如:

  • noise_immunity_high
  • noise_immunity_low
  • noise_immunity_above_high (overshoot)
  • noise_immunity_below_low (undershoot).

功耗建模(Power Dissipation Modeling)

​ 单元库包含与单元中的功耗相关的信息。这包括有功功率以及待机或泄漏功率。顾名思义,有功功率与设计中的活动有关,而待机功率是在待机模式下消耗的功率,这主要是由于泄漏造成的。

有功功率(Active Power)

​ 有功功率与单元输入和输出引脚的活动有关。单元中的有功功率来自输出负载的充电以及内部开关。这两者通常分别称为output switching power 和 internal switching power。

​ 输出开关功率(output switching power)与单元类型无关,仅取决于输出容性负载、开关频率和单元的电源。内部开关功率取决于单元的类型,因此该值包含在单元库中。下面描述库中内部开关电源的规格。

​ 内部开关电源在单元库中称为 internal power。这是当单元的输入或输出有活动时单元内的功耗。对于组合电池,输入引脚转换会导致输出切换,从而产生内部开关电源。例如,只要输入切换(在输入处有上升或下降转换),逆变器单元就会消耗功率。库中的内部电源描述为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
pin (Z1) {

. . .

power_down_function : "!VDD + VSS";

related_power_pin : VDD;

related_ground_pin : VSS;

internal_power () {

related_pin : "A";

power (template_2x2) {

index_1 ("0.1, 0.4"); /* Input transition */

index_2 ("0.05, 0.1"); /* Output capacitance */

values ( /* 0.05 0.1 */ \

/* 0.1 */ "0.045, 0.050", \

/* 0.4 */ "0.055, 0.056");

}

}

}

​ 上例显示了从输入引脚 A 到电池输出引脚 Z1 的功耗。模板中的 2x2 表是根据引脚 A 的输入转换和引脚 Z1 的输出电容。请注意,虽然该表包括输出电容,但表中的值仅对应于内部开关,不包括输出电容的贡献。这些值代表每个开关转换(上升或下降)在电池中耗散的内部能量。这些单位源自库中的其他单位(通常电压以伏特 (V) 为单位,电容以皮法 (pF) 为单位,这映射到以皮焦 (pJ) 为单位的能量)。因此,库中的内部功率实际上指定了每次转换消耗的内部能量。

​ 除了功率表之外,上面的示例还说明了电源引脚、接地引脚和断电功能的规范,该功能指定了电池可以断电的条件。这些构造允许在不同电源可能断电的设计和场景中使用多个电源。下图显示了每个单元的电源引脚规格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cell (NAND2) {

. . .

pg_pin (VDD) {

pg_type : primary_power;

voltage_name : COREVDD1;

. . .

}

pg_pin (VSS) {

pg_type : primary_ground;

voltage_name : COREGND1;

. . .

}

}

​ 电源规范语法允许单独构造上升和下降功率(指输出检测)。就像时序弧一样,功率规范也可以与状态相关。例如,异或单元的状态相关功耗可以指定为依赖于各种输入的状态。

​ 对于组合单元,开关功率是在输入输出引脚对的基础上指定的。然而,对于具有互补输出 Q 和 QN 的触发器等时序单元,CLK->Q 转换也会导致 CLK->QN 转换。因此,库可以将内部开关功率指定为一个三维表,如下所示。下面示例中的三个维度分别是 CLK 的输入压摆和 Q 和 QN 的输出电容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
pin (Q) {

. . .

internal_power() {

related_pin : "CLK";

equal_or_opposite_output : "QN";

rise_power(energy_template_3x2x2) {

index_1 ("0.02, 0.2, 1.0"); /* Clock transition */

index_2 ("0.005, 0.2"); /* Output Q capacitance */

index_3 ("0.005, 0.2"); /* Output QN capacitance */

values ( /* 0.005 0.2 */ /* 0.005 0.2 */ \

/* 0.02 */ "0.060, 0.070", "0.061, 0.068", \

/* 0.2 */ "0.061, 0.071", "0.063, 0.069", \

/* 1.0 */ "0.062, 0.080", "0.068, 0.075");

}

fall_power(energy_template_3x2x2) {

index_1 ("0.02, 0.2, 1.0");

index_2 ("0.005, 0.2");

index_3 ("0.005, 0.2");

values ( \

"0.070, 0.080", "0.071, 0.078", \

"0.071, 0.081", "0.073, 0.079", \

"0.066, 0.082", "0.068, 0.085");

}

}

​ 即使输出或内部状态没有转换,也可以消耗开关功率。一个常见的例子是在触发器的时钟引脚上切换的时钟。触发器在每次时钟切换时消耗功率 - 通常是由于触发器单元内部的反相器的切换。即使触发器输出不切换,时钟引脚切换引起的功率也会耗散。因此,对于时序单元,输入引脚功率是指单元内部的功耗,即输出不转换时的功耗。下面是输入引脚电源规格的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
cell (DFF) {

. . .

pin (CLK) {

. . .

rise_power () {

power (template_3x1) {

index_1 ("0.1, 0.25, 0.4"); /* Input transition */

values ( /* 0.1 0.25 0.4 */ \

"0.045, 0.050, 0.090");

}

}

fall_power () {

power (template_3x1) {

index_1 ("0.1, 0.25, 0.4");

values ( \

"0.045, 0.050, 0.090");

}

}

}

. . .

}

​ 此示例显示了 CLK 引脚切换时的电源规格。这表示即使输出不切换时时钟切换导致的功耗。

时钟引脚的功率是否被重复计算了(Double Counting Clock Pin Power?)

​ 请注意,触发器还包含由于 CLK->Q 转换引起的功耗。因此,重要的是 CLK->Q 功率规格表中的值不包括由于对应于输出 Q 不切换时的条件的 CLK 内部功率的贡献。

​ 上述准则是指应用工具使用功率表的一致性,并确保在功率计算过程中不会重复计算由于时钟输入而指定的内部功率。

泄露功率(Leakage Power)

​ 大多数标准单元都设计为仅在输出或状态发生变化时才耗散功率。当电池通电但没有活动时消耗的任何功率都是由于非零泄漏电流。泄漏可能是由于 MOS 器件的亚阈值电流或由于通过栅极氧化物的隧道电流。在前几代 CMOS 工艺技术中,漏电功率一直可以忽略不计,在设计过程中也不是主要考虑因素。然而,随着技术的缩小,泄漏功率变得越来越重要,与有功功率相比不再可以忽略不计。

高 Vt 单元是指阈值电压高于工艺技术标准的单元。

​ 上所述,泄漏功率贡献来自两种现象:MOS 器件中的亚阈值电流和栅极氧化物隧穿。通过使用高 Vt 单元,可以降低亚阈值电流;然而,由于高 Vt 单元的速度降低,因此需要进行权衡。高 Vt 单元具有较小的泄漏但速度较慢。类似地,低 Vt 单元具有更大的泄漏但允许更快的速度。通过切换到高(或低)Vt 单元,栅极氧化物隧道效应不会显着改变。因此,控制泄漏功率的一种可能方式是使用高 Vt 单元。与高 Vt 和标准 Vt 单元之间的选择类似,设计中使用的单元强度是泄漏和速度之间的权衡。更高强度的单元具有更高的泄漏功率,但提供更高的速度。与电源管理相关的权衡在第 10.6 节中详细描述。

​ 亚阈值 MOS 泄漏与温度具有很强的非线性相关性。在大多数工艺技术中,随着器件结温从 25C 增加到 125C,亚阈值泄漏会增加 10 到 20 倍。栅极氧化物隧道效应的贡献相对于温度或器件的 Vt 而言是相对不变的。在 100 纳米及以上工艺技术中可忽略不计的栅极氧化物隧道效应,已成为 65 纳米或更精细技术在较低温度下泄漏的重要因素。例如,对于 65nm 或更精细的工艺技术,栅极氧化物隧道泄漏可能等于室温下的亚阈值泄漏。在高温下,亚阈值泄漏仍然是泄漏功率的主要贡献者。

​ 为库中的每个单元指定了泄漏功率。例如,逆变器单元可能包含以下规格:

1
cell_leakage_power : 1.366;

​ 这是单元中耗散的泄漏功率 - 泄漏功率单位在库的标题中指定,通常以纳瓦为单位。通常,泄漏功率取决于单元的状态,并且可以使用 when 条件指定状态相关值。

​ 例如,INV1 单元格可以具有以下规范:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cell_leakage_power : 0.70;

leakage_power() {

when : "!I";

value : 1.17;

}

leakage_power() {

when : "I";

value : 0.23;

}

​ 其中 I 是 INV1 单元的输入引脚。应该注意的是,规范包括一个默认值(在when条件之外),并且默认值通常是在when条件内指定的泄漏值的平均值。

单元库其他属性(Other Attributes in Cell Library)

​ 除了时序信息之外,库中的单元描述还指定了时序弧的区域、功能和 SDF 条件。本节简要介绍了这些内容;有关更多详细信息,请参阅 Liberty 手册。

面积规格(Area Specification)

​ area规范提供了一个单元格或单元格组的面积。

1
area : 2.35;

​ 以上指定单元格的面积为 2.35 个面积单位。这可以代表单元使用的实际硅面积,也可以是面积的相对量度。

功能规格(Function Specification)

​ function规范指定引脚(或引脚组)的功能。

1
2
3
4
5
6
7
pin (Z) {

function: "IN1 & IN2";

. . .

}

​ 以上指定了两个输入and单元的 Z 引脚的功能。

SDF条件(SDF Condition)

​ SDF 条件属性支持标准延迟格式 (SDF) 文件生成和反注释期间的条件匹配。正如when为时序分析的状态相关模型指定条件一样,SDF注释的状态相关时序使用的相应规范由sdf_cond表示。

​ 以下示例说明了这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
timing() {

related_pin : "A1";

when : "!A2";

sdf_cond : "A2 == 1'b0";

timing_sense : positive_unate;

cell_rise(delay_template_7x7) {

. . .

}

}

表征和操作条件(Characterization and Operating Conditions)

单元库指定了创建库的特征和操作条件。例如,库的标题可能包含以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nom_process : 1;

nom_temperature : 0;

nom_voltage : 1.1;

voltage_map(COREVDD1, 1.1);

voltage_map(COREGND1, 0.0);

operating_conditions("BCCOM"){

process : 1;

temperature : 0;

voltage : 1.1;

tree_type : "balanced_tree";

}

​ 标称环境条件(指定为 nom_process、nom_temperature 和 nom_voltage)指定了表征库的过程、电压和温度。操作条件指定使用该库中的单元的条件。如果特性和工作条件不同,延迟计算时得到的时序值需要降额;这是通过使用库中指定的降额因子(k 因子)来实现的。

​ 在不同于用于表征的条件下使用降额获得时序值会导致时序计算不准确。仅当在感兴趣的条件下表征库不可行时才采用降额程序。

什么是过程变量?(What is the Process Variable?)

​ 与作为物理量的温度和电压不同,该过程不是可量化的量。出于数字表征和验证的目的,它可能是一种缓慢、典型或快速的过程。因此, 1.0(或任何其他值)的过程值是什么意思?答案如下。

​ 库表征是一个耗时的过程,并且表征不同工艺角的库可能需要数周时间。过程变量设置允许使用以特定过程角为特征的库用于不同过程角的时序计算。过程的 k 因子可用于降低从特征过程到目标过程的延迟。如上所述,降额因子的使用会在时序计算过程中引入不准确性。跨工艺条件降额特别不准确,很少使用。总而言之,指定不同过程值(例如 1.0 或任何其他值)的唯一功能是允许在很少(如果曾经)使用的条件下降额。

使用K因子降额

​ 如上所述,降额因子(称为 k 因子)用于在操作条件与特征条件不同时获得延迟。 k 因子是近似因子。库中 k 因子的示例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* k-factors */

k_process_cell_fall : 1;

k_process_cell_leakage_power : 0;

k_process_cell_rise : 1;

k_process_fall_transition : 1;

k_process_hold_fall : 1;

k_process_hold_rise : 1;

k_process_internal_power : 0;

k_process_min_pulse_width_high : 1;

k_process_min_pulse_width_low : 1;

k_process_pin_cap : 0;

k_process_recovery_fall : 1;

k_process_recovery_rise : 1;

k_process_rise_transition : 1;

k_process_setup_fall : 1;

k_process_setup_rise : 1;

k_process_wire_cap : 0;

k_process_wire_res : 0;

k_temp_cell_fall : 0.0012;

k_temp_cell_rise : 0.0012;

k_temp_fall_transition : 0;

k_temp_hold_fall : 0.0012;

k_temp_hold_rise : 0.0012;

k_temp_min_pulse_width_high : 0.0012;

k_temp_min_pulse_width_low : 0.0012;

k_temp_min_period : 0.0012;

k_temp_rise_propagation : 0.0012;

k_temp_fall_propagation : 0.0012;

k_temp_recovery_fall : 0.0012;

k_temp_recovery_rise : 0.0012;

k_temp_rise_transition : 0;

k_temp_setup_fall : 0.0012;

k_temp_setup_rise : 0.0012;

k_volt_cell_fall : -0.42;

k_volt_cell_rise : -0.42;

k_volt_fall_transition : 0;

k_volt_hold_fall : -0.42;

k_volt_hold_rise : -0.42;

k_volt_min_pulse_width_high : -0.42;

k_volt_min_pulse_width_low : -0.42;

k_volt_min_period : -0.42;

k_volt_rise_propagation : -0.42;

k_volt_fall_propagation : -0.42;

k_volt_recovery_fall : -0.42;

k_volt_recovery_rise : -0.42;

k_volt_rise_transition : 0;

k_volt_setup_fall : -0.42;

k_volt_setup_rise : -0.42;

​ 这些因素用于在延迟计算期间操作条件的过程、电压或温度与库中的标称条件不同时获得时序。请注意,k_volt 因子为负,这意味着延迟随着电压供应的增加而减少,而 k_temp 因子是正的,这意味着延迟通常随着温度的升高而增加(除了在 2.10 节中描述的表现出温度反转现象的电池)。 k 因子的使用方法如下:

1
2
3
4
5
6
7
Result with derating = Original_value *

( 1 + k_process * DELTA_Process

+ k_volt * DELTA_Volt

+ k_temp * DELTA_Temp)

​ 例如,假设一个库在 1.08V 和 125C 下具有慢速过程模型。如果要获得 1.14V 和 100C 的延迟,则慢速工艺模型的单元上升延迟可通过下式获得:

1
2
3
4
5
Derated_delay = Library_delay *

( 1 + k_volt_cell_rise * 0.06

- k_temp_cell_rise * 25)

​ 假设使用了上面概述的 k_factors,则前面的等式映射为:

1
2
3
Derated_delay = Library_delay * (1 - 0.42 * 0.06 - 0.0012 * 25)

= Library_delay * 0.9448

​ 降额条件下的延迟计算为原始延迟的 94.48%。

库单元(Library Units)

​ 单元描述具有库单位方面的所有值。这些单位是使用 Liberty 命令集在库文件中声明的。电压、时间、电容和电阻的单位声明如下例所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
library("my_cell_library") {

voltage_unit : "1V";

time_unit : "1ns";

capacitive_load_unit (1.000000, pf);

current_unit : 1mA;

pulling_resistance_unit : "1kohm";

. . .

}

​ 在本文中,我们假设库时间单位以纳秒 (ns) 为单位,电压以伏特 (V) 为单位,每次跃迁的内部功率以皮焦 (pJ) 为单位,泄漏功率以纳瓦 (nW) 为单位,电容值为以皮法 (pF) 为单位,电阻值以 Kohms 为单位,面积单位为平方微米 (mm2),除非明确指定以帮助解释。

互连寄生(Interconnect Parasitics)

​ 本章概述了处理和表示互连寄生的各种技术,用于设计的时序验证。

在数字设计中,连接标准单元和模块引脚的导线称为网络(net)。net通常只有一个驱动,而它可以驱动多个扇出单元或块。物理实现后,net可以在芯片的多个金属层上移动。不同的金属层可以有不同的电阻和电容值。对于等效电学表示,通常将net分成若干段,每个段由等效寄生参数表示。我们将互连迹线(interconnect trace)称为段的同义词,也就是说,它是特定金属层上网络的一部分。

互连RLC(RLC for Interconnect )

​ 互连电阻来自设计实现中各种金属层和通孔中的互连走线。图 4-1 显示了穿过各种金属层和通孔的示例网络。因此,互连电阻可以被认为是单元的输出引脚和扇出单元的输入引脚之间的电阻。

img

​ 互连电容的贡献也来自金属走线,包括接地电容以及相邻信号路径之间的电容。

​ 电感是由电流回路引起的。通常,电感的影响在芯片内可以忽略,仅在封装和板级分析时考虑。在芯片级设计中,电流回路又窄又短——这意味着电流返回路径是通过靠近布线的电源或接地信号。在大多数情况下,时序分析不考虑片上电感。对片上电感分析的任何进一步描述超出了本书的范围。接下来描述互连电阻和电容的表示。

​ 一段互连走线的电阻和电容 (RC) 理想地由分布式 RC 树表示,如图 4-2 所示。在该图中,RC 树的总电阻和电容 - 分别为 Rt 和 Ct -—对应于 Rp* L 和 Cp* L,其中 Rp、Cpare 每单位长度的走线互连电阻和电容值,L 是走线长度。 Rp、Cp 值通常从提取的各种配置的寄生参数中获得,由 ASIC 代工厂提供。

img

​ RC 互连可以用各种简化模型表示。这些在下面的小节中进行了描述。

T -model

​ 在 T 模型表示中,总电容 Ct 建模为连接在电阻树的中间。总电阻 Rt 分为两部分(每部分都是 Rt/2),Ct连接在电阻树的中点,如图 4-3 所示。

img

Pi -model

​ 在图 4-4 所示的 Pi 模型中,总电容 Ct 分为两部分(每部分为 Ct/2)并连接在电阻的任一侧。

img

​ 更准确的分布RC树的表示是通过将Rt和Ct分解成多个部分得到的。对于分解成的N段,R和C的每一个中间段都是Rt/ N和Ct/ N。末端段可以按照T-model或Pi-model的概念建模。图4-5为末端段采用T-model的N段,图4-6为末端段采用Pi-model的N段。

img

​ 通过对 RC 互连建模的广泛概述,我们现在描述如何在布局前阶段( pre-layout)(通过估计)或布局后阶段(post-layout)(通过详细提取)利用寄生互连。下一节描述了预布局过程中寄生互连的建模。

线载模型(Wireload Models)

​ 在布局规划或布局之前,线载模型可用于估计电容、电阻和互连引起的面积开销。线载模型用于根据网络的扇出数量估计网络的长度。线载模型取决于块的面积,不同面积的设计可以选择不同的线载模型。线载模型还将估计的网络长度映射到电阻、电容和相应的布线面积开销。

​ 块内的平均线长与块的大小密切相关;平均net长度随着块大小的增加而增加。图 4-7 显示,对于不同的区域(芯片或块大小),通常会使用不同的线载模型来确定寄生参数。因此,该图描绘了较小尺寸块的较小电容。

img

​ 这是线载模型的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
wire_load (“wlm_conservative”) {

resistance : 5.0;

capacitance : 1.1;

area : 0.05;

slope : 0.5;

fanout_length (1, 2.6);

fanout_length (2, 2.9);

fanout_length (3, 3.2);

fanout_length (4, 3.6);

fanout_length (5, 4.1);

}

resistance是互连线单位长度的电阻值,capacitance是互连线单位长度的电容值,area是互连线单位长度的面积开销,slope是用于扇出-长度(fanout_length)表中未指定的数据点的外推斜率。

img

​ 线载模型说明了如何将线的长度描述为扇出的函数。上面的例子如图 4-8 所示。对于表中未明确列出的任何扇出数,互连长度是使用具有指定斜率的线性外推法获得的。例如,扇出 8 会导致以下结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Length = 4.1 + (8 - 5) * 0.5 = 5.6 units

Capacitance = Length * cap_coeff(1.1) = 6.16 units

Resistance = Length * res_coeff(5.0) = 28.0 units

Area overhead due to interconnect = Length * area_coeff(0.05)

= 0.28 area units



互连线长度 = 4.1 + (8 - 5) * 0.5 = 5.6



电容值 = 5.6 * 1.1 = 6.16



电阻值 = 5.6 * 5 =28.0



面积开销 = 5.6 * 0.05 = 0.28

​ length, capacitance, resistance 和 area的单位在liberty中指定。

互连树(Interconnect Trees)

​ 一旦确定了预布局互连的电阻和电容估计值,比如 Rwire 和 Cwire,下一个问题就是互连的结构。互连RC结构如何相对于驱动单元定位?这很重要,因为从驱动引脚到负载引脚的互连延迟取决于互连的结构。通常,互连延迟取决于路径上的互连电阻和电容。因此,此延迟可能因网络所采用的拓扑而异。

​ 对于预布局估计,互连 RC 树可以使用以下三种不同表示法之一来表示(见图 4-9)。请注意,在三种情况中的每一种情况下,总互连长度(以及电阻和电容估计值)都相同。

  • 最佳情况树(Best-case tree):

​ 在最佳情况树中,假设目标(负载)引脚在物理上与驱动相邻。因此,在通向目标引脚的路径中,没有任何导线电阻。来自其他扇出引脚的所有导线电容和引脚电容仍充当驱动引脚上的负载。

  • 平衡树( Balanced tree):

​ 在这种情况下,假设每个目标引脚都位于互连线的单独部分。到目的地的每条路径都会看到总导线电阻和电容的相等部分。

  • 最坏情况树(Worst-case tree):

​ 在这种情况下,假设所有目标引脚都位于线路的远端。因此,每个目标引脚都会看到总导线电阻和总导线电容。

img

指定线载模型(Specifying Wireload Models)

​ 使用以下命令指定线载模型:

1
2
3
set_wire_load_model “wlm_cons” -library “lib_stdcell”

# 以上命令表示使用单元库lib_stdcell中的线负载模型wlm_cons

​ 当网络跨越层次边界时,可以根据线载模式将不同的线载模型应用于每个层次边界中网络的不同部分。这些线载模式是:

  • top
  • enclosed
  • segmented

​ 可以使用 set_wire_load_mode 规范指定线载模式,如下所示。

1
set_wire_load_mode enclosed

​ 在top线载模式下,层次结构内的所有网络都继承顶层的线载模型,即忽略低层模块中指定的任何线载模型。因此,顶级线载模型优先。对于图 4-10 所示的示例,块 B1 中指定的 wlm_cons 线载模型优先于块 B2、B3 和 B4 中指定的所有其他线载模型。

img

​ 在enclosed线载模式下,完全包围网络的块的线载模型用于整个网络。对于图 4-11 所示的示例,网络 NETQ 包含在块 B2 中,因此块 B2 的线载模型 wlm_light 用于该网络。完全包含在块 B3 中的其他网络使用 wlm_aggr 线载模型,而完全包含在块 B5 中的网络使用 wlm_typ 线载模型。

img

​ 在segmented线负载模式下,网络的每段(segment)都从包含该段的块中获取其线负载模型,网络的每个部分都在该层次内使用适当的线负载模型。图4-12举例说明了一个网络NETQ,它的三段分别在三个块中。B3块中此网络的扇出互连使用wlm_aggr线负载模型,B4块中使用wlm_typ线负载模型,B2块中使用wlm_light线负载模型。

img

​ 通常,根据模块的芯片面积选择线载模型。但是,这些可以根据用户的判断进行修改或更改。例如,可以为 0 到 400 之间的块区域选择线载模型 wlm_aggr,为 400 到 1000 之间的区域选择线载模型 wlm_typ,以及为 1000 或更高的区域选择线载模型 wlm_cons。线载模型通常在单元库中定义 - 但是用户也可以定义自定义线载模型。可以选择在单元库中将默认线载模型指定为:

1
default_wire_load: "wlm_light";

​ 在单元库中定义了基于面积选择线载模型的线载选择组。这是一个这样的例子:

1
2
3
4
5
6
7
8
9
10
11
wire_load_selection (WireAreaSelGrp){

wire_load_from_area(0, 50000, "wlm_light");

wire_load_from_area(50000, 100000, "wlm_cons");

wire_load_from_area(100000, 200000, "wlm_typ");

wire_load_from_area(200000, 500000, "wlm_aggr");

}

​ 一个单元库可以包含许多这样的选择组。通过使用 set_wire_load_selection_group 规范,可以选择特定的一个用于 STA。

1
set_wire_load_selection_group WireAreaSelGrp

​ 本节描述了在物理实现之前,即在预布局阶段期间对估计寄生参数的建模。下一节描述了从布局中提取的寄生参数的表示。

提取寄生参数的表示(Representation of Extracted Parasitics)

​ 从布局中提取的寄生参数可以用三种格式描述:

  • 详尽寄生参数格式 :Detailed Standard Parasitic Format(DSPF)
  • 精简寄生参数格式 :Reduced Standard Parasitic Format(RSPF)
  • 标准寄生参数格式 :Standard Parasitic Extraction Format(SPEF)

​ 一些工具提供了寄生生物的专有二进制表示,如SBPF;这有助于保持较小的文件大小,并加快工具对寄生生物的读取。下面简要介绍上述三种格式。

详细标准寄生格式(Detailed Standard Parasitic Format)

电路模拟器可读的格式,如SPICE。更多信息,请参阅[NAG75]或任何关于模拟集成电路设计或模拟的书籍

​ 使用DSPF格式时,详尽的寄生参数以SPICE格式表示。SPICE中的Comment语句用于表明单元类型、单元引脚及其电容。电阻和电容值采用标准SPICE语法,并且单元实例也包含在此表示格式中。这种格式的优势在于,DSPF文件可以用作SPICE仿真器本身的输入。但是,缺点是DSPF语法过于详细和冗长,导致模块的总文件大小非常大。因此,这种格式在实际中仅用于相对较小的一组网络。

​ 这里是一个示例DSPF文件,它描述了从主输入IN到缓冲器BUF的输入引脚a的互连,以及从BUF的输出引脚OUT到主输出引脚OUT的另一个网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
.SUBCKT TEST_EXAMPLE OUT IN

* Net Section

*|GROUND_NET VSS

*|NET IN 4.9E-02PF

*|P (IN I 0.0 0.0 4.1)

*|I (BUF1:A BUF A I 0.0 0.7 4.3)

C1 IN VSS 2.3E-02PF

C2 BUF1:A VSS 2.6E-02PF

R1 IN BUF1:A 4.8E00

*|NET OUT 4.47E-02PF

*|S (OUT:1 8.3 0.7)

*|P (OUT O 0.0 8.3 0.0)

*|I (BUF1:OUT BUF1 OUT O 0.0 4.9 0.7)

C3 BUF1:OUT VSS 3.5E-02PF

C4 OUT:1 VSS 4.9E-03PF

C5 OUT VSS 4.8E-03PF

R2 BUF1:OUT OUT:1 12.1E00

R3 OUT:1 OUT 8.3E00

*Instance Section

X1 BUF1:A BUF1:OUT BUF

.ENDS

​ DSPF中的非标准SPICE语句是以 * |开头,并具有以下格式:

1
2
3
4
5
6
7
8
9
*|I(InstancePinName InstanceName PinName PinType PinCap X Y)

*|P(PinName PinType PinCap X Y)

*|NET NetName NetCap

*|S(SubNodeName X Y)

*|GROUND_NET NetName

精简标准寄生格式(Reduced Standard Parasitic Format)

​ 在RSPF表示中,寄生以简化形式表示。简化格式包括电压源和受控电流源。RSPF格式也是SPICE文件,因为它可以读入类似SPICE的模拟器。RSPF格式要求减少详细的寄生并映射到减少的格式中。因此,这是RSPF表示的一个缺点,因为寄生提取过程的重点通常是提取精度,而不是简化为类似RSPF的紧凑格式。RSPF表示的另一个限制是双向信号流不能用这种格式表示。

​ 下面是一个RSPF文件的示例。原始设计和等效表示如图4-13所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
* Design Name : TEST1

* Date : 7 September 2002

* Time : 02:00:00

* Resistance Units : 1 ohms

* Capacitance Units : 1 pico farads

*| RSPF 1.0

*| DELIMITER "_"

.SUBCKT TEST1 OUT IN

*| GROUND_NET VSS

*|NET CP 0.075PF

*|DRIVER CKBUF_Z CKBUF Z

*|S (CKBUF_Z_OUTP 0.0 0.0)

R1 CKBUF_Z CKBUF_Z_OUTP 8.85

C1 CKBUF_Z_OUTP VSS 0.05PF

C2 CKBUF_Z VSS 0.025PF

*|LOAD SDFF1_CP SDFF1 CP

*|S (SDFF1_CP_INP 0.0 0.0)

E1 SDFF1_CP_INP VSS CKBUF_Z VSS 1.0

R2 SDFF1_CP_INP SDFF1_CP 52.0

C3 SDFF1_CP VSS 0.1PF

*|LOAD SDFF2_CP SDFF2 CP

*|S (SDFF2_CP_INP 0.0 0.0)

E2 SDFF2_CP_INP VSS CKBUF_Z VSS 1.0

R3 SDFF2_CP_INP SDFF2_CP 43.5

C4 SDFF2_CP VSS 0.1PF

*Instance Section

X1 SDFF1_Q SDFF1_QN SDFF1_D SDFF1_CP SDFF1_CD VDD VSS SDFF

X2 SDFF2_Q SDFF2_QN SDFF2_D SDFF2_CP SDFF2_CD VDD VSS SDFF

X3 CKBUF_Z CKBUF_A VDD VSS CKBUF

.ENDS

.END

​ 此文件具有以下功能:

  • 在每个扇出单元的输入引脚上都使用0.1pF的电容(C3和C4)和电阻(R2和R3)对引脚到引脚(pin-to-pin)的互连延迟进行建模,电阻值的选取原则是使RC延迟对应于引脚到引脚的互连延迟。驱动单元输出引脚上的π型负载模拟了通过该单元的延迟。
  • 输入端的RC元件由理想电压源(E1和E2)驱动,该电压源等于驱动单元输出端的电压。

img

标准寄生交换格式(Standard Parasitic Extraction Format)

​ SPEF 是一种紧凑的格式,可以表示详细的寄生参数。下面显示了具有两个扇出的网络示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
*D_NET NET_27 0.77181

*CONN

*I *8:Q O *L 0 *D CELL1

*I *10:I I *L 12.3

*CAP

1 *9:0 0.00372945

2 *9:1 0.0206066

3 *9:2 0.035503

4 *9:3 0.0186259

5 *9:4 0.0117878

6 *9:5 0.0189788

7 *9:6 0.0194256

8 *9:7 0.0122347

9 *9:8 0.00972101

10 *9:9 0.298681

11 *9:10 0.305738

12 *9:11 0.0167775

*RES

1 *9:0 *9:1 0.0327394

2 *9:1 *9:2 0.116926

3 *9:2 *9:3 0.119265

4 *9:4 *9:5 0.0122066

5 *9:5 *9:6 0.0122066

6 *9:6 *9:7 0.0122066

7 *9:8 *9:9 0.142205

8 *9:9 *9:10 3.85904

9 *9:10 *9:11 0.142205

10 *9:12 *9:2 1.33151

11 *9:13 *9:6 1.33151

12 *9:1 *9:9 1.33151

13 *9:5 *9:10 1.33151

14 *9:12 *8:Q 0

15 *9:13 *10:I 0

*END

​ 寄生参数 R 和 C 的单位在 SPEF 文件的开头指定。附录 C 中提供了对 SPEF 的更详细描述。 由于其表示的紧凑性和完整性,SPEF 是表示设计中寄生效应的首选格式。

表示耦合电容(Representing Coupling Capacitances)

​ 上一节说明了将网络电容表示为接地电容(grounded capacitances)的情况。由于纳米技术中的大多数电容是侧壁电容(sidewall capacitances),这些电容的正确表示是信号到信号耦合电容(coupling capacitance)。

​ DSPF 中耦合电容的表示是原始 DSPF 标准的附加内容,因此不是唯一的。耦合电容在两组耦合网络之间复制。这意味着 DSPF 不能直接读入 SPICE,因为两组网络中的耦合电容是重复的。一些输出 DSPF 的工具通过在两个耦合网络中包含一半的耦合电容来解决这种差异。

​ RSPF 是简化的表示,因此不适合表示耦合电容。

​ SPEF 标准以统一和明确的方式处理耦合电容,因此是当对串扰时序感兴趣时选择的提取格式。此外,SPEF 是文件大小方面的紧凑表示,用于表示有和没有耦合的寄生效应。

​ 如附录 C 中所述,管理文件大小的机制之一是在文件开头设置名称目录。许多提取工具现在在 SPEF 文件的开头指定一个网络名称目录(将网络名称映射到索引),以避免重复网络名称的冗长。这显着减小了文件大小。 SPEF 的附录中显示了名称为目录的示例。

分层方法(Hierarchical Methodology)

​ 大型复杂设计在物理设计过程中通常需要分层方法来进行寄生提取和时序验证。在这种情况下,块的寄生参数在块级别被提取,然后可以在更高层次的层次结构中使用。

​ 一个块的布局提取寄生参数可用于与布局尚未完成的另一个块的时序验证。在这种情况下,布局完整块的布局提取寄生参数通常与基于线载模型的pre-layout块的估计寄生参数一起使用。

​ 在分层流的情况下,顶级布局已完成但块仍表示为黑盒(pre-layou),基于线载模型的寄生参数估计可用于较低级别的块以及布局提取的寄生参数最高水平。块的布局完成后,可以将顶部的布局提取寄生参数和块缝合在一起。

在布局中复制块(Block Replicated in Layout)

​ 如果一个设计块在布局中被多次复制,则一个实例的寄生提取可以用于所有实例。这要求对于块的各种实例化,块的布局在所有方面都相同。例如,从块内布线的网络来看,布局环境应该没有区别。这意味着块级网络不与块外的任何网络电容耦合。实现这一点的一种方法是确保没有顶层网络在块上布线,并且在块边界附近布线的网络有足够的屏蔽或间距。

减少关键网络寄生效应(Reducing Parasitics for Critical Nets)

​ 本节简要概述了管理关键网络寄生效应影响的常用技术。

降低互连电阻(Reducing Interconnect Resistance)

​ 对于关键网络,保持低转换值(或快速转换时间)很重要,这意味着应降低互连电阻。通常,有两种方法可以实现低电阻:

  • 宽走线(Wide trace):走线比最小宽度更宽可降低互连电阻,而不会导致寄生电容显着增加。因此,减少了总的 RC 互连延迟和转换时间。
  • 上层(较厚)金属布线(Routing in upper (thicker) metals):上层金属层通常具有低电阻率,可用于布线关键信号。低互连电阻减少了互连延迟以及目标引脚的转换时间。

增加线距(Increasing Wire Spacing)

​ 增加走线之间的间距会降低网络的耦合电容和总电容。大耦合电容会增加串扰,避免串扰是在相邻走线中长距离布线的网络的重要考虑因素。

相关网络的寄生参数(Parasitics for Correlated Nets)

​ 在很多情况下,一组网络必须在时序上匹配。一个例子是高速 DDR 接口的字节通道内的数据信号。由于字节通道内的所有信号看到相同的寄生信号很重要,因此所有信号都在同一金属层中布线。例如,虽然金属层 M2 和 M3 具有相同的平均值和相同的统计变化,但这些变化是独立的,因此这两个金属层中的寄生变化不会相互跟踪。因此,如果关键信号的时序匹配很重要,那么每个金属层的布线必须相同。

延迟计算(Delay Calculation)

解释了如何为布局前和布局后时序验证计算单元延迟和路径延迟。本章扩展了前面章节中描述的概念,介绍了整个设计的时序。本章概述了用于 pre-layout 和 post-layout时序验证的基于单元设计的延迟计算。

前几章重点介绍了互连和单元库的建模。单元和互连建模技术用于获得设计时序。

概述(Overview)

延迟计算基础(Delay Calculation Basics)

​ 典型的设计包括各种组合单元和顺序单元。我们使用图5-1所示的示例的逻辑片段来描述延迟计算的概念。

img

标准单元库通常不为单元输出指定引脚电容。

​ 每个单元的库描述指定每个输入引脚的引脚电容值。因此,设计中的每个网络都有一个电容负载,它是网络中每个扇形输出的引脚电容负载加上互连的任何贡献的总和。为了简单起见,本节不考虑互连的贡献,这些贡献将在后面的章节中描述。在不考虑互连寄生的情况下,图5-1中的内部网络NET0具有由UAND1和UNOR2单元的输入引脚电容组成的网络电容。输出O1具有UNOR2单元的引脚电容加上逻辑块输出的任何电容负载。输入I1和I2具有对应于UAND1和UINV0单元的引脚电容。通过这种抽象,图5-1中的逻辑设计可以用图5-2中所示的等效表示来描述。

img

​ 如第3章所述,单元库包含各种时序弧的NLDM定时模型。非线性模型表示为输入过渡时间和输出电容的二维表格。逻辑单元的输出跃迁时间也被描述为一个二维表,表示输入跃迁和网络总输出电容。因此,如果在逻辑块的输入端指定了输入转换时间(或转换slew),则可以从库单元描述中获得通过UINV0单元和UAND1单元(对于输入I1)的时序弧的输出转换时间和延迟。通过扇出单元扩展相同的方法,则可以获得通过UAND1单元的另一条时序弧(从NET0到O1)以及通过UNOR2单元的过渡时间和延迟。对于多输入单元(如UAND1),不同的输入引脚可以提供不同的输出过渡时间值。扇出网络过渡时间的选择取决于转换合并选项,如第5.4节所述。使用上述方法,可根据输入引脚的过渡时间和输出引脚的电容获得通过任何逻辑单元的延迟。

互连延迟计算(Delay Calculation with Interconnect)

预布局时序(Pre-layout Timing)

​ 如第4章所述,在预布局时序验证期间,使用线性负载模型估算了互连寄生参数。在许多情况下,线性负载模型中的电阻贡献被设置为0。在这种情况下,线性负载贡献纯粹是电容性的,上一节中描述的延迟计算方法适用于获得设计中所有时序弧的延迟。

​ 在线性性负载模型包括互连电阻影响的情况下,NLDM模型与单元延迟的总网络电容一起使用。由于互连是电阻式的,因此从驱动单元的输出到扇出单元的输入引脚会有额外的延迟。

布局后时序(Post-layout Timing)

​ 金属走线的寄生参数映射到驱动单元和目标单元之间的RC网络中。使用图5-1的示例,网络的互连电阻如图5-3所示。内部网络(如图5-1中的NET0)映射到多个子节点,如图5-3所示。因此,逆变单元UINV0的输出负载由RC结构组成。由于NLDM表格是关于输入转换和输出电容的,因此输出引脚处的电阻负载意味着NLDM表格不直接适用。下一节将介绍使用具有电阻互连的NLDM。

img

使用有效电容的单元延迟(Cell Delay using Effective Capacitance)

​ 如上所述,当单元输出端的负载包括互连电阻时,NLDM模型不能直接使用。相反,采用“有效”电容法来处理电阻效应。

​ 有效电容法试图找到可用作等效负载的单个电容,以便原始设计以及具有等效电容负载的设计在单元输出的定时方面表现相似。这种等效单电容被称为有效电容(effective capacitance)

​ 图5-4(a)所示为扇出端带有RC互连的单元。RC互连由图5-4(b)所示的等效RC PI网络表示。有效电容的概念是获得等效输出电容Ceff(如图5-4(c)所示),其通过电池的延迟与RC负载的原始设计相同。一般来说,RC负载的电池输出波形与单个电容负载的波形非常不同。

img

​ 图5-5显示了总电容、有效电容和实际RC互连的单元输出波形的代表性波形。选择有效电容Ceff时,应确保图5-4(c)中单元输出端的延迟(在过渡中点测量)与图5-4(a)中的延迟相同。如图5-5所示。

img

​ 关于PI等效表示,有效电容可表示为:

​ 其中C1为近端电容,C2为远端电容,如图5-4(b)所示。k值介于0和1之间。在互连电阻可忽略不计的情况下,有效电容几乎等于总电容。这可以通过在图5-4(b)中将R设置为0来直接解释。类似地,如果互连电阻相对较大,则有效电容几乎等于近端电容C1(图5-4(b))。这可以通过将R增加到极限情况来解释,在极限情况下,R变为无穷大(本质上是一个开路)。

​ 有效电容是以下各项的函数:

  • 驱动单元
  • 从驱动单元看,负载的特性或负载的输入阻抗

​ 对于给定的互连线,输出驱动较弱的单元将比驱动较强的单元具有更大的有效电容。因此有效电容的值将介于最小值C1(对于较大的互连电阻或者较强的驱动单元)与最大值C1+C2(对于小到可忽略的互连电阻或较弱的驱动单元)之间。注意,目标引脚的转换要晚于驱动单元的输出。近端电容充电速度比远端电容快的现象也被称为互连线的电阻屏蔽效应(resistive shielding effect),因为驱动单元只能看到一部分远端电容。

​ 与通过在库中直接查找NLDM模型计算延迟不同,延迟计算工具通过迭代程序获得有效电容。在算法方面,第一步是获得实际RC负载的单元输出所看到的驱动点阻抗。使用二阶AWE或Arnoldi算法1等任何方法计算实际RC负载的驱动点阻抗。计算有效电容的下一步是在两种情况下,将转移的电荷等效到过渡的中点。当使用实际RC负载(基于驱动点阻抗)时,电池输出处转移的电荷与使用有效电容作为负载时的电荷传输量相匹配,请注意,电荷转移仅在过渡中点之前匹配。该过程从有效电容的估计开始,然后迭代更新估计值。在大多数实际情况下,有效电容值在少量迭代内收敛。

​ 因此,有效电容近似是计算单元延迟的良好模型。然而,使用有效电容获得的输出摆幅与电池输出的实际波形不一致。单元输出处的波形,尤其是波形后半部分的波形,不能用有效电容近似表示。请注意,在典型场景中,感兴趣的波形不在单元输出处,而是在互连的目标点处,即扇出单元的输入管脚处。

​ 有多种方法可以计算互连终点处的延迟和波形。在许多实现中,有效电容程序还计算驱动单元的等效戴维南电压源。戴维南源由一个斜坡源和一个串联电阻Rd组成,如图5-6所示。串联电阻Rd对应于电池输出级的下拉(或上拉)电阻。

img

​ 本节介绍了使用有效电容替代RC互连来计算通过驱动单元的延迟。有效电容的计算还提供了等效的戴维宁电压源模型,然后将其用于获取通过RC互连的时序。接下来将具体介绍获取通过RC互连时序信息的过程。

互连延迟(Interconnect Delay)

​ 如第4章所述,网络的互连寄生通常由RC电路表示。RC互连可以是预布局或后布局。虽然布局后寄生互连可包括与相邻网络的耦合,但基本延迟计算将所有电容(包括耦合电容)视为对地电容。图5-7显示了网络及其驱动单元和扇出单元的寄生示例。

img

​ 采用有效电容法,分别获得了通过驱动单元和通过互连的延迟。有效电容法通过驱动单元以及单元输出端的等效戴维南源提供延迟。然后使用戴维南源分别计算通过互连的延迟。互连部分具有一个输入和与目的地管脚一样多的输出。使用互连输入端的等效戴维南电压源,计算每个目标引脚的延迟。如图5-6所示。

​ 在布局前进行分析时,RC互连结构由RC树类型决定,而RC互连结构又决定了互连线延迟。4.2节中已详细介绍了三种类型的RC互连树表示形式,所选的RC树类型通常在库中定义。通常,最坏情况(worst-case)的慢速库会选择最坏情况的RC树,因为该类型的树提供了最大的互连线延迟。类似地,最佳情况(best-case)的RC树结构中不包括从源引脚到目标引脚的任何电阻,通常在最佳情况的快速工艺角时被选择。因此,最佳情况RC树的互连延迟等于零。典型(typical)情况RC树和最坏情况RC树的互连延迟的处理方式与布局后RC互连一样。

Elmore延迟

​ Elmore延迟适用于RC树。什么是RC树?RC树满足以下三个条件:

  • 具有单个输入(源)节点。
  • 没有任何电阻回路。
  • 所有电容都位于节点和接地之间。

​ Elmore延迟可以看作是找到每段的延迟,即R与下游电容的乘积,然后取各延迟之和。

img

​ 到各个中间节点的延迟表示为:

1
2
3
4
5
6
7
Td1= C1* R1;

Td2= C1* R1+ C2* (R1+ R2);

. . .

Tdn= S(i=1,N) Ci(S(j=1,i) Rj); # Elmore delay equation

​ Elmore延迟在数学上考虑的是脉冲响应的第一时刻。 现在,我们将Elmore延迟模型进行如下简化表示:互连线的寄生电阻与电容分别为Rwire和Cwire,互连线远端的引脚电容由负载电容Cload来建模。等效的RC网络可以简化为π模型或T模型,分别如前面章节四中图4-4和图4-3所示。两种模型都具有如下走线延迟(基于Elmore延迟方程):

​ 这是因为Cload在其充电路径中看到整个导线电阻,而Cwire电容在T表示中看到Rwire/2,在PI表示中Cwire/2在其充电路径中看到Rwire。上述方法也可以扩展到更复杂的互连结构。

​ 下面给出了使用带平衡RC树(以及最坏情况RC树)的线负载模型计算网络Elmore延迟的示例。

​ 使用平衡RC树模型时,网络的电阻和电容在网络的各个分支之间平均分配(假设扇出为N)。对于具有引脚负载Cpin的分支,使用平衡RC树的延迟为:

1
net delay = (Rwire/ N) * (Cwire/ (2 * N) + Cpin)

​ 使用最坏情况RC树模型时,网络的每个分支终点都考虑了网络的电阻和整个电容。此时的延迟值如下所示,这里的Cpins是所有扇出的总引脚负载:

1
Net delay = Rwire* (Cwire/ 2 + Cpins)

​ 图5-9显示了一个设计示例。

img

​ 如果我们使用最坏情况RC树模型来计算网络N1的延迟,我们将得到:

1
2
3
Net delay = Rwire* (Cwire/2 + Cpins)

= 0.3 * (0.5 + 2.3) = 0.84

​ 如果我们使用平衡树模型,我们得到网络N1的两个分支的以下延迟:

1
2
3
4
5
6
7
8
9
Net delay to NOR2 input pin = (0.3/2) * (0.5/2 + 1.3)

= 0.2325



Net delay to BUF input pin= (0.3/2) * (0.5/2 + 1.0)

= 0.1875

高阶互连延迟估计(Higher Order Interconnect Delay Estimation)

​ 如上所述,Elmore延迟是脉冲响应的第一个时刻。AWE(Asymptotic Waveform Evaluation渐近波形评估)、Arnoldi或其他方法匹配高阶响应矩。通过考虑高阶估计,可以获得更高的互连延迟计算精度。

全芯片延迟计算(Full Chip Delay Calculation)

​ 到目前为止,本章描述了单元延迟的计算以及单元输出端的互连。因此,给定单元输入端的过渡时间,可以计算通过单元的延迟和单元输出端的互连线的延迟。互连远端(目的地或汇点)的过渡时间是下一级的输入,整个设计过程中都会重复此过程,这样就计算出了设计中每个时序弧的延迟。

转换合并(Slew Merging)

​ 当多个转换(slew)到达一个公共点时会发生什么情况,例如在多输入单元或多驱动网络的情况下?这种公共点称为转换合并点(slew merge point)。选择哪个slew在slew merge point向前传播?考虑图5-10所示的2输入单元。

img

​ 由于引脚 A 上的信号变化,引脚 Z 处的转换提前到达但上升缓慢(缓慢s转换)。由于引脚 B 上的信号变化,引脚 Z 处的转换延迟到达,但上升很快(快速转换)。在转换合并点,例如 pin Z应该选择哪个slew进行进一步传播?

​ 根据如下所述执行的时序分析的类型(最大或最小),这些转换值中的任何一个都可能是正确的。

​ 执行最大路径分析时有两种可能性:

  • 最差转换传播(Worst slew propagation):此模式选择合并点的最差转换进行传播。这将是图5-10(A)中的slew。对于通过管脚A->Z的时序路径,此选择是精确的,但对于通过管脚B->Z的任何时序路径则是悲观的。
  • 最差到达传播(Worst arrival propagation):此模式选择合并点的最差到达时间进行传播。这与图5-10(b)中的摆动相对应。在这种情况下选择的摆幅对于通过管脚B->Z的时序路径是精确的,但是对于通过管脚A->Z的时序路径是乐观的。

​ 同样,执行最小路径分析时有两种可能性:

  • 最佳转换传播(Best slew propagation):此模式选择要传播的合并点处的最佳转换。这将是图5-10(b)中的回转。对于通过管脚B->Z的定时路径,该选择是精确的,但是对于通过管脚A->Z的任何时序路径,该选择较小。对于通过A->Z的路径,路径延迟小于实际值,因此对于最小路径分析是悲观的。
  • 最佳到达传播(Best arrival propagation):此模式选择合并点的最佳到达时间进行传播。这与图5-10(A)中的转换slew相对应。这种情况下选择的slew对于通过管脚A->Z的时序路径是精确的,但是选择的值大于通过管脚B->Z的定时路径的实际值。对于通过B->Z的路径,路径延迟大于实际值,因此对于最小路径分析是乐观的。

​ 设计者可以在静态时序分析环境之外执行延迟计算以生成SDF。在这种情况下,延迟计算工具通常使用最差的转换传播(worst slew propagation)。所得到的SDF对于最大路径分析是足够的,但是对于最小路径分析可能是乐观的。

​ 大多数静态时序分析工具使用最差和最好的转换传播作为它们的默认设置,因为它以保守的方式限制了分析。但是,在分析特定路径时,可以使用精确的转换传播。准确的转换传播可能需要在时序分析工具中启用一个选项。因此,重要的是要了解静态时序分析工具中默认使用的转换传播模式,并了解其可能过于悲观的情况。

不同的转换阈值(Different Slew Thresholds)

​ 通常,库指定单元角色化过程中使用的转换(转换时间)【slew (transition time)】阈值。问题是,当具有一组转换阈值的单元驱动具有不同组转换阈值设置的其他单元时,会发生什么情况?考虑图5-11所示的情况,其中特征为20-80转换阈值的单元驱动两个扇出单元;一个转换阈值为10-90,另一个转换阈值为30-70,转换降低率为0.5。

img

​ 单元格U1的转换设置在单元库中定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
slew_lower_threshold_pct_rise : 20.00

slew_upper_threshold_pct_rise : 80.00



slew_derate_from_library : 1.00

input_threshold_pct_fall : 50.00

output_threshold_pct_fall : 50.00

input_threshold_pct_rise : 50.00

output_threshold_pct_rise : 50.00

slew_lower_threshold_pct_fall : 20.00

slew_upper_threshold_pct_fall : 80.00

​ 来自另一个库的单元格U2可以具有如下定义的转换设置:

1
2
3
4
5
6
7
8
9
10
11
slew_lower_threshold_pct_rise : 10.00

slew_upper_threshold_pct_rise : 90.00



slew_derate_from_library : 1.00

slew_lower_threshold_pct_fall : 10.00

slew_upper_threshold_pct_fall : 90.00

​ 来自另一个库的单元格U3可以具有如下定义的转换设置:

1
2
3
4
5
6
7
8
9
10
11
slew_lower_threshold_pct_rise : 30.00

slew_upper_threshold_pct_rise : 70.00



slew_derate_from_library : 0.5

slew_lower_threshold_pct_fall : 30.00

slew_upper_threshold_pct_fall : 70.00

​ 上面只显示了U2和U3的转换相关设置;输入和输出阈值的延迟相关设置为50%,上面没有显示。延迟计算工具根据连接网络的单元的转换阈值计算转换时间。图5-11显示了U1/Z处的转换如何与该引脚上的开关波形相对应。利用U1/Z的等效戴维南源获得扇出单元输入端的开关波形。根据U2/A和U3/A的波形及其转换阈值,延迟计算工具计算U2/A和U3/A的转换。请注意,U2/A的转换基于10-90设置,而用于U3/A的转换基于30-70设置,然后根据库中指定的slew_derate 0.5递减。此示例说明如何根据扇出单元的切换波形和转换阈值设置计算扇出单元输入端的转换时间。

​ 在可能不考虑互连电阻的预布局(pre-layout)设计阶段时,可以按以下方式计算具有不同阈值的网络处的转换时间。例如,10%-90%转换阈值和20%-80%转换阈值之间的关系为:

1
slew2080 / (0.8 - 0.2) = slew1090 /(0.9 - 0.1)

​ 因此,具有 10-90 个测量点的 500ps 转换对应于具有 20-80 个测量点的 (500ps * 0.6) / 0.8 = 375ps 转换。类似地,具有 20-80 个测量点的 600ps 转换对应于具有 10-90 个测量点的 (600ps * 0.8) / 0.6 = 800ps 转换。

个同的电压域(Different Voltage Domains)

​ 典型的设计可能对芯片的不同部分使用不同的电源电平。在这种情况下,电平转换单元用于不同电源域之间的接口。电平转换单元在一个电源域接受输入并在另一个电源域提供输出。例如,标准单元输入可以是 1.2V,其输出可以是降低的电源,可能是 0.9V。图 5-12 显示了一个示例

img

​ 请注意,延迟是根据 50% 阈值点计算的。对于接口单元的不同引脚,这些点处于不同的电压。

路径延迟计算(Path Delay Calculation)

​ 一旦每个时序弧的所有延迟都可用,设计中单元的时序就可以表示为时序图。通过组合单元的时序可以表示为从输入到输出的时序弧。类似地,互连由从源到每个目的地(或汇)点的相应弧表示为单独的时序弧。一旦整个设计由相应的弧线注释,计算路径延迟涉及将沿路径的所有网络和单元时序弧线相加。

组合路径延迟(Combinational Path Delay)

​ 考虑串联的三个逆变器,如图 5-13 所示。在考虑从网络 N0 到网络 N3 的路径时,我们同时考虑上升沿和下降沿路径。假设在网络 N0 处有一个上升沿。

img

​ 可以指定第一个逆变器输入端的 transition time (or slew);如果没有这样的规范,则假定过渡时间为 0(对应于理想步长)。输入 UINVa/A 的转换时间是通过使用上一节中指定的互连延迟模型来确定的。相同的延迟模型也用于确定网络 N0 的延迟 Tn0。

​ 基于在UINVa的输出处的负载的RC获得在输出UINVa / Z的有效电容。然后在输入UINVa / A,并在输出UINVa / Z等效有效负荷的转换时间是用于获得单元输出下降延迟。

​ 引脚 UINVa/Z 处的等效戴维南源模型用于通过使用互连模型确定引脚 UINVb/A 处的转换时间。互连模型还用于确定网络 N1 上的延迟 Tn1。

​ 一旦知道输入 UINVb/A 处的转换时间,就可以类似地使用通过 UINVb 计算延迟的过程。 UINVb/Z 处的 RC 互连和 UINVc/A 引脚的引脚电容用于确定 N2 处的有效负载。 UINVb/A 的转换时间用于确定通过反相器 UINVb 的上升延迟,依此类推。

​ 最后阶段的负载由提供的任何明确的负载规范确定,或者在没有规范的情况下仅使用网络 N3 的线负载。

​ 上述分析假设在网络 N0 处有一个上升沿。对于网络 N0 上的下降沿的情况,可以进行类似的分析。因此,在这个简单的示例中,有两条时序路径具有以下延迟:

1
2
3
Tfall= Tn0rise+ Tafall+ Tn1fall+ Tbrise+ Tn2rise+ Tcfall+ Tn3fall

Trise= Tn0fall+ Tarise+ Tn1rise+ Tbfall+ Tn2fall+ Tcrise+ Tn3rise

​ 通常,由于驱动单元输出端的戴维南源模型不同,通过互连的上升和下降延迟可能不同。

触发器的路径(Path to a Flip-flop)

输入到触发器路径(Input to Flip-flop Path)

​ 考虑如图5-14从输入SDT到触发器UFF1的路径的时序。

img

​ 我们需要同时考虑上升沿和下降沿路径。对于输入 SDT 上升沿的情况,数据路径延迟为:

​ 同样,对于输入 SDT 的下降沿,数据路径延迟为:

​ 输入 MCLK 上升沿的捕获时钟路径延迟为:

触发器到触发器路径(Flip-flop to Flip-flop Path)

​ 图 5-15 显示了两个触发器和相应时钟路径之间的数据路径示例。

img

​ UFF0/Q 上升沿的数据路径延迟为:

​ 输入 PCLK 上升沿的启动时钟路径延迟为:

​ 输入 PCLK 上升沿的捕获时钟路径延迟为:

​ 请注意,需要考虑单元的完整性,因为边缘方向在通过单元时可能会发生变化。

多路径(Multiple Paths)

​ 在任意两点之间,可以有许多路径。最长的路径是花费时间最长的路径;这也称为最坏路径、延迟路径或最大路径。最短的路径是需要最短时间的路径;这也称为最佳路径、早期路径或最小路径。

​ 通过图 5-16 中的时序弧查看逻辑和延迟。两个触发器之间最长的路径是通过单元 UBUF1、UNOR2 和 UNAND3。两个触发器之间的最短路径是通过单元 UNAND3。

img

裕量计算(Slack Calculation)

​ 裕量(Slack)是信号需要到达时间(Required Time)与实际到达时间(Arrival Time)之差。在图5-17中,要求数据在7ns时保持稳定才能满足建立时间(setup)要求。但是,数据在1ns时就已稳定。因此,裕量为6ns(= 7ns-1ns)。

img

​ 假设所需的数据时间是从捕获触发器的设置时间获得的,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Slack = Required_time - Arrival_time

Required_time = Tperiod - Tsetup(capture_flip_flop)

= 10 - 3 = 7ns

Arrival_time = 1ns

Slack = 7 - 1 = 6ns



需要到达时间Required_Time = Tperiod - Tsetup = 10 - 3 = 7ns



实际到达时间Arrival_Time = 1ns



裕量Slack = Required_Time - Arrival_Time = 7 - 1 = 6ns

​ 同样,如果两个信号之间的偏斜(skew)要求为100ps,并且测得的偏斜为60ps,则偏斜的裕量为40ps(= 100ps-60ps)。

串扰和噪声(Crosstalk and Noise)

在纳米技术中,串扰的影响在设计的信号完整性中起着重要作用。本章描述相关的噪声和串扰分析,即毛刺分析和串扰分析。这些技术使 ASIC 从时序的角度表现稳定运行。

在深亚微米技术中,串扰对设计的信号完整性起着重要作用。串扰噪声是指两个或多个信号之间活动的无意耦合。相关的噪声和串扰分析技术,即故障分析和串扰分析,允许在静态时序分析期间包括这些影响,本章对此进行了描述。这些技术可用于使ASIC性能稳定。

概述(Overview)

​ 噪声(noise)是指影响芯片正常运行的非期望或无意影响。在纳米技术中,噪声会影响设备的功能或时序。

​ 为什么会有噪声和信号完整性?

​ 噪声在深亚微米技术中扮演重要角色的原因有几个:

  • 金属层数量的增加:例如,0.25mm 或 0.3mm 工艺有四到五个金属层,在 65nm 和 45nm 工艺几何结构中增加到十个或更多金属层。图 4-1 描绘了金属互连的多层。
  • 垂直主导金属纵横比:这意味着与早期工艺几何形状中的宽而细不同,线又细又高。因此,更大比例的电容由侧壁耦合电容组成,该电容映射到相邻线之间的线对线电容。
  • 更精细的几何形状带来更高的布线密度:因此,在紧密的物理距离上封装了更多的金属线。
  • 更多数量的交互设备和互连:因此,更多的有源标准单元和信号走线被封装在相同的硅区域中,从而导致更多的交互。
  • 由于频率更高,波形更快::快速边沿速率会导致更多的电流尖峰以及对相邻迹线和单元的更大耦合影响。
  • 更低的电源电压:电源电压的降低为噪声留下了很小的余量。

​ 在本章中,我们特别研究了串扰噪声的影响。串扰噪声是指两个或多个信号之间的无意耦合活动。串扰噪声是由管芯上相邻信号之间的电容耦合引起的。这会导致网络上的开关活动对耦合信号造成意外影响。 受影响的信号称为受害者(victim),而产生影响的信号称为攻击者(aggressor)。请注意,两个耦合的网络可能会相互影响,并且通常一个网络可能既是受害者又是攻击者。

​ 图 6-1 显示了几个信号线耦合在一起的示例。描述了耦合互连的分布式 RC 提取与几个驱动器和扇出单元。在此示例中,网络 N1 和 N2 将 Cc1 Cc4 作为它们之间的耦合电容,而 Cc2 Cc5 是网络 N2 和 N3 之间的耦合电容。

img

一些分析工具将毛刺(glitch)称为噪声。同样,一些工具使用串扰(crosstalk )来指代串扰对延迟的影响。

​ 从广义上讲,串扰有两种类型的噪声影响 - 毛刺(glitch)指的是由于相邻干扰源的开关活动耦合而在稳定的受害信号上引起的噪声,以及由开关耦合引起的时序变化(串扰增量延迟)受害者的活动与攻击者的转换活动。这两种类型的串扰噪声的在接下来的两个部分进行说明。

串扰毛刺分析(Crosstalk Glitch Analysis)

基础知识(Basics)

​ 由于开关攻击者通过耦合电容传输的电荷,稳定的信号网络可能会出现毛刺(正或负)。图 6-2 说明了由上升的攻击者网络的串扰引起的正毛刺。两个网络之间的耦合电容被描述为一个集总电容 Cc 而不是分布式耦合,这是为了简化下面的说明,而又不失一般性。在提取的网表的典型表示中,耦合电容可能分布在多个段上,如前面第 6.1 节中所见。

img

​ 在此示例中,NAND2 单元 UNAND0 对其输出网络(标记为 Aggressor)进行切换和充电。一些电荷也通过耦合电容 Cc 转移到受害网络并导致正毛刺。转移的电荷量与攻击者和受害网络之间的耦合电容 Cc 直接相关。在受害网络的接地电容上传输的电荷会导致该网络出现故障。由于传输的电荷通过驱动单元 INV2 的下拉阶段耗散,因此受害网络上的稳定值(在这种情况下为 0 或低)恢复。

​ 引起的毛刺的大小取决于多种因素。其中一些因素是:

  • 攻击者网络和受害者之间的耦合电容:耦合电容越大,毛刺的幅度越大。
  • 攻击者网络的转换(slew):攻击者网络的转换速度越快,毛刺的幅度就越大。通常,更快的转换是因为驱动攻击者网络的单元具有更高的输出驱动强度。
  • 受害网络接地电容:受害网络上的接地电容越小,毛刺的幅度越大。
  • 受害网络驱动强度:驱动受害网络的单元的输出驱动强度越小,毛刺的幅度越大。

​ 总体而言,虽然受害网络上的稳定值得到恢复,但毛刺会由于下述原因影响电路的功能。

  • 毛刺幅度可能大到足以被扇出单元视为不同的逻辑值(例如,逻辑 0 处的受害者可能表现为扇出单元的逻辑 1)。这对于顺序单元(触发器、锁存器)或存储器尤其重要,其中时钟故障或异步设置/复位可能对设计的功能造成灾难性影响。类似地,锁存器输入端数据信号上的毛刺会导致不正确的数据被锁存,如果在输入数据时出现毛刺,这也可能是灾难性的。
  • 即使受害网络不驱动顺序单元,宽毛刺也可能通过受害网络的扇出传播并到达顺序单元输入,对设计造成灾难性后果。

毛刺类型(Types of Glitches)

​ 毛刺具有许多不同种类:

上升和下降毛刺(Rise and Fall Glitches)

​ 前面小节中的讨论说明了受害者网络上的上升毛刺(Rise Glitch),该受害者网络一直稳定在低电平。类似的情况是在稳定的高电平信号上出现负毛刺,电平下降切换的攻击者网络会在稳定的高电平信号上引起下降毛刺(Fall Glitch)

过冲和欠冲毛刺(Overshoot and Undershoot Glitches)

​ 当一个上升的攻击者与一个稳定高电平的受害者网络结合时会发生什么?仍然存在使受害网络电压高于其稳定高值的毛刺。这种毛刺称为过冲毛刺(overshoot glitch)。类似地,当耦合到稳定的低电平受害网络时,下降的攻击者会导致受害网络上出现欠冲毛刺Undershoot Glitches)。

​ 图 6-3 说明了由串扰引起的所有四种毛刺情况。

img

​ 如上一小节所述,毛刺由耦合电容、攻击者转换和受害者网络的驱动强度决定。毛刺计算基于开关攻击者注入的电流量、受害者网络的RC互连以及驱动受害者网络的单元的输出阻抗。详细的毛刺计算基于库模型;用于计算的相关噪声模型是第3章中描述的标准单元库模型的一部分。第3.7节中的输出 dc_current模型与单元的输出阻抗相关。

毛刺阈值和传播(Glitch Thresholds and Propagation)

​ 如何确定网络上的毛刺是否可以通过扇出单元传播?正如前面的小节所讨论的,由开关干扰源耦合引起的毛刺可以通过扇出单元传播,具体取决于扇出单元和毛刺属性,例如毛刺高度和毛刺宽度。这种分析可以基于直流或交流噪声阈值。 DC 噪声分析仅检查毛刺幅度并且是保守的,而 AC 噪声分析检查其他属性,例如毛刺宽度和扇出单元输出负载。下面描述了在毛刺的 DC 和 AC 分析中使用的各种阈值指标。

直流阈值(DC Thresholds)

​ DC 噪声容限(noise margin)是用于检查毛刺幅度的检查,指的是确保正确的逻辑功能同时,单元输入的 DC 噪声限制。例如,只要输入保持在单元的 VIL 最大值以下,反相器单元的输出就可以是高的(即,保持在 VOH 的最小值以上)。类似地,只要输入保持在 VIH 最小值以上,反相器单元的输出就可以是低的(即保持在 VOL 最大值以下)。这些限制是根据单元的直流传输特性获得的,并且可以填充在单元库中。

​ VOH 是被视为逻辑 1 或高的输出电压范围。 VIL 是被视为逻辑零或低的输入电压范围。 VIH 是被视为逻辑 1 的输入电压范围。 VOL 是被视为逻辑零的输出电压范围。图 6-4 给出了逆变器单元输入-输出直流传输特性的示例。

img

​ VILmax 和 VIHmin 限制也称为 DC 裕度限制。基于 VIH 和 VIL 的直流裕度是稳态噪声限值。因此,这些可以用作确定毛刺是否会通过扇出单元传播的过滤器。 DC 噪声容限限制适用于单元的每个输入引脚。通常,对于rise_glitch(输入低)和fall_glitch(输入高),DC 裕度限制是分开的。 DC 裕度的模型可以指定为单元库描述的一部分。无论毛刺的宽度如何,低于 DC 裕度限制的毛刺(例如,低于扇出引脚 VILmax 的上升毛刺)都无法通过扇出传播。因此,保守的毛刺分析检查峰值电压电平(对于所有毛刺)是否满足扇出单元的 VIL 和 VIH 电平。只要所有网络满足扇出单元的 VIL 和 VIH 水平,尽管存在任何毛刺,就可以得出结论,毛刺对设计的功能没有影响(因为毛刺不会导致输出改变)。

​ 图 6-5 显示了直流裕度限制的示例。对于设计中的所有网络,DC 噪声容限也可以固定为相同的限制。可以设置最大的可容忍噪声(或毛刺)幅度,高于该幅度的噪声可以通过单元传播到输出引脚。通常,此检查可确保毛刺电平小于 VILmax 且大于 VIHmin。高度通常表示为电源的百分比。因此,如果 DC 噪声容限设置为 30%,则表明任何大于电压摆幅 30% 的毛刺高度都被识别为潜在毛刺,它可以通过单元传播并可能影响设计的功能。

img

​ 并非所有幅度大于直流噪声容限的毛刺都能改变单元的输出。在确定毛刺是否会传播到输出时,毛刺的宽度也是一个重要的考虑因素。单元输入处的窄毛刺通常不会对单元输出造成任何影响。然而,无论信号噪声宽度如何,直流噪声容限仅使用恒定的最坏情况值。参见图 6-6。这提供了噪声抑制水平,它是对单元噪声容限的非常保守的估计。

img

交流阈值(AC Thresholds)

​ 如上小节所述,毛刺分析的 DC 裕度限制是保守的,因为这些限制是在最坏情况下分析设计的。 DC 裕量限制验证即使毛刺任意宽,也不会影响设计的正常运行。

​ 在大多数情况下,设计可能无法通过保守的 DC 噪声分析限制。因此,必须验证毛刺对毛刺宽度和单元输出负载的影响。通常,如果毛刺很窄或者如果扇出单元具有大的输出电容,则毛刺不会影响正常的功能操作。毛刺宽度和输出电容的影响都可以用扇出单元的惯性来解释。通常,单级单元将停止比通过单元的延迟窄得多的任何输入毛刺。这是因为对于窄毛刺,毛刺在扇出单元可以响应之前就结束了。因此,非常窄的毛刺不会对电池产生任何影响。由于输出负载增加了通过单元的延迟,因此增加输出负载具有将输入端毛刺的影响降至最低的效果,尽管它具有增加单元延迟的不利影响。

​ AC 噪声抑制如图 6-7 所示(对于固定输出电容)。深色阴影区域代表良好或可接受的毛刺,因为这些毛刺太窄或太短,或两者兼而有之,因此对单元的功能行为没有影响。浅阴影区域表示不良或不可接受的毛刺,因为这些毛刺太宽或太高,或既宽又高,因此在单元输入端的这种毛刺会影响单元的输出。在毛刺较宽的极限情况下,毛刺阈值对应于DC噪声裕量,如图6-7所示。

img

​ 对于给定的单元,增加输出负载会增加噪声容限,因为它会增加惯性延迟和可以通过单元的毛刺宽度。下面通过一个例子来说明这种现象。图 6-8(a) 显示了一个无负载的逆变器单元,其输入端有一个正毛刺。输入毛刺高于单元的直流裕度,并导致逆变器输出出现毛刺。图 6-8(b) 显示了在其输出端带有一些负载的相同逆变器单元。输入端相同的输入毛刺会导致输出上的毛刺小得多。如果逆变器单元的输出负载更高,如图 6-8(c) 所示,则逆变器单元的输出没有任何毛刺。因此,增加输出端的负载会使单元更不受从输入端传播到输出端的噪声的影响。

img

​ 如上所述,低于 AC 阈值(图 6-7 中的 AC 噪声抑制区域)的毛刺可以被忽略,或者可以认为扇出单元不受此类毛刺的影响。 AC 阈值(或抗扰度)区域取决于输出负载和毛刺宽度。如第3章中所述,抗扰度模型(noise immunity model)包括上述AC噪声抑制的影响,3.7节中介绍的propagated_noise模型除了对通过单元的传播进行建模外,还包括了AC噪声阈值的影响。

​ 如果毛刺大于 AC 阈值会发生什么?在毛刺幅度超过 AC 阈值的情况下,单元输入处的毛刺会在单元输出处产生另一个毛刺。输出毛刺高度和宽度是输入毛刺宽度和高度以及输出负载的函数。此信息在单元库中进行了表征,其中包含输出毛刺幅度和宽度的详细表格或函数,作为输入引脚毛刺幅度、毛刺宽度和输出引脚负载的函数。毛刺传播由包含在库单元描述中的propagated_noise模型控制。propagated_noise(低和高)模型在第 3 章中详细描述。

​ 基于以上内容,在扇出单元的输出处计算毛刺,并在扇出网络上进行相同的检查(以及毛刺传播到扇出),依此类推。

虽然我们在上面的讨论中使用了通用术语“毛刺”,但应注意,这分别适用于前一小节中提到的所有类型的毛刺:上升毛刺(由早期模型中的propagated_noise_highnoise_immunity_high建模),下降毛刺(由早期模型中的propagated_noise_lownoise_immunity_low建模),过冲毛刺(由noise_immunity_above_high建模)和欠冲毛刺(由noise_immunity_below_low建模)。

​ 总之,单元的不同输入对毛刺阈值有不同的限制,毛刺阈值是毛刺宽度和输出电容的函数。这些限制对于输入高(低转换毛刺)和输入低(高转换毛刺)是分开的。噪声分析会检查毛刺的峰值和宽度,并分析它是否可以被忽略或它是否可以传播到扇出。

多个干扰源的噪声累积(Noise Accumulation with Multiple Aggressors)

​ 图 6-9 描述了由于单个攻击者网络切换和在受害网络上引入串扰毛刺引起的耦合。一般而言,受害网络可以电容耦合到许多网络。当多个网络同时切换时,由于有多个攻击者,串扰耦合噪声对受害者的影响更加复杂。

img

​ 由于多个攻击者引起的耦合的大多数分析都会添加由于每个攻击者引起的毛刺效应,并计算对受害者的累积影响。这可能看起来很保守,但它确实表明了受害者最坏的情况。另一种方法是使用 RMS(均方根)方法。使用 RMS 选项时,受害设备上的毛刺幅度是通过取个别攻击者引起的毛刺的均方根来计算的。

干扰源时序相关性(Aggressor Timing Correlation)

​ 对于由多个干扰源引起的串扰毛刺,分析必须包括干扰源网络的时序相关性,并确定多个干扰源是否可以同时切换。 STA 从攻击者网络的时序窗口中获取此信息。在时序分析过程中,得到网络最早和最晚的切换时间。这些时间代表网络可以在一个时钟周期内切换的时序窗口。切换窗口(上升和下降)提供有关攻击者网络是否可以一起切换的必要信息。

​ 根据多个干扰源是否可以同时切换,将单个干扰源造成的毛刺组合起来用于受害网络。作为第一步,毛刺分析为每个潜在干扰源分别计算四种类型的毛刺(上升、下降、欠冲和过冲)。下一步结合来自各个干扰源的故障贡献。多个干扰源可以针对每种类型的毛刺单独组合。例如,考虑耦合到攻击者网络 A1、A2、A3 和 A4 的受害者网络 V。在分析过程中,A1、A2 和 A4 可能会导致上升和过冲毛刺,而只有 A2 和 A3 会导致欠冲和下降毛刺。

​ 考虑另一个示例,其中当攻击者网络转换时,四个攻击者网络会导致上升的毛刺。图 6-10 显示了由每个攻击者网络引起的时序窗口和毛刺幅度。根据时序窗口,毛刺分析确定导致最大毛刺的干扰源切换的最坏可能组合。在这个例子中,切换窗口区域被分为四个 bin - 每个 bin 显示可能的干扰源切换。图 6-10 还描述了来自每个干扰源的毛刺贡献。 Bin 1 具有 A1 和 A2 切换,这可能导致 0.21 (= 0.11+ 0.10) 的毛刺幅度。 Bin 2 具有 A1、A2 和 A3 切换,这会导致毛刺幅度为 0.30 (= 0.11+ 0.10+ 0.09)。 Bin 3 具有 A1 和 A3 切换,这会导致毛刺幅度为 0.20 (= 0.11 +0.09)。 Bin 4 具有 A3 和 A4 切换,这会导致毛刺幅度为 0.32 (= 0.09+ 0.23)。

​ 因此,bin 4 具有 0.32 的最坏可能的毛刺幅度。请注意,不使用时序窗口的分析将预测组合毛刺幅度为 0.53 (= 0.11+ 0.10+ 0.09 +0.23),这可能过于悲观。

img

干扰源功能相关性(Aggressor Functional Correlation)

​ 对于多个干扰源,通过考虑网络可能切换的切换窗口,使用时序窗口减少了分析中的悲观情绪。此外,另一个需要考虑的因素是各种信号之间的功能相关性。例如,scan(在DFT test mode) 控制信号仅在扫描模式期间切换,并且在设计的功能或任务模式期间稳定。因此,在功能模式期间,扫描控制信号不会对其他信号造成毛刺。扫描控制信号只能是扫描模式期间的干扰源。在某些情况下,测试时钟和功能时钟是相互排斥的,因此测试时钟仅在测试期间当功能时钟关闭时才有效。在这些设计中,由测试时钟控制的逻辑和由功能时钟控制的逻辑创建了两组不相交的干扰源。在这种情况下,测试时钟控制的干扰源不能与功能时钟控制的其他干扰源结合进行最坏情况噪声计算。功能相关的另一个例子是两个干扰源,它们是彼此的补充(逻辑相反)。在这种情况下,信号及其补码不能在相同方向上切换以计算串扰噪声。

​ 图 6-11 显示了网络 N1 与其他三个网络 N2、N3 和 N4 耦合的示例。在功能关联中,需要考虑网络的功能。假设网络 N4 是一个常数(例如,模式设置网络),因此不能成为网络 N1 上的干扰源,尽管它是耦合的。假设 N2 是一个网络,它是调试总线的一部分,但在功能模式下处于稳定状态。因此,网络 N2 不能成为网络 N1 的干扰源。假设网络 N3 携带功能数据,只有网络 N3 可以被视为网络 N1 的潜在干扰源。

img

串扰延迟分析(Crosstalk Delay Analysis)

基础知识(Basics)

​ 纳米设计中典型网络的电容提取由许多相邻导体的贡献组成。其中一些是接地电容,而其他许多来自作为其他信号网络一部分的走线。接地电容和信号间电容如图 6-1 所示。在基本延迟计算期间,所有这些电容都被视为网络总电容的一部分(不考虑任何串扰)。当相邻网络稳定(或未切换)时,信号间电容可被视为接地。当相邻网络切换时,通过耦合电容的充电电流会影响网络的时序。根据攻击者网络切换的方向,从网络上看到的等效电容可以更大或更小。这在下面的一个简单示例中进行了解释。

img

​ 图 6-12 显示了网络 N1,它有一个到相邻网络(标记为 Aggressor)的耦合电容 Cc 和一个到地的电容 Cg。此示例假设网络 N1 在输出端具有上升过渡,并根据攻击者网络是否同时切换来考虑不同的场景。

​ 如下文所述,驱动单元在各种情况下所需的电容性电荷可能不同。

  • 攻击者网络处于稳定状态:在这种情况下,网络N1的驱动单元将提供电荷使Cg和Cc充电至Vdd。因此,该网络的驱动单元提供的总电荷为(Cg + Cc)* Vdd。这种情况可以进行基本的延迟计算,因为在这种情况下未考虑来自攻击者网络的串扰。表6-13中为此情况下在网络N1电平切换前后Cg和Cc中的电荷量:

img

  • 攻击者网络朝同方向切换电平: 在这种情况下,往同方向电平切换的攻击者网络可以起辅助驱动单元的作用。如果攻击者网络同时以相同的转换slew(相同的transition time)进行电平切换,则驱动单元提供的总电荷仅为(Cg * Vdd )。如果攻击者网络的转换比N1网络转换更快,则所需的实际电荷可能甚至小于(Cg * Vdd),因为攻击者网络也可以为Cg提供充电电流。因此,在攻击者朝相同方向切换电平时,来自驱动单元的所需电荷会小于表6-13中描述的攻击者处于稳定状态时的所需电荷。因此,当攻击者网络朝相同方向切换电平时会导致网络N1切换电平的延迟更短, 延迟的减少被标记为负串扰延迟(negative crosstalk delay)。这种情况请参见表6-14,通常会在进行最小路径分析时考虑此情况。

img

  • 攻击者网络朝相反方向切换电平:在这种情况下,耦合电容需要从-Vdd充电到Vdd。因此在电平切换前后,耦合电容上的电荷变化量为(2 * Cc * Vdd),网络N1的驱动单元以及攻击者网络均需要提供额外的电荷。这种情况会导致网络N1切换电平的延迟更大,延迟的增加被标记为正串扰延迟(positive crosstalk delay)。这种情况请参阅表6-15,通常会在进行最大路径分析时考虑此情况。

img

​ 上面的例子说明了 Cc 在各种情况下的充电以及它如何影响交换网络的延迟(标记为 N1)。该示例仅考虑网络 N1 处的上升过渡,但类似的分析也适用于下降过渡。

正负串扰(Positive and Negative Crosstalk)

​ 基本延迟计算(没有任何串扰)假设驱动单元为网络总电容 Ctotal (= Cground +Cc) 的轨到轨(rail-to-rail)转换提供所有必要的电荷。如前一小节所述,当耦合(攻击者)网络和受害者网络在相反方向切换时,耦合电容 Cc 所需的电荷更大。在相反方向上的攻击者切换增加了受害网络的驱动单元所需的电荷量,并增加了受害网络的驱动单元和互连的延迟。

​ 类似地,当耦合(攻击者)网络和受害者网络在同一方向切换时,Cc 上的电荷在受害者和攻击者转换之前和之后保持不变。这减少了受害网络的驱动单元所需的电荷。减少了驱动单元和受害网络互连的延迟。

​ 如上所述,受害者和攻击者的并发切换会影响受害者转换的时间。根据干扰源的切换方向,串扰延迟效应可以是正的(减缓受害转换)或负的(加速受害转换)。

​ 图 6-16 显示了正串扰延迟效应的示例。当受害网络发生下降过渡时,攻击者网络正在上升。相反方向的攻击者网络切换增加了受害网络的延迟。正串扰会影响驱动单元和互连——这两者的延迟都会增加。

img

​ 图6-17显示了串扰延迟为负的情况。攻击者网络与受害者网络同时上升,攻击者网络与受害者网络朝相同方向的电平切换可减少受害者网络的延迟。如前所述,负串扰(negative crosstalk)会影响驱动单元和互连线的时序,两者的延迟都会减小。

img

​ 注意,最差的正串扰延迟和最差的负串扰延迟会分别针对上升和下降延迟进行计算。一般来说,由于串扰而导致的最大上升时间、最小上升时间、最大下降时间、最大下降时间延迟的干扰源是不同的,这将在下面的小节中进行介绍。

多个干扰源的累积(Accumulation with Multiple Aggressors)

​ 具有多个干扰源的串扰延迟分析涉及对每个干扰源的串扰造成的影响进行累加。这类似于第 6.2 节中描述的串扰毛刺分析。当多个网络同时切换时,由于多个攻击者,对受害者的串扰延迟效应会变得更加复杂。

​ 由于多个干扰源引起的耦合的大多数分析都会添加每个攻击者的增量贡献并计算对受害者的累积影响。这可能看起来很保守,但它确实表明受害设备上的最坏情况串扰延迟。

​ 与用于串扰毛刺分析的多个干扰源的分析类似,也可以使用均方根 (RMS) 来添加贡献,这比单个贡献的直和更不悲观。

攻击者-受害者时间相关性(Aggressor Victim Timing Correlation)

​ 串扰延迟分析的时序相关处理在概念上类似于第 6.2 节中描述的串扰毛刺分析的时序相关。串扰会影响受害者的延迟,前提是攻击者可以与受害者同时切换。这是使用攻击者和受害者的时序窗口确定的。如第 6.2 节所述,时序窗口表示网络可以在一个时钟周期内切换的最早和最晚切换时间。如果攻击者和受害者的时序窗口重叠,则计算串扰对延迟的影响。对于多个攻击者,多个攻击者的时序窗口也进行了类似的分析。计算各种时序仓中的可能影响,并考虑串扰延迟影响最严重的时序仓进行延迟分析。

​ 考虑下面的示例,其中三个攻击者网络可以影响受害者网络的时间。攻击者网络 (A1, A2, A3) 电容耦合到受害者网络 (V) 并且它们的时序窗口与受害者网络重叠。图 6-18 显示了时序窗口和每个干扰源可能造成的串扰延迟影响。基于时序窗口,串扰延迟分析确定引起最大串扰延迟影响的干扰源切换的最坏可能组合。在这个例子中,时间窗口重叠区域被分成三个 bin - 每个 bin 显示可能的攻击者切换。 Bin 1 具有 A1 和 A2 切换,这会导致串扰延迟影响为 0.26 (= 0.12 +0.14)。 Bin 2 具有 A1 切换,这会导致 0.14 的串扰延迟影响。 Bin 3 具有 A3 切换,可导致 0.23 的串扰延迟影响。因此,bin 1 具有 0.26 的最坏可能的串扰延迟影响。

img

​ 如前所述,串扰延迟分析将分别计算四种类型的串扰延迟。串扰延迟的四种类型是:正上升延迟(上升沿提前到达)、负上升延迟(上升沿滞后到达)、正下降延迟和负下降延迟。通常,在这四种情况下,网络可以具有不同的攻击者组合。例如,受害者网络具有攻击者网络A1、A2、A3和A4。在串扰延迟分析过程中,A1、A2、A4可能对正上升和负下降延迟有影响,而A2和A3对负上升和正下降延迟有影响。

攻击者-受害者功能相关性(Aggressor Victim Functional Correlation)

​ 除了时序窗口,串扰延迟计算还可以考虑各种信号之间的功能相关性。例如,扫描控制信号仅在扫描模式期间切换并且在设计的功能或任务模式期间稳定。因此,扫描控制信号在功能模式期间不能成为干扰源。在扫描模式期间,扫描控制信号只能是干扰源,在这种情况下,这些信号不能与其他功能信号组合以进行最坏情况噪声计算。

​ 功能相关的另一个例子是两个干扰源互为补充的场景。在这种情况下,信号及其补码永远不能在相同方向上切换以计算串扰噪声。当可用时,可以利用这种类型的函数相关信息,从而通过确保只有实际可以一起切换的信号作为干扰源被包括在内,从而使串扰分析结果不悲观。

使用串扰延迟进行时序验证(Timing Verification Using Crosstalk Delay)

​ 需要为设计中的每个单元和互连线计算以下四种类型的串扰延迟影响:

  • 正上升延迟(Positive rise delay):上升沿提前到达
  • 负上升延迟(Negative rise delay):上升沿滞后到达
  • 正下降延迟(Positive fall delay):下降沿提前到达
  • 负下降延迟(Negative fall delay):下降沿滞后到达

​ 然后在时序分析期间利用串扰延迟贡献来验证最大和最小路径(setup and hold checks)。启动和捕获触发器的时钟路径处理方式不同。本节描述了用于建立和保持检查的数据路径和时钟路径分析的详细信息。

6.4.1建立时间分析(Setup Analysis)

​ 具有串扰分析功能的 STA 使用数据路径和时钟路径的最坏情况串扰延迟来验证设计。考虑图 6-19 中所示的逻辑,其中数据路径和时钟路径上的各种网络可能会发生串扰。建立时间检查的最坏情况是启动时钟路径(launch clock path)和数据路径都具有正串扰,而捕获时钟路径(capture clock path)具有负串扰。发射时钟路径和数据路径上的正串扰贡献延迟了数据到达捕获触发器。此外,捕获时钟路径上的负串扰导致捕获触发器提前计时。

img

​ 基于以上描述,建立时间(或最大路径)分析假设:

  • 发起时钟路径出现正串扰延迟,因此发起数据较迟。
  • 数据路径出现正串扰延迟,因此数据到达目的地需要更长的时间。
  • 捕获时钟路径出现负串扰延迟,因此数据被捕获触发器提早捕获。

​ 由于建立时间检查的启动和捕获时钟沿不同(通常相隔一个时钟周期),公共时钟路径(图 6-19)可能对启动和捕获时钟沿有不同的串扰贡献。

6.4.2保持时间分析(Hold Analysis)

​ STA 的最坏情况保持时间(或最小路径)分析类似于上一小节中描述的最坏情况设置分析。根据图 6-19 中所示的逻辑,当启动时钟路径和数据路径都具有负串扰并且捕获时钟路径具有正串扰时,会发生保持时间检查的最坏情况。发射时钟路径和数据路径上的负串扰贡献导致数据提前到达捕获触发器。此外,捕获时钟路径上的正串扰导致捕获触发器的时钟延迟。

​ 与时钟路径公共部分上的串扰相关的保持时间和建立时间分析之间存在一个重要区别。对于保持时间分析,启动和捕获时钟边沿通常是相同的边沿。通过公共时钟部分的时钟沿不能对启动时钟路径和捕获时钟路径具有不同的串扰贡献。因此,最坏情况保持时间分析消除了公共时钟路径中的串扰影响。

​ 因此,具有串扰的STA最差情况保持时间(或最小路径)分析将假定:

  • 发起时钟(不包括公共时钟路径部分)的串扰延迟影响为负,因此可以较早地发起数据;
  • 数据路径的串扰延迟影响为负,因此数据会较早到达目的地;
  • 捕获时钟(不包括公共时钟路径部分)的串扰延迟影响为正,因此捕获触发器会较迟地捕获数据

​ 如上所述,保持时间分析不考虑对时钟树公共部分的串扰影响。仅针对时钟树的非公共部分计算启动时钟的正串扰贡献和捕获时钟的负串扰贡献。在用于保持分析的 STA 报告中,公共时钟路径可能会显示启动时钟路径和捕获时钟路径的不同串扰贡献。然而,来自公共时钟路径的串扰贡献作为单独的行项目被移除,标记为公共路径悲观消除。 STA 报告中常见路径悲观消除的示例在第 10.1 节中提供。

​ 如前一小节所述,建立时间分析涉及时钟的两个不同边沿,它们可能会在时序上受到不同的影响。因此,在建立时间分析期间,对启动和捕获时钟路径都考虑了公共路径串扰贡献。

​ 时钟信号至关重要,因为时钟树上的任何串扰都会直接转化为时钟抖动并影响设计的性能。因此,应特别考虑减少时钟信号上的串扰。一种常见的噪声避免方法是时钟树的屏蔽——这将在第 6.6 节中详细讨论。

计算复杂性(Computational Complexity)

​ 大型纳米设计通常过于复杂,无法在合理的周转时间内分析每个耦合电容。典型网络的寄生提取包含与许多相邻信号的耦合电容。大型设计通常需要为寄生提取和串扰延迟和毛刺分析进行适当的设置。选择这些设置是为了提供可接受的分析精度,同时确保 CPU 要求仍然可行。本节介绍一些可用于分析大型纳米设计的技术。

分层设计和分析(Hierarchical Design and Analysis)

​ 第 4.5 节介绍了验证大型设计的分层方法。类似的方法也适用于降低提取和分析的复杂性。

​ 对于大型设计,在一次运行中获得寄生提取通常是不切实际的。可以单独提取每个分层块的寄生参数。这反过来又要求在设计实现中使用分层设计方法。这意味着分层块内的信号和块外的信号之间没有耦合。这可以通过在块上不布线或通过在块上添加屏蔽层来实现。此外,信号网络不应靠近模块边界布线,靠近模块边界布线的任何网络都应屏蔽。这避免了与来自其他块的网络的任何耦合。

耦合电容滤波(Filtering of Coupling Capacitances)

​ 即使对于中等大小的模块,寄生效应通常也会包括大量非常小的耦合电容。可以在提取或分析过程中过滤小耦合电容。

这样的过滤是基于以下原则的:

  • 较小的值:在串扰或噪声分析中,可以忽略非常小的耦合电容,例如低于1fF。在提取过程中,数值较小的耦合电容可以视为接地电容。
  • 耦合比:耦合对受害者网络的影响是基于耦合电容相对于受害者网络总电容的相对值。具有较小耦合比(例如低于0.001)的攻击者网络可以从串扰延迟分析或串扰毛刺分析中排除。
  • 合并小型干扰源:可以将影响很小的多个干扰源映射为一个较大的虚拟干扰源。这可能有点悲观,但可以简化分析。可以通过切换干扰源的子集来缓解一些悲观度,干扰源的确切子集可以通过统计方法来确定。

噪声避免技术(Noise Avoidance Techniques)

​ 前面的部分描述了串扰效应的影响和分析。在本节中,我们将介绍一些可在物理设计阶段使用的噪声避免技术。

  • 屏蔽(Shielding):此方法要求将屏蔽线放置在关键信号的任一侧。屏蔽连接到电源或接地导轨。关键信号的屏蔽确保关键信号没有主动干扰源,因为同一金属层中最近的邻居是固定电位的屏蔽走线。虽然不同金属层中的路径可能存在一些耦合,但大多数耦合电容是由于同一层中的电容耦合。由于不同金属层(上方和下方)通常会正交走线,这样跨层的电容耦合会最小化。因此,将屏蔽线放置在同一金属层中可确保关键信号的耦合最小。在由于布线拥塞而无法使用接地或电源轨进行屏蔽的情况下,具有低开关活动(例如在功能模式期间固定的扫描控制)的信号可以作为关键信号的直接邻居进行布线。这些屏蔽方法可确保不会因相邻设备的电容耦合而产生串扰。
  • 线间距(Wire spacing):这减少了与相邻网络的耦合。
  • 快速转换率(Fast slew rate):网络上的快速转换率意味着网络不易受串扰影响,并且本质上不受串扰效应的影响。
  • 保持良好的稳定电源(Maintain good stable supply):这对于减少由于电源变化引起的抖动而不是串扰很重要。由于电源上的噪声,时钟信号上可能会引入大量噪声。应添加足够的去耦电容以将电源噪声降至最低。
  • 保护环(Guard ring):基板中的保护环(或双保护环)有助于保护关键模拟电路免受数字噪声的影响。
  • 深 n 阱(Deep n-well):这与上述类似,因为模拟部分具有深 n 阱有助于防止噪声耦合到数字部分。
  • 隔离块(Isolating a block):在分层设计流程中,可以将布线晕圈(halos)添加到块的边界;此外,还可以将隔离缓冲器(isolation buffers)添加到块的每个IO中。

配置 STA 环境(Configuring the STA Environment)

第 7 章是后续章节的先决条件。它描述了如何配置时序分析环境。描述了指定时钟、IO 特性、伪路径和多周期路径的方法。

正确约束的说明对于分析STA结果非常重要。应准确指定设计环境,以便STA分析能够识别设计中的所有时序问题。STA的准备包括设置时钟、指定IO定时特性以及指定伪路径和多周期路径。在继续下一章关于时间验证之前,彻底理解本章非常重要。

什么是STA环境?(What is the STA Environment?)

​ 大多数数字设计都是同步的,从上一个时钟周期计算的数据锁存在活动时钟边缘的触发器中。考虑图7-1所示的典型同步设计,假设分析设计(DUA)与其他同步设计相互作用。这意味着DUA从时钟触发器接收数据,并将数据输出到DUA外部的另一个时钟触发器。

img

​ 要在此设计上执行STA,需要指定触发器的时钟,以及通向设计的所有路径和退出设计的所有路径的时序约束。

​ 图7-1中的示例假设只有一个时钟,C1、C2、C3、C4和C5表示组合块。组合块C1和C5不在所分析的设计范围内。

​ 在典型设计中,从一个时钟域到另一个时钟域可以有多个时钟,具有多条路径。以下各节介绍如何在此类场景中指定环境。

指定时钟(Specifying Clocks)

​ 要定义时钟,我们需要提供以下信息:

  • 时钟源(Clock source):它可以是设计的端口,也可以是设计内部单元的引脚(通常是时钟生成逻辑的一部分)。
  • 周期(Period):时钟的周期。
  • 占空比(Duty cycle):高电平持续时间(正相位)和低电平持续时间(负相位)。
  • 边沿时间(Edge times):上升沿和下降沿的时刻。

​ 图7-2显示了基本定义。通过定义时钟,所有内部时序路径(所有触发器到触发器路径)都受到约束;这意味着所有内部路径都可以仅使用时钟规格进行分析。时钟规范规定触发器到触发器的路径必须占用一个周期。我们将在后面描述如何放宽这一要求(一个周期时间)。

img

​ 以下是一个基本的时钟约束规范:

1
2
3
4
5
6
7
8
9
create_clock \

-name SYSCLK \

-period 20 \

-waveform {0 5} \

[get_ports2SCLK]

​ 时钟的名称为SYSCLK,在端口SCLK处定义。SYSCLK的周期指定为20个单位-如果未指定,则默认时间单位为纳秒(通常,时间单位指定为技术库的一部分。)波形中的第一个参数指定上升沿出现的时间,第二个参数指定下降沿出现的时间。

waveform选项中可以指定任意数量的边。但是,所有边缘必须在一个周期内。沿时间从时间零点后的第一个上升沿开始交替,然后是下降沿,然后是上升沿,依此类推。这意味着waveform列表中的所有时间值必须是单调递增的。

1
-waveform {time_rise time_fall time_rise time_fall ...}

​ 此外,必须指定偶数条边。 waveform选项指定一个时钟周期内的波形,然后该时钟周期自身重复。

​ 如果未指定waveform选项,默认值为:

1
-waveform {0, period/2}

​ 这里是一个没有波形规范的时钟规范示例(见图7-3)。

1
create_clock -period 5 [get_ports SCAN_CLK]

​ 在此约束中,由于未指定-name选项,因此时钟的名称与端口的名称相同,即SCAN_CLK。

img

​ 以下是时钟约束的另一个示例,其中波形的边沿在一个周期的中间位置(见图7-4)。

1
2
3
create_clock -name BDYCLK -period 15 \

-waveform {5 12} [get_ports GBLCLK]

​ 时钟的名称为BDYCLK,在端口GBLCLK处定义。实际上,保持时钟名称与端口名称相同是一个好主意。

img

这里有更多的时钟约束示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# See Figure 7-5(a):

create_clock -period 10 -waveform {5 10} [get_ports FCLK]

# Creates a clock with the rising edge at 5ns and the

# falling edge at 10ns.

# See Figure 7-5(b):

create_clock -period 125 \

-waveform {100 150} [get_ports ARMCLK]

# Since the first edge has to be rising edge,

# the edge at 100ns is specified first and then the

# falling edge at 150ns is specified. The falling edge

# at 25ns is automatically inferred.

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# See Figure 7-6(a):

create_clock -period 1.0 -waveform {0.5 1.375} MAIN_CLK

# The first rising edge and the next falling edge

# is specified. Falling edge at 0.375ns is inferred

# automatically.

# See Figure 7-6(b):

create_clock -period 1.2 -waveform {0.3 0.4 0.8 1.0} JTAG_CLK

# Indicates a rising edge at 300ps, a falling edge at 400ps,

# a rising edge at 800ps and a falling edge at 1ns, and this

# pattern is repeated every 1.2ns.

create_clock -period 1.27 \

-waveform {0 0.635} [get_ports clk_core]

create_clock -name TEST_CLK -period 17 \

-waveform {0 8.5} -add [get_ports {ip_io_clk[0]}]

# The -add option allows more than one clock

# specification to be defined at a port.

img

锁相环PLL(Phase-locked loop):在专用集成电路中常用来产生高频时钟 。

​ 除上述属性外,还可以选择指定时钟源处的转换时间。在某些情况下,例如某些PLL模型的输出或输入端口,该工具无法自动计算过渡时间。在这种情况下,明确指定时钟源处的转换时间非常有用。这是使用set_clock_transition命令指定的。

1
2
3
set_clock_transition -rise 0.1 [get_clocks CLK_CONFIG]

set_clock_transition -fall 0.12 [get_clocks CLK_CONFIG]

​ 这个约束仅适用于理想时钟,一旦构建了时钟树就将其忽略,因为此时将会使用时钟引脚上的实际过渡时间。如果在输入端口上定义了时钟,也可以使用set_input_transition命令(参见7.7节)来约束时钟的转换。

时钟不确定性(Clock Uncertainty)

​ 可以使用 set_clock_uncertainty 约束指定时钟周期的时序不确定性。不确定性可用于模拟可以减少有效时钟周期的各种因素。这些因素可以是时钟抖动和任何其他可能希望用于时序分析的悲观因素。

1
2
3
set_clock_uncertainty -setup 0.2 [get_clocks CLK_CONFIG]

set_clock_uncertainty -hold 0.05 [get_clocks CLK_CONFIG]

​ 注意,建立时间检查的时钟不确定度将减少可用的有效时钟周期,如图7-7所示。对于保持时间检查,时钟不确定度将用作需要满足的额外时序裕量。

img

​ 以下命令可用于指定跨时钟边界路径上的时钟不确定度,称为时钟间不确定度(inter-clock uncertainty)。

1
2
3
4
5
6
7
8
9
10
11
set_clock_uncertainty -from VIRTUAL_SYS_CLK -to SYS_CLK \

-hold 0.05

set_clock_uncertainty -from VIRTUAL_SYS_CLK -to SYS_CLK \

-setup 0.3

set_clock_uncertainty -from SYS_CLK -to CFG_CLK -hold 0.05

set_clock_uncertainty -from SYS_CLK -to CFG_CLK -setup 0.1

​ 图 7-8 显示了两个不同时钟域 SYS_CLK 和 CFG_CLK 之间的路径。根据上述时钟间不确定性约束,100ps 用作建立时间检查的不确定性,50ps 用作保持时间检查的不确定性。

img

时钟延迟(Clock Latency)

​ 可以使用set_clock_latency命令指定时钟的延迟。

1
2
3
4
5
6
7
8
9
10
11
# Rise clock latency on MAIN_CLK is 1.8ns:

set_clock_latency 1.8 -rise [get_clocks MAIN_CLK]

# Fall clock latency on all clocks is 2.1ns:

set_clock_latency 2.1 -fall [all_clocks]

# The -rise, -fall refer to the edge at the clock pin of a

# flip-flop.

​ 时钟延迟有两种类型:网络延迟(network latency)和源延迟(source latency)。网络延迟是从时钟定义点 (create_clock) 到触发器时钟引脚的延迟。源延迟,也称为插入延迟(insertion delay),是从时钟源到时钟定义点的延迟。源延迟可以代表片上或片外延迟。图 7-9 显示了这两种情况。触发器时钟引脚的总时钟延迟是源延迟和网络延迟的总和。

img

​ 下面是一些指定源和网络延迟的示例命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Specify a network latency (no -source option) of 0.8ns for

# rise, fall, max and min:

set_clock_latency 0.8 [get_clocks CLK_CONFIG]

# Specify a source latency:

set_clock_latency 1.9 -source [get_clocks SYS_CLK]

# Specify a min source latency:

set_clock_latency 0.851 -source -min [get_clocks CFG_CLK]

# Specify a max source latency:

set_clock_latency 1.322 -source -max [get_clocks CFG_CLK]

​ 源延迟和网络延迟之间的一个重要区别是:一旦为设计建立了时钟树,就可以忽略网络延迟(假设指定了set_propagated_clock命令)。但是,即使在建立时钟树之后,源延迟也会保留。网络延迟是在进行时钟树综合(Clock Tree Synthesis)之前对时钟树延迟的估计值。在时钟树综合完成后,从时钟源到触发器时钟引脚的总时钟延迟是源延迟加上时钟树从时钟定义点到触发器的实际延迟。

​ 生成时钟在下一节中描述,虚拟时钟在 7.9 节中描述。

生成时钟(Generated Clocks)

​ 生成时钟是从主时钟派生的时钟。主时钟是使用 create_clock 命令定义的时钟。

​ 在基于主时钟的设计中生成新时钟时,可以将新时钟定义为生成时钟。例如,如果时钟有一个 3 分频电路,则可以在该电路的输出端定义一个生成时钟。这个定义是必需的,因为 STA 不知道分频逻辑输出端的时钟周期已经改变,更重要的是新的时钟周期是什么。图 7-10 显示了生成时钟的示例,该时钟是主时钟 CLKP 的 2 分频。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
create_clock -name CLKP 10 [get_pins UPLL0/CLKOUT]

# Create a master clock with name CLKP of period 10ns

# with 50% duty cycle at the CLKOUT pin of the PLL.



create_generated_clock -name CLKPDIV2 -source UPLL0/CLKOUT \

-divide_by 2 [get_pins UFF0/Q]



# Creates a generated clock with name CLKPDIV2 at the Q

# pin of flip-flop UFF0. The master clock is at the CLKOUT

# pin of PLL. And the period of the generated clock is double

# that of the clock CLKP, that is, 20ns.

​ 可以在触发器的输出端口定义一个新时钟是主时钟,而非生成时钟吗?答案是肯定的,这确实是可能的,但是它也有一些缺点。定义主时钟而不是生成时钟会创建一个新的时钟域。通常这不是问题,除了在设置STA约束时需要处理更多的时钟域外。相反,将新时钟定义为生成时钟不会创建新的时钟域,并且生成时钟会被认为与其主时钟同相,生成时钟不需要进行额外的约束。因此,尽量将内部新生成的时钟定义为生成时钟,而不是将其声明为另一个主时钟。

​ 主时钟和生成时钟之间的另一个重要区别是时钟源的概念。在主时钟中,时钟的源点位于主时钟的定义点。在生成时钟中,时钟源是主时钟的源,而不是生成时钟的源。这意味着在时钟路径报告中,时钟路径的起点始终是主时钟定义点。这是生成时钟相对于定义新主时钟的一大优势,因为对于新主时钟的情况不会自动包含源延迟。

​ 图 7-11 显示了一个多路复用器的示例,其两个输入都有时钟。在这种情况下,无需在多路复用器的输出上定义时钟。如果选择信号设置为常数,多路复用器的输出会自动获得正确的时钟传播。如果多路复用器的选择引脚不受约束,则两个时钟都通过多路复用器传播以供 STA 使用。在这种情况下,STA 可能会报告 TCLK 和 TCLKDIV5 之间的路径。请注意,这种路径是不可能的,因为选择线只能选择多路复用器输入之一。在这种情况下,可能需要设置一条错误路径或指定这两个时钟之间的独占时钟关系,以避免报告错误路径。这当然假设设计中其他地方的 TCLK 和 TCLKDIV5 之间没有路径。

img

​ 如果多路复用器选择信号不是静态的并且可以在设备操作期间发生变化,会发生什么情况?在这种情况下,会对多路复用器输入端进行时钟门控(clock gating)检查。时钟门控检查在第 10 章中解释;这些检查确保多路复用器输入处的时钟相对于多路复用器选择信号安全切换。

​ 图 7-12 显示了一个示例,其中时钟 SYS_CLK 由触发器的输出进行门控。由于触发器的输出可能不是常数,因此处理这种情况的一种方法是在和单元的输出处定义一个与输入时钟相同的生成时钟。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
create_clock 0.1 [get_ports SYS_CLK]

# Create a master clock of period 100ps with 50%

# duty cycle.



create_generated_clock -name CORE_CLK -divide_by 1 \

-source SYS_CLK [get_pins UAND1/Z]

# Create a generated clock called CORE_CLK at the

# output of the and cell and the clock waveform is

# same as that of the master clock.

​ 下一个示例是频率高于源时钟频率的生成时钟。图 7-13 显示了波形。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
create_clock -period 10 -waveform {0 5} [get_ports PCLK]

# Create a master clock with name PCLK of period 10ns

# with rise edge at 0ns and fall edge at 5ns.

create_generated_clock -name PCLKx2 \

-source [get_ports PCLK] \

-multiply_by 2 [get_pins UCLKMULTREG/Q]

# Creates a generated clock called PCLKx2 from the

# master clock PCLK and the frequency is double that of

# the master clock. The generated clock is defined at the

# output of the flip-flop UCLKMULTREG.

​ 请注意,-multiply_by 和 -divide_by 选项指的是时钟频率,即使在主时钟定义中指定了时钟周期。

时钟门控单元输出的主时钟示例(Example of Master Clock at Clock Gating Cell Output)

​ 考虑图7-14中所示的时钟门控示例,两个时钟分别输入进一个与门单元中,问题是与门单元的输出是什么呢?如果与门单元的输入均为时钟,则可以安全地在与门单元的输出端定义一个新的主时钟,因为该单元的输出与任何一个输入时钟都没有相位关系的可能性很小。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create_clock -name SYS_CLK -period 4 -waveform {0 2} \

[get_pins UFFSYS/Q]

create_clock -name CORE_CLK -period 12 -waveform {0 4} \

[get_pins UFFCORE/Q]

create_clock -name MAIN_CLK -period 12 -waveform {0 2} \

[get_pins UAND2/Z]

# Create a master clock instead of a generated clock

# at the output of the and cell.

​ 在内部引脚上创建时钟的一个缺点是它会影响路径延迟计算并迫使设计人员手动计算源延迟。

使用Edge和Edge_shift选项生成时钟(Generated Clock using Edge and Edge_shift Options)

​ 图 7-15 显示了生成时钟的示例。除了两个异相时钟之外,还会生成一个 2 分频时钟。图中还显示了时钟的波形。

img

​ 下面给出了该示例中所有时钟的定义。衍生时钟的定义使用了-edges选项,这是定义衍生时钟的另一种方法。该选项采用源主时钟{上升,下降,上升}的边沿列表,以形成新的衍生时钟。主时钟的第一个上升沿是沿1,第一个下降沿是沿2,下一个上升沿是沿3,依此类推。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
create_clock 2 [get_ports DCLK]

# Name of clock is DCLK, has period of 2ns with a

# rise edge at 0ns and a fall edge at 1ns.

create_generated_clock -name DCLKDIV2 -edges {2 4 6} \

-source DCLK [get_pins UBUF2/Z]

# The generated clock with name DCLKDIV2 is defined at

# the output of the buffer. Its waveform is formed by

# having a rise edge at edge 2 of the source clock,

# fall edge at edge 4 of the source clock and the next

# rise edge at edge 6 of the source clock.

create_generated_clock -name PH0CLK -edges {3 4 7} \

-source DCLK [get_pins UAND0/Z]

# The generated clock PH0CLK is formed using

# the 3, 4, 7 edges of the source clock.

create_generated_clock -name PH1CLK -edges {1 2 5} \

-source DCLK [get_pins UAND1/Z]

# The generated clock with name PH1CLK is defined at

# the output of the and cell and is formed with

# edges 1, 2 and 5 of the source clock.

​ 如果生成时钟的第一个边沿是下降沿怎么办?考虑生成的时钟 G3CLK,如图 7-16 所示。可以通过指定边沿 5、7 和 10 来定义此类生成的时钟,如下面的时钟约束所示。自动推断 1ns 处的下降沿。

img

1
2
3
create_generated_clock -name G3CLK -edges {5 7 10} \

-source DCLK [get_pins UAND0/Z]

​ -edge_shift 选项可与 -edges 选项结合使用,以指定相应边沿的任何移位以形成新生成的波形。它指定边列表中每个边的移动量(以时间为单位)。这是使用此选项的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create_clock -period 10 -waveform {0 5} [get_ports MIICLK]

create_generated_clock -name MIICLKDIV2 -source MIICLK \

-edges {1 3 5} [get_pins UMIICLKREG/Q]

# Create a divide-by-2 clock.

create_generated_clock -name MIIDIV2 -source MIICLK \

-edges {1 1 5} -edge_shift {0 5 0} [get_pins UMIIDIV/Q]

# Creates a divide-by-2 clock with a duty cycle different

# from the source clock's value of 50%.

​ 边沿列表中的边沿列表必须按非递减顺序排列,但同一边沿可用于两个条目以指示独立于源时钟占空比的时钟脉冲。上例中的 -edge_shift 选项指定第一个边沿是通过将(源时钟的边沿 1)移动 0ns 获得的,第二个边沿是通过将(源时钟的边沿 1)移动 5ns 获得的,第三个边沿是通过以下方式获得的将(源时钟的边沿 5)移动 0ns。图 7-17 显示了波形。

img

使用Invert 选项生成的时钟(Generated Clock using Invert Option)

​ 这是生成时钟的另一个示例;这个使用 -invert 选项。

1
2
3
4
5
create_clock -period 10 [get_ports CLK]

create_generated_clock -name NCLKDIV2 -divide_by 2 -invert \

-source CLK [get_pins UINVQ/Z]

​ -invert 选项在应用所有其他生成的时钟选项后将反转应用于生成的时钟。图 7-18 显示了生成这种反相时钟的原理图。

img

生成时钟的时钟延迟(Clock Latency for Generated Clocks)

​ 也可以为生成的时钟指定时钟延迟。在生成时钟上指定的源延迟指定了从主时钟定义到生成时钟定义的延迟。因此,到由生成时钟驱动的触发器的时钟引脚的总时钟延迟是主时钟的源延迟、生成时钟的源延迟和生成时钟的网络延迟之和。如图 7-19 所示。

img

​ 一个生成时钟可以有另一个生成时钟作为其源,即可以有生成时钟的生成时钟,以此类推。但是,生成的时钟只能有一个主时钟。生成时钟的更多示例将在后面的章节中描述。

典型时钟生成场景(Typical Clock Generation Scenario)

​ 图 7-20 显示了时钟分布如何出现在典型 ASIC 中的场景。振荡器在芯片外部并产生低频(典型值 10-50 MHz)时钟,片上 PLL 将其用作参考时钟以生成高频低抖动时钟(典型值 200-800 MHz) .然后将该 PLL 时钟馈送到时钟分频器逻辑,该逻辑为 ASIC 生成所需的时钟。

img

​ 在时钟分配的一些分支上,可能有时钟门,用于在必要时关闭设计的非活动部分的时钟以节省功耗。 PLL 的输出端还可以有一个多路复用器,以便在必要时可以绕过 PLL。

​ 在进入设计的芯片输入引脚上为参考时钟定义了一个主时钟,在 PLL 的输出端定义了第二个主时钟。 PLL 输出时钟与参考时钟没有相位关系。因此,输出时钟不应是参考时钟的生成时钟。最有可能的是,时钟分频器逻辑生成的所有时钟都被指定为 PLL 输出的主时钟的生成时钟。

约束输入路径(Constraining Input Paths)

​ 本节将介绍输入路径的约束。这里需要注意的一点是,STA无法检查不受约束的路径上的任何时序,因此需要约束所有路径以进行时序分析。在后面的章节中会介绍一些示例,其中一些示例可能并不关心某些逻辑,因而这些输入路径可能可以不用约束。例如,设计人员可能并不在乎一些输入控制信号的时序,因此可能并不需要进行本节中将要介绍的时序检查。但是,本节假定我们要约束全部的输入路径。

​ 图 7-21 显示了被分析设计 (DUA) 的输入路径。触发器 UFF0 位于设计外部,并向设计内部的触发器 UFF1 提供数据。数据通过输入端口 INP1 连接。

img

​ CLKA 的时钟定义指定了时钟周期,它是两个触发器 UFF0 和 UFF1 之间可用的总时间量。外部逻辑所用的时间是 Tclk2q,即启动触发器 UFF0 的 CK 到 Q 延迟,加上 Tc1,即通过外部组合逻辑的延迟。因此,输入引脚 INP1 上的延迟规范定义了 Tclk2q 加上 Tc1 的外部延迟。在本例中,此延迟是相对于时钟 CLKA 指定的。

​ 这是输入延迟约束。

1
2
3
4
5
6
7
set Tclk2q 0.9

set Tc1 0.6

set_input_delay -clock CLKA -max [expr Tclk2q + Tc1] \

[get_ports INP1]

​ 该约束指定输入 INP1 上的外部延迟为 1.5ns,这与时钟 CLKA 相关。假设 CLKA 的时钟周期为 2ns,则 INP1 引脚的逻辑只有 500ps (= 2ns - 1.5ns) 可用于在设计内部传播。此输入延迟规范映射到输入约束,即 Tc2 加上 UFF1 的 Tsetup 必须小于 500ps,触发器 UFF1 才能可靠地捕获触发器 UFF0 启动的数据。请注意,上面的外部延迟被指定为最大数量。

img

​ 让我们考虑同时考虑最大和最小延迟的情况,如图 7-22 所示。以下是此示例的限制条件。

1
2
3
4
5
create_clock -period 15 -waveform {5 12} [get_ports CLKP]

set_input_delay -clock CLKP -max 6.7 [get_ports INPA]

set_input_delay -clock CLKP -min 3.0 [get_ports INPA]

​ INPA 的最大和最小延迟源自 CLKP 到 INPA 的延迟。最大和最小延迟分别指最长和最短路径延迟。这些通常也可能对应于最坏情况下的慢速(最大时序角)和最佳情况下的快速(最小时序角)。因此,最大延迟对应于最大拐角处的最长路径延迟,最小延迟对应于最小拐角处的最短路径延迟。在我们的示例中,1.1ns 和 0.8ns 是 Tck2q 的最大和最小延迟值。组合路径延迟 Tc1 的最大延迟为 5.6ns,最小延迟为 2.2ns。 INPA 上的波形显示了数据到达设计输入的窗口以及预期稳定的时间。从 CLKP 到 INPA 的最大延迟为 6.7ns (= 1.1ns +5.6ns)。最小延迟为 3ns (= 0.8ns+ 2.2ns)。这些延迟是根据时钟的有效边沿指定的。在给定外部输入延迟的情况下,设计内部的可用建立时间是慢角(slow corner)下的8.3ns(= 15ns-6.7ns)和快角(fast corner)下的12ns(= 15ns-3.0ns)中的最小值。因此,8.3ns是用来可靠地捕获DUA内部数据的可用时间。

​ 以下是输入约束的更多示例。

1
2
3
set_input_delay -clock clk_core 0.5 [get_ports bist_mode]

set_input_delay -clock clk_core 0.5 [get_ports sad_state]

​ 由于未指定maxmin选项,因此500ps这个值将同时用于最大延迟和最小延迟。此外部输入延迟是相对于时钟clk_core的上升沿指定的(如果输入延迟是相对于时钟的下降沿指定的,则必须使用-clock_fall选项)。

约束输出路径(Constraining Output Paths)

​ 本节将借助以下三个说明性示例描述输出路径的约束。

示例 A

​ 图 7-23 显示了通过分析设计的输出端口的路径示例。 Tc1 和 Tc2 是通过组合逻辑的延迟。

img

​ 时钟 CLKQ 的周期定义了触发器 UFF0 和 UFF1 之间的总可用时间。外部逻辑的总延迟为 Tc2 加 Tsetup。该总延迟 Tc2 Tsetup 必须指定为输出延迟规范的一部分。请注意,输出延迟是相对于捕获时钟指定的。数据必须及时到达外部触发器UFF1以满足其建立时间要求。

1
2
3
4
5
6
7
set Tc2  3.9

set Tsetup 1.1

set_output_delay -clock CLKQ -max [expr Tc2 + Tsetup] \

[get_ports OUTB]

​ 这指定相对于时钟边沿的最大外部延迟为 Tc2 加 Tsetup;并且应该对应5ns的延迟。可以类似地指定最小延迟。

示例 B

img

​ 图 7-24 显示了具有最小和最大延迟的示例。最大路径延迟为 7.4ns(= 最大 Tc2 加上 Tsetup = 7 0.4)。最小路径延迟为 -0.2ns(= 最小 Tc2 减去 Thold = 0 - 0.2)。因此输出约束为:

1
2
3
4
5
create_clock -period 20 -waveform {0 15} [get_ports CLKQ]

set_output_delay -clock CLKQ -min -0.2 [get_ports OUTC]

set_output_delay -clock CLKQ -max 7.4 [get_ports OUTC]

​ 图 7-24 中的波形显示了何时 OUTC 必须稳定才能被外部触发器可靠地捕获。这描述了数据必须在所需的稳定区域开始之前在输出端口准备好,并且必须保持稳定直到稳定区域结束。这映射到 DUA 内部输出端口 OUTC 的逻辑时序要求。

示例 C

​ 这是显示输入和输出规范的另一个示例。该模块有两个输入,DATAIN 和 MCLK,以及一个输出 DATAOUT。图 7-25 显示了预期的波形。

img

1
2
3
4
5
6
7
8
9
10
11
create_clock -period 100 -waveform {5 55} [get_ports MCLK]

set_input_delay 25 -max -clock MCLK [get_ports DATAIN]

set_input_delay 5 -min -clock MCLK [get_ports DATAIN]



set_output_delay 20 -max -clock MCLK [get_ports DATAOUT]

set_output_delay -5 -min -clock MCLK [get_ports DATAOUT]

时序路径组(Timing Path Groups)

​ 设计中的时序路径可被视为路径的集合。每条路径都有一个起点和一个终点(a startpoint and an endpoint)。有关一些示例路径,请参见图 7-26。

img

​ 在STA中,时序路径是根据有效的起点和终点(valid startpoints and valid endpoints)来划分的。有效的起点包括:输入端口或者同步器件(如触发器和存储器)的时钟引脚。有效的终点包括:输出端口或者同步器件的数据输入引脚。因此,有效的时序路径包括:

  • 从输入端口到输出端口
  • 从输入端口到触发器或存储器的数据输入引脚
  • 从一个触发器或存储器的时钟引脚到另一个触发器或存储器的数据输入引脚
  • 从一个触发器或存储器的时钟引脚到输出端口

​ 图7-26中的有效时序路径包括:

  • 输入端口A到输出端口Z
  • 输入端口A到触发器UFFA的D引脚
  • 触发器UFFA的CK引脚到触发器UFFB的D引脚
  • 触发器UFFB的CK引脚到输出端口Z

​ 时序路径可以根据与路径终点相关的时钟分为不同时序路径组(path groups)。因此,每个时钟都有一组与之相关的时序路径。还有一个默认时序路径组(default path group),其中包括了所有non-clocked(异步)路径。

在图7-27的示例中,时序路径分组为:

  • CLKA组:输入端口A到触发器UFFA的D引脚
  • CLKB组:触发器UFFA的CK引脚到触发器UFFB的D引脚
  • 默认组:输入端口A到输出端口Z、触发器UFFB的CK引脚到输出端口Z

img

*静态时序分析和报告通常对每个路径组分别执行。*

外部属性建模(Modeling of External Attributes)

​ 虽然 create_clock、set_input_delay 和 set_output_delay 足以约束设计中的所有路径以执行时序分析,但这些不足以为模块的 IO 引脚获得准确的时序。还需要以下属性来准确地对设计环境进行建模。对于输入,需要指定输入的转换。可以使用以下方式提供此信息:

  • set_drive*(此命令已过时,不推荐使用。)*
  • set_driving_cell
  • set_input_transition

​ 对于输出,需要指定输出引脚看到的容性负载。这是通过使用以下命令约束指定的:

  • set_load

驱动强度建模(Modeling Drive Strengths)

set_driveset_driving_cell约束用于对驱动模块输入端口的外部单元的驱动强度进行建模。在没有这些约束的默认情况下,假定所有输入都具有无限的驱动强度,即输入引脚的过渡时间为0。

set_drive明确指定了DUA输入引脚上的驱动电阻值,该电阻值越小,驱动强度越高,电阻值为0表示无限的驱动强度。

img

1
2
3
4
5
6
7
8
9
10
11
set_drive 100 UCLK

# Specifies a drive resistance of 100 on input UCLK.



# Rise drive is different from fall drive:

set_drive -rise 3 [all_inputs]

set_drive -fall 2 [all_inputs]

​ 输入端口的驱动用于计算第一个单元的转换时间。指定的驱动值还用于计算存在任何 RC 互连时从输入端口到第一个单元的延迟。

1
2
3
4
5
6
7
Delay_to_first_gate =

(drive * load_on_net) + interconnect_delay



延迟值 = (驱动强度 * 网络负载) + 互连线延迟

​ set_driving_cell 命令提供了一种更方便、更准确的方法来描述端口的驱动能力。 set_driving_cell 可用于指定驱动输入端口的单元。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
set_driving_cell -lib_cell INV3 \

-library slow [get_ports INPB]

# The input INPB is driven by an INV3 cell

# from library slow.

set_driving_cell -lib_cell INV2 \

-library tech13g [all_inputs]

# Specifies that the cell INV2 from a library tech13g is

# the driving cell for all inputs.

set_driving_cell -lib_cell BUFFD4 -library tech90gwc \

[get_ports {testmode[3]}]

# The input testmode[3] is driven by a BUFFD4 cell

# from library tech90gwc.

​ 与驱动规范一样,输入端口的驱动单元用于计算第一个单元的转换时间,并在存在任何互连时计算从输入端口到第一个单元的延迟。

​ set_driving_cell 命令的一个警告是,由于输入端口上的容性负载而导致的驱动单元的增量延迟作为输入上的附加延迟包括在内。

​ 作为上述方法的替代方法,set_input_transition 命令提供了一种在输入端口表达转换的便捷方式。可以选择指定参考时钟。以下是图 7-30 中所示示例的规范以及其他示例。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
set_input_transition 0.85 [get_ports INPC]

# Specifies an input transition of 850ps on port INPC.

set_input_transition 0.6 [all_inputs]

# Specifies a transition of 600ps on all input ports.

set_input_transition 0.25 [get_ports SD_DIN*]

# Specifies a transition of 250ps on all ports with

# pattern SD_DIN*.

# Min and max values can optionally be specified using

# the -min and -max options.

​ 总之,需要输入端的转换值来确定输入路径中第一个单元的延迟。在没有此约束的情况下,假设理想的过渡值为 0,这可能不现实。

7.7.2 容性负载建模(Modeling Capacitive Load)

set_load约束在输出端口上设置了电容性负载,以模拟由输出端口驱动的外部负载。默认情况下,端口上的电容性负载为0。可以将负载显式地指定为电容值或某个单元的输入引脚电容。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
set_load 5 [get_ports OUTX]

# Places a 5pF load on output port OUTX.

set_load 25 [all_outputs]

# Sets 25pF load capacitance on all outputs.

set_load -pin_load 0.007 [get_ports {shift_write[31]}]

# Place 7fF pin load on the specified output port.

# A load on the net connected to the port can be

# specified using the -wire_load option.

# If neither -pin_load nor -wire_load option is used,

# the default is the -pin_load option.

​ 指定输出负载很重要,因为该值会影响驱动输出的单元的延迟。在没有这样的规范的情况下,假设负载为 0,这可能是不现实的。

​ set_load 命令还可用于在设计中指定内部网络上的负载。下面是一个例子:

1
2
3
set_load 0.25 [get_nets UCNT5/NET6]

# Sets the net capacitance to be 0.25pF.

设计规则检查(Design Rule Checks)

​ STA中两个常用的设计规则是最大过渡时间-max_transition和最大电容-max_capacitance。这些规则将会检查设计中的所有端口和引脚是否满足过渡时间和电容的规定约束。这些规则可以使用以下命令指定:

  • set_max_transition
  • set_max_capacitance

​ 作为STA的一部分,任何设计规则的违例(violation)均以裕量(slack)的形式报告。以下是些例子:

1
2
3
4
5
6
7
8
9
set_max_transition 0.6 IOBANK

# Sets a limit of 600ps on IOBANK.

set_max_capacitance 0.5 [current_design]

# Max capacitance is set to 0.5pf on all nets in

# current design.

网络上的电容是通过将所有引脚电容加上任何IO负载再加上网络上的任何互连电容的总和计算得出的。下图7-32为一个示例:

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Total cap on net N1 =

pin cap of UBUF1:pin/A +

pin cap of UOR2:pin/B +

load cap specified on output port OUTP +

wire/routing cap

= 0.05 + 0.03 + 0.07 + 0.02

= 0.17pF



Total cap on net N2 =

pin cap of UBUF2/A +

wire/routing cap from input to buffer

= 0.04 + 0.03

= 0.07pF



网络N1的总电容 = UBUF1的A引脚电容 + UOR2的B引脚电容 + OUTP的输出负载电容 + 走线互连电容



= 0.05 + 0.03 + 0.07 + 0.02 = 0.17 pF



网络N2的总电容 = UBUF2的A引脚电容 + 走线互连电容



= 0.03 + 0.04 = 0.07 pF

​ 过渡时间是延迟计算的一部分。对于图7-32中的示例(假设UBUF2单元使用线性延迟模型):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Transition time on pin UBUF2/A =

drive of 21* total cap on net N2

= 2 * 0.07 = 0.14ns = 140ps



Transition time on output port OUTP =

drive resistance of UBUF2/Z * total cap of net N1 =

1 * 0.17 = 0.17ns = 170ps



UBUF2的A引脚过渡时间 = 2 * 网络N2的总电容

= 2 * 0.07 = 0.14ns = 140ps



输出端口OUTP过渡时间 = UBUF2的Z引脚的驱动电阻 * 网络N1的总电容



= 1 * 0.17 = 0.17ns = 170ps

​ 还可以为设计指定其他设计规则检查,比如:set_max_fanout(指定设计中所有引脚的扇出约束),set_max_area(用于设计)。但是,这些检查适用于综合(synthesis)而非STA。

虚拟时钟(Virtual Clocks)

​ 虚拟时钟是存在但不与设计的任何引脚或端口相关联的时钟。它用作 STA 分析中的参考,以指定相对于时钟的输入和输出延迟。图 7-33 显示了一个适用虚拟时钟的示例。分析中的设计从 CLK_CORE 获取时钟,但驱动输入端口 ROW_IN 的时钟是 CLK_SAD。在这种情况下,如何指定输入端口 ROW_IN 上的 IO 约束?同样的问题发生在输出端口 STATE_O 上。

img

​ 为了处理这种情况,可以定义一个不指定源端口或引脚的虚拟时钟。在图 7-33 的示例中,为 CLK_SAD 和 CLK_CFG 定义了虚拟时钟。

1
2
3
4
5
6
7
create_clock -name VIRTUAL_CLK_SAD -period 10 -waveform {2 8}

create_clock -name VIRTUAL_CLK_CFG -period 8 \

-waveform {0 4}

create_clock -period 10 [get_ports CLK_CORE]

​ 定义了这些虚拟时钟后,可以相对于该虚拟时钟指定 IO 约束。

1
2
3
4
5
6
7
set_input_delay -clock VIRTUAL_CLK_SAD -max 2.7 \

[get_ports ROW_IN]

set_output_delay -clock VIRTUAL_CLK_CFG -max 4.5 \

[get_ports STATE_O]

​ 图 7-34 显示了输入路径上的时序关系。这将被分析设计中的输入路径限制为 5.3ns 或更小。

img

​ 图 7-35 显示了输出路径上的时序关系。这将被分析设计中的输出路径限制为 3.5ns 或更小。

img

​ -min 选项在 set_input_delay 和 set_output_delay 约束中指定时,用于验证快速(或最小)路径。使用虚拟时钟只是限制输入和输出 (IO) 的一种方法;设计人员也可以选择其他方法来约束 IO。

完善时序分析(Refining the Timing Analysis)

用于约束分析的四个常用命令是:

  • set_case_analysis :在单元的引脚或输入端口上指定常量值。
  • set_disable_timing :中断单元的时序弧。
  • set_false_path :指定实际不存在的路径,这意味着在STA中不需要检查这些路径。
  • set_multicycle_path :指定可能花费超过一个时钟周期的路径。

第8章将详细讨论set_false_pathset_multicycle_path约束。

指定非活动信号(Specifying Inactive Signals)

​ 在设计中,某些信号在芯片的特定模式下会具有恒定值。例如,如果芯片中具有DFT(可测性设计)逻辑,则在正常功能模式下,芯片的TEST引脚将一直为0。为STA指定这样的常量值通常很有用,除了不必报告任何不相关的路径之外,这还有助于减少分析空间。例如,如果未将TEST引脚设置为常数,则可能会存在一些奇怪的长路径,而这些长路径在功能模式下永远不会存在。通过使用set_case_analysis约束来指定此类常数信号。

1
2
3
4
5
6
7
8
9
10
11
set_case_analysis 0 TEST



set_case_analysis 0 [get_ports {testmode[3]}]

set_case_analysis 0 [get_ports {testmode[2]}]

set_case_analysis 0 [get_ports {testmode[1]}]

set_case_analysis 0 [get_ports {testmode[0]}]

​ 如果设计具有多种功能模式,而只需要分析其中一种功能模式,则可以使用set_case_analysis来指定要分析的模式。

1
2
3
4
5
set_case_analysis 1 func_mode[0]

set_case_analysis 0 func_mode[1]

set_case_analysis 1 func_mode[2]

​ 请注意,可以在设计中的任何引脚上指定案例分析。案例分析的另一个常见应用是设计可以在多个时钟上运行,并且适当时钟的选择由多路复用器控制。为了使 STA 分析更容易并减少 CPU 运行时间,对每个时钟选择分别进行 STA 是有益的。图 7-36 显示了多路复用器选择具有不同设置的不同时钟的示例。

img

1
2
3
4
5
set_case_analysis 1 UCORE/UMUX0/CLK_SEL[0]

set_case_analysis 1 UCORE/UMUX1/CLK_SEL[1]

set_case_analysis 0 UCORE/UMUX2/CLK_SEL[2]

​ 第一个 set_case_analysis 导致为 MIICLK 选择 PLLdiv16。 PLLdiv8 的时钟路径被阻塞,不会通过多路复用器传播。因此,没有使用时钟 PLLdiv8 分析时序路径(假设时钟在多路复用器之前没有进行任何翻转)。类似地,最后一个 set_case_analysis 导致为 ADCCLK 选择 SCANCLK,并阻塞 CLK200 的时钟路径。

打破单元格中的时序弧(Breaking Timing Arcs in Cells)

​ 每个单元都有从其输入到输出的时序弧,并且时序路径可能会通过这些时序弧中的其中一个。在某些情况下,单元中的一条路径可能无法发生。例如可能有这样一种情况,其中时钟连接到多路复用器的选择端,而多路复用器的输出是数据路径的一部分。在这种情况下,中断多路复用器选择引脚和输出引脚之间的时序弧可能很有用。图7-37为一个示例,通过多路复用器选择端的路径不是有效的数据路径。可以使用set_disable_timing命令来中断这种时序弧。

1
set_disable_timing -from S -to Z [get_cells UMUX0]

img

​ 由于时序弧不再存在,因此需要分析的时序路径更少。另一个类似用法的例子是禁用触发器的最小时钟脉冲宽度检查。

​ 使用set_disable_timing命令需要格外小心,因为它会删除通过指定引脚的所有时序路径。在可能的情况下,最好使用set_false_pathset_case_analysis命令。

点对点规范(Point-to-Point Specification)

​ 可以通过使用set_min_delayset_max_delay命令来约束点对点路径,这将引脚到引脚之间的路径延迟限制在了命令指定值内。该约束将覆盖所有默认的单周期时序路径以及此类路径的任何多周期路径约束。set_max_delay约束了指定路径的最大延迟,而set_min_delay约束了指定路径的最小延迟。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
set_max_delay 5.0 -to UFF0/D

# All paths to D-pin of flip-flop should take 5ns max.

set_max_delay 0.6 -from UFF2/Q -to UFF3/D

# All paths between the two flip-flops should take a

# max of 600ps.

set_max_delay 0.45 -from UMUX0/Z -through UAND1/A -to UOR0/Z

# Sets max delay for the specified paths.

set_min_delay 0.15 -from {UAND0/A UXOR1/B} -to {UMUX2/SEL}

​ 在上述示例中,需要注意的是,使用非标准的内部引脚将迫使它们成为起点和终点,并在这些点处分割路径。

​ 还可以类似地指定从一个时钟到另一个时钟的点对点约束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
set_max_delay 1.2 -from [get_clocks SYS_CLK] \

-to [get_clocks CFG_CLK]

# All paths between these two clock domains are restricted

# to a max of 1200ps.

set_min_delay 0.4 -from [get_clocks SYS_CLK] \

-to [get_clocks CFG_CLK]

# The min delay between any path between the two

# clock domains is specified as 400ps.

​ 如果路径上有多个时序约束,例如时钟频率约束、set_max_delayset_min_delay,则最严格的那个约束是始终用于检查的约束。多个时序约束可能是先应用某些全局(global)约束,然后再应用某些局部(local)约束。

路径分割(Path Segmentation)

​ 路径分段(path segmentation)是指将时序路径分解为可以进行时序分析的较小路径。

​ 时序路径具有起点和终点,可以使用set_input_delayset_output_delay命令在时序路径上创建其它起点和终点。通常在单元的输出引脚上指定set_input_delay来定义新起点,而通常在单元的输入引脚上指定set_output_delay来定义新终点。这些约束定义了新的时序路径,它是原始时序路径的子集。

​ 考虑图7-38中所示的路径。为SYSCLK定义时钟后,待分析的时序路径即为从UFF0 / CK到UFF1 / D。如果仅对报告从UAND2 / Z到UAND6 / A的路径延迟感兴趣,则可以使用以下两个命令:

1
2
3
4
5
6
7
set STARTPOINT [get_pins UAND2/Z]

set ENDPOINT [get_pins UAND6/A]

set_input_delay 0 $STARTPOINT

set_output_delay 0 $ENDPOINT

img

​ 定义这些约束会导致从UFF0 / CK到UFF1 / D的原始时序路径被分段,并分别在UAND2 / Z和UAND6 / A处创建内部起点和内部终点。现在,时序报告将明确显示此新路径。请注意,还会自动创建另外两条时序路径,一条从UFF0 / CK到UAND2 / Z,另一条从UAND6 / A到UFF1 / D。因此,原始的时序路径已被分为了三个部分,每个部分分别进行时序分析。

​ set_disable_timing、set_max_delay 和 set_min_delay 命令也会导致时序路径被分段。

时序验证(Timing Verification)

描述了时序检查,这个各种时序检查是作为各种时序分析的一部分执行。其中包括amongst others - setup、保持和异步恢复和移除检查。这些时序检查旨在彻底验证被分析设计的时序。

两个主要检查是建立时间检查和保持时间检查。一旦在触发器的时钟引脚上定义了时钟,就会自动推断出该触发器的建立时间检查和保持时间检查。时序检查通常在多种条件下执行,包括最坏情况下的慢速条件和最佳情况下的快速条件。通常,最坏情况下的慢速条件对于建立时间检查至关重要,而最佳情况下的快速条件对于保持时间检查至关重要-尽管保持时间检查也可能在最坏情况下的慢速条件下执行。

本章中给出的示例假设网络延迟为零;这样做是为了简单,不会改变本文提出的概念。

建立时间时序检查(Setup Timing Check)

​ 建立时间检查(setup timing check)验证时钟和触发器的数据引脚之间的时序关系,以便满足建立时间要求。换句话说,建立时间检查确保数据在触发器输入之前在触发器的输入端可用。在时钟的有效边沿到达触发器之前,数据应该稳定一段时间,即触发器的建立时间。这一要求确保数据被可靠地捕获到触发器中。图 8-1 显示了典型触发器的建立时间要求。建立时间检查验证触发器的建立时间要求。

img

​ 通常,有一个发起触发器(用于发起数据的触发器)和捕获触发器(用于捕获数据的触发器),这个捕获触发器的建立时间要求必须满足。建立时间检查将验证从发起触发器到捕获触发器的最长(或最大)路径,这两个触发器的时钟可以相同也可以不同。建立时间检查是从发起触发器中时钟的第一个有效沿到捕获触发器中时钟后面最接近的那个有效沿。建立时间检查将确保上一个时钟周期发起的数据准备好在一个周期后被捕获。

img

​ 现在我们研究一个简单的示例,如图8-2所示,其中发起触发器和捕获触发器具有相同的时钟。时钟CLKM的第一个上升沿在Tlaunch时间后出现在发起触发器的时钟引脚上,由该时钟沿发起的数据出现在触发器UFF1的D引脚的所需时间为Tlaunch + Tck2q + Tdp。时钟CLKM的第二个上升沿(通常在一个周期后检查建立时间)出现在捕获触发器UFF1的时钟引脚上的时间为Tcycle + Tcapture。这两个时间之差必须大于触发器UFF1的建立时间要求,以确保触发器UFF1可靠地捕获数据。

​ 建立时间检查可以用数学公式表示:

​ 其中Tlaunch是发起触发器UFF0的时钟树延迟,Tdp是组合逻辑数据路径的延迟,Tcycle是时钟周期,Tcapture是捕获触发器UFF1的时钟树延迟。

​ 换句话说,数据到达捕获触发器D引脚所花费的总时间必须小于时钟传输到捕获触发器所花费的时间加上时钟周期再减去建立时间要求。

​ 由于建立时间检查受到-max的约束,因此建立时间检查始终使用最长或最大的时序路径。出于同样的原因,通常在延迟最大的慢工艺角(slow corner)下执行建立时间检查。

触发器到触发器路径(Flip-flop to Flip-flop Path)

​ 以下是一份建立时间检查的路径报告:

img

​ 该报告中显示发起触发器(由Startpoint指定)的实例名称为UFF0,由时钟CLKM的上升沿触发。捕获触发器(由Endpoint指定)为UFF1,也由时钟CLKM的上升沿触发。路径组(Path Group)显示它属于路径组CLKM。如上一章所述,设计中的所有路径都基于捕获触发器的时钟归类为路径组。路径类型(Path Type)显示此报告中的延迟均为最大路径延迟,表明这是建立时间检查。这是因为建立时间检查对应于通过逻辑的最大(或最长路径)延迟。注意,保持时间检查对应于通过逻辑的最小(或最短路径)延迟。

Incr列显示了指定端口或引脚的单元或网络延迟增量,Path列显示了数据实际到达和需要到达的路径累积延迟,这是用于此示例的时钟约束:

1
2
3
4
5
6
7
8
9
create_clock -name CLKM -period 10 -waveform {0 5} \

[get_ports CLKM]

set_clock_uncertainty -setup 0.3 [all_clocks]

set_clock_transition -rise 0.2 [all_clocks]

set_clock_transition -fall 0.15 [all_clocks]

​ 启动路径( launch path)需要 0.26ns 才能到达触发器 UFF1 的 D 引脚 - 这是到达捕获触发器输入的时间。捕获边沿(建立时间检查时为一个周期)为10ns。为该时钟指定了 0.3ns 的时钟不确定性(clock uncertainty) - 因此,时钟周期减少了不确定性余量。时钟不确定性包括由于时钟源中的抖动( jitter )和用于分析的任何其他时序裕量而导致的周期时间变化。触发器的建立时间 0.04ns(称为库建立时间library setup time)从总捕获路径中扣除,产生所需的时间为 9.66ns。由于到达时间为 0.26ns,因此该时序路径上存在 9.41ns 的正裕量( positive
slack
)。请注意,所需时间和到达时间之间的差异可能看起来为 9.40 ns - 但实际值​​是 9.41 ns,出现在报告中。之所以存在异常,是因为报告仅显示小数点后两位,而内部计算和存储的值比报告的值具有更高的精度。

​ 时序报告中的时钟网络延迟(clock network delay)是什么?为什么将其标记为ideal?时序报告中的这一行表明时钟树被认为是ideal的,时钟路径中的任何缓冲器(buffer)都假定为零延迟。一旦构建了时钟树,就可以将时钟网络标记为“propagated”,从而使得时钟路径显示实际延迟值,如下一个示例时序报告中所示:0.11ns延迟是发起时钟上的时钟网络延迟,而0.12ns延迟是捕获触发器上的时钟网络延迟。

img

​ 时序路径报告可以选择包含扩展的时钟路径,即明确显示时钟树。这是一个这样的例子。

img

img

​ 请注意,时钟缓冲器 UCKBUF0、UCKBUF1 和 UCKBUF2 出现在上面的路径报告中,并提供了如何计算时钟树延迟的详细信息。

​ 如何计算第一个时钟单元 UCKBUF0 的延迟?如前几章所述,单元延迟是根据单元的输入转换时间和输出电容计算的。因此,问题是在时钟树中第一个单元的输入处使用什么转换时间。可以使用 set_input_transition 命令明确指定第一个时钟单元输入引脚上的转换时间(或转换)。

1
2
3
set_input_transition -rise 0.3 [get_ports CLKM]

set_input_transition -fall 0.45 [get_ports CLKM]

​ 在上面显示的 set_input_transition 命令中,我们将输入上升转换时间指定为 0.3ns,将下降转换时间指定为 0.45ns。在没有输入转换命令的情况下,在时钟树的原点假设理想的转换,这意味着上升和下降转换时间都是 0ns。

​ 时序报告中的“r”和“f”字符表示时钟或数据信号的上升沿(和下降沿)。上一个时序路径报告中显示了一条从UFF0 / Q的下降沿开始到UFF1 / D的上升沿结束的路径。由于UFF1 / D可以为0或1,因此也可以有一条路径在UFF1 / D的下降沿结束。以下就是这样一条路径:

img

img

​ 注意,触发器时钟引脚的边沿(称为有效边沿active edge)保持不变。它只能是上升或下降有效沿,具体取决于触发器是由上升沿触发的还是由下降沿触发的。

​ 什么是时钟源延迟(clock source latency)? 这也被称为插入延迟(insertion delay),是时钟从其源端传播到待分析设计的时钟定义点所花费的时间,如图8-3所示,这对应于设计之外的时钟树延迟。例如,如果该设计是较大模块的一部分,则时钟源延迟是指直到待分析设计时钟引脚为止的时钟树延迟。可以使用set_clock_latency命令明确指定此延迟。

img

1
2
3
set_clock_latency -source -rise 0.7 [get_clocks CLKM]

set_clock_latency -source -fall 0.65 [get_clocks CLKM]

​ 如果没有这样的命令,则假定延迟为 0。这是早期路径报告中使用的假设。请注意,源延迟不会影响设计内部且具有相同启动时钟和捕获时钟的路径。这是因为相同的延迟被添加到启动时钟路径和捕获时钟路径。然而,这种延迟确实会影响经过分析设计的输入和输出的时序路径。

​ 如果没有-source选项,则set_clock_latency命令将定义时钟网络延迟,这是从DUA中时钟定义点到触发器的时钟引脚的延迟。时钟网络延迟用于在建立时钟树之前(即在时钟树综合之前)对通过时钟路径的延迟进行建模。一旦建立了时钟树并标记为了“已传播”(propagated),便会忽略此时钟网络延迟约束。set_clock_latency命令也可用于对从主时钟到其衍生时钟的延迟进行建模,如7.3节所述。当时钟生成逻辑不是设计的一部分时,该命令也可用于建模片外时钟延迟。

触发器路径的输入(Input to Flip-flop Path)

​ 这是通过输入端口到触发器的路径报告示例。图 8-4 显示了与输入路径和时钟波形相关的原理图。

img

img

img

​ 首先要注意的是第一行中的input port clocked by VIRTUAL_CLKM。如7.9节中所述,该时钟可以被认为是驱动设计输入端口INA的虚拟触发器,该虚拟触发器的时钟为VIRTUAL_CLKM。此外,从该虚拟触发器的时钟引脚到输入端口INA的最大延迟指定为2.55ns,在报告中显示为input external delay。可以使用以下SDC命令指定这些参数:

1
2
3
4
5
create_clock -name VIRTUAL_CLKM -period 10 -waveform {0 5}

set_input_delay -clock VIRTUAL_CLKM \

-max 2.55 [get_ports INA]

​ 请注意,虚拟时钟VIRTUAL_CLKM的定义没有与设计中任何引脚相关,这是因为它是在设计之外定义的(它是虚拟的)。输入延迟约束set_input_delay指定了相对于虚拟时钟的延迟。

​ 输入路径从端口INA开始,如何计算连接到端口INA的第一个单元UINV1的延迟呢?一种方法是指定输入端口INA的驱动单元,该驱动单元用于确定驱动强度,从而确定端口INA上的转换时间,然后用于计算单元UINV1的延迟。在输入端口INA上没有任何转换时间约束的情况下,将假定端口上的过渡时间是理想的,即过渡时间为0ns。

1
2
3
set_driving_cell -lib_cell BUFF \

-library lib013lwc [get_ports INA]

​ 图8-4还展示了如何进行建立时间检查。数据必须到达UFF2 / D的时间为9.85ns,但是数据实际到达的时间为2.65ns,因此该报告显示该路径的正裕量为7.2ns。

具有实际时钟的输入路径(Input Path with Actual Clock)

​ 也可以根据实际时钟指定输入到达时间;这些不一定必须针对虚拟时钟进行指定。实际时钟的示例是设计中内部引脚或输入端口上的时钟。图 8-5 描述了一个示例,其中端口 CIN 上的输入约束是相对于输入端口 CLKP 上的时钟指定的。此约束指定为:

1
set_input_delay -clock CLKP -max 4.3 [get_ports CIN]

img

​ 这里是这个约束对应的输入路径报告。

img

img

​ 请注意,起始点(Startpoint)与预期一致,将输入端口的延迟参考时钟指定为了CLKP。

触发器到输出路径(Flip-flop to Output Path)

​ 与上述输入端口约束类似,输出端口可以相对于虚拟时钟或设计的内部时钟、输入时钟端口或输出时钟端口受到约束。这是一个示例,显示了相对于虚拟时钟约束的输出引脚 ROUT。输出约束如下:

1
2
3
4
5
set_output_delay -clock VIRTUAL_CLKP \

-max 5.1 [get_ports ROUT]

set_load 0.02 [get_ports ROUT]

​ 为了确定最后一个单元连接到输出端口的延迟,需要指定该端口上的负载,上面使用了set_load命令来指定输出负载。请注意,端口ROUT可能在DUA内部具有负载,而set_load约束指定的是额外的负载,即来自DUA外部的负载。在没有set_load命令约束的情况下,将假定外部负载的值为0(这可能不现实,因为该设计很可能会在其它设计中使用)。下图8-6显示了具有虚拟时钟的虚拟触发器的时序路径:

img

​ 通过输出端口的路径报告如下所示。

img

img

img

​ 注意,指定的输出延迟在报告中显示为output external delay,其作用类似于虚拟触发器所需的建立时间。

输入到输出路径(Input to Output Path)

​ 设计也可以具有从输入端口到输出端口的纯组合逻辑路径。可以像我们前面看到的输入和输出路径一样,对路径进行约束和时序分析。下图8-7显示了这种路径的一个示例,虚拟时钟同时用于指定输入和输出端口上的约束。

​ 以下是输入和输出延迟约束:

1
2
3
4
5
6
7
set_input_delay -clock VIRTUAL_CLKM \

-max 3.6 [get_ports INB]

set_output_delay -clock VIRTUAL_CLKM \

-max 5.8 [get_ports POUT]

img

​ 以下是一个时序路径报告,它经过从输入INB到输出POUT的组合逻辑。请注意,任何内部时钟延迟(如果存在)都不会对该路径报告产生影响。

img

img

img

频率直方图(Frequency Histogram)

​ 如果要绘制一个典型设计的建立时间裕量与路径数的频率直方图,则如图8-8所示。根据设计的状态(是否进行了优化) ,对于未优化的设计,零裕量(zero slack)线将更靠近右侧,而对于优化后的设计则更趋向于左侧。对于没有时序违例的设计(即没有路径的裕度为负),整个曲线将在零裕量线的右侧。

img

​ 这是一个以文本形式显示的直方图,通常可以由静态时序分析工具生成。

img

​ 前两个索引表示裕量的范围,第三个索引是该裕量范围内的路径数,例如,有941条路径的裕量范围为410ps至415ps。直方图表明该设计没有时序违例的路径,即所有路径均具有正的裕量,而关键路径的裕量值在375ps至380ps之间。

​ 难以满足时序要求的设计会使直方图的驼峰向左偏大,也就是说,许多路径的裕量值接近于零。通过观察频率直方图可以得出的另一结果是:可以进一步优化设计以实现零裕量的可能性,即时序收敛有多困难。如果违例路径的数量少并且负裕量值也很小,则设计相对比较容易满足所需的时序。但是,如果违例路径的数量很大并且负裕量值也很大,则这意味着设计将需要付出很大努力才能满足所需的时序。

保持时间检查(Hold Timing Check)

保持时间检查确保正在改变的触发器输出值不会传递到捕获触发器并在触发器有机会捕获其原始值之前覆盖其输出。此检查基于触发器的保持要求。触发器的保持约束要求被锁存的数据应该在时钟的有效边沿之后的指定时间内保持稳定。图 8-9 显示了典型触发器的保持要求。

img

​ 就像建立时间检查一样,保持时间检查是在发起触发器(发起数据的触发器)和捕获触发器(捕获数据的触发器以及必须满足其保持时间要求的触发器)之间进行保持时间检查的。这两个触发器的时钟可以相同也可以不同。保持检查是从启动触发器时钟的一个有效边沿到捕获触发器的同一时钟边沿。因此,保持检查与时钟周期无关。保持检查在捕获触发器时钟的每个有效边沿上执行。

​ 现在我们来看一个简单的示例,如图8-10所示,其中发起触发器和捕获触发器具有相同的时钟。

img

​ 考虑时钟CLKM的第二个上升沿。时钟上升沿发起的数据需要Tlaunch + Tck2q + Tdp时间到达捕获触发器UFF1的D引脚。时钟的同一边沿需要Tcapture时间才能到达捕获触发器的时钟引脚,目的是使捕获触发器在下一个时钟周期捕获来自发起触发器的数据。如果在同一时钟周期内捕获数据,则捕获触发器中的预期数据(来自上一个时钟周期)将被覆盖,因此保持时间检查旨在确保捕获触发器中的目标数据不会被覆盖。保持时间检查可验证这两个时间之差(捕获触发器的数据到达时间和时钟到达时间)必须大于捕获触发器的保持时间,这样触发器上的数据才不会被覆盖,并且捕获到可靠的数据。

​ 保持时间检查可以用数学公式表示为:

​ 其中Tlaunch是发起触发器的时钟树延迟,Tdp是组合逻辑数据路径中的延迟,Tcapture是捕获触发器的时钟树延迟。换句话说,由时钟边沿发起的数据到达捕获触发器D引脚所需的总时间必须大于时钟同一边沿到达捕获触发器所需的时间加上保持时间。这样可以确保UFF1 / D保持稳定状态,直到触发器的时钟引脚UFF1 / CK时钟上升沿之后的保持时间为止。

​ 保持时间检查对捕获触发器的数据路径施加了最小值(-min)约束,需要确定到捕获触发器D引脚的最快路径。这意味着将始终使用最短时序路径来进行保持时间检查,同样,通常在 fast timing corner下进行保持时间检查。

​ 即使设计中只有一个时钟,时钟树也会导致时钟在发起触发器和捕获触发器处的到达时间大不相同。为了确保可靠的数据捕获,捕获触发器的时钟沿必须在数据可改变之前到达。保持时间检查可确保(见图8-11):

  • 当前数据发起时钟沿(Setup launch edge)的下一个时钟沿发起的数据不被当前数据捕获时钟沿(Setup receiving edge)所捕获。
  • 当前数据发起时钟沿发起的数据不被当前数据捕获时钟沿的前一个时钟沿所捕获。

img

​ 如果发起时钟和捕获时钟都属于同一时钟域,则这两个保持时间检查实质上是相同的。但是,当发起时钟和捕获时钟处于不同频率或处于不同时钟域时,以上两个保持时间检查就有可能是不同的。在这种情况下,最差的保持时间检查就是所要报告的检查。上图8-11说明了这两个保持时间检查。

​ UFF0是发起触发器,UFF1是捕获触发器。建立时间检查在这一个数据发起时钟沿(Setup launch edge)和这一个数据捕获时钟沿(Setup receiving edge)之间。下一个数据发起时钟沿(Subsequent launch edge)不得以太快的速度传播数据,因为这可能会导致这一个数据捕获时钟沿没有时间可靠地捕获这一个数据。此外,这一个数据发起时钟沿同样不得以太快的速度传播数据,因为这可能会导致前一个数据捕获时钟沿(Preceding receiving edge)没有时间可靠地捕获前一个数据。在上述各种情况中,最差情况的保持时间检查对应于最严格的保持时间检查。

​ 稍后将在8.3节和8.8节中分别讨论更通用的时钟,例如用于多周期路径和多频率路径的时钟。讨论内容将涵盖建立时间检查和保持时间检查之间的关系,尤其是如何从建立时间检查中推断出保持时间检查。虽然建立时间违例会导致设计的工作频率降低,但保持时间违例会“杀死”(kill)设计,即设计在任何频率下都无法运行。因此,了解保持时间检查并解决任何违例行为非常重要。

触发器到触发器路径(Flip-flop to Flip-flop Path)

​ 本节基于图 8-2 中描述的示例说明了触发器到触发器的保持路径。以下是第 8.1 节中设置检查路径示例的保持时序检查的路径报告。

img

img

​ 注意,路径类型(Path Type)为最小值(min),表示使用了最短路径的单元延迟值,这对应于保持时间检查。库保持时间(library hold time)指定了触发器UFF1的保持时间。如前3.4节所述,触发器的保持时间也可以为负。请注意,发起和捕获路径都是从时钟CLKM的上升沿(触发器的有效沿)开始计算的。时序报告显示,新数据最早可以到达UFF1、同时又可以安全地捕获上一个时钟周期数据的时间为0.19ns。由于新数据的实际到达时间为0.33ns,因此报告显示正的保持时间裕量(slack)为0.14ns。

​ 图8-12显示了时钟信号到达发起和捕获触发器时钟引脚的时间,以及数据在捕获触发器处的最早允许到达时间和实际到达时间。由于数据实际到达的时间晚于数据所需到达的时间(允许的最早到达时间),因此满足保持时间要求。

img

保持时间裕量计算(Hold Slack Calculation)

​ 需要注意的一点是,为建立时间和保持时间的时序报告计算裕量值的方式有所不同。在建立时间报告中,会计算数据实际到达时间和数据需要到达时间,然后将需要到达时间减去实际到达时间,从而得到建立时间的裕量值。但是,在保持时间报告中,当我们把需要到达时间减去实际到达时间后,负的结果将转化为正的裕量值(表示满足保持时间要求),而正的结果将转化为负的裕量值(表示保持时间违例)。

触发器路径的输入(Input to Flip-flop Path)

​ 接下来描述来自输入端口的保持时序检查。有关示例,请参见图 8-4。输入端口上的最小延迟使用虚拟时钟指定为:

1
2
3
set_input_delay -clock VIRTUAL_CLKM \

-min 1.1 [get_ports INA]

​ 这是保持时间报告。

img

img input external delay中的值为输入延迟约束命令中的指定值。在0时刻的VIRTUAL_CLKM上升沿和CLKM上升沿之间进行保持时间检查。UFF2在不违反其保持时间的情况下捕获数据所需的到达时间为0.25ns,这表明数据应在0.25ns之后到达。由于数据实际上在1.2ns才到达,因此显示出0.95ns的正裕量。

触发器到输出路径(Flip-flop to Output Path)

​ 这是一个输出端口的保持时序检查。有关示例,请参见图 8-6。输出端口命令显示为:

1
2
3
set_output_delay -clock VIRTUAL_CLKP \

-min 2.5 [get_ports ROUT]

​ 输出延迟是相对于虚拟时钟指定的。这是保持时间报告。

img

​ 请注意,output external delay中的值为输出延迟约束命令中的指定值。

触发器到具有实际时钟的输出路径(Flip-flop to Output Path with Actual Clock)

​ 有一条输出端口保持时间检查的路径,如图8-13所示。请注意,最小输出延迟是相对于实际时钟指定的。

1
2
3
set_output_delay -clock CLKP -min 3.5 [get_ports QOUT]

set_load 0.55 [get_ports QOUT]

img

输入到输出路径(Input to Output Path)

​ 这是对输入到输出路径的保持时间检查,如图8-7所示。端口的约束为:

1
2
3
4
5
6
7
8
9
10
11
set_load -pin_load 0.15 [get_ports POUT]

set_output_delay -clock VIRTUAL_CLKM \

-min 3.2 [get_ports POUT]

set_input_delay -clock VIRTUAL_CLKM \

-min 1.8 [get_ports INB]

set_input_transition 0.8 [get_ports INB]

img

​ 输入端口和输出端口上的延迟约束是相对于虚拟时钟指定的,因此,保持时间检查是在该虚拟时钟的上升沿(默认有效沿default active)处执行的。

多周期路径(Multicycle Paths)

​ 在某些情况下,两个触发器之间的数据路径可能需要一个以上的时钟周期才能传播通过逻辑。在这种情况下,这条组合逻辑路径会被定义为多周期路径(multicycle path)。虽然数据还是会在每个时钟沿上都被捕获触发器捕获,但我们需要告知STA在指定数量的时钟周期之后才会出现有效的捕获时钟沿。

​ 图8-14是一个示例。由于数据路径最多需要三个时钟周期,因此应指定三个周期的多周期建立时间检查。为此需要指定如下的多周期建立时间约束:

1
2
3
4
5
6
7
create_clock -name CLKM -period 10 [get_ports CLKM]

set_multicycle_path 3 -setup \

-from [get_pins UFF0/Q] \

-to [get_pins UFF1/D]

img

​ 多周期建立时间约束规定,建立时间检查时从UFF0 / CK到UFF1 / D的路径最多可以花费三个时钟周期,这意味着设计每三个周期才会使用一次UFF1 / Q引脚上输出的数据,而不是每个周期都使用。

​ 以下是一份具有多周期约束的建立时间路径报告:

img

img

img

​ 注意,现在捕获触发器的时钟沿距离发起触发器的时钟沿三个时钟周期,为30ns。

​ 现在,我们来检查一下多周期路径上的保持时间检查。在最常见的情况下,我们希望保持时间检查保持不变(与单周期路径一致),如图8-14所示,这样可使数据在三个时钟周期之内任意进行改变。只有指定多周期保持时间为2,才可以获得与单周期建立时间检查情况相同的保持时间检查。这是因为在没有这样的多周期保持时间约束的情况下,默认的保持时间检查是在建立时间捕获沿的前一个有效时钟沿上执行的,这显然不是我们希望的。我们需要将执行保持时间检查的时钟沿移动到默认时钟沿之前的两个周期,因此指定了多周期保持时间为2。预期的检查如图8-15所示,通过多周期保持时间约束,数据路径的最小延迟可以小于一个时钟周期。

1
2
3
set_multicycle_path 2 -hold -from [get_pins UFF0/Q] \

-to [get_pins UFF1/D]

img

​ 多周期保持时间约束命令中的周期数指定了从默认保持时间检查沿(建立时间捕获沿之前的一个有效沿)需要移回多少个时钟周期。 以下是一份保持时间检查的路径报告:

img

img

img

​ 由于此路径的多周期建立时间约束为3,因此其默认保持时间检查是在建立时间捕获沿之前的有效时钟沿上执行的。在大多数设计中,如果最大路径(或建立时间)需要N个时钟周期,则大于(N-1)个时钟周期的最小路径约束是不可行的。通过指定两个周期的多周期保持时间约束,可以将保持时间检查时钟沿移回到数据发起沿处(即0ns处),如上面的路径报告中所示。

​ 因此在大多数设计中,指定为N(周期)的多周期建立时间约束应伴随着指定为N-1(周期)的多周期保持时间约束。

​ 如果指定了N个周期的多周期建立时间约束,但缺少了相应的N-1个周期的多周期保持时间约束,会发生什么情况呢?在这种情况下,会在建立时间捕获沿之前的一个周期时钟沿上执行保持时间检查。图8-16显示了仅约束多周期建立时间为3个周期时,进行这种保持时间检查的情况。

img

​ 如图所示,这规定了数据只能在建立时间捕获沿之前的一个周期内进行改变。因此,数据路径必须具有至少两个时钟周期的最小延迟才能满足此要求。以下是这种情况的路径报告:

img

img

img

跨时钟域(Crossing Clock Domains)

​ 让我们考虑在周期相同的两个不同时钟之间存在多周期路径的情况。(时钟周期也不同的情况将在本章后面进行介绍)

​ 例子1:

1
2
3
4
5
6
7
create_clock -name CLKM \

-period 10 -waveform {0 5} [get_ports CLKM]

create_clock -name CLKP \

-period 10 -waveform {0 5} [get_ports CLKP]

​ 多周期建立时间约束指定了给定路径的时钟周期数,如图8-17所示。默认建立时间捕获沿总是与发起沿相隔一个时钟周期,约束多周期建立时间为2会使建立时间捕获沿与发起沿相隔2个时钟周期。

img

​ 多周期保持时间约束指定了保持时间检查应该在建立时间捕获沿之前几个时钟周期的时钟沿处执行,无论建立时间发起沿在何处,如图8-18所示。默认的保持时间检查是在建立时间捕获沿之前一个周期的时钟沿处执行的。约束多周期保持时间为1会将保持时间检查放置于默认保持时间检查之前一个周期的时钟沿处,因此变为建立时间捕获沿之前两个周期的时钟沿处。

img

1
2
3
4
5
6
7
8
9
set_multicycle_path 2 \

-from [get_pins UFF0/CK] -to [get_pins UFF3/D]

# Since no -hold option is specified, the default option

# -setup is assumed. This implies that the setup

# multiplier is 2 and the hold multiplier is 0.

​ 这是与多周期约束相对应的建立时间路径报告。

img

​ 请注意,路径报告中指定的路径组始终是捕获触发器的路径组,在本例中为 CLKP。

​ 接下来是保持时间检查的路径报告。由于多周期保持时间约束默认为0,因此将在建立时间捕获沿(20ns)之前一个时钟周期的10ns处进行保持时间检查。

img

​ 以上报告报出了保持时间违例,这可以通过将多周期保持时间约束指定为1来消除。接下来将在一个单独的示例中说明这一点。

​ 例子2:

​ 下面给出了跨两个不同时钟域指定的多周期的另一个示例。

1
2
3
4
5
6
7
8
9
set_multicycle_path 2 \

-from [get_pins UFF0/CK] -to [get_pins UFF3/D] -setup

set_multicycle_path 1 \

-from [get_pins UFF0/CK] -to [get_pins UFF3/D] -hold

# The -setup and -hold options are explicitly specified.

​ 以下是多周期建立时间约束为2时建立时间检查的路径报告:

img

img

​ 以下是多周期保持时间约束为1时保持时间检查的路径报告:

img

​ 请注意,本节中建立和保持检查的示例报告针对相同的时序角(timing corner)。然而,在最坏情况下的慢角(worst-case slow corner)通常最难满足建立时间检查(具有最低的裕量),而在最佳情况下的快速角( best-case fast corner)通常最难满足保持检查(具有最低的裕量)。

伪路径(False Paths)

​ 当设计的功能运行时,某些时序路径可能不真实(或不可能)存在。在执行STA时可以将这些路径设置为伪路径(false path),这样就可以关闭这些路径,那么STA就不会对这些伪路径去进行分析了。

​ 伪路径可能是从一个时钟域到另一个时钟域、从触发器的时钟引脚到另一触发器的输入引脚、通过一个单元的引脚、通过多个单元的引脚或这些情况的组合 。当通过单元的引脚指定了伪路径后,通过该引脚的所有路径都将被忽略,无需进行时序分析。辨别出伪路径的好处在于减少了分析空间,从而使分析可以专注于真实存在的路径,这同样有助于减少分析时间。但是,过多使用-through选项去指定伪路径同样会降低分析的速度。

​ 可以使用set_false_path命令来约束伪路径,以下是一些例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
set_false_path -from [get_clocks SCAN_CLK] \

-to [get_clocks CORE_CLK]

# Any path starting from the SCAN_CLK domain to the

# CORE_CLK domain is a false path.



set_false_path -through [get_pins UMUX0/S]

# Any path going through this pin is false.



set_false_path \

-through [get_pins SAD_CORE/RSTN]]

# The false path specifications can also be specified to,

# through, or from a module pin instance.



set_false_path -to [get_ports TEST_REG*]

# All paths that end in port named TEST_REG* are false paths.



set_false_path -through UINV/Z -through UAND0/Z

# Any path that goes through both of these pins

# in this order is false.

​ 下面给出了一些关于设置伪路径的建议。要在两个时钟域之间设置伪路径,请使用:

1
2
3
set_false_path -from [get_clocks clockA] \

-to [get_clocks clockB]

而不是

1
2
3
set_false_path -from [get_pins {regA_*}/CP] \

-to [get_pins {regB_*}/D]

​ 后者这种方式要慢得多。

​ 另一个建议是尽可能少使用-through选项,因为它增加了运行时不必要的复杂性。仅在绝对有必要且没有替代方法可以指定该伪路径的情况下,才可以使用-through选项。

​ 从优化的角度来看,还有一个建议是不要将一条多周期路径约束为伪路径。如果需要在已知或可预测的时刻对信号进行采样,则无论时间间隔多大,都应使用多周期路径约束,以使路径具有一定的约束条件并进行优化以满足多周期约束。如果把一条许多时钟周期后进行采样的路径指定为了伪路径,则对设计中其余逻辑路径的优化可能会使该路径变长,甚至超出所需的时间。

半周期路径(Half-Cycle Paths)

​ 如果设计中同时具有负边沿触发的触发器(有效时钟沿为下降沿)和正边沿触发的触发器(有效时钟沿为上升沿),则设计中可能存在半周期路径(half-cycle path)。半周期路径可能是从一个触发器的上升沿到另一个触发器的下降沿,或者反过来。图8-19给出了一个示例,其中数据的发起沿在触发器UFF5的时钟下降沿,而数据的捕获沿在触发器UFF3的时钟上升沿。

img

​ 以下是建立时间检查的路径报告:

img

​ 请注意起点(Startpoint)和终点(Endpoint)中的边沿说明。时钟CLKP的下降沿出现在6ns,上升沿出现在12ns。因此,数据需要在半个周期6ns内到达捕获触发器的输入引脚。

​ 虽然在建立时间检查时数据路径仅有半个时钟周期,但额外的半个周期可用于保持时间检查。以下是保持时间检查的路径报告:

img

​ 保持时间检查通常是在捕获沿之前一个周期的捕获沿上执行的。由于捕获沿是在12ns处,因此前一个捕获沿在0ns处,故将在0ns处检查保持时间。这为保持时间检查有效地增加了半个时钟周期的裕量,因此可以看见保持时间检查有较大的正裕量(slack)。

移除时间检查(Removal Timing Check)

移除时间检查( removal timing check)可确保在有效时钟沿与释放异步控制信号之间有足够的时间。该检查可确保有效时钟沿不带来影响,因为异步控制信号将保持有效状态,直到有效时钟沿之后一段撤销时间为止。换句话说,异步控制信号会在有效时钟沿之后被释放(变为无效),因此该时钟沿不会产生任何影响,如图8-20所示。该检查基于的是触发器异步引脚上指定的撤销时间。以下是单元库中与撤销时间检查有关的描述片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pin(CDN) {

. . .

timing() {

related_pin : "CK";

timing_type : removal_rising;

. . .

}

}

img

​ 与保持时间检查一样,该检查也是针对最小路径的,不过是在触发器的异步引脚上。

img

img

img

​ 终点(Endpoint)表明这是移除时间检查,且在触发器UFF6的异步引脚CDN上。该触发器的移除时间在报告中显示为library removal time,值为0.19ns。

​ 所有异步时序检查均被分配给了async_default路径组。

恢复时间检查(Recovery Timing Check)

恢复时间检查(recovery timing check)可确保异步信号变为无效状态的时刻与下一个有效时钟沿之间的时间间隔大于一个最小值。换句话说,此检查可确保在异步信号变为无效状态之后,有足够的时间恢复,以便下一个有效时钟沿可以生效。例如,考虑从异步复位变为无效的时刻到触发器有效时钟沿之间的时间间隔。如果该时间间隔太短即有效时钟沿在复位释放后太早出现,则触发器可能进入未知的状态。恢复时间检查如图8-21所示。该检查基于的是触发器异步引脚上指定的恢复时间,单元库文件中与恢复时间有关的描述片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pin(RSN) {

. . .

timing() {

related_pin : "CK";

timing_type : recovery_rising;

. . .

}

}

img

​ 与建立时间检查一样,该检查也是针对最大路径的,不过是在触发器的异步引脚上。

​ 以下是一份恢复时间检查的路径报告:

img

img

​ 终点(Endpoint)表明这是恢复时间检查,并且触发器UFF6的恢复时间在报告中显示为library recovery time,值为0.09ns。恢复时间检查也属于async_default路径组。

跨时钟域的时序(Timing across Clock Domains)

慢到快时钟域(Slow to Fast Clock Domains)

​ 让我们来对一条从慢速时钟域到快速时钟域的路径来进行建立时间与保持时间检查,如图8-22所示。

img

​ 这是以上示例的时钟定义:

1
2
3
4
5
6
7
create_clock -name CLKM \

-period 20 -waveform {0 10} [get_ports CLKM]

create_clock -name CLKP \

-period 5 -waveform {0 2.5} [get_ports CLKP]

​ 当发射触发器和捕获触发器的时钟频率不同时,STA通过首先确定一个共同的基周期来执行。下面给出了一个使用上述两个时钟进行STA时产生的消息示例。将较快的时钟展开,以获得一个普通周期。

1
2
3
Expanding clock 'CLKP' to base period of 20.00

(old period was 5.00, added 6 edges).

img

​ 图8-23中为建立时间检查。默认情况下,将使用最严格的建立时间边沿去检查,在本例中为5ns处的时钟沿。以下是此时建立时间检查的路径报告:

img

img

​ 请注意,发起时钟沿为0ns,而捕获时钟沿为5ns。

​ 如前所述,保持时间检查与建立时间检查有关,并确保由当前时钟沿发起的数据不会干扰先前数据的捕获。这是保持时间检查的报告:

img

​ 在上面的示例中,我们可以看到发起的数据在捕获时钟的第四个周期可用。让我们假设该设计的目的不是在CLKP的下一个有效沿上就捕获数据,而是在每第4个捕获沿上捕获数据。该假设给触发器之间的组合逻辑路径提供了4个CLKP周期的时间,即20ns。我们可以通过设置以下多周期路径约束来做到这一点:

1
2
3
set_multicycle_path 4 -setup \

-from [get_clocks CLKM] -to [get_clocks CLKP] -end

-end选项指定了多周期4是用于终点(endpoint)或捕获时钟的。此多周期路径约束将建立时间和保持时间检查更改为了图8-24中所示。

img

​ 以下是这种情况下建立时间检查的路径报告:

img

img

​ 上图8-24中也说明了保持时间检查,请注意,保持时间检查是根据建立时间检查而决定的,默认为当前数据捕获沿之前的一个周期。以下是保持时间检查的路径报告。注意,保持时间捕获沿为15ns,比建立时间捕获沿(20ns)早一个周期(5ns)。

img

img

​ 在大多数设计中,这不是理想的时序检查,应将保持时间检查一直移回到数据发起沿所在位置。因此,我们可以约束多周期保持时间为3。

1
2
3
set_multicycle_path 3 -hold \

-from [get_clocks CLKM] -to [get_clocks CLKP] -end

​ 3是指将保持时间检查沿向后移三个CLKP时钟周期,即0ns时刻处。与多周期建立时间约束的区别在于:在多周期建立时间约束中,建立时间捕获沿会从默认的建立时间捕获沿向前移动指定的周期数;而在多周期保持时间约束中,保持时间检查沿会从默认的保持时间检查沿向后移动指定的周期数。-end选项意味着我们想将终点(或捕获边沿)移回指定的周期数,即捕获时钟的周期数。代替-end的另一种选项-start指定了要移动的发起时钟周期数,-end选项指定了要移动的捕获时钟周期数。-end是多周期建立时间约束的默认值,-start是多周期保持时间约束的默认值。

img

​ 使用多周期保持时间约束,可以将保持时间检查的时钟沿往回移,检查效果如图8-25所示。具有多周期保持时间约束的保持时间检查路径报告如下:

img

img 总之,如果指定了N个周期的多周期建立时间,那么很可能还应指定N-1个周期的多周期保持时间。对于慢速到快速时钟域之间的路径,多周期路径约束的一个好经验是使用-end选项。使用此选项,可以根据快速时钟的时钟周期来调整建立时间和保持时间检查。

快到慢时钟域(Fast to Slow Clock Domains)

​ 在本小节中,我们考虑数据路径从快速时钟域到慢速时钟域的示例。使用以下时钟定义时,默认的建立时间和保持时间检查如图8-26所示。

1
2
3
4
5
6
7
create_clock -name CLKM \

-period 20 -waveform {0 10} [get_ports CLKM]

create_clock -name CLKP \

-period 5 -waveform {0 2.5} [get_ports CLKP]

img

​ 总共可能有四种建立时间检查,请参阅图8-26中的Setup1,Setup2,Setup3和Setup4。其中,最严格的是Setup4检查。以下是此最严格检查的路径报告。请注意,数据发起时钟沿为15ns,捕获时钟沿为20ns。

img

img

​ 与建立时间检查类似,总共也可能有四种保持时间检查。图8-26中所示为最严格的保持时间检查,该检查可确保0ns处的捕获沿不捕获0ns处正在发起的数据。以下是这种情况下保持时间检查的路径报告。

img

img

​ 通常,设计人员可以将从快时钟域到慢时钟域的数据路径指定为多周期路径。如果想要放宽建立时间检查,比如为数据路径提供两个快时钟周期,则此多周期路径约束如下:

1
2
3
4
5
6
7
8
9
10
11
set_multicycle_path 2 -setup \

-from [get_clocks CLKP] -to [get_clocks CLKM] -start

set_multicycle_path 1 -hold \

-from [get_clocks CLKP] -to [get_clocks CLKM] -start

# The -start option refers to the launch clock and is

# the default for a multicycle hold.

​ 在这种情况下,图8-27中为用于建立时间和保持时间检查的时钟沿。-start选项指定周期数的单位(在这种情况下为2)是发起时钟周期(在这种情况下为CLKP)。约束多周期建立时间为2会将发起沿移动到默认发起沿之前的一个时钟沿,即在10ns而不是默认的15ns处。多周期保持时间约束确保了在0ns处发起沿发起的数据,不会被0ns处的捕获沿捕获到。

img

​ 以下是建立时间检查的路径报告。与预期一样,发起时钟沿为10ns,捕获时钟沿为20ns。

img

img

​ 以下是保持时间检查的路径报告。保持时间检查是在0ns处执行的,此时捕获时钟和发起时钟均为上升沿。

img

img

​ 与从慢速时钟域到快速时钟域的路径不同,在从快速时钟域到慢速时钟域的路径中,多周期路径约束的一个好经验是使用-start选项,然后再根据快速时钟调整建立时间和保持时间检查。

例子

​ 在本节中,我们将介绍发起和捕获时钟的不同情况,并分别说明如何执行建立时间和保持时间检查。图8-28为所举例子的示意图:

img

半周期路径 - 案例 1(Half-cycle Path - Case 1)

​ 在此示例中,两个时钟具有相同的周期,但相位相反。以下是时钟定义,其波形如图8-29所示。

1
2
3
4
5
6
7
create_clock -name CLKM \

-period 20 -waveform {0 10} [get_ports CLKM]

create_clock -name CLKP \

-period 20 -waveform {10 20} [get_ports CLKP]

img

​ 建立时间检查是从发起沿(0ns)到下一个捕获沿(10ns)的。半个时钟周期的裕量可用于保持时间检查,以验证在20ns处发起的数据是否在10ns处未被捕获沿所捕获。以下是建立时间检查的路径报告。

img

img

​ 以下是保持时间检查的路径报告。

img

img

半周期路径 - 案例2(Half-cycle Path - Case 2)

​ 此示例与情况1类似,不过发起时钟和捕获时钟的相位相反。以下是时钟定义,其波形如图8-30所示。

1
2
3
4
5
6
7
create_clock -name CLKM \

-period 10 -waveform {5 10} [get_ports CLKM]

create_clock -name CLKP \

-period 10 -waveform {0 5} [get_ports CLKP]

img

​ 建立时间检查从5ns的发起时钟沿到10ns的下一个捕获时钟沿。保持时间检查从5ns的发起时钟沿到0ns的捕获时钟沿。以下是建立时间检查的路径报告。

img

以下是保持时间检查的路径报告。

img

快到慢时钟域(Fast to Slow Clock Domain)

​ 在此示例中,捕获时钟是发起时钟的二分频。以下是时钟定义。

1
2
3
4
5
6
7
create_clock -name CLKM \

-period 10 -waveform {0 5} [get_ports CLKM]

create_clock -name CLKP \

-period 20 -waveform {0 10} [get_ports CLKP]

​ 波形如图8-31所示。建立时间检查是从10ns的发起沿到20ns的捕获沿,保持时间检查是从0ns的发起沿到0ns的捕获沿。

img

​ 以下是建立时间检查的路径报告:

img

img

​ 以下是保持时间检查的路径报告:

img

img

慢到快时钟域(Slow to Fast Clock Domain)

​ 在此示例中,捕获时钟速度是发起时钟速度的2倍。图8-32中为建立时间和保持时间检查对应的时钟沿:从发起沿0ns到下一个捕获沿5ns进行建立时间检查,保持时间检查是在建立时间捕获沿前一个周期的捕获沿进行的,也就是说,发起沿和捕获沿都为0ns。

img

以下是建立时间检查的路径报告。

img

以下是保持时间检查的路径报告

img

img

多倍时钟(Multiple Clocks)

整数倍数(Integer Multiples)

​ 在设计中通常会定义多个时钟,这些时钟的频率是彼此的整数倍。在这种情况下,会通过计算所有相关时钟(related clocks)之间的公共基本周期来执行STA(如果两个时钟域之间具有数据路径,则两个时钟相关)。建立公共基本周期的目的是以便所有时钟都同步。

​ 以下是3个相关时钟的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
create_clock -name CLKM \

-period 20 -waveform {0 10} [get_ports CLKM]

create_clock -name CLKQ -period 10 -waveform {0 5}

create_clock -name CLKP \

-period 5 -waveform {0 2.5} [get_ports CLKP]
Expanding clock 'CLKP' to base period of 20.00 (old period was

5.00, added 6 edges).

Expanding clock 'CLKQ' to base period of 20.00 (old period was

10.00, added 2 edges).

​ 分析CLKP和CLKM时钟域之间的路径时,将使用20ns的公共基本周期,如图8-33所示。

img

​ 以下是建立时间检查的路径报告,用于从较快时钟CLKP到较慢时钟CLKM的路径。

img

​ 相应保持时间检查的路径报告如下:

img

img

非整数倍数(Non-Integer Multiples)

​ 考虑当两个频率不是彼此整数倍的时钟域之间存在数据路径的的情况。例如,发起时钟是公共时钟的8分频,而捕获时钟是公共时钟的5分频,如图8-34所示。本节将介绍在这种情况下如何执行建立时间和保持时间检查。

img

​ 以下是时钟定义,其波形如图8-35所示:

1
2
3
4
5
6
7
8
9
create_clock -name CLKM \

-period 8 -waveform {0 4} [get_ports CLKM]

create_clock -name CLKQ -period 10 -waveform {0 5}

create_clock -name CLKP \

-period 5 -waveform {0 2.5} [get_ports CLKP]

img

​ 时序分析会先计算相关时钟的公共周期,然后再将时钟扩展到该公共周期。请注意,仅针对相关时钟(即在它们之间具有时序路径的时钟)去计算公共周期。CLKQ和CLKP之间数据路径的公共周期仅扩展为10ns的公共周期,CLKM和CLKQ之间数据路径的公共周期为40ns,而CLKM和CLKP之间数据路径的公共周期也为40ns。

​ 让我们考虑一条从CLKM时钟域到CLKP时钟域的数据路径,这种情况下时序分析的公共基本周期为40ns。

1
2
3
4
5
6
7
Expanding clock 'CLKM' to base period of 40.00 (old period was

8.00, added 8 edges).

Expanding clock 'CLKP' to base period of 40.00 (old period was

5.00, added 14 edges).

​ 建立时间检查在时钟发起沿和捕获沿之间的最短时间内进行。在我们从CLKM到CLKP的示例路径中,这就是24ns处的时钟CLKM发起沿以及25ns处的时钟CLKP捕获沿。

img

img

​ 以下是保持时间检查的路径报告,最严格的保持时间检查是从0ns处的CLKM发起沿到0ns处的CLKP捕获沿。

img

img

​ 现在,我们对从CLKP时钟域到CLKM时钟域的路径的建立时间进行检查。在这种情况下,最严格的建立时间检查是从15ns处的时钟CLKP发起沿到16ns处的时钟CLKM捕获沿。

img

img

​ 以下是保持时间检查的路径报告,同样,最严格的还是0ns处的检查。

img

img

相移(Phase Shifted)

​ 在以下示例中,两个时钟有90°的相移(phase shift):

1
2
3
create_clock -period 2.0 -waveform {0 1.0} [get_ports CKM]

create_clock -period 2.0 -waveform {0.5 1.5} [get_ports CKM90]

​ 图8-36给出了使用这两个时钟的示例。

img

​ 建立时间检查的路径报告如下:

img

img

​ 0.5ns处的CKM90第一个上升沿是捕获沿,保持时间检查是在建立时间捕获沿之前一个周期的时钟沿处。对于2ns的发起沿,建立时间捕获沿为2.5ns,因此保持时间检查沿就在0.5ns处的前一个捕获沿。保持时间检查的路径报告如下:

img

​ 在第10章中还会介绍其它时序检查,例如数据到数据(data to data)检查和时钟门控(clock gating)检查。

接口分析(Interface Analysis)

​ 本章描述了各种类型的输入和输出路径的时序分析程序,以及几种常用的接口。还描述了特殊接口(如SDRM)的时序分析和源同步接口(如DDR sdram)的时序分析。

IO 接口(IO Interfaces)

​ 本节给出的示例说明了如何定义DUA(设计的芯片)的输入和输出接口的约束。后面的部分提供了SRAM和DDR SDRAM接口的时序约束示例。

输入接口(Input Interface)

​ 大致有两种指定的输入时序的替代方法:

  • 作为 AC 约束的DUA 输入端的波形。
  • 指定外部逻辑到输入的路径延迟。

数字设备的约束分为两部分:DC - 恒定值(静态)和 AC - 变化的波形(动态)。

输入波形约束(Waveform Specification at Inputs)

​ 考虑图 9-1 所示的输入交流约束。约束是输入CIN在时钟CLKP上升沿前4.3ns稳定,值保持稳定直到时钟上升沿后2ns。

img

​ 首先考虑 4.3ns 约束。给定 8ns 的时钟周期(如图 9-1 所示),此要求映射到从虚拟触发器(驱动此输入的触发器)到输入 CIN 的延迟。从虚拟触发器时钟到 CIN 的延迟必须最多为 3.7ns (= 8.0 - 4.3),最大延迟为 3.7ns。这可确保输入 CIN 处的数据在上升沿之前 4.3ns 到达。因此,AC 约束的这一部分可以等效地指定为 3.7ns 的最大输入延迟。

​ AC 约束还指出,输入 CIN 在时钟上升沿后稳定 2ns。这个规范也可以映射到虚拟触发器的延迟,即虚拟触发器到输入CIN的延迟必须至少为2.0ns。因此最小输入延迟指定为 2.0ns。

​ 这里的输入约束为:

1
2
3
4
5
create_clock -name CLKP -period 8 [get_ports CLKP]

set_input_delay -min 2.0 -clock CLKP [get_ports CIN]

set_input_delay -max 3.7 -clock CLKP [get_ports CIN]

​ 以下是这些输入条件下设计的路径报告。首先是建立时间报告。

img

​ 指定的最大输入延迟 (3.7ns) 被添加到数据路径。建立时间检查可确保 DUA 内的延迟小于 4.3ns,并且可以锁存正确的数据。接下来是保持时间报告。

img

img

​ 最小输入延迟被添加到保持检查中的数据路径。该检查确保,时钟边沿后 2ns 处的最早数据变化不会覆盖触发器处的先前数据。

输入路径延迟约束(Path Delay Specification to Inputs)

​ 已知连接到输入的外部逻辑的路径延迟时,指定输入约束是一项简单的任务。添加外部逻辑路径到输入的任何延迟,并使用 set_input_delay 命令指定路径延迟。

​ 图9-2示例输入的外部逻辑路径。添加Tck2q和Tc1延迟以获得外部延迟。知道Tck2q和Tc1后,直接获得输入延迟作为Tck2q Tc1。

img

​ 外部最大和最小路径延迟转换为以下输入约束。

1
2
3
4
5
create_clock -name RCLK -period 10 [get_ports RCLK]

set_input_delay -max 6.2 -clock RCLK [get_ports INIT]

set_input_delay -min 3.0 -clock RCLK [get_ports INIT]

​ 它们的路径报告类似于第8.1节和第8.2节中的路径报告。

​ 注意,当计算设计内部触发器的数据引脚处的到达时间时,最大和最小输入延迟值被添加到数据路径延迟中,这取决于是执行最大路径检查(建立时间)还是最小路径检查(保持时间)。

输出接口(Output Interface)

​ 与输入情况类似,指定输出时序要求大致有两种替代方法:

  • 作为AC约束的DUA输出端所需的波形。
  • 指定外部逻辑的路径延迟。

输出波形约束(Output Waveform Specification)

​ 考虑图9-3所示的输出AC约束,输出QOUT应该稳定在时钟CKP的上升沿之前的输出2ns。此外,输出应在时钟上升沿后1.5ns后才改变。这些约束通常从与QOUT接口的外部块的设置和保持要求中获得。

img

​ 以下是在输出上表达此需求的约束。

1
2
3
4
5
6
7
8
9
create_clock -name CLKP -period 6 -waveform {0 3} [get_ports CLKP}

# Setup delay of virtual flip-flop:

set_output_delay -clock CLKP -max 2.0 [get_ports QOUT]

# Hold time for virtual flip-flop:

set_output_delay -clock CLKP -min -1.5 [get_ports QOUT]

​ 输出的外部路径延迟最大输出路径延迟指定为2.0ns。这将确保数据QOUT在时钟边缘之前的2ns窗口之前发生变化。最小输出路径延迟-1.5ns从虚拟触发器的角度指定了要求,也就是说,为了确保在输出端口 QOUT的1.5ns的保持时间需求。1.5ns的保持时间要求就是set_output_delay中指定的最小值-1.5。

这里是建立时间时序报告。

img

​ 从下一个时钟沿减去最大输出延迟,以确定到达 DUA 输出所需的时间。

​ 接下来是保持时间检查路径报告。

img

​ 从捕获时钟边沿中减去最小输出延迟(-1.5ns),以确定满足保持时间要求的 DUA 输出的最早到达时间。负最小输出延迟要求很常见。

输出的外部路径延迟( External Path Delays for Output)

​ 在这种情况下,明确指定了外部逻辑的路径延迟。请参见图 9-4 中的示例。

img

​ 让我们首先检查建立时间检查。从Tc2_max和Tsetup获得最大输出延迟(set_output_delay max)建立时间。为了检查DUA内部触发器(如UFF0)和虚拟触发器之间输出路径的建立时间要求,将最大输出延迟指定为Tc2_max + Tsetup。

​ 接下来,让我们检查保持时间检查。最小输出延迟(set_output_delay min)设置由Tc2_min和Thold获得。由于捕获触发器的保持时间被添加到捕获时钟路径,最小输出延迟被指定为(Tc2_min-Thold)。

​ 输出上的约束转化为以下内容:

1
2
3
4
5
6
7
8
9
10
11
create_clock -name SCLK -period 5 [get_ports SCLK]

# Setup of the external logic (Tc2_max = 2.5,

# Tsetup = 0.6):

set_output_delay -max 3.1 -clock SCLK [get_ports RDY]

# Hold of the external logic (Tc2_min=1.6, Thold=0.15):

set_output_delay -min 1.45 -clock SCLK [get_ports RDY]

​ 它们的路径报告类似于第8.1节和第8.2节中的路径报告。

窗口内的输出变化(Output Change within Window)

set_output_delay 命令可用于指定输出信号相对于时钟的最大和最小到达时间。本节考虑指定约束的特殊情况,以验证当输出只能在相对于时钟边沿的时序窗口内更改时的场景。在验证源同步接口的时序时,此要求经常出现。

​ 在源同步接口中,时钟也作为输出与数据一起出现。在这种情况下,通常需要时钟和数据之间的时序关系。例如,可能只需要在时钟上升沿附近的特定窗口内更改输出数据。

​ 图 9-5 显示了对源同步接口的示例要求。

img

​ 要求是 DATAQ 的每一位只能在时钟上升沿前 2ns 和时钟上升沿后最多 1ns 的指定窗口内发生变化。这与前几节讨论的输出延迟约束完全不同,后者要求数据引脚在时钟上升沿附近的指定时序窗口中保持稳定。

​ 我们在主时钟为 CLKM 的 CLK_STROBE 上创建一个生成时钟。这是为了帮助指定与此接口要求相对应的时序约束。

1
2
3
4
5
create_clock -name CLKM -period 6 [get_ports CLKM}

create_generated_clock -name CLK_STROBE -source CLKM \

-divide_by 1 [get_ports CLK_STROBE]

​ 使用具有多周期路径约束的建立和保持时间检查的组合来指定窗口要求。时序要求映射到必须在单个上升沿(启动和捕获的同一沿)发生的建立时间检查。因此,我们为建立时间指定了一个多周期为 0。

1
set_multicycle_path 0 -setup -to [get_ports DATAQ]

​ 此外,保持时间检查必须发生在同一边上,因此我们需要为保持时间检查指定 -1(减一)的多周期。

1
set_multicycle_path -1 -hold -to [get_ports DATAQ]

​ 现在指定关于时钟 CLK_STROBE 的输出时序约束。

1
2
3
set_output_delay -max -1.0 -clock CLK_STROBE [get_ports DATAQ]

set_output_delay -min +2.0 -clock CLK_STROBE [get_ports DATAQ]

​ 请注意,输出延迟约束指定的最小值大于最大值。之所以存在这种异常,是因为在这种情况下,输出延迟约束与实际逻辑块不对应。与典型输出接口的情况不同,输出延迟约束对应于输出端的逻辑块,源同步接口中的 set_output_delay 约束只是一种机制,用于验证输出是否被限制在了时钟有效沿附近的指定窗口内才能切换。因此,我们有最小输出延迟约束大于最大输出延迟约束的异常。

​ 这是指定约束的建立时间时序检查路径报告。

img

img

​ 请注意,发射边沿和捕获边沿是相同的时钟边沿,即时间 0。报告显示 DATAQ 在 0.61ns 处发生变化,而 CLK_STROBE 在 0.09ns 处发生变化。由于 DATAQ 可以在 CLK_STROBE 的 1ns 内发生变化,因此在考虑 0.3ns 的时钟不确定性后有 0.18ns 的裕量。

​ 这是检查时钟另一侧边界的保持路径报告。

img

img

​ 通过最小路径分析,DATAQ 到达时间为0.48ns,而 CLK_STROBE 到达时间为 0.09ns。由于要求数据在 CLK_STROBE 之前最多可以更改 2ns 限制,因此在考虑 50ps 的时钟不确定性后,我们得到 2.35ns 的裕量。

​ 源同步接口的另一个示例如图 9-6 所示。在这种情况下,输出时钟是主时钟的 2 分频,并且是数据同步接口的一部分。 POUT 被限制在 QCLKOUT 之前不早于 2ns 且不晚于 QCLKOUT 之后的 1ns 切换。

img

​ 这是约束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create_clock -name CLKM -period 6 [get_ports CLKM}

create_generated_clock -name QCLKOUT -source CLKM -divide_by 2 [get_ports QCLKOUT]

set_multicycle_path 0 -setup -to [get_ports POUT]



set_multicycle_path -1 -hold -to [get_ports POUT]



set_output_delay -max -1.0 -clock QCLKOUT [get_ports POUT]

set_output_delay -min +2.0 -clock QCLKOUT [get_ports POUT]

​ 下面是建立时间时序报告。

img

img

​ 请注意,多周期约束已将建立时间检查移回一个周期,以便在同一时钟沿执行检查。输出 POUT 在 0.61ns处 变化,而时钟 QCLKOUT 在 0.27ns处 变化。鉴于要求在 1ns 内改变,并考虑 0.30ns 的时钟不确定性,我们得到 0.36ns 的裕量。

​ 这是检查切换窗口上的其他约束的保持路径报告。

img

img

​ 路径报告显示,数据在 QCLKOUT 时钟边沿之前 2ns 的允许窗口内发生变化,并且存在 2.17ns 的裕量。

SRAM 接口(SRAM Interface)

​ SRAM 接口中的所有数据传输仅在时钟的有效边沿发生。所有信号都由 SRAM 锁存或仅在有效时钟沿由 SRAM 启动。构成 SRAM 接口的信号包括命令、地址和控制输出总线 (CAC)、双向数据总线 (DQ) 和时钟。在写周期中,DUA 将数据写入 SRAM,数据和地址从 DUA 传输到 SRAM,并在有效时钟沿锁存在 SRAM 中。在读周期中,地址信号仍然从 DUA 到 SRAM,而从 SRAM 输出的数据信号到 DUA。因此地址和控制是单向的,从 DUA 到 SRAM,如图 9-7 所示。 DLL(delay-locked loop延迟锁定环 )通常放置在时钟路径中。 DLL 允许延迟时钟(如有必要),以解决由于 PVT 和其他外部变化引起的跨接口的各种信号的延迟变化。通过考虑这些变化,对于往返 SRAM 的读周期和写周期的数据传输都有很好的时序余量。

​ 图 9-8 显示了典型 SRAM 接口的交流特性。请注意,图9-8中的数据输入和数据输出是指SRAM看到的方向。来自SRAM的Data out是DUA的输入,进入SRAM的Data in是DUA的输出。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# First define primary clock at the output of UPLL0:

create_clock -name PLL_CLK -period 5 [get_pins UPLL0/CLKOUT]

# Next define a generated clock at clock output pin of DUA:

create_generated_clock -name SRAM_CLK \

-source [get_pins UPLL0/CLKOUT] -divide_by 1 \

[get_ports SRAM_CLK]

# Constrain the address and control:

set_output_delay -max 1.5 -clock SRAM_CLK \

[get_ports ADDR[0]]

set_output_delay -min -0.5 -clock SRAM_CLK \

[get_ports ADDR[0]]

. . .

# Constrain the data going out of DUA:

set_output_delay -max 1.7 -clock SRAM_CLK [get_ports DQ[0]]

set_output_delay -min -0.8 -clock SRAM_CLK [get_ports DQ[0]]

# Constrain the data coming into the DUA:

set_input_delay -max 3.2 -clock SRAM_CLK [get_ports DQ[0]]

set_input_delay -min 1.7 -clock SRAM_CLK [get_ports DQ[0]]

​ 这是地址引脚的代表性建立时间路径报告。

img

​ 建立时间检查验证地址信号是否在 SRAM_CLK 边沿之前 1.5ns处(存储器地址引脚的设置时间)到达存储器。

​ 这是同一引脚的保持时间时序路径报告。

img

​ 保持时间检查验证地址信号是否在时钟边沿后 0.5ns 内保持稳定。

DDR SDRAM 接口(DDR SDRAM Interface)

​ DDR SDRAM 接口可以看作是上一节描述的 SRAM 接口的扩展。就像SRAM接口一样,有两条主要的总线。图 9-9 说明了 DUA 和 SDRAM 之间的总线连接和总线方向。第一个总线由命令、地址和控制引脚(通常称为 CAC)组成,使用标准方案在内存时钟的一个时钟沿(或每个时钟周期一次)发送信息。两条双向总线由数据总线 DQ 和数据选通 DQS 组成。 DDR 接口的主要区别在于双向数据选通 DQS。为一组数据信号提供 DQS 选通。这允许数据信号(每字节一个或每半字节一个)与选通信号具有紧密匹配的时序;如果时钟对于整个数据总线是通用的,那么这种紧密匹配对于时钟信号可能是不可行的。双向选通信号 DQS 用于读取和写入操作。选通用于在其两个边沿(下降沿和上升沿或双倍数据速率)上捕获数据。在SDRAM的读模式下,DQ总线源同步于数据选通DQS(而不是存储器时钟),即DQ和DQS从SDRAM发出时是对齐的。在另一个方向,即 DUA 发送数据时,DQS 相移 90 度。请注意,数据 DQ 和选通 DQS 边沿均源自 DUA 内的存储器时钟。

img

​ 如上所述,对于一组 DQ 信号(四位或八位)有一个数据选通 DQS。这样做是为了使 DQ 和 DQS 的所有位之间的偏斜平衡要求更容易。例如,一个字节一个DQS,一组9个信号(8个DQ和一个DQS)需要平衡,这比用时钟平衡72位数据总线要容易得多。

​ 上面的描述不是对 DDR SDRAM 接口的完整解释,尽管足以解释这种接口的时序要求。

​ 图 9-10 显示了典型 DDR SDRAM 接口的 CAC 总线(在 DUA 处)的交流特性。这些建立和保持要求映射到 CAC 总线的以下接口约束。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# DDRCLK is typically a generated clock of the PLL

# clock internal to DUA:

create_generated_clock -name DDRCLK \

-source [get_pins UPLL0/CLKOUT]\

-divide_by 1 [get_ports DDRCLK]



# Set output constraints for each bit of CAC:

set_output_delay -max 0.75 -clock DDRCLK [get_ports CAC]

set_output_delay -min -0.75 -clock DDRCLK [get_ports CAC]

​ 在某些情况下,地址总线可能会驱动比时钟大得多的负载,尤其是在与无缓冲存储器模块接口时。在这种情况下,地址信号比时钟信号具有更大的存储器延迟,这种延迟差异可能导致与图 9-10 中描述的不同的 AC 约束。

​ DQS 和 DQ 的对齐对于读和写周期是不同的。这将在以下小节中进一步探讨。

读取周期(Read Cycle)

​ 在读周期中,存储器输出的数据与 DQS 边沿对齐。波形如图 9-11 所示;图中的 DQ 和 DQS 代表存储器引脚上的信号。数据 (DQ) 由存储器在 DQS 的每个边沿发出,并且 DQ 转换与 DQS 的下降沿和上升沿边沿对齐。

img

​ 由于 DQS 选通信号和 DQ 数据信号名义上彼此对齐,因此 DUA 内的存储器控制器通常使用 DLL(或任何替代方法来实现四分之一周期延迟)来延迟 DQS,从而对齐延迟的DQS 边缘与数据有效窗口的中心。

​ 即使 DQ 和 DQS 名义上在内存中对齐,但 DQ 和 DQS 选通信号可能不再在 DUA 内的内存控制器上对齐。这可能是由于 IO 缓冲器之间的延迟差异以及 PCB 互连走线的差异等因素造成的。

​ 图9-12中为基本的数据读取原理图。上升沿触发的触发器在DQS_DLL的上升沿捕获数据DQ,而下降沿触发的触发器在DQS_DLL的下降沿捕获数据DQ。虽然图中的DQ路径上没有DLL,但某些设计可能在数据路径上也会放置一个DLL。这样可以用来延迟信号(以解决由于PVT或互连走线长度或其它差异引起的变化),以便可以在数据有效窗口的中间准确地采样数据。

img

​ 为了约束控制器上的读取接口,在 DQS 上定义了一个时钟,并在与时钟相关的数据上指定了输入延迟。

1
create_clock -period 5 -name DQS [get_ports DQS]

​ 这假设内存读取接口以 200 MHz 运行(相当于 400 Mbps,因为数据在两个时钟边沿传输),并且对应于每 2.5ns 采样一次的 DQ 信号。由于数据是在两条边上捕获的,因此需要为每条边明确指定输入约束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# For rising clock edge:

set_input_delay 0.4 -max -clock DQS [get_ports DQ]

set_input_delay -0.4 -min -clock DQS [get_ports DQ]

# This is with respect to clock rising edge (default).

# Similarly for falling edge:

set_input_delay 0.35 -max -clock DQS -clock_fall \

[get_ports DQ]

set_input_delay -0.35 -min -clock DQS -clock_fall \

[get_ports DQ]

# The launch and capture are on the same edge:

set_multicycle_path 0 -setup -to UFF0/D

set_multicycle_path 0 -setup -to UFF5/D

​ 输入延迟命令指定了DUA引脚上DQ和DQS沿之间的延迟差,即使这两个信号通常是从存储器中同时输出的,但由于不同存储器的规格,在时序上仍会存在偏差。因此,DUA内的控制器设计应考虑到两个信号之间可能存在偏斜(skew)。以下是两个触发器建立时间检查的路径报告。假设捕获触发器的建立时间要求为0.05ns、保持时间要求为0.03ns,且DLL延迟设置为1.25ns,即四分之一周期 。

img

img

img

​ 保持时间时序报告。

img

img

写周期(Write Cycle)

​ 在写周期中,DQS 边沿与来自 DUA 内的存储器控制器的 DQ 信号有四分之一周期的偏移,因此 DQS 选通可用于捕获存储器中的数据。

​ 图9-13显示了存储器引脚上所需的波形,在存储器引脚处,DQS信号必须与DQ数据窗口的中心对齐。请注意,仍然是由于IO缓冲器延迟不匹配或者PCB互连走线的变化,仅在存储控制器(DUA内部)中对齐DQ和DQS还不足以使这些信号在SDRAM存储器引脚处真正的对齐。因此,DUA通常在写周期中使用额外的DLL去进行控制,以实现DQS和DQ信号之间所需的四分之一周期偏移(offset)。

img

​ 约束此模式的输出取决于在控制器中生成时钟的方式。我们考虑两种情况。

情况 1:内部 2x 时钟(Case 1: Internal 2x Clock)

​ 如果有两倍于 DDR 时钟频率的内部时钟可用,则输出逻辑可以类似于图 9-14 中所示的逻辑。 DLL 提供了一种机制,可在必要时偏移 DQS 时钟,以便满足存储器引脚上的建立和保持要求。在某些情况下,可能不使用 DLL - 而是使用负沿触发器来获得 90 度偏移。

img

​ 对于图 9-14 所示的场景,输出可以被约束为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 166MHz (333Mbps) DDR; 2x clock is at 333MHz:

create_clock -period 3 [get_ports CLK2X]

# Define a 1x generated clock at the output of flip-flop:

create_generated_clock -name pre_DQS -source CLK2X \

-divide_by 2 [get_pins UFF1/Q]

# Create the delayed version as DQS assuming 1.5ns DLL delay:

create_generated_clock -name DQS -source UFF1/Q \

-edges {1 2 3} -edge_shift {1.5 1.5 1.5} [get_ports DQS]

​ DQ 输出引脚的时序必须相对于生成的时钟 DQS 进行约束。

​ 假设DDR SDRAM的DQ和DQS管脚之间的设置要求分别为DQ的上升沿和下降沿为0.25ns和0.4ns。同样,假设 DQ 引脚的上升沿和下降沿需要 0.15ns 和 0.2ns 的保持时间。 DQS 输出的 DLL 延迟已设置为四分之一周期,即 1.5ns。波形如图 9-15 所示。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
set_output_delay -clock DQS -max 0.25 -rise [get_ports DQ]

# Default above is rising clock.

set_output_delay -clock DQS -max 0.4 -fall [get_ports DQ]

# If setup requirements are different for falling edge of DQS,

# that can be specified by using the -clock_fall option.

set_output_delay -clock DQS -min -0.15 -rise DQ

set_output_delay -clock DQS -min -0.2 -fall DQ

​ 这是通过输出 DQ 的建立时间报告。建立时间检查是从 0ns 时 CLK2X 的上升沿开始,在 1.5ns 时启动 DQ 到 DQS 的上升沿。

img

​ 请注意,上述报告中的四分之一周期延迟出现在了时钟DQS上升沿的第一行中,而不是在DLL实例UDLL0的那行中。这是因为DLL延迟已被建模为了衍生时钟DQS定义的一部分,而不是DLL时序弧中的一部分。

​ 以下是通过输出DQ路径的保持时间检查报告。保持时间检查从3ns处发起DQ的时钟CLK2X上升沿到1.5ns处的DQS前一个上升沿。

img

情况 2:内部 1x 时钟(Case 2: Internal 1x Clock)

​ 当只有内部 1x 时钟可用时,输出电路通常类似于图 9-16 中所示的电路。

img

​ 有两个触发器用于生成 DQ 数据。第一个触发器NEGEDGE_REG由时钟CLK1X的负沿触发,第二个触发器POSEDGE_REG由时钟CLK1X的正沿触发。每个触发器锁存适当的边沿数据,然后使用 CLK1X 作为多路复用器选择多路复用输出该数据。当 CLK1X 为高电平时,触发器 NEGEDGE_REG 的输出被送到 DQ。当 CLK1X 为低电平时,触发器 POSEDGE_REG 的输出被送到 DQ。因此,数据在时钟 CLK1X 的两个边沿到达输出 DQ。请注意,每个触发器都有半个周期将数据传播到多路复用器的输入,以便输入数据在被 CLK1X 边沿选择之前在多路复用器处准备就绪。相关波形如图 9-17 所示。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Create the 1x clock:

create_clock -name CLK1X -period 6 [get_ports CLK1X]

# Define a generated clock at DQS. It is a divide-by-1 of

# CLK1X. Assume a quarter-cycle delay of 1.5ns on UDLL0:

create_generated_clock -name DQS -source CLK1X \

-edges {1 2 3} -edge_shift {1.5 1.5 1.5} [get_ports DQS]

# Define a setup check of 0.25 and 0.3 between DQ and DQS

# pins on rising and falling edge of clock:

set_output_delay -max 0.25 -clock DQS [get_ports DQ]

set_output_delay -max 0.3 -clock DQS -clock_fall \

[get_ports DQ]

set_output_delay -min -0.2 -clock DQS [get_ports DQ]

set_output_delay -min -0.27 -clock DQS -clock_fall \

[get_ports DQ]

​ 建立和保持检查验证从多路复用器到输出的时序。设置检查之一是从多路复用器输入处的 CLK1X 上升沿(启动 NEGEDGE_REG 数据)到 DQS 的上升沿。另一个设置检查是从多路复用器输入(启动 POSEDGE_REG 数据)处的 CLK1X 下降沿到 DQS 的下降沿。类似地,保持检查是从相同的 CLK1X 边沿(如设置检查)到 DQS 的前一个下降沿或上升沿。

​ 这是通过端口 DQ 的建立时间检查报告。检查在选择 NEGEDGE_REG 输出的 CLK1X 的上升沿和 DQS 的上升沿之间进行。

img

img

img

​ 这是通过端口 DQ 的另一个设置时序检查报告。此设置检查在选择 POSEDGE_REG 输出的 CLK1X 下降沿和 DQS 下降沿之间进行。

img

​ 这是通过端口 DQ 的保持时间检查报告。检查在 CLK1X 的上升沿和 DQS 的前一个下降沿之间进行。

img

​ 这是通过端口 DQ 的另一个保持时序检查报告。该检查在 CLK1X 的下降沿和 DQS 的前一个上升沿之间进行。

img

img

​ 虽然上述接口时序分析忽略了任何负载对输出的影响,但可以指定额外的负载(使用 set_load)以获得更高的准确性。然而,STA 可以通过电路模拟来补充,以实现如下所述的稳健 DRAM 时序。

​ DDR 接口的 DQ 和 DQS 信号通常在读取和写入模式下使用 ODT(On-Die Termination),以减少由于 DRAM 和 DUA 的阻抗不匹配引起的任何反射。存在 ODT 终端时,用于 STA 的时序模型无法提供足够的精度。设计人员可以使用另一种机制,例如详细的电路级模拟来验证 DRAM 接口的信号完整性和时序。

视频 DAC 接口(Interface to a Video DAC)

​ 考虑图 9-18,它显示了一个典型的 DAC(Digital to Analog Converter)接口,其中高速时钟正在将数据传输到 DAC 的低速时钟接口。

img

​ 时钟 DAC_CLK 是时钟 XPLL_CLK 的 2 分频。 DAC 建立和保持检查与 DAC_CLK 的下降沿有关。

​ 在这种情况下,建立时间被视为单周期 (XPLL_CLK) 路径,即使从较快时钟域到较慢时钟域的接口可以在必要时指定为多周期路径。如图 9-18 所示,XPLL_CLK 的上升沿发射数据,DAC_CLK 的下降沿捕获数据。这是建立时间报告。

img

​ 请注意,接口是从较快的时钟到较慢的时钟,因此如有必要,可以将其设置为双周期路径。

​ 这是保持时间报告。

img

​ 保持时间检查是在建立时间捕获沿之前一个周期完成的。在这种接口情况下,最关键的保持时间检查是在发起沿和捕获沿重合处执行的,这显示在保持时序报告中。

稳健验证(Robust Verification)

​ 本章描述了特殊的 STA 分析,例如时间借用( time borrowing)、时钟门控(clock gating)和非顺序时序检查(non-sequential timing checks)。此外,还介绍了先进的 STA 概念,例如片上变化(on-chip variation)、统计时序(statistical timing analysis)以及功率与时序之间的权衡。

片上变化(On-Chip Variations)

​ 通常,工艺和各环境参数在芯片的不同部分上可能不一致。由于工艺差异,芯片上不同部分的相同MOS晶体管可能没有相似的特性,这些差异是由于芯片内部的工艺差异引起的。请注意,多个制造批次中的工艺参数差异可能会覆盖慢工艺到快工艺(2.10节中所介绍)。在本节中,我们讨论的是对一个芯片上可能存在的工艺差异(称为局部工艺差异local process variations)的分析,该差异远小于多个制造批次之间的差异(称为全局工艺差异 global process variations)。

​ 除了工艺参数的变化,设计的不同部分也可能会遇到不同的电源电压和温度。因此,同一芯片的两个区域可能不处于相同的 PVT 条件。这些差异可能由许多因素引起,包括:

  • 会影响局部电源电压的沿芯片区域的IR压降变化
  • PMOS或NMOS器件的电压阈值变化
  • PMOS或NMOS器件的沟道长度变化
  • 由于局部热点造成的温度变化
  • 互连金属刻蚀或厚度变化会影响互连电阻或电容

​ 上述 PVT 变化被称为片上变化 (On-Chip Variations,OCV),这些变化会影响芯片不同部分的线延迟和单元延迟。如上所述,OCV 的建模并不是要对晶片与晶片之间可能的 PVT 变化的整个范围进行建模,而是要对单个管芯内局部可能的 PVT 变化进行建模。 OCV 效应通常在时钟路径上更明显,因为它们在芯片中行进的距离更长。考虑局部 PVT 变化的一种方法是在 STA 期间合并 OCV 分析。前几章中描述的静态时序分析是在特定时序角(timing corner)获得时序,而不是对沿芯片的变化进行建模。由于 OCV 对时钟和数据路径的影响可能不同,时序验证可以通过使发射和捕获路径的 PVT 条件略有不同来模拟 OCV 效应。 STA 可以通过降额(derate)特定路径的延迟来包含 OCV 效应,也就是说,通过使这些路径更快或更慢,然后使用这些变化来验证设计的行为。单元延迟或线延迟或两者都可以降额以模拟 OCV 的影响。

​ 我们现在检查 OCV 降额是如何进行建立时间检查的。考虑图 10-1 中所示的逻辑,其中 PVT 条件可以随芯片变化。当启动时钟路径和数据路径具有导致最大延迟的 OCV 条件,而捕获时钟路径具有导致最小延迟的 OCV 条件时,建立时间检查的最差条件发生。请注意,这里的最小和最大是由于裸片上的局部 PVT 变化。

img

对于此示例,以下是建立时间检查,注意此处还不包括任何用于降额延迟的OCV设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
LaunchClockPath + MaxDataPath <= ClockPeriod + CaptureClockPath - Tsetup_UFF1



This implies that the minimum clock period =

LaunchClockPath + MaxDataPath - CaptureClockPath + Tsetup_UFF1



From the figure,



LaunchClockPath = 1.2 + 0.8 = 2.0



MaxDataPath = 5.2



CaptureClockPath = 1.2 + 0.86 = 2.06



Tsetup_UFF1 = 0.35



This results in a minimum clock period of:

2.0 + 5.22.06 + 0.35 = 5.49ns

​ 上述路径延迟对应于没有任何 OCV 降额的延迟值。可以使用 set_timing_derate 规范来降低单元和网络延迟。例如,命令:

1
2
3
set_timing_derate -early 0.8

set_timing_derate -late 1.1

​ 上述命令将最小/最短/最早路径的延迟降低了20%,并将最大/最长/最迟路径的延迟增加了10%。长路径的延迟(例如,用于建立时间检查的数据路径和发起时钟路径或用于保持时间检查的捕获时钟路径)将乘以使用-late选项指定的降额值,而短路径的延迟(例如,用于建立时间检查的捕获时钟路径或用于保持时间检查的数据路径和发起时钟路径)将乘以使用-early选项指定的降额值。如果未指定降额系数,则假定值为1.0。

​ 降额系数将统一应用于所有网络延迟和单元延迟,如果某个应用场景中需要保证单元和网络的降额系数不同,则可以在set_timing_derate命令中使用-cell_delay-net_delay选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Derate only the cell delays - early paths by -10%, and

# no derate on the late paths:

set_timing_derate -cell_delay -early 0.9

set_timing_derate -cell_delay -late 1.0

# Derate only the net delays - no derate on the early paths

# and derate the late paths by +20%:

set_timing_derate -net_delay -early 1.0

set_timing_derate -net_delay -late 1.2

​ 可以使用-cell_check选项来对单元检查(例如建立时间和保持时间)的延迟进行降额。使用此选项时,使用set_output_delay指定的任何输出延迟也将被降额,因为此约束也是输出建立时间要求的一部分。但是,对于使用set_input_delay指定的输入延迟,是不会被降额的。

1
2
3
4
5
6
7
8
9
10
11
12
13
# Derate the cell timing check values:

set_timing_derate -early 0.8 -cell_check

set_timing_derate -late 1.1 -cell_check

# Derate the early clock paths:

set_timing_derate -early 0.95 -clock

# Derate the late data paths:

set_timing_derate -late 1.05 -data

-clock选项仅将降额应用于时钟路径。同样,-data选项仅将降额应用于数据路径。

​ 我们现在将以下降额应用于图 10-1 的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
set_timing_derate -early 0.9

set_timing_derate -late 1.2

set_timing_derate -late 1.1 -cell_check
使用这些降额值,我们得到以下建立时间检查的结果:

LaunchClockPath = 2.0 * 1.2 = 2.4

MaxDataPath = 5.2 * 1.2 = 6.24

CaptureClockPath = 2.06 * 0.9 = 1.854

Tsetup_UFF1 = 0.35 * 1.1 = 0.385

最小时钟周期为

2.4 + 6.241.854 + 0.385 = 7.171ns

​ 在上面的建立时间检查中,存在差异,因为时钟树的公共时钟路径(图 10-1)具有 1.2ns 的延迟,对于启动时钟和捕获时钟的降额不同。时钟树的这一部分对启动时钟和捕获时钟都是通用的,不应以不同的方式降额。对启动和捕获时钟应用不同的降额过于悲观,因为实际上时钟树的这一部分将真正处于一个 PVT 条件下,要么作为最大路径,要么作为最小路径(或介于两者之间),但永远不会同时处于同时。对时钟树公共部分应用不同降额因子引起的悲观情绪称为公共路径悲观情绪(Common Path Pessimism,CPP),在分析过程中应将其去除。 CPPR 代表 Common Path Pessimism Removal,通常在路径报告中作为单独的项目列出。它也被标记为时钟重新收敛悲观消除Clock Reconvergence Pessimism Removal,CRPR)

​ CPPR 是在时序分析中去除启动时钟路径和捕获时钟路径之间人为引起的悲观情绪。如果相同的时钟同时驱动捕获和启动触发器,那么时钟树可能会在分支之前共享一个公共部分。由于启动和捕获时钟路径的降额不同,CPP 本身就是沿时钟树的这个公共部分的延迟差异。时钟信号在公共点的最小和最大到达时间之间的差值是 CPP。公共点( common point)定义为时钟树公共部分中最后一个单元的输出引脚。

1
CPP = LatestArrivalTime@CommonPointEarliestArrivalTime@CommonPoint

​ 上述分析中的“最晚时间”和“最早时间”是指在特定工艺角(Corner)下的OCV降额值,例如最坏情况下的慢速(Worst-Case-Slow)或最佳情况下的快速(Best-Case-Fast)。对于图10-1的示例:

1
2
3
4
5
6
7
8
9
LatestArrivalTime@CommonPoint = 1.2 * 1.2 = 1.44

EarliestArrivalTime@CommonPoint = 1.2 * 0.9 = 1.08

This implies a CPP of: 1.44 - 1.08 = 0.36ns

With the CPP correction, this results in a

minimum clock period of: 7.171 - 0.36 = 6.811ns

​ 应用OCV降额将本示例设计的最小时钟周期从5.49ns增加到6.811ns。这说明,由这些降额系数模拟的OCV变化可降低设计的最大运行频率。

在最坏 PVT 条件下使用 OCV 进行分析(Analysis with OCV at Worst PVT Condition)

​ 如果在最坏的 PVT 条件下执行建立时序检查,则不需要对后期路径进行降额,因为它们已经是最差的。但是,可以通过使用特定的降额来使这些路径更快,例如,将早期路径加速 10%,从而将降额应用于早期路径。在最坏情况下慢速corner的降额约束可能类似于:

1
2
3
4
5
6
7
set_timing_derate -early 0.9

set_timing_derate -late 1.0

# Don’t derate the late paths as they are already the slowest,

# but derate the early paths to make these faster by 10%.

​ 上述降额设置用于最坏情况慢速角的最大路径(或setup)检查;因此,后期路径 OCV 降额设置保持在 1.0,以免使其减速超过最坏情况的慢速转角。

​ 下面描述了在最坏情况下慢转角的setup时序检查示例。为以下捕获时钟路径指定了降额约束:

1
2
3
# Derate the early clock paths:

set_timing_derate -early 0.8 -clock

​ 以下是在最坏情况下的慢角执行的setup时序检查路径报告。延迟路径使用的降额报告为Max Data Paths Derating Factor 和 Max Clock Paths Derating Factor。

​ 用于早期路径的降额报告为Min Clock Paths Derating Factor(最小时钟路径降额因子)。

img

​ 请注意,捕获时钟路径降额了 20%。请参阅时序报告中的单元 UCKBUF0。在发射路径中,它具有 56ps 的延迟,而在捕获路径中具有 45ps 的降额延迟。单元 UCKBUF0 在公共时钟路径上,即在捕获时钟路径和启动时钟路径上。由于公共时钟路径不能有不同的降额,因此该公共路径的时序差异 56ps - 45ps = 11ps 将单独校正。这在报告中表现为线路clock reconvergence pessimism。总之,如果要比较这条路径的报告,有和没有降额,人们会注意到只有捕获时钟路径的单元和网络延迟被降额了。

OCV 用于保持检查(OCV for Hold Checks)

​ 我们现在检查如何进行降额以进行保持时序检查。考虑图 10-2 所示的逻辑。如果沿芯片的 PVT 条件不同,当启动时钟路径和数据路径具有导致最小延迟的 OCV 条件时,即当我们有最早的启动时钟时,保持检查的最坏条件发生,并且捕获时钟路径具有导致最大延迟的 OCV 条件,即具有最新的捕获时钟。

img

​ 对于此示例,在以下表达式中指定了保持时序检查 :

​ 将图 10-2 中的延迟值应用于表达式,我们得到(不应用任何降额):

​ 这意味着条件是:

​ 这是真的,因此不存在保持违规。

​ 应用以下降额约束:

1
2
3
4
5
set_timing_derate -early 0.9

set_timing_derate -late 1.2

set_timing_derate -early 0.95 -cell_check

​ 可以得到

1
2
3
4
5
6
7
8
9
10
11
LaunchClockPath = 0.85 * 0.9 = 0.765

MinDataPath = 1.7 * 0.9 = 1.53

CaptureClockPath = 1.00 * 1.2 = 1.2

Thold_UFF1 = 1.25 * 0.95 = 1.1875



Common clock path pessimism: 0.25 * (1.2 - 0.9) = 0.075

​ 通过对启动和捕获时钟路径的公共时钟树应用降额而产生的公共时钟路径悲观情绪也被移除以进行保持时序检查。然后保持检查条件变为:

​ 它小于 0,因此表明存在违反保持的情况,将 OCV 降额因子应用于早期和晚期路径。

​ 通常,保持时序检查在最佳情况下的快速 PVT corner执行。在这种情况下,不需要对早期路径进行降容,因为这些路径已经是最早的可能。但是,可以通过将延迟路径降低特定的降额因子来对延迟路径应用降额,例如,将延迟路径减慢 20%。这个corner的降额约束将类似于:

1
2
3
4
5
6
7
set_timing_derate -early 1.0

set_timing_derate -late 1.2

# Don’t derate the early paths as they are already the

# fastest, but derate the late paths slower by 20%.

​ 在图10-2例子中,

1
2
3
LatestArrivalTime@CommonPoint = 0.25 * 1.2 = 0.30

EarliestArrivalTime@CommonPoint = 0.25 * 1.0 = 0.25

​ 这意味着一个共同的路径悲观性:

​ 以下是使用此降额的示例设计的保持时序检查路径报告。

img

​ 请注意,后期路径的额定值降低了 20%,而早期的路径并未降低额定值。请参阅单元格 UCKBUF0。它在发射路径上的延迟为 56ps,而在捕获路径上的延迟为 67ps - 降额了 20%。 UCKBUF0是公共时钟树上的单元,因此该公共时钟树上因不同降额引入的悲观情绪为,67ps - 56ps = 11ps,在线clock reconvergence pessimism中单独考虑。

时间借用(Time Borrowing)

​ 时间借用( time borrowing)技术,也称为cycle stealing,发生在锁存器上。在锁存器中,时钟的一个边沿使锁存器透明,也就是说,它打开锁存器,使锁存器的输出与数据输入相同;这个时钟边缘称为开启边沿( opening edge)。时钟的第二个边沿关闭锁存器,即数据输入上的任何更改在锁存器的输出端不再可用;此时钟边沿称为闭合边沿( closing edge)。

​ 通常,数据应该在时钟的有效边沿之前在锁存输入端准备就绪。然而,由于锁存器在时钟有效时是透明的,因此数据到达的时间可能晚于有效时钟边沿,也就是说,它可以从下一个周期借用时间。如果借用了这样的时间,则可用于下一阶段(锁存到另一顺序单元)的时间减少。

​ 图10-3显示了使用主动上升沿借用时间的示例。如果数据DIN在10 ns的CLK上升沿上的锁存器打开之前的时间A准备就绪,则数据在锁存器打开时流向锁存器的输出。如果数据如DIN(延迟)所示在时间B到达,则借用时间Tb。然而,这减少了从锁存器到下一个触发器UFF2的可用时间-而不是整个时钟周期,只有时间Ta可用。

img

​ 锁存器时序的第一条规则是,如果数据在锁存器的开启边缘之前到达,则行为建模与触发器完全相同。起始边沿捕获数据,相同的时钟边沿启动数据作为下一条路径的起始点。

​ 第二个规则适用于数据信号到达时,而锁存器是透明的(在开口和闭合边缘之间)。锁存器的输出,而不是时钟引脚,被用作下一级的启动点。在锁存器结束的路径借用的时间量决定了下一阶段的启动时间。

​ 在锁存器的闭合沿之后到达的数据信号是时序冲突。图10-4显示了positive slack, zero slack, 和negative slack (即发生违规时)的数据到达时序区域。

img

img

​ 图10-5(A)显示了具有通向下一级触发器的半周期路径的锁存器的使用。图10-5(B)描述了借用时间场景的波形。时钟周期为10 ns。数据由UFF0在时间0启动,但数据路径需要7 ns。锁闩ULAT1以5 ns的速度打开。因此,从路径ULAT1到UFF1借用2 ns。ULAT1到UFF1路径的可用时间仅为3 ns(5 ns-2 ns)。

​ 接下来,我们将为图10-5(A)中的锁存示例描述三组时序报告,以说明从下一阶段借用的不同时间量。

没有借用时间的示例(Example with No Time Borrowed)

​ 以下是从触发器UFF0到锁存器ULAT1的数据路径延迟小于5 ns时的setup路径报告。

img

img

img

​ 在这种情况下,不需要借用,因为数据在锁存器打开之前及时到达锁存器ULAT1。

有借用时间的示例(Example with Time Borrowed)

​ 下面的路径报告显示了从触发器UFF0到锁存器ULAT1的数据路径延迟大于5 ns的情况。

img

img

​ 在这种情况下,由于在锁存器透明的同时数据变为可用,因此从后续路径借用所需的1.81 ns的延迟,并且仍然满足定时。下面是后续路径的路径报告,显示前一路径已经借用了1.81 ns。

img

有时序违规的示例(Example with Timing Violation)

​ 在这种情况下,数据路径延迟要大得多,只有在锁存器关闭后数据才可用。这显然是timing violation

img

img

img

数据到数据检查(Data to Data Checks)

​ setup和hold检查也可以在任意两个数据引脚之间应用,这两个引脚都不是时钟。一个管脚是约束管脚( constrained pin),其作用类似于触发器的数据管脚,第二个管脚是相关管脚(related pin),其作用类似于触发器的时钟管脚。关于触发器的setup检查的一个重要区别在于,数据到数据setup检查在与启动边沿相同的边沿上执行(与触发器的正常setup检查不同,在触发器的正常setup检查中,捕获时钟边沿通常与启动时钟边沿相差一个周期)。因此,数据到数据setup检查也称为 zero-cycle checkssame-cycle checks

​ 使用 set_data_check 约束指定数据到数据检查。以下是 SDC 约束示例。

1
2
3
set_data_check -from SDA -to SCTRL -setup 2.1

set_data_check -from SDA -to SCTRL -hold 1.5

​ 参见图 10-6。 SDA 是related pin,SCTRL 是 constrained pin。setup数据检查意味着 SCTRL 应在相关引脚 SDA 的边缘之前至少 2.1ns 到达。否则它是数据到数据setup检查违规。hold数据检查指定 SCTRL 应在 SDA 之后至少 1.5ns 到达。如果约束信号早于此约束到达,则它是数据到数据hold检查违规。

img

​ 这种检查在 custom-designed block 中很有用,在这种情况下,可能需要提供一个信号相对于另一个信号的特定到达时间。一种常见的情况是数据信号被使能信号门控,当数据信号到达时,需要保证使能信号稳定。

​ 考虑图 10-7 中所示的 and 单元格。我们假设要求是确保 PNA 在 PREAD 上升沿之前 1.8ns 到达,并且在 PREAD 上升沿之后的 1.0ns 内不应改变。在本例中,PNA 是 constrained pin,PREAD 是related pin。所需的波形如图 10-7 所示。

img

​ 可以使用数据到数据建立和保持检查来指定这样的要求。

1
2
3
set_data_check -from UAND0/A1 -to UAND0/A2 -setup 1.8

set_data_check -from UAND0/A1 -to UAND0/A2 -hold 1.0

​ 这是setup报告。

img

​ setup时间在报告中指定为data check setup time。失败的报告表明 PREAD 需要至少延迟 1.72ns,以确保 PENA 在 PREAD 之前 1.8ns 到达——这是我们的要求

​ 数据到数据setup检查的一个重要方面是,启动constrained pinrelated pin的时钟边沿来自相同的时钟周期(也称为same-cycle checks)。因此,请注意报告中捕获沿 (UDFF0/CK) 的开始时间为 0ns,而不是像setup报告中通常看到的那样晚一个周期。

​ zero-cycle setup check导致保持时序检查与其他保持检查报告不同 - 保持检查不再在同一时钟沿上。下面是用于保持路径报告的 CLKPLL 的时钟约束。

1
2
3
create_clock -name CLKPLL -period 10 -waveform {0 5} \

[get_ports CLKPLL]

img

img

​ 请注意,用于启动related pin以进行保持检查的时钟沿比 constrained pin的启动沿早一个周期。这是因为根据定义,保持检查通常在建立捕获沿之前的一个周期执行。由于constrained pinrelated pin的时钟沿对于数据到数据setup检查是相同的,因此保持检查在启动沿前一个周期完成。

​ 在某些情况下,设计人员可能需要在同一时钟周期内执行数据到数据保持检查。相同的周期保持要求意味着将用于related pin的时钟沿移回受constrained pin的时钟沿所在的位置。这可以通过指定 -1 的多周期来实现。

1
set_multicycle_path -1 -hold -to UAND0/A2

​ 以下是具有此多周期约束的上述示例的保持时序报告。

img

img

​ 现在,对constrained pin 和 the related pin使用相同的时钟沿执行保持检查。在同一周期中执行数据到数据保持检查的另一种方法是将其指定为反向引脚之间的数据到数据setup检查。

1
set_data_check -from UAND0/A2 -to UAND0/A1 -setup 1.0

​ 数据到数据检查在定义no-change data check时也很有用。这是通过在上升沿指定setup检查和在下降沿指定保持检查来完成的,以便有效定义不变窗口。如图 10-8 所示。

img

​ 以下是此方案的约束:

1
2
3
set_data_check -rise_from D2 -to D1 -setup 1.2

set_data_check -fall_from D2 -to D1 -hold 0.8

非顺序检查(Non-Sequential Checks)

​ 单元或宏的(cell 和 macro)库文件可以将时序弧指定为非顺序检查(non-sequential check),例如两个数据引脚之间的时序弧。非顺序检查是两个引脚之间的检查,这两个引脚都不是时钟。一个引脚是constrained pin,其作用类似于数据,而第二个引脚是related pin,其作用类似于时钟。该检查指定在related pin上发生变化之前和之后,constrained pin上的数据必须保持稳定多长时间。

​ 请注意,此检查被指定为单元库约束的一部分,并且不需要显式数据到数据检查约束。以下是这样的时间弧如何出现在单元库中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
pin (WEN) {

timing () {

timing_type: non_seq_setup_rising;

intrinsic_rise: 1.1;

intrinsic_fall:1.15;

related_pin: “D0”;

}

timing () {

timing_type: non_seq_hold_rising;

intrinsic_rise: 0.6;

intrinsic_fall:0.65;

related_pin: “D0”;

}

}

​ setup_rising 是指相关管脚的上升沿。固有上升和下降值是指受限引脚的上升和下降设置时间。可以为hold_rising、setup_falling 和hold_falling 定义类似的时序弧。

​ 非顺序检查(non-sequential check)类似于第10.3节中描述的数据对数据检查,但是它们有两个主要区别。在非顺序检查中,建立和保持值从标准单元库中获得,其中建立和保持时序模型可以使用NLDM表格模型或其他高级时序模型来描述。在数据到数据检查中,只能为数据到数据建立或保持检查指定一个值。第二个区别是,非顺序检查只能应用于单元的pin,而数据对数据检查可以应用于设计中的任意两个pin。

非顺序建立检查(non-sequential setup check)指定相对于related pin,受约束信号必须多早到达。如图10-9所示。单元库包含建立时序弧D0->WEN,该弧被指定为非顺序弧。如果WEN信号出现在建立窗口内,则非顺序建立检查失败。

非顺序保持检查(non-sequential hold check)指定相对于related pin,受约束信号必须到达多晚。见图10-9。如果WEN在保持窗口内发生变化,则保持检查失败。

img

时钟门控检查(Clock Gating Checks)

​ 当门控信号(gating signal)可以控制逻辑单元处的时钟信号(clock signal)的路径时,发生时钟门控检查。如图10-10示例。连接到时钟的逻辑单元的引脚称为时钟引脚(clock pin),连接门控信号的引脚称为门控引脚(gating pin)。发生时钟门控的逻辑单元也称为门控单元(gating cell)

img

​ 时钟门控检查的一个条件是通过单元的时钟必须用作下游时钟(clock downstream)。下游时钟使用既可以作为触发器时钟,也可以扇出到输出端口,或者作为生成时钟,将门控单元的输出称为其主时钟。如果时钟不用作门控单元之后的时钟,则不会推断时钟门控检查。

​ 时钟门控检查的另一个条件适用于门控信号。检查的门控引脚上的信号不应是时钟,或者如果是时钟,则不应用作下游时钟(本节后面将包含作为门控信号的时钟示例)。

​ 在一般情况下,时钟信号和门控信号不需要连接到单个逻辑单元,例如and、或or,而是可以是任意逻辑块的输入。在这种情况下,要推断时钟门控检查,检查的时钟引脚和检查的门控引脚必须扇出到公共输出引脚。

​ 推断出两种类型的时钟门控检查:

  • 高电平有效时钟门控检查(Active-high clock gating check):当门控单元具有and 或 nand功能时发生。
  • 低电平有效时钟门控检查( Active-low clock gating check):当门控单元具有 or或 nor功能时发生。

​ 高电平有效和低电平有效是指门控信号的逻辑状态,它激活门控单元输出端的时钟信号。如果门控单元是门控关系不明显的复杂功能,例如多路复用器或异或单元,则 STA 输出通常会提供警告,指出未推断出时钟门控检查。然而,这可以通过使用命令 set_clock_gating_check 明确指定门控单元的时钟门控关系来改变。在这种情况下, 如果set_clock_gating_check 约束与门控单元的功能不一致,STA 通常会提供警告。我们将在本节后面介绍此类命令的示例。

​ 如前所述,只有当时钟不用作下游时钟时,它才能成为门控信号。考虑图 10-11 中的示例。由于 CLKA 的生成时钟的定义,CLKB 不用作下游时钟 - CLKB 的路径被生成的时钟定义阻塞。因此,为and单元推断时钟 CLKA 的时钟门控检查。

img

高电平有效时钟门控(Active-High Clock Gating)

​ 我们现在检查高电平有效时钟门控检查的时序关系。这发生在一个and或一个 nand 单元上;使用and的示例如图 10-12 所示。门控单元的引脚 B 是时钟信号,门控单元的引脚 A 是门控信号。

img

​ 让我们假设时钟 CLKA 和 CLKB 具有相同的波形 。

1
2
3
4
5
6
7
create_clock -name CLKA -period 10 -waveform {0 5} \

[get_ports CLKA]

create_clock -name CLKB -period 10 -waveform {0 5} \

[get_ports CLKB]

​ 因为它是一个and单元,门控信号 UAND0/A 上的高电平打开门控单元并允许时钟通过。时钟门控检查旨在验证门控引脚转换不会为扇出时钟创建有效边沿。对于正边沿触发逻辑,这意味着门控信号的上升沿发生在时钟的非活动周期(低电平时)。类似地,对于负沿触发逻辑,门控信号的下降沿应仅在时钟为低电平时出现。请注意,如果时钟同时驱动正边沿和负边沿触发的触发器,则门控信号(上升沿或下降沿)的任何转换都必须仅在时钟为低电平时发生。图 10-13 显示了需要延迟以通过时钟门控检查的活动边沿期间门控信号转换的示例。

img

​ 高电平有效时钟门控建立检查要求门控信号在时钟变高之前发生变化。这是建立路径报告。

img

img 请注意,端点指示它是时钟门控检查。此外,该路径位于 Path Group中指定的clock_gating_default 路径组中。该检查验证门控信号在 10ns 时钟 CLKB 的下一个上升沿之前发生变化。

​ 高电平有效时钟门控保持检查要求门控信号仅在时钟下降沿之后发生变化。这是保持路径报告。

img

​ 保持门控检查失败,因为门控信号在 5ns 处的 CLKB 下降沿之前变化太快。如果在 UDFF0/Q 和 UAND0/A1 引脚之间添加 5ns 延迟,则建立和保持门控检查都将通过验证门控信号仅在指定window中发生变化。

​ 可以看出,保持时间要求相当大。这是因为门控信号的意义和被门控的触发器是相同的。这可以通过使用不同类型的启动触发器来解决,例如,一个负边沿触发的触发器来生成门控信号。这样的例子如下所示。

​ 在图 10-14 中,触发器 UFF0 由时钟 CLKA 的负沿控制。安全时钟门控意味着触发器 UFF0 的输出必须在门控时钟的非活动部分(5ns 到 10ns 之间)发生变化。

img

​ 对应于图 10-14 中原理图的信号波形如图 10-15 所示。

img

​ 这是时钟门控建立报告。

img

img

img

​ 这是时钟门控保持报告。请注意,新设计更容易满足保持时间检查。

img

​ 由于启动门控信号的时钟沿(负沿)与被门控的时钟(高电平有效)相反,建立和保持要求非常容易满足。这是门控时钟最常用的结构。

低电平有效时钟门控(Active-Low Clock Gating)

​ 图 10-16 显示了低电平有效时钟门控检查的示例。

img

1
2
3
4
5
6
7
create_clock -name MCLK -period 8 -waveform {0 4} \

[get_ports MCLK]

create_clock -name SCLK -period 8 -waveform {0 4} \

[get_ports SCLK]

​ 低电平有效时钟门控检查验证门控信号的上升沿是否到达正沿触发逻辑的时钟的有效部分(当它为高电平时)。如前所述,关键是门控信号不应导致输出门控时钟的有效边沿。当门控信号为高电平时,时钟无法通过。因此,只有当时钟为高电平时,门控信号才应切换,如图 10-17 所示。

img

​ 这是低电平有效时钟门控建立时序报告。此检查可确保门控信号在时钟边沿变为无效之前到达,在本例中为 4ns。

img

img

​ 这是时钟门控保持时序报告。此检查确保门控信号仅在时钟信号的上升沿之后发生变化,在本例中为 0ns。

img

带多路复用器的时钟门控(Clock Gating with a Multiplexer)

​ 图10-18显示了使用多路复用器单元的时钟门控示例。多路复用器输入端的时钟门控检查确保多路复用器选择信号在正确的时间到达,以便在MCLK和TCLK之间干净地切换。对于本例,我们感兴趣的是在MCLK之间切换,并假设在选择信号切换时TCLK较低。这意味着多路复用器的选择信号应仅在MCLK低时切换。这类似于高电平有效时钟门控检查。

img

​ 图 10-19 显示了时序关系。多路复用器的选择信号必须在 MCLK 为低电平时到达。此外,假设选择更改时 TCLK 将为低。

img

​ 由于门控单元是一个多路复用器,因此不会自动推断时钟门控检查,如 STA 期间报告的此消息所示。

img

​ 但是,可以通过提供 set_clock_gating_check 明确强制进行时钟门控检查。

1
2
3
4
5
set_clock_gating_check -high [get_cells UMUX0]

# The -high option indicates an active-high check.

set_disable_clock_gating_check UMUX0/I1

​ 禁用检查(disable check)关闭特定引脚上的时钟门控检查,因为我们不关心该引脚。多路复用器上的时钟门控检查已指定为高电平有效时钟门控检查。这是建立时序路径报告。

img

img

​ 接下来是时钟门控保持时序报告。

img

img

具有时钟反转的时钟门控(Clock Gating with Clock Inversion)

​ 图10-20显示了另一个时钟门控示例,其中触发器的时钟反转,触发器的输出为门控信号。由于门控单元是and单元,因此只有当and单元的时钟信号较低时,门控信号才必须切换。这定义了建立和保持时钟门控检查。

img

​ 这是时钟门控建立时序报告 。

img

img

img

​ 请注意,建立检查会验证数据是否在时间 15ns 的 MCLK 边沿之前发生更改。这是时钟门控保持时序报告。

img

​ 保持检查验证数据(门控信号)是否在时间 10ns 的 MCLK 下降沿之前发生变化。

​ 如果门控单元是复杂单元并且建立和保持检查不明显,则可以使用 set_clock_gating_check 命令指定对时钟信号进行门控的门控信号的建立和保持检查。建立检查验证门控信号在时钟信号的有效边沿之前是否稳定。建立失败会导致门控单元输出出现故障。保持检查验证门控信号在时钟信号的非活动边沿是否稳定。以下是 set_clock_gating_check 约束的一些示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
set_clock_gating_check -setup 2.4 -hold 0.8 \

[get_cells U0/UXOR1]

# Specifies the setup and hold time for the clock

# gating check at the specified cell.

set_clock_gating_check -high [get_cells UMUX5]

# Check is performed on high level of clock. Alternately, the

-low option can be used for an active-low clock gating check.

功耗管理(Power Management)

​ 管理功率是任何设计及其实现方式的一个重要方面。在设计实施期间,设计人员通常需要评估不同的方法,以在设计的速度、功耗和面积之间进行权衡。

​ 如第 3 章所述,设计逻辑部分的功耗由泄漏功率(leakage power)和有功功率(active power)组成。此外,模拟宏和 IO 缓冲器(尤其是那些具有有源端接的)可以消耗与活动无关且不泄漏的功率。在本节中,我们关注设计逻辑部分功耗的权衡。

​ 一般来说,管理由标准单元和内存宏组成的数字逻辑的功率贡献有两个考虑事项:

  • 最小化设计的总有功功率:设计人员将确保总功耗保持在可用功率限制范围内。设计的不同操作模式可能有不同的限制。此外,设计中使用的不同电源也可能有不同的限制。
  • 将设计在待机模式下的功耗降至最低:对于电池供电的设备(例如手机)来说,这是一个重要的考虑因素,其目标是将待机模式下的功耗降至最低。待机模式下的功耗是泄漏功耗加上待机模式下活动逻辑的任何功耗。如上所述,可能有其他模式,例如睡眠模式,对功率有不同的限制。

​ 本节介绍功率管理的各种方法。这些方法中的每一种都有其优点和缺点,本文将对其进行描述。

时钟门控(Clock Gating)

​ 如第 3 章所述,触发器的时钟活动占总功耗的重要组成部分。即使触发器输出不切换,触发器也会由于时钟切换而耗散功率。考虑图 10-21(a) 中的示例,其中触发器仅在使能信号 EN 有效时才接收新数据,否则保持先前状态。在 EN 信号无效期间,触发器的时钟翻转(toggle)不会引起任何输出变化,尽管时钟活动仍会导致触发器内部的功率耗散。时钟门控的目的是,通过在触发器输入无效的clock cycles期间消除触发器的时钟活动来最小化这种贡献。通过时钟门控进行的逻辑重组在触发器引脚处引入了时钟门控。图 10-21 说明了时钟门控引起的转换示例。

img

​ 因此,时钟门控确保触发器的时钟引脚仅在其数据输入端有新数据时才触发。

电源门控(Power Gating)

​ 电源门控涉及关闭电源,以便可以关闭非活动块的电源。此过程如图 10-22 所示,其中添加了一个与电源串联的footer(或header)MOS 器件。配置控制信号 SLEEP ,使得在块的正常操作期间footer(或header)MOS 器件处于开启状态。由于电源门控 MOS 器件(footer or header)在正常操作期间处于开启状态,因此该模块已通电并在正常功能模式下运行。在模块的非活动(或睡眠)模式期间,门控 MOS 器件(footer or header)被关闭,从而消除了逻辑模块中的任何活动功耗。footer是在实际的地与模块的地网络之间的大型NMOS器件,可通过电源门控对其进行控制。header是实际电源和模块的电源网络之间的大型 PMOS 器件,通过电源门控进行控制。在睡眠模式期间,块中唯一耗散的功率是通过footer(或header)设备的泄漏功率。

img

​ footer or header通常使用多个电源门控单元来实现,这些电源门控单元对应于多个并联的 MOS 器件。footer or header设备向电源引入了串联电阻。如果导通电阻值不小,通过门控 MOS 器件的 IR 压降会影响逻辑块中单元的时序。虽然关于门控器件尺寸的主要标准是确保导通电阻值较小,但由于电源门控 MOS 器件决定了非活动或睡眠模式下的泄漏功率,因此需要进行权衡。

​ 总之,应该有足够数量的电源门控单元并联,以确保在有源模式下串联电阻的 IR 降最小。然而,处于非活动或睡眠模式的门控单元的泄漏功率也是选择并联电源门控单元数量的一个标准。

多电压阈值单元(Multi Vt Cells)

​ 如第3章(第3.8节)所述,多电压阈值(Vt)单元用于权衡速度和泄露功率。高Vt单元具有较少的泄露功率,尽管其速度比标准Vt单元慢,标准Vt单元速度更快,但具有较高的泄露功率。类似地,低Vt单元比标准Vt单元快,但泄露功率也相应地更高。

​ 在大多数设计中,目标是在达到所需操作速度的同时将总功率降至最低。尽管泄露功率可能是总功率的重要组成部分,但实现仅使用高Vt单元来减少泄露功率的设计可以增加总功率,即使泄露功率贡献可能会降低。这是因为最终的设计实现可能需要更多(或更高强度)的高Vt单元来实现所需的性能。与使用高Vt单元导致的泄漏功率的降低相比,等效gate数目的增加可以更多地增加有功功率。然而,在某些情况下,泄漏功率是总功率的主要组成部分;在这种情况下,采用高Vt单元的设计可能会导致总功率降低。需要适当地利用具有不同Vt的单元之间在其速度和泄露功率方面的上述权衡,因为它取决于设计及其开关活动曲线。下面说明了高性能块的两个场景,其中实现方法可以根据块是非常活跃的还是具有低切换活动而不同。

具有高活性的高性能块(High Performance Block with High Activity)

​ 这种情况是具有高开关活动的高性能块,并且功率由有功功率支配。对于此类块,仅关注降低泄漏功率会导致总功率增加,即使泄漏功率贡献可被最小化。在这种情况下,初始设计实现应使用标准 Vt(或低 Vt)单元以满足所需的性能。在达到所需的时序后,沿着具有正时序裕量的路径的单元可以更改为高 Vt 单元,从而在仍然满足时序要求的同时减少泄漏贡献。因此,在最终实现中,标准 Vt(或低 Vt)单元仅用于关键或难以实现的时序路径,而沿非关键时序路径的单元可以是高 Vt 单元。

具有低活性的高性能块(High Performance Block with Low Activity)

​ 这种情况是具有非常低开关活动的高性能模块,因此泄漏功率是总功率的重要组成部分。由于模块的活动性较低,因此有功功率不是设计总功率的主要组成部分。对于此类模块,初始实现尝试仅在组合逻辑和触发器中使用高 Vt 单元。一个例外是时钟树,它始终处于活动状态,因此使用标准 Vt(或低 Vt)单元构建。在仅使用高 Vt 单元进行初始实施后,可能存在一些无法实现所需时序的时序路径。然后将沿这些路径的单元替换为标准 Vt(或低 Vt)单元,以实现所需的时序性能。

阱偏置(Well Bias)

阱偏置(well bias)是指在分别用于 NMOS 和 PMOS 器件的 P-well 或 N-well 上添加一个小的电压偏置。图 2-1 所示 NMOS 器件的衬底(或 P 阱)连接通常接地。同样,图 2-1 所示 PMOS 器件的衬底(或 N 阱)连接通常连接到电源 (Vdd) 。

img

​ 如果阱连接具有轻微的负偏压,可以显著降低泄漏功率。这意味着 NMOS 器件的 P 阱连接到一个小的负电压(例如 -0.5V)。同样,PMOS 器件的 Nwell 连接连接到高于电源的电压(例如 Vdd +0.5V)。通过添加阱偏置,单元的速度受到影响;然而,泄漏功率大大减少。单元库中的时序是通过将阱偏置考虑在内而生成的。

​ 使用阱偏置的缺点是P阱和N阱连接需要额外的供电电源(例如-0.5V和Vdd + 0.5V)。

反标(Backannotation)

SPEF

​ STA 如何知道设计的寄生参数是什么?通常,该信息是通过使用寄生提取工具提取的,并且该数据由 STA 工具以 SPEF 的形式读取。附录 C 中描述了 SPEF 的详细信息和格式。

​ 物理设计布局工具内的 STA 引擎的行为也类似,不同之处在于提取信息写入内部数据库。

SDF

​ 在某些情况下,单元和互连的延迟由另一个工具计算,并通过 SDF 为 STA 读取。使用 SDF 的优点是不再需要计算单元延迟和互连延迟——因为它们直接来自 SDF,因此 STA 可以专注于时序检查。但是,这种延迟注释的缺点是由于缺少寄生信息,STA 无法执行串扰计算。 SDF 是通常用于将延迟信息传递给模拟器的机制。

​ SDF 的详细信息和格式在附录 B 中描述。

sign off方法(Sign-off Methodology)

​ STA 可以针对许多不同的场景运行。决定场景的三个主要变量是:

  • 寄生角(Parasitics corners)(RC 互连角和用于寄生提取的操作条件)
  • 操作模式 (Operating mode)
  • PVT 角(PVT corner)

互连寄生角(Parasitic Interconnect Corners)

​ 可以在许多corner提取寄生参数。这些主要取决于制造过程中金属宽度和金属蚀刻的变化。其中一些是:

  • Typical:这是指互连电阻和电容的标称值。
  • Max C:这是指导致最大电容的互连角。互连电阻比 typical corner小。该角会导致短网路径的最大延迟,可用于最大路径分析。
  • Min C:这是指导致最小电容的互连角。互连电阻比 typical corner大。该角导致具有短网络的路径的最小延迟并可用于最小路径分析。
  • Max RC:这是指使互连RC 乘积最大化的互连角。这通常对应于减小走线宽度的较大蚀刻。这导致最大电阻但对应于小于Typical电容。总体而言,对于具有长互连的路径,该角具有最大延迟,可用于最大路径分析。
  • Min RC:这是指使互连RC 乘积最小的互连角。这通常对应于增加走线宽度的较小蚀刻。这导致最小的电阻,但对应于大于Typical电容。总体而言,对于具有长互连的路径,该角具有最小的路径延迟,可用于最小路径分析。

​ 基于上述各个角的互连电阻和电容,具有较大电容的互连角会导致电阻较小,具有较小电容的互连角会导致电阻较大。因此,电阻在一定程度上补偿了各个互连角下的电容。这意味着对于所有类型网络的延迟,没有一个角会真正对应极限情况(最差情况或最佳情况)。使用Cworst / Cbest角下的路径延迟仅对于较短网络是极限情况,而RCworst / RCbest角仅对于较长网络是极限情况,而对于平均长度的网络,Typical互连角通常在路径延迟方面是极限的。因此,设计人员经常会在上述各个互连角下都去验证设计的时序。但是,即使在每个角处都进行了验证也可能无法涵盖所有可能的情况,因为不同的金属层实际上可以独立地处于不同互连角下,例如:METAL2在Max C角下而METAL1在Max RC角下。10.9节中介绍的统计(statistical)时序分析将提出一种静态时序分析的机制,其中不同的金属层可以处于不同的互连角下。

操作模式(Operating Modes)

  • 功能模式1(工作在高速时钟下)
  • 功能模式2(工作在低速时钟下)
  • 功能模式3(睡眠模式)
  • 功能模式4(调试模式)
  • 测试模式1(scan capture)
  • 测试模式2(scan shift)
  • 测试模式3(bist)
  • 测试模式4(jtag)

PVT corner

​ PVT corner指示在什么条件下进行STA分析。最常见的PVT corner是:

  • WCS(慢工艺,低电源,高温)
  • BCF(快工艺,高电源,低温)
  • Typical(典型工艺,额定电源,额定温度)
  • WCL(冷慢工艺,低电源,低温)
  • 或PVT domin中的任何其他点

​ 任何情况下都可以执行STA分析。这里的场景指的是上述互连角、操作模式和PVT corner的组合。

多模式多角分析(Multi-Mode Multi-Corner Analysis)

多模式多角(Multi-mode multi-corner ,MMMC)分析是指同时对多个工作模式、PVT角和寄生互连角进行STA分析。例如,假设DUA有四种工作模式(Normal, Sleep, Scan shift, Jtag),并在三个PVT角(WCS、BCF、WCL)和三个寄生互连角(Typical、Min C、Min RC)进行分析,如表10-23所示。

img

​ 总共有 36 种可能的场景,在这些场景中可以执行所有时序检查,例如建立、保持、转换和时钟门控检查。根据设计的规模,同时为所有 36 个场景运行 STA 在运行时间方面可能会令人望而却步。一个场景可能不需要,因为它可能包含在另一个场景中,或者一个场景可能不需要。例如,设计者可以确定场景 4、6、7 和 9 不相关,因此不需要。此外,可能没有必要在一个corner运行所有模式,例如场景 5 中可能不需要 Scan shift 或 Jtag 模式。 如果多模式多角功能是可用的,则可以在单个场景或多个场景中同时运行 STA可用的。

​ 运行多模式多角 STA 的优点是节省了运行时间和设置分析脚本的复杂性。 MMMC 场景中的额外节省是设计和寄生参数只需加载一次或两次,而不是为每个mode或corner单独加载多次。这样的工作也更适合在 LSF 场上运行它们。多模式多角在优化流程中具有更大的优势,其中优化在所有场景中完成,以便在一个场景中修复时序违规不会在另一个场景中引入时序违规。

​ 对于 IO 约束,-add_delay 选项可以与多个时钟源一起使用,以在一次运行中分析不同的模式,例如扫描或双模式,或对应于不同速度的 PHY(物理层接口 IP 块,例如 10G PHY)中的不同操作模式。通常,每种模式都在单独的运行中进行分析,但并非总是如此。

​ 发现具有大量时钟的设计需要数十次独立运行才能覆盖最大和最小corner的每个模式,并且包括串扰和噪声的影响,这并不罕见。

统计静态时序分析(Statistical Static Timing Analysis)

​ 到目前为止描述的静态时序分析技术是确定性的,因为该分析基于设计中所有时序弧的固定延迟。根据操作条件以及工艺和互连模型计算每个电弧的延迟。虽然可能存在多个mode和多个corner,但是可以确定性地获得给定场景的时序路径延迟。

​ 实际上,执行STA时通常使用的工艺和工作条件的最差情况(WCS)或最佳情况(BCF)对应于极端的3σ角(这里的σ指的是统计建模的自变量的标准差)。时序库基于的是代工厂提供的带有工作条件的工艺角模型,这些条件对应于单元时序值的不同角。例如,使用快速工艺模型、最高电源和最低温度来表征最佳情况的快速时序库。

工艺和互连变化(Process and Interconnect Variations)

全局工艺变化(Global Process Variations)

​ 全局工艺变化(global process variations)(也称为芯片间器件变化inter-die device variations),指的是影响芯片(或晶片)上所有器件的工艺参数的变化。参见图10-24。这描述了芯片上的所有设备都受到这些工艺变化的类似影响-芯片上的每个设备都将变slow或变fast,或者介于两者之间的任何位置。因此,由全局工艺参数建模的变化旨在捕捉不同模具之间的变化。

img

​ 图10-25显示了全局参数值(例如g_par1)的变化。例如,参数g_par1可以对应于标准(这里的标准设备是指长度和宽度固定的设备。)NMOS器件的IDSsat(器件饱和电流)。由于这是一个全局参数,因此芯片上所有单元实例中的所有NMOS器件将对应于相同的g_par1值。可以有如下选择:所有单元实例的g_par1的变化是完全相关的,或者芯片上g_par1的变化相互影响。注意,可能还存在其它全局参数(g_par2,...),其可能可以对PMOS器件饱和电流和其它相关变量建模。

img

​ 不同的全局参数(g_par1、g_par2、.。。。)。是不相关的。不同全局参数中的变化不会相互影响,这意味着g_par1和g_par2参数彼此独立变化;在芯片中,g_par1可能处于最大值,而g_par2可能处于最小值。

​ 在确定性(即非统计性)分析中,慢速工艺模型可能对应于芯片间变化的+ 3σ角的条件。类似地,快速工艺模型可能对应于芯片间变化的-3σ角的条件。

局部工艺变化(Local Process Variations)

​ 局部工艺变化(也称为芯片内器件变化intra-die device variations)指的是工艺参数中的变化,这些变化可能以不同方式影响给定芯片上的器件。参见图10-26。这意味着并排放置的芯片上的相同器件在同一芯片上可能具有不同的行为。由局部工艺变化建模的变化旨在捕捉模具内的随机工艺变化。

img

​ 图10-27显示了局部工艺参数的变化。芯片上的局部参数变化不会相互影响,并且它们从一个单元实例到另一个单元实例的变化是不相关的。这意味着对于同一芯片上的不同器件,局部参数可能具有不同的值。例如,芯片上的不同NAND2单元实例可能会看到不同的局部工艺参数值。这会导致同一NAND2单元的不同实例具有不同的延迟值,即使其他参数(例如输入转换和输出负载)是相同的。

img

​ 图10-28显示了由全局和局部变化引起的NAND2信元延迟的变化。该图说明了全局参数变化比局部参数变化引起的时延变化更大。

img

​ 局部工艺变化是打算在使用 OCV 建模的分析中捕获的变化之一,如第 10.1 节所述。由于统计时序模型通常包括局部工艺变化,使用统计时序模型的 OCV 分析不应包括 OCV 设置中的局部工艺变化。

互连变化(Interconnect Variations)

​ 如第 10.8 节所述,有各种互连角代表影响互连电阻和电容值的每个金属层的参数变化。这些参数变化通常是金属和电介质的厚度,以及影响各种金属层中金属走线的宽度和间距的金属蚀刻。通常,影响金属的参数会影响该金属层中所有走线的寄生效应,但对其他金属层中走线的寄生效应影响很小或没有影响。

​ 第 10.8 节中描述的互连角对互连变化进行建模,以便所有金属层映射到相同的互连角。对互连走线变化进行统计建模时,每个金属层都可以独立地变化。

​ 统计方法对互连空间中所有可能的变化组合进行建模,从而对仅通过在指定的互连角处分析无法捕捉到的变化进行建模。例如,时钟树的启动路径可能在 METAL2 中,而时钟树的捕获路径在 METAL3 中。传统互连corner处的时序分析考虑了所有金属一起变化的各个corner,因此无法模拟 METAL2 位于导致最大延迟的corner而 METAL3 位于导致最小延迟的corner的情况。这种组合对应于设置路径的最坏情况,只能通过对互连变化进行统计建模来捕获。

统计分析(Statistical Analysis)

什么是 SSTA?

​ 如果对单元时序模型和互连寄生进行统计建模,则上述变化的建模是可行的。除了延迟之外,单元输入端的引脚电容值也被统计建模。这意味着时序模型是根据工艺参数(全局和局部)的平均值和标准偏差来描述的。互连电阻和电容是根据互连参数的平均值和标准偏差来描述的。延迟计算程序(在第 5 章中描述)获得每个时序弧(单元以及互连)的延迟,然后用关于各种参数的平均值和标准偏差表示。因此,每个延迟都由平均值和 N 个标准偏差表示(其中 N 是统计建模的独立过程和互连参数的数量)。

​ 由于通过各个时序弧的延迟是用统计形式表示的,因此统计静态时序分析SSTA(Statistical Static Timing Analysis)过程中会结合时序弧的延迟以获得路径延迟,该路径延迟同样会以统计形式表示(具有均值和标准差)。SSTA会根据独立的工艺和互连参数的标准差,来获得路径延迟的总体标准差。例如,考虑由两个时序弧组成的路径延迟,如图10-29所示。由于每个延迟分量都有其变化,因此根据变化是相关的还是不相关的,将对变化进行不同的组合。如果变化来自同一来源(例如,由相互影响的g_par1参数引起),则路径延迟的σ仅等于(σ1 + σ2)。但是,如果变化是不相关的(例如由于l_par1参数),那么路径延迟的σ等于 ,该值小于(σ1 + σ2)。当对局部(不相关的)工艺变化建模时,路径延迟σ较小的现象也称为各个延迟变化的统计抵消(statistical cancellation)

img

​ 对于实际设计,相关和不相关的变化都被建模,因此需要适当组合这两种类型的变化的贡献。

​ 发起和捕获时钟的时钟路径延迟也以相同的统计形式表示。基于数据和时钟路径延迟,可以将裕量(slack)作为具有标准值和标准差的统计量。

​ 假设使用正态分布,可以获得对应于(平均值mean +/- 3σ)的有效最小值和最大值。 (平均值mean -/ + 3σ)对应于图10-30中所示正态分布的0.135%和99.865%的分位数。0.135%的分位数意味着仅0.135%的结果分布小于此值(平均值mean-3σ);同样,99.865%的分位数表示99.865%的结果小于此值,或仅0.135%(100%-99.865%)的结果大于此值(平均值mean+3σ)。有效的下限和上限在SSTA报告中称为分位数(quantile),设计人员可以选择分析中使用的分位数,例如0.5%或99.5%,对应于(平均值mean -/ + 2.576σ)。

img

​ 对于噪声和串扰分析(第 6 章),所使用的路径延迟和时序窗口是根据各种参数的平均值和标准偏差进行统计建模的。

​ 根据路径裕量分布,SSTA会报告每个路径裕量的平均值、标准差和分位数,从而可以根据所需的统计置信度(confidence)来判断时序是通过还是违例。

统计时序库(Statistical Timing Libraries)

​ 在 SSTA 方法中,标准单元库(以及设计中使用的其他宏的库)提供各种环境条件下的时序模型。例如,在最小 Vdd 和高温corner处的分析利用在此条件下表征的库,但对工艺参数进行统计建模。库包括标称参数值以及参数变化的时序模型。对于 N 个工艺参数,在 0.9V 和 125C 电源下表征的统计时序库可能包括以下内容:

  • 具有标准工艺参数的时序模型,加上以下关于每个工艺参数的信息
  • 参数i为(标准值+1σ)的时序模型,其他参数保持为标准值
  • 参数i为(标准值-1σ)的时序模型,其他参数保持为标准值

​ 对于具有两个独立工艺参数的简化示例场景,时序模型的特征在于标称参数值以及参数值的变化,如图 10-31 所示。

img

统计互连变化(Statistical Interconnect Variations)

​ 每个金属层有三个独立的参数:

  • 金属刻蚀( Metal etch):这可以控制金属宽度以及与相邻导体的间距。金属层中的大刻蚀减小了宽度(这增加了电阻)并增加了到相邻走线的间距(这减小了到相邻走线的耦合电容)。该参数表示为导体宽度的变化。
  • 金属厚度( Metal thickness):较厚的金属意味着与下面各层的电容更大。该参数表示为导体厚度的变化。
  • IMD厚度(金属间介电层厚度,Inter Metal Dielectric thickness):较大的IMD厚度会减少与下面各层的耦合。该参数表示为IMD厚度的变化。

SSTA 结果(SSTA Results)

​ 统计分析中输出的结果将根据平均值和角的有效值来提供路径的裕量。以下是用于建立时间检查(最大路径分析)的SSTA报告示例:

img

img

​ 上面的报告显示,尽管时序路径的均值满足要求,但0.135%的分位数却有0.43ns的时序违例,时序路径裕量的分位数为-0.43ns。时序路径裕量的平均值为+ 0.86ns,标准差为0.43ns,这意味着+/- 2σ的分布结果满足要求。由于95.5%的分布落在2σ的变化范围内,这意味着只有2.275%的路径会出现时序违例(其余的2.275%分布具有较大的正裕量)。因此,把分位数设置为2.275%后可以使得裕量为0或没有时序违例。到达时间和路径裕量分布如下图10-32所示:

img

​ 请注意,以上报告是针对建立时间检查的,因此分位数那一列提供的是分位数上限(例如,路径延迟的+ 3σ值),保持时间检查时则会指定为分位数下限(例如-3σ值)。报告中的“sensitiv”列是指敏感度,即标准差与平均值的比值(表示为百分比)。就裕量而言,需要较小的灵敏度,这意味着即使平均值发生变化,以平均值通过的路径也会继续通过。“incr”列中指定了报告中该行的增量标准差。

​ 使用单元和互连走线的统计模型,统计时序方法可以分析各种角条件下的设计,并分析由于工艺和互连参数变化而导致的情况。例如,在最差VT(电压和温度)情况下进行统计分析将分析整个全局工艺和互连走线空间。在最佳VT(电压和温度)情况下的另一种统计分析也将分析整个工艺和互连走线空间。这些分析可以与在最差PVT情况或最佳PVT情况下进行的传统分析进行对比,传统分析仅探讨工艺和互连空间中的单个点。

路径失败时序?(Paths Failing Timing?)

​ 在本节中,我们将提供一些示例,突出显示设计者在调试STA结果期间需要关注的关键方面。这些例子中有几个只包含STA报告的相关摘录 。

未找到路径(No Path Found)

​ 如果用户尝试获取路径报告,而STA报告找不到路径,或者它提供了路径报告但slack时间是无限的,该怎么办?在这两种情况下,出现这种情况可能是因为:

  • 时序路径已断开
  • 该路径不存在
  • 这是一条false path

​ 在上述每种情况下,都需要仔细调试约束以确定是什么约束导致路径被阻塞。一种强力选项是删除所有错误的路径设置和时序中断,然后查看该路径是否可以进行时序分析。(时序中断是从STA中移除时序弧,通过使用set_disable_timing现,如第7.10节所述。)

时钟交叉域(Clock Crossing Domain)

​ 这是路径报告的头部。

img

img

​ 首先要注意的是,该路径从输入端口( input port)开始,在触发器的clear pin结束,并且正在验证clear pin上的恢复检查(参见库恢复时间library recovery time)。接下来要注意的是,路径跨越两个不同的时钟域,SYS_IN_CLK,启动输入的时钟,和 PX9_CLK,触发器的时钟,正在检查其恢复时序。尽管从时序报告中看不出来,但从设计知识来看,可以检查两个时钟是否完全异步以及这两个时钟域之间的任何路径是否应该被视为错误。

​ lesson:验证启动时钟和捕获时钟以及两者之间的路径是否有效。

反向生成时钟(Inverted Generated Clocks)

​ 创建生成时钟时,需要谨慎使用 -invert 选项。如果使用 -invert 选项指定生成的时钟,则 STA 假定指定点的生成时钟属于指定类型。但是根据逻辑,设计中可能不会出现这样的波形。 STA 通常会提供错误或警告消息,指示生成的时钟无法实现,但它会继续分析并报告时序路径。

​ 考虑图 10-33。让我们在单元 UCKBUF0 的输出上定义一个带有 -invert 的生成时钟。

1
2
3
4
5
6
7
create_clock -name CLKM -period 10 -waveform {0 5} \

[get_ports CLKM]

create_generated_clock -name CLKGEN -divide_by 1 -invert \

-source [get_ports CLKM] [get_pins UCKBUF0/C]

img

​ 这是基于上述约束的建立时间时序报告。

img

img

​ 请注意,STA 假设单元 UCKBUF0 输出的波形是时钟 CLKM 的反相时钟。因此,上升沿为 5ns,捕获设置时钟沿为 15ns。除了时钟的上升沿在 5ns 而不是 0ns 的事实之外,从时序报告中看不出有什么问题。应该注意的是,由于错误位于启动和捕获时钟路径的公共部分,因此建立和保持时序检查确实正确执行。 STA产生的警告和错误需要仔细分析和理解。

​ 需要注意的重要一点是,无论是否可实现,STA 都会按照指定的方式创建生成的时钟。

​ 现在让我们尝试使用 -invert 选项将生成的时钟移动到单元 UCKBUF1 的输出,看看会发生什么。

1
2
3
4
5
6
7
create_clock -name CLKM -period 10 -waveform {0 5} \

[get_ports CLKM]

create_generated_clock -name CLKGEN -divide_by 1 -invert \

-source [get_ports CLKM] [get_pins UCKBUF1/C]

​ 这是setup报告。

img

img

​ 该路径看起来像半周期路径,但这是不正确的,因为在实际逻辑中时钟路径上没有反转。 STA 再次假设 UCKBUF1/C 引脚上的时钟是 create_generated_clock 命令中指定的时钟。因此上升沿发生在 5ns。捕获时钟边沿正在运行时钟 CLKM,其下一个上升沿发生在 10ns。下面的保持路径报告也包含与建立路径类似的差异。

img

img

​ 通常,STA 输出将包括错误或警告,指示生成的时钟不可实现。调试此类不正确路径的最佳方法是实际绘制捕获触发器和启动触发器处的时钟波形,并尝试了解所显示的边沿是否确实有效。

​ lesson:检查捕获和启动时钟的边沿,看看它们是否确实是它们应该的样子。

缺少虚拟时钟延迟(Missing Virtual Clock Latency)

​ 考虑以下路径报告。

img

img

​ 它是从输入引脚开始的路径。请注意,起始到达时间列为 0。这表明时钟 VCLKM 上没有指定延迟 - 该时钟用于定义输入引脚 RESET_L 上的输入到达时间;这很可能是一个虚拟时钟,这就是缺少到达时间的原因。

​ lesson:使用虚拟时钟时,请确保在 set_input_delay 和 set_output_delay 约束中指定或考虑了虚拟时钟的延迟。

大 I/O 延迟(Large I/O Delays)

​ 当输入或输出路径有时序违例时,首先要检查的是时钟延迟,该延迟用作指定输入到达时间或输出所需时间的参考。这同样适用于前面所讲的例子。

​ 要检查的第二件事是输入或输出延迟,即输入路径上的输入到达时间或输出路径上的输出所需时间。我们可能会发现这些数值对于目标频率是不现实的。输入到达时间通常是时序报告中数据路径的第一个值,而输出所需时间通常是时序报告中数据路径的最后一个值。

img

​ 在输入失败路径的这个数据路径中,注意输入到达时间为 14ns。在这种特殊情况下,输入到达时间规范存在错误,因为它太大。

​ lesson:在检查输入或输出路径时,检查指定的外部延迟是否合理。

错误的 I/O 缓冲区延迟(Incorrect I/O Buffer Delay)

​ 当路径经过输入缓冲器或输出缓冲器时,约束不正确可能会导致输入或输出缓冲器延迟值较大。在如下所示的情况中,请注意18ns这个较大的输出缓冲器延迟值,这是由于输出引脚上指定的负载值较大导致的。

img

img lesson:注意由不正确的负载规范引起的缓冲区的大延迟。

延迟值不正确(Incorrect Latency Numbers)

​ 当时序路径出现故障时,需要检查的一件事是启动时钟和捕获时钟的延迟是否合理,即确保这些时钟之间的偏差在可接受的范围内。时钟构建期间不正确的延迟规范或不正确的时钟平衡都可能导致启动和捕获时钟路径中的大偏差,从而导致时序违规。

​ lesson:检查时钟偏差是否在合理范围内。

半周期路径(Half-cycle Path)

​ 如前面的示例所述,设计人员需要检查违例路径的时钟域。随之而来的是,设计人员可能需要检查发起和捕获触发器的时钟沿。在某些情况下,可能会发现一个半周期路径(上升沿至下降沿路径或下降沿至上升沿路径)并且可能无法满足半周期路径的时序要求,又或者这些半周期路径不是真实存在的 。

​ lesson:确保数据路径有足够的时间进行传播。

大延迟和转换时间(Large Delays and Transition Times)

​ 一项关键项目是检查沿数据路径的延迟或转换时间的异常大的数值。其中一些可能是由于:

  • 高扇出网络(High-fanout nets):未适当缓冲(buffered)的网络。
  • 较长网络( Long nets):需要在中间插入缓冲器的网络。
  • 低强度单元(Low strength cells):由于在设计中标有“don't touch”,因此未被更换的单元。
  • 存储器路径(Memory paths):这些路径通常会由于存储器输入上的建立时间较长以及存储器输出上的输出延迟较大而导致时序违规。

缺少多周期保持(Missing Multicycle Hold)

​ 对于多周期 N 设置规范,通常会看到缺少相应的多周期 N-1 保持规范。因此,这会导致在工具修复保持违规时插入大量不必要的延迟单元。

​ lesson:在修复之前始终审核保留违规,以确保正在修复的保留违规是真实的。

路径未优化(Path Not Optimized)

​ STA违例也可能出现在尚未优化的路径上,可以通过检查数据路径来确定这种情况。是否存在延迟较大的单元?可以手动改善数据路径的时序吗?也许数据路径需要进一步优化,工具可能正在其它违例路径上工作。

路径仍然不满足时序(Path Still Not Meeting Timing)

​ 如果数据路径具有强驱动能力的单元,而该路径仍然时序违例,则需要检查布线延迟和线负载较高的引脚。这可能是下一个改进方法:也许可以将单元移动得更近一些,从而可以减少线负载和布线延迟。

如果仍然无法满足时序怎么办(What if Timing Still Cannot be Met)*

​ 可以利用有用偏斜(useful skew)来帮助时序收敛。有用偏斜是指故意使时钟树失衡的地方,尤其是时序违例路径的发起时钟和捕获时钟路径,从而使时序在该路径上收敛。通常,这意味着可以延迟捕获时钟,以使捕获触发器的时钟在数据准备就绪稍后到达。当然,这假定了后续数据路径(即下一级触发器到触发器的数据路径)上有足够的裕量。

​ 也可以尝试相反的操作,也就是说,可以使发起时钟路径更短,以便更早地发起来自发起触发器的数据,从而帮助满足建立时间要求。同样,只有在前一级触发器到触发器路径具有多余的裕量时,才能做到这一点。

​ 有用偏斜技术不仅可用于修复建立时间违例,还可用于修复保持时间违例。此技术的一个缺点是,如果设计具有多种操作模式,则有用偏斜可能会在另一种模式下引起问题。

验证时序约束(Validating Timing Constraints)

​ 随着芯片尺寸的增长,将越来越依赖静态时序分析所交付的时序。仅依赖STA的风险在于STA取决于时序约束的合理与否。因此,时序约束的验证成为重要的考虑因素。

检查路径例外(Checking Path Exceptions)

​ 有一些工具可以根据设计的结构(网表)检查伪路径和多周期路径的有效性,这些工具会检查指定的伪路径或多周期路径约束是否有效。此外,这些工具还可能可以根据设计的结构生成缺少的伪路径和多周期路径约束。但是,这些工具生成的某些路径例外(path exception)也可能是无效的。这是因为这些工具通常使用形式验证技术(formal verification techniques)通过逻辑结构来确定伪路径或多周期路径,而设计人员对设计的功能行为有更深入的了解。因此,在接受并在STA中使用它们之前,设计人员需要检查工具生成的路径例外。可能还存在其它基于设计语义行为的路径例外,如果工具无法提取此类路径例外,设计者必须手动定义这些路径例外。

​ 时序约束中最大的风险就是路径例外。因此,应在仔细分析设计后确定出伪路径和多周期路径。通常,相比于伪路径,最好使用多周期路径,这确保了该路径至少受到一定程度的约束。如果在已知或可预期的时间会对信号进行采样,则无论信号离时钟沿有多远,都应使用多周期路径,这样静态时序分析至少可以知道一些时序约束的信息。伪路径可能会导致时序优化工具完全忽略这些路径,而实际上,它们确实可能在经过大量时钟周期后才被采样。

检查时钟域交叉(Checking Clock Domain Crossing)

​ 可用工具来确保设计中所有的跨时钟域均有效,这些工具还可以自动生成必要的伪路径约束。这样的工具也可能可以识别出非法(illegal)的跨时钟域,即数据在没有任何时钟同步逻辑的情况下跨越了两个不同时钟域。在这种情况下,这些工具可以提供在需要时自动插入合适的时钟同步逻辑的功能。请注意,并非所有跨异步时钟域都需要时钟同步器,应该取决于数据性质以及是否需要在下一个周期或几个周期后捕获数据。

​ 使用STA检查跨异步时钟域的另一种方法是设置一个很大的时钟不确定度(uncertainty),该不确定度等于采样时钟的周期。这样可以确保至少存在一些时序违例行为,根据这些时序违例行为,可以确定适当的路径例外,或者将时钟同步逻辑添加到设计中。

验证 IO 和时钟约束(Validating IO and Clock Constraints)

​ 验证IO和时钟约束仍然是一个挑战,设计人员会经常进行时序仿真以检查设计中所有时钟的有效性。可以进行系统级时序仿真来验证IO时序,以确保芯片可以与其外围设备通信且没有任何时序问题。

附录A:SDC

本附录将介绍1.7版本的SDC格式,此格式主要用于指定设计的时序约束。它不包含任何特定工具的命令,例如链接(link)和编译(compile)。它是一个文本文件,可以手写或由程序创建,并由程序读取。某些SDC命令仅适用于实现(implementation)或综合(synthesis),但是本附录会列出所有SDC命令。

SDC语法是基于TCL的格式,即所有命令都遵循TCL语法。一个SDC文件会在文件开头包含SDC版本号,其次是设计约束,注释(注释以字符#开始,并在行尾处结束)在SDC文件中可以散布在设计约束中。设计约束中较长的命令行可以使用反斜杠()字符分成多行。

A.1 基本命令

以下是SDC中的基本命令:

current_instance [instance_pathname]

上述命令设置了设计的当前实例,这允许其它命令从该实例中设置或获取属性(attribute)。如果未提供任何参数,则当前实例将成为顶层(top-level)。

例子:

current_instance /core/U2/UPLL

current_instance .. (向上一层)

current_instance (设为顶层)

expr arg1 arg2 ... argn

list arg1 arg2 ... argn

set variable_name value

set_hierarchy_separator separator

上述命令指定了SDC文件中使用的默认层次结构分隔符。在允许的情况下,可以通过在各个SDC命令中使用-hsc选项来覆盖此设置。

例子:

set_hierarchy_separator /

set_hierarchy_separator .

set_units [-capacitance cap_unit] [-resistance res_units] [-time time_unit] [-voltage voltage_unit] [-current current_unit] [-power power_unit]

上述命令指定了SDC文件中使用的单位。

例子:

set_units -capacitance pf -time ps

A.2 对象访问命令

以下命令指定了如何访问设计实例中的对象。

all_clocks命令会返回一个所有时钟的集合:

foreach_in_collection clkvar [all_clocks]

set_clock_transition 0.150 [all_clocks]

all_inputs [-level_sensitive] [-edge_triggered] [-clock clock_name] 命令会返回一个设计中所有输入端口的集合:

set_input_delay -clock VCLK 0.6 -min [all_inputs]

all_outputs [-level_sensitive] [-edge_triggered] [-clock clock_name] 命令会返回一个设计中所有输出端口的集合:

set_load 0.5 [all_outputs]

all_registers [-no_hierarchy] [-clock clock_name] [-rise_clock clock_name] [-fall_clock clock_name] [-cells] [-data_pins] [-clock_pins] [-slave_clock_pins] [-async_pins] [-output_pins] [-level_sensitive] [-edge_triggered] [-master_slave] 命令会返回一个具有指定属性的寄存器的集合:

all_registers -clock DAC_CLK

上述这个命令返回的集合中为所有由时钟DAC_CLK触发的寄存器。

current_design [design name] 命令会返回当前设计的名称。如果使用参数指定,则将会设置当前设计为指定的名称:

current_design FADD

current_design

get_cells [-hierarchical] [-hsc separator] [-regexp] [-nocase] [-of_objects objects] patterns 命令会返回一个设计中与指定模型(pattern)匹配的单元的集合,通配符可用于匹配多个单元:

get_cells RegEdge*

foreach_in_collection cvar [get_cells -hierarchical *]

get_clocks [-regexp] [-nocase] patterns 命令会返回一个设计中与指定模型匹配的时钟的集合。当在-from-to等上下文中使用时,它将返回一个由指定时钟驱动的所有触发器的集合:

set_propagated_clock [get_clocks SYS_CLK]

set_multicycle_path -to [get_clocks jtag*]

get_lib_cells [-hsc separator] [-regexp] [-nocase] patterns 命令会创建一个当前正在加载的库中并且与指定模型匹配的库单元的集合:

get_lib_cells cmos131v/AOI3*

get_lib_pins [-hsc separator] [-regexp] [-nocase] patterns 命令会返回一个与指定模型匹配的库单元引脚的集合。

get_libs [-regexp] [-nocase] patterns 命令会返回一个设计中当前加载的库的集合。

get_nets [-hierarchical] [-hsc separator] [-regexp] [-nocase] [-of_objects objects] patterns 命令会返回一个与指定模型匹配的网络的集合:

get_nets -hierarchical *

get_nets FIFO_patt*

get_pins [-hierarchical] [-hsc separator] [-regexp] [-nocase] [-of_objects objects] patterns 命令会返回一个与指定模型匹配的引脚名称的集合:

get_pins *

get_pins U1/U2/U3/UAND/Z

get_ports [-regexp] [-nocase] patterns 命令会返回一个与指定模型匹配的设计(输入和输出)端口名称的集合:

foreach_in_collection port_name [get_ports clk*]

可以在不“获取”对象的情况下引用诸如端口(port)之类的对象吗?当设计中只有一个具有该名称的对象时,实际上没有任何区别。但是,当多个对象具有相同的名称时,使用get_ * 命令将变得更加重要,它可以避免在引用哪种类型对象方面所带来的任何可能的混淆。假设有一个名为BIST_N1的网络和一个名为BIST_N1的端口,考虑以下SDC命令:

set_load 0.05 BIST_N1

问题是要引用哪个BIST_N1?网络还是端口?在大多数情况下,最好明确表明对象的类型,例如:

set_load 0.05 [get_nets BIST_N1]

现在再假设有一个时钟MCLK和另一个也称为MCLK的端口,考虑以下SDC命令:

set_propagated_clock MCLK

该对象是引用名为MCLK的端口还是引用称为MCLK的时钟?在此特定情况下,它指的是时钟,因为这是set_propagated_clock命令的优先级所选择的。但是,要明确一点,最好明确表明对象类型,如下所示:

set_propagated_clock [get_clocks MCLK]

set_propagated_clock [get_ports MCLK]

有了这种明确的条件申明,就不必依赖优先级规则了,并且SDC命令会非常清楚。

A.3 时序约束

本节将介绍与时序约束有关的SDC命令。

create_clock -period period_value [-name clock_name] [-waveform edge_list] [-add] [source_objects] 命令可用于定义时钟。如果未指定clock_name,则时钟名称将是第一个源对象的名称。-period选项指定时钟周期,-add选项用于在已经具有时钟定义的引脚上创建时钟。否则,如果不使用此选项,则此时钟定义将覆盖该节点上任何其它现有的时钟定义。-waveform选项指定时钟的上升沿和下降沿(占空比),默认值为(0,period / 2)。如果时钟定义的节点位于另一个时钟之后的路径上,则它将阻塞该点之前一个时钟。

例子:

create_clock -period 20 -waveform {0 6} -name SYS_CLK [get_ports SYS_CLK]

create_clock -name CPU_CLK -period 2.33 -add [get_ports CPU_CLK]

create_generated_clock [-name clock_name] [-source master_pin] [-edges edge_list] [-divide_by factor] [-multiply_by factor] [-duty_cycle percent] [-invert] [-edge_shift shift_list] [-add] [-master_clock clock] [-combinational] [source_objects] 命令可用于定义内部的衍生时钟。如果未指定-name,则时钟名称为第一个源对象的名称。-source指定衍生时钟的源是设计中的引脚或端口。如果有多个时钟输入源节点,必须使用-master_clock选项指定将这些时钟中的哪一个用作衍生时钟的源。-divide_by选项用于指定时钟的分频系数,与-multiply_by类似。-duty_cycle可以用于指定时钟的占空比。如果时钟的相位已反转,则可以指定-invert选项。除了使用时钟倍频或分频,还可以使用-edges-edge_shift选项指定衍生时钟。-edges选项指定一个由三个数字组成的列表,该列表指定用于第一个上升沿、下一个下降沿和下一个上升沿的主时钟边沿。例如,可以将时钟分频器指定为-divide_by 2或-edges {1 3 5}。-edge_shift选项可以与-edges选项一起使用,以指定三个边沿中每个边沿的偏移量。

例子:

create_generated_clock -divide_by 2 -source [get_ports sys_clk] -name gen_sys_clk [get_pins UFF/Q]

create_generated_clock -add -invert -edges {1 2 8} -source [get_ports mclk] -name gen_clk_div

create_generated_clock -multiply_by 3 -source [get_ports ref_clk] -master_clock clk10MHz [get_pins UPLL/CLKOUT] -name gen_pll_clk

group_path [-name group_name] [-default] [-weight weight_value] [-from from_list] [-rise_from from_list] [-fall_from from_list] [-to to_list] [-rise_to to_list] [-fall_to to_list] [-through through_list] [-rise_through through_list] [-fall_through through_list] 命令可以为指定的路径组命名。

set_clock_gating_check [-setup setup_value] [-hold hold_value] [-rise] [-fall] [-high] [-low] [object_list] 命令可以提供对任何对象指定时钟门控检查的功能。时钟门控检查仅在具有时钟信号的逻辑门处执行,默认情况下建立时间和保持时间值为0。

例子:

set_clock_gating_check -setup 0.15 -hold 0.05 [get_clocks ck20m]

set_clock_gating_check -hold 0.3 [get_cells U0/clk_divider/UAND1]

set_clock_groups [-name name] [-logically_exclusive] [-physically_exclusive] [-asynchronous] [-allow_paths] -group clock_list 命令指定了一组具有特定属性的时钟,并为该组分配了一个名称。

set_clock_latency [-rayise] [-fall] [-min] [-max] [-source] [-late] [-early] [-clock clock_list] delay object_list 命令指定给定时钟的时钟延迟。有两种类型的延迟:网络延迟和源延迟。源延迟是时钟定义引脚与其源之间的时钟网络延迟,而网络延迟是时钟定义引脚与触发器时钟引脚之间的时钟网络延迟。

例子:

set_clock_latency 1.86 [get_clocks clk250]

set_clock_latency -source -late -rise 2.5 [get_clocks MCLK]

set_clock_latency -source -late -fall 2.3 [get_clocks MCLK]

set_clock_sense [-positive] [-negative] [-pulse pulse] [-stop_propagation] [-clock clock_list] pin_list 命令在引脚上设置时钟属性。

set_clock_transition [-rise] [-fall] [-min] [-max] transition_clock_list 命令指定时钟定义点处的时钟过渡时间。

例子:

set_clock_transition -min 0.5 [get_clocks SERDES_CLK]

set_clock_transition -max 1.5 [get_clocks SERDES_CLK]

set_clock_uncertainty [-from from_clock] [-rise_from rise_from_clock] [-fall_from fall_from_clock] [-to to_clock] [-rise_to rise_to_clock] [-fall_to fall_to_clock] [-rise] [-fall] [-setup] [-hold] uncertainty [object_list] 命令指定了时钟或时钟到时钟传输的时钟不确定度。STA将从路径的数据需要到达时间中减去建立时间不确定度,并将保持时间不确定度增加到路径的数据需要到达时间中。

例子:

set_clock_uncertainty -setup -rise -fall 0.2 [get_clocks CLK2]

set_clock_uncertainty -from [get_clocks HSCLK] -to [get_clocks SYSCLK] -hold 0.35

set_data_check [-from from_object] [-to to_object] [-rise_from from_object] [-fall_from from_object] [-rise_to to_object] [-fall_to to_object] [-setup] [-hold] [-clock clock_object] value 命令在两个数据引脚之间执行指定的检查。

例子:

set_data_check -from [get_pins UBLK/EN] -to [get_pins UBLK/D] -setup 0.2

set_disable_timing [-from from_pin_name] [-to to_pin_name] cell_pin_list 命令中断了指定单元内的时序弧。

例子:

set_disable_timing -from A -to ZN [get_cells U1]

set_false_path [-setup] [-hold] [-rise] [-fall] [-from from_list] [-to to_list] [-through through_list] [-rise_from rise_from_list] [-rise rise_to_list] [-rise_through rise_through_list] [-fall_from fall_from_list] [-fall_to fall_to_list] [-fall_through fall_through_list] 命令指定了STA不需要考虑的路径例外。

set_false_path -from [get_clocks jtag_clk] -to [get_clocks sys_clk]

set_false_path -through U1/A -through U4/ZN

set_ideal_latency [-rise] [-fall] [-min] [-max] delay object_list 命令用于为特定对象设置理想的延迟。

set_ideal_network [-no_propagate] object_list 命令将指定设计中理想网络的源节点。

set_ideal_transition [-rise] [-fall] [-min] [-max] transition_time object_list 命令将指定理想网络的过渡时间。

set_input_delay [-clock clock_name] [-clock_fall] [-rise] [-fall] [-max] [-min] [-add_delay] [-network_latency_included] [-source_latency_included] delay_value port_pin_list 命令将指定相对于指定时钟的输入端口数据到达时间,默认为时钟的上升沿。-add_delay选项允许向该引脚或端口添加多个约束,可以使用此-add_delay选项将时钟设置为不同的时钟。默认情况下,会将发起时钟的时钟源延迟添加到输入延迟值中,但是当指定了-source_latency_included选项时,由于假设已将源网络延迟添加到了输入延迟值中,因此不再添加源网络延迟。-max选项指定的延迟用于建立时间和恢复时间检查,而-min选项指定的延迟用于保持时间和撤销时间检查。如果仅指定-min-max或两者均未指定,则两者将使用相同的值。

例子:

set_input_delay -clock SYSCLK 1.1 [get_ports MDIO*]

set_input_delay -clock virtual_mclk 2.5 [all_inputs]

set_max_delay [-rise] [-fall] [-from from_list] [-to to_list] [-through through_list] [-rise_from rise_from_list] [-rise_to rise_to_list] [-rise_through rise_through_list] [-fall_from fall_from_list] [-fall_to fall_to_list] [-fall_through fall_through_list] delay_value 命令用于设置指定路径上的最大延迟。这个命令用于指定两个任意引脚之间的延迟,而不是从一个触发器到另一个触发器的延迟。

例子:

set_max_delay -from [get_clocks FIFOCLK] -to [get_clocks MAINCLK] 3.5

set_max_delay -from [all_inputs] -to [get_cells UCKDIV/UFF1/D] 2.66

set_max_time_borrow delay_value object_list 命令可用于设置在分析锁存器路径时可以借用的最长时间。

例子:

set_max_time_borrow 0.6 [get_pins CORE/CNT_LATCH/D]

set_min_delay [-rise] [-fall] [-from from_list] [-to to_list] [-through through_list] [-rise_from rise_from_list] [-rise_to rise_to_list] [-rise_through rise_through_list] [-fall_from fall_from_list] [-fall_to fall_to_list] [-fall_through fall_through_list] delay_value 命令用于设置指定路径上的最小延迟,该延迟可以在任意两个引脚之间。

例子:

set_min_delay -from U1/S -to U2/A 0.6

set_min_delay -from [get_clocks PCLK] -to [get_pins UFF/*/S]

set_multicycle_path [-setup] [-hold] [-rise] [-fall] [-start] [-end] [-from from_list] [-to to_list] [-through through_list] [-rise_from rise_from_list] [-rise_to rise_to_list] [-rise_through rise_through_list] [-fall_from fall_from_list] [-fall_to fall_to_list] [-fall_through fall_through_list] path_multiplier 命令将路径指定为多周期路径,可以使用多个-through选项。如果多周期路径仅用于建立时间检查,请使用-setup选项,而如果多周期路径用于保持时间检查,请使用-hold选项。如果-setup-hold均未指定,则默认为-setup且默认的保持时间周期为0。-start选项指定了时钟周期数使用的是发起时钟的 ,而-end选项指定使用的是捕获时钟的,默认值为-start-hold选项指定的时钟周期数表示需要偏离默认多周期保持时间值0的时钟沿数。

例子:

set_multicycle_path -start -setup -from [get_clocks PCLK] -to [get_clocks MCLK] 4

set_multicycle_path -hold -from UFF1/Q -to UCNTFF/D 2

set_multicycle_path -setup -to [get_pins UEDGEFF*] 4

set_output_delay [-clock clock_name] [-clock_fall] [-level_sensitive] [-rise] [-fall] [-max] [-min] [-add_delay] [-network_delay_included] [-source_latency_included] delay_value port_pin_list 命令可以指定相对于时钟的输出所需时间,默认是上升沿。默认情况下,时钟源延迟会添加到输出延迟值中,但是当指定-source_latency_included选项时,不会添加时钟延迟值,因为会假定它已包含在输出延迟值中。-add_delay选项可用于在一个引脚/端口上指定多个set_output_delay

set_propagated_clock object_list 命令指定时钟延迟需要计算,即不是理想的。

set_propagated_clock [all_clocks]

A.4 环境命令

本节介绍了用于设置待分析设计环境的命令。

set_case_analysis value port_or_pin_list 命令用于指定被设置为常数的端口或引脚。

例子:

set_case_analysis 0 [get_pins UDFT/MODE_SEL]

set_case_analysis 1 [get_ports SCAN_ENABLE]

set_drive [-rise] [-fall] [-min] [-max] resistance port_list 命令用于指定输入端口的驱动强度,它指定端口的外部驱动电阻,值为0表示驱动强度是最高的。

例子:

set_drive 0 {CLK RST}

set_driving_cell [-lib_cell lib_cell_name] [-rise] [-fall] [-library lib_name] [-pin pin_name] [-from_pin from_pin_name] [-multiply_by factor] [-dont_scale] [-no_design_rule] [-input_transition_rise rise_time] [-input_transition_fall fall_time] [-min] [-max] [-clock clock_name] [-clock_fall] port_list 命令用于模拟驱动输入端口的单元的驱动电阻。

例子:

set_driving_cell -lib_cell BUFX4 -pin ZN [all_inputs]

set_fanout_load value port_list 命令在输出端口上设置指定的扇出负载。

例子:

set_fanout_load 5 [all_outputs]

set_input_transition [-rise] [-fall] [-min] [-max] [-clock clock_name] [-clock_fall] transition port_list 命令指定了输入端口上的过渡时间。

例子:

set_input_transition 0.2 [get_ports SD_DIN*]

set_input_transition -rise 0.5 [get_ports GPIO*]

set_load [-min] [-max] [-subtract_pin_load] [-pin_load] [-wire_load] value objects 命令用于指定在设计中引脚或网络上的电容性负载的值。-subtract_pin_load选项表示从指定负载中减去引脚电容。

例子:

set_load 50 [all_outputs]

set_load 0.1 [get_pins UFF0/Q]

set_load -subtract_pin_load 0.025 [get_nets UCNT0/NET5]

set_logic_dc port_list 命令、set_logic_one port_list 命令以及set_logic_zero port_list 命令将指定的端口设置为不关心(don't care)、逻辑1或逻辑0。

例子:

set_logic_dc SE

set_logic_one TEST

set_logic_zero [get_pins USB0/USYNC_FF1/Q]

set_max_area area_value 命令指定了当前设计的最大面积限制。

例子:

set_max_area 20000.0

set_max_capacitance value object_list 命令指定了端口或设计中的最大电容。如果是设计,则指定了设计中所有引脚的最大电容。

set_max_capacitance 0.2 [current_design]

set_max_capacitance 1 [all_outputs]

set_max_fanout value object_list 命令指定了端口或设计中的最大扇出值。如果是设计,则指定了设计中所有输出引脚的最大扇出值。

set_max_fanout 16 [get_pins UDFT0/JTAG/ZN]

set_max_fanout 50 [current_design]

set_max_transition [-clock_path] [-data_path] [-rise] [-fall] value object_list 命令指定了端口或设计中的最大过渡时间。如果是设计,则指定了设计中所有引脚上的最大过渡时间。

例子:

set_max_transition 0.2 UCLKDIV0/QN

set_min_capacitance value object_list 命令指定了设计中端口或引脚上的最小电容值。

例子:

set_min_capacitance 0.05 UPHY0/UCNTR/B1

set_operating_conditions [-library lib_name] [-analysis_type type] [-max max_condition] [-min min_condition] [-max_library max_lib] [-min_library min_lib] [-object_list objects] [condition] 命令可以设置用于时序分析的工作条件。分析类型可以是single(单个情况),bc_wc(最佳情况/最差情况)或者on_chip_variation(片上变化)。可以使用operating_conditions命令在库中定义工作条件。

例子:

set_operating_conditions -analysis_type bc_wc

set_operating_conditions WCCOM

set_operating_conditions -analysis_type on_chip_variation

set_port_fanout_number value port_list 命令可用于设置端口的最大扇出数。

例子:

set_port_fanout_number 10 [get_ports GPIO*]

set_resistance [-min] [-max] value list_of_nets 命令可用于设置指定网络上的电阻。

例子:

set_resistance 10 -min U0/U1/NETA

set_resistance 50 -max U0/U1/NETA

set_timing_derate [-cell_delay] [-cell_check] [-net_delay] [-data] [-clock] [-early] [-late] derate_value [object_list] 命令指定了降额系数。

set_wire_load_min_block_size size 命令指定了将线负载模型设置为“enclosed”时使用的最小的块大小。

例子:

set_wire_load_min_block_size 5000

set_wire_load_mode mode_name 命令定义了如何对分层设计(hierarchical design)中的网络使用线负载模型的机制。mode_name可以是top,enclosure或segmented。top模式规定在顶层定义的线负载模型将用于所有较低级别上。enclosure模式规定完全封闭在模块中的网络的线负载模型用于该网络。segmented模式规定模块中的网络段使用该模块的线负载模型。

例子:

set_wire_load_mode enclosed

set_wire_load_model -name model_name [-library lib_name] [-min] [-max] [object_list] 命令定义了用于当前设计或指定网络的线负载模型。

例子:

set_wire_load_model -name "eSiliconLightWLM"

set_wire_load_selection_group [-library lib_name] [-min] [-max] group_name [object_list] 命令会在根据块的单元面积确定线负载模型时,为设计设置线负载选择组,该选择组通常在技术库中定义。

A.5 多电压命令

当设计中存在多电压岛(multi-voltage islands)时,以下命令适用。

create_voltage_area -name name [-coordinate coordinate_list] [-guard_band_x float] [-guard_band_y float] cell_list

set_level_shifter_strategy [-rule rule_type]

set_level_shifter_threshold [-voltage float] [-percent float]

set_max_dynamic_power power [unit] 命令指定了最大动态功率。

例子:

set_max_dynamic_power 0 mw

set_max_leakage_power power [unit] 命令指定了最大漏电功率。

例子:

set_max_leakage_power 12 mw

附录B:SDF

本附录将介绍标准延迟标注格式,并说明了如何在仿真中执行反标。

延迟格式描述了设计网表的单元延迟和互连走线延迟,无论设计是用两种主要硬件描述语言(VHDL或Verilog HDL)中的哪一种所描述的。

本章还会介绍仿真的反标(backannotation),STA的反标其实是一个简单直接的过程,其中DUA中的时序弧将由SDF所指定的延迟进行标注。

B.1 什么是SDF?

SDF是指标准延迟格式(Standard Delay Format)。它是一个IEEE标准——IEEE Std1497,它是ASCII文本文件,它描述了时序信息和约束,其目的是用作各种工具之间的文本类型的时序信息交换媒介,它也可以用来描述需要它的工具的时序数据。由于它是IEEE标准,因此由一个工具生成的时序信息可以被支持该标准的许多其它工具所使用。SDF中的数据与工具和语言都无关,且包括了互连走线延迟、器件延迟以及时序检查的规范。

由于SDF是ASCII文件,因此它易于阅读,尽管对于实际设计而言,这些文件往往很大。但是,它是作为工具之间的交换媒介。经常在进行信息交换时,一个工具可能会在生成SDF文件时产生一个问题,而另一个读取SDF的工具可能无法正确读取SDF。读取SDF的工具可能会在读取SDF时产生一个错误或警告,或者它可能会错误地解释SDF中的值。在这种情况下,设计人员可能必须查看SDF文件,看看出了什么问题。本章介绍了SDF文件的基础知识,并提供了必要和足够的信息,以帮助理解和调试任何标注问题。

图B-1显示了如何使用SDF文件的典型流程。时序计算工具通常会生成时序信息存储在SDF文件中。然后,通过读取SDF的工具将该信息反标到设计中。请注意,完整的设计信息不会都存储到SDF文件中,而只会存储延迟值。例如,实例名称和实例的引脚名称将被存储到SDF文件中,因为它们对于指定实例相关或引脚相关的延迟是必需的。因此,必须为SDF生成工具和SDF读取工具提供相同的设计。

图B-1

一个设计可以具有多个与之关联的SDF文件。可以为一个设计创建一个SDF文件,在分层设计中,也可以为分层中的每个块创建多个SDF文件。在标注期间,每个SDF都将应用于适当的分层实例中,如图B-2所示。

图B-2

SDF文件包含了用于反标和标注的时序数据。更具体地说,它包含:

● 单元延迟(Cell delays)

● 脉冲传播(Pulse propagation)

● 时序检查(Timing checks)

● 互连走线延迟(Interconnect delays)

● 时序环境(Timing environment)

引脚到引脚的延迟(pin-to-pin delay)和分布式延迟(distributed delay)都可以针对单元延迟进行建模。引脚到引脚的延迟使用IOPATH结构(construct)表示,这些结构定义了每个单元输入到输出的路径延迟。COND结构还可以用于额外指定有条件的引脚到引脚延迟。状态相关(state-dependent)的路径延迟也可以使用COND结构来指定,分布式延迟的建模是使用DEVICE结构指定的。

脉冲传播结构——PATHPULSEPATHPULSEPERCENT可用于指定使用引脚到引脚延迟模型时允许传播到单元输出端口的毛刺大小。

可以在SDF中指定的时序检查包括:

● 建立时间:SETUP,SETUPHOLD

● 保持时间:HOLD,SETUPHOLD

● 恢复时间:RECOVERY,RECREM

● 撤销时间:REMOVAL,RECREM

● 最大偏斜:SKEW,BIDIRECTSKEW

● 最小脉冲宽度:WIDTH

● 最小周期:PERIOD

● 不变化:NOCHANGE

时序检查中的信号可能存在某些条件。在时序检查中允许使用负值,不支持负值的工具可以选择将其替换为零。

SDF描述中支持三种类型的互连走线建模。INTERCONNECT结构是最通用且最常用的,可用于指定点对点延迟(从源端到接收端),因此单个网络可以具有多个INTERCONNECT结构。PORT结构可用于指定负载端口处的网络延迟,假定网络只有一个源端驱动。NETDELAY结构可用于指定整个网络的延迟,而无需考虑其源端或接收端,因此是指定网络上延迟的最不具体的方法。

时序环境提供了设计在工作时所依据的信息,这些信息包括ARRIVALDEPARTURESLACKWAVEFORM结构。这些结构主要用于标注,例如可用于综合。

B.2 SDF格式

SDF文件包含一个首部(header section),后跟一个或多个单元。每个单元代表设计中的一个区域或范围,它可以是库原语(primitive)或用户自定义的黑盒。

首部包含一般信息,除了层次结构分隔符、时间刻度(timescale)和SDF版本号外,都不会影响SDF文件的语义。默认情况下,层次结构分隔符DIVIDER是点字符(“.”)。通过以下方法,可以将其替换为“/”字符:

● (DIVIDER /)

如果首部中没有时间刻度信息,则默认值为1ns。否则,可以使用以下命令明确指定时间刻度TIMESCALE

● (TIMESCALE 10ps)

也就是说,将SDF文件中指定的所有延迟值乘以10ps。

SDF版本号SDFVERSION是必需的,SDF文件的使用者会根据它来确保文件符合指定的SDF版本。首部中可能存在的其它信息(属于常规信息类别)包括日期、程序名称、版本和工作条件。

首部之后是一个或多个单元的描述,每个单元在设计中代表一个或多个实例(使用通配符),单元可以是库原语或分层块(hierarchical block)。

单元的顺序很重要,因为数据是从上到下进行处理的。后面的单元描述可以覆盖前面的单元描述所指定的时序信息(通常,两次定义同一单元实例的时序信息并不常见)。另外,可以将时序信息标注为绝对值或增量的形式。如果时序信息使用增量的形式,它将会把新值添加到现有值中。而如果时序信息是绝对值,它将覆盖任何先前指定的时序信息。

单元实例可以是分层实例名称。用于层次结构分隔的分隔符必须符合首部中指定的分隔符。单元实例名称可以选择为“ * ”字符,即通配符,这表示指定类型的所有单元实例。

单元中可以描述四种类型的时序规范:

DELAY:用于描述延迟

TIMINGCHECK:用于描述时序检查

TIMINGENV:用于描述时序环境

LABEL:声明可用于描述延迟的时序模型变量。

以下是一些例子:

DELAY时序规范有四种类型:

ABSOLUTE:在反标期间替换单元实例的现有延迟值。

INCREMETN:将新的延迟数据添加到单元实例的任何现有延迟值。

PATHPULSE:指定设计输入和输出之间的脉冲传播极限。此极限值用于决定是将出现在输入上的脉冲传播到输出,还是将其标记为“ X ”,或者将其滤除。

PATHPULSEPERCENT:除了值以百分比表示外,这与PATHPULSE完全相同。

以下是一些例子:

RN和Q是单元的输入端口和输出端口。第一个值3是脉冲抑制极限(pulse rejection limit),称为r-limit,它定义了可以出现在输出上的最窄脉冲。窄于此的任何脉冲都会被拒绝通过,也就是说,它将不会出现在输出上。第二个值7(如果存在)是错误极限(error limit),也称为e-limit。任何小于e-limit的脉冲都会导致输出为“ X ”。e-limit必须大于r-limit,如图B-3所示。 当出现小于3(r-limit)的脉冲时,该脉冲不会传播到输出;当脉冲宽度在3(r-limit)和7(e-limit)之间时,输出为X ;当脉冲宽度大于7(e-limit)时,脉冲会传播到输出且没有任何滤除(unfiltered)。

图B-3

可以使用ABSOLUTEINCREMENT描述八种延迟定义:

IOPATH:输入到输出路径的延迟。

RETAIN:保留时间定义,可以用于指定输出端口在其相关输入端口改变后应保留其先前值的时间。

COND:条件路径延迟,可以用于指定状态相关的输入到输出路径延迟。

CONDELSE:默认路径延迟,可以用于指定条件路径的默认值。

PORT:端口延迟,可以用于指定互连走线延迟,该延迟被建模为输入端口的延迟。

INTERCONNECT:互连走线延迟,可以用于指定从其源端到接收端的整个网络的传播延迟。

NETDELAY:网络延迟,可以用于指定从一个网络的所有源端到所有接收端的传播延迟。

DEVICE:器件延迟,主要用于描述分布式时序模型,可以用于指定通过单元到输出端口的所有路径的传播延迟。

以下是一些例子:

输入A上的值发生更改后,Y将保留其先前值50ps(低电平为40ps)。50ps是保持高电平的值,40ps是保持低电平的值,101ps是传播上升沿延迟,90ps是传播下降沿延迟,如图B-4所示。

图B-4

延迟

到目前为止,我们已经看过了许多不同形式的延迟,其实延迟规范还有其它形式。通常,可以将延迟指定为一个、两个、三个、六个或十二个令牌(token)的集合,这些令牌可用于描述以下过渡的延迟:0-> 1、1-> 0、0-> Z,Z-> 1,1-> Z,Z-> 0,0-> X,X-> 1,1-> X,X-> 0,X-> Z,Z-> X。下表展示了如何使用少于十二个延迟令牌来表示十二种过渡情况。

以下是这些延迟的一些示例:

每个延迟令牌可以依次写为一个、两个或三个值,如以下示例所示:

一个SDF文件中的延迟值可以使用有符号的实数或以下形式的三元数组来编写:

● ( 8.0:3.6:9.8 )

为了表示出设计在三个工艺工作条件下的最小、典型以及最大延迟,注释器通常会根据用户提供的选项来决定去选择哪个值。三元数组形式中的值是可选的,但是至少应有一个。例如,以下形式是规范的:

● ( : : 0.22)

● ( 1.001 : : 0.998 )

未指定的值就不会去标注。

时序检查

在以TIMINGCHECK关键字开头的部分中指定了时序检查的极限。在任何这些检查中,可以使用COND结构指定有条件的时序检查。在某些情况下,可以指定两个额外的条件检查SCONDCCOND,它们与stamp eventcheck event关联。

以下是一组检查:

SETUP:建立时间检查

HOLD:保持时间检查

SETUPHOLD:建立时间和保持时间检查

RECOVERY:恢复时间检查

REMOVAL:撤销时间检查

RECREM:恢复时间和撤销时间检查

SKEW:单向偏斜时序检查

BIDIRECTSKEW:双向偏斜时序检查

WIDTH:脉宽时序检查

PERIOD:周期时序检查

NOCHANGE:不变化时序检查

以下是一些例子:

标签

标签可用于指定VHDL泛型(generics)或Verilog HDL参数的值。

时序环境

有许多结构可用于描述设计的时序环境。但是,这些结构可用于标注,而不是用于反标,例如在逻辑综合工具中。这些未在本文中描述。

B.2.1 例子

接下去,我们将为两个设计提供完整的SDF文件。

全加器

这是用于全加器(full-adder)电路的Verilog HDL网表(netlist):

以下是时序分析工具生成的完整SDF文件:

INTERCONNECT中的所有延迟均为0,因为这是布局前的数据,因此建模的是理想互连走线模型。

十进制计数器

这是十进制计数器的Verilog HDL模型:

对应的完整SDF文件如下:

B.3 标注过程

在本节中,我们将介绍如何在HDL描述中进行SDF的标注(annotation)。SDF的标注可以通过多种工具执行,例如逻辑综合工具、仿真工具和静态时序分析工具。SDF标注器(annotator)是这些工具的组件,可用于读取SDF、解释并向设计中标注时序值。假定会使用与HDL模型一致的信息创建SDF文件,并且在反标期间使用相同的HDL模型。此外,SDF标注器还需要负责正确解释SDF中的时序值。

SDF标注器标注了反标时序的泛型和参数。如果在语法或映射(mapping)过程中不符合该标准,它将给出错误报告。如果一个SDF标注器不支持某些SDF结构,则不会产生任何错误,标注器将忽略这些错误。

如果SDF标注器未能修改反标时序的泛型,则在反标过程中不会修改泛型的值,即保持不变。

在仿真工具中,反标通常发生在规划(elaboration)阶段之后,紧接在负约束延迟计算之前。

B.3.1 Verilog HDL

在Verilog HDL中,标注的主要机制是指定块(specify block),指定块可以指定路径延迟和时序检查。实际延迟值和时序检查极限值是通过SDF文件指定的,映射是一种行业标准,在IEEE Std 1364中定义。

从SDF文件中获得并在Verilog HDL模块的指定块中标注的信息包括指定路径的延迟、参数值、时序检查约束极限值和互连走线延迟。向一个Verilog HDL模型进行标注时,将忽略SDF文件中的其它结构。SDF中的LABEL部分定义了参数值。通过将SDF结构与相应的Verilog HDL声明进行匹配,然后将现有的时序值替换为SDF文件中的时序值,即可完成反标。

下表显示了SDF延迟值如何映射到Verilog HDL延迟值:

下表描述了SDF结构到Verilog HDL结构的映射:

有关示例,请参见后面部分。

B.3.2 VHDL

SDF到VHDL的标注是一个行业标准,它在VITAL ASIC建模规范的IEEE标准IEEE Std 1076.4中定义,该标准的其中一部分描述了SDF延迟到ASIC库的标注。在这里,我们仅介绍与SDF映射有关的VITAL标准的相关部分。

SDF可用于直接在符合VITAL的模型中修改反标时序泛型,只能使用SDF为符合VITAL的模型指定时序数据。有两种方法可以将时序数据传递到VHDL模型中:通过配置,或直接传递到仿真中去。SDF标注过程包括在仿真期间在符合VITAL的模型中映射SDF结构和相应的泛型。

在符合VITAL的模型中,存在着有关如何命名和声明泛型的规则,以确保可以在模型的时序泛型和相应的SDF时序信息之间建立映射。

时序泛型由泛型名称及其类型组成,名称指定时序信息的种类,类型指定时序值的种类。如果泛型名称不符合VITAL标准,则它不是时序泛型,也不会被标注。

下表显示了SDF延迟值如何映射到VHDL延迟:

在VHDL中,时序信息是通过泛型进行反标的。泛型名称遵循一定的规则,以便保持一致或从SDF结构中获取。利用每个时序泛型名称,可以指定条件边沿的可选后缀。边沿可以指定一个与时序信息相关联的边沿。

下表列出了各种时序泛型名称:

B.4 映射示例

以下是将SDF结构映射到VHDL泛型(generic)和Verilog HDL声明(declaration)的示例。

传播延迟

● 从输入端口A到输出端口Y的传播延迟:上升时间为0.406,下降时间为0.339:

● 从输入端口OE到输出端口Y的传播延迟:上升时间为0.441,下降时间为0.409。最小、标准和最大延迟是相同的:

● 从输入端口S0到输出端口Y的条件传播延迟:

● 从输入端口A到输出端口Y的条件传播延迟:

● 从输入端口CK到输出端口Q的传播延迟:

● 从输入端口A到输出端口Y的条件传播延迟:

● 从输入端口CK到输出端口ECK的传播延迟:

● 从输入端口CI到输出端口S的条件传播延迟:

● 从输入端口CS到输出端口S的条件传播延迟:

● 从输入端口A到输出端口ICO的条件传播延迟:

● 从输入端口A到输出端口CO的条件传播延迟:

● 从CK的上升沿到Q的延迟:

输入建立时间

● D的上升沿与CK的上升沿之间的建立时间:

● D的下降沿与CK的上升沿之间的建立时间:

● 输入端口E的上升沿与参考CK的上升沿之间的建立时间:

● 输入端口E的下降沿和参考CK的上升沿之间的建立时间:

● SE和CK之间的条件建立时间:

输入保持时间

● D的上升沿与CK的上升沿之间的保持时间:

● RN与SN之间的保持时间:

● 输入端口SI与参考端口CK之间的保持时间:

● E和CK上升沿之间的条件保持时间:

输入建立和保持时间

● 在D和CLK之间的建立时间与保持时间检查。这是一个有条件的检查,第一个延迟值是建立时间,第二个延迟值是保持时间:

输入恢复时间

● CLKA和CLKB之间的恢复时间:

● CLKA上升沿与CLKB上升沿之间的条件恢复时间:

● SE与CK之间的恢复时间:

● RN与CK之间的恢复时间:

输入撤销时间

● E的上升沿与CK的下降沿之间的撤销时间:

● CK的上升沿和SN之间的条件撤销时间:

周期

● 输入CLKB的周期:

● 输入端口EN的周期:

● 输入端口TCK的周期:

脉宽

● CK上高脉冲的脉冲宽度:

● CK上低脉冲的脉冲宽度:

● RN上高脉冲的脉冲宽度:

输入偏斜时间

● CK与TCK之间的偏斜:

● SE和CK下降沿之间的偏斜:

无变化的建立时间

SDF文件中的NOCHANGE结构将同时映射到VHDL中的tncsetup和tnchold泛型。

● D和CK下降沿之间无变化的建立时间:

无变化的保持时间

SDF文件中的NOCHANGE结构将同时映射到VHDL中的tncsetup和tnchold泛型。

● E和CLKA之间无变化的条件保持时间:

端口延迟

● 端口OE的延迟:

● 端口RN的延迟:

网络延迟

● 连接到端口CKA的网络延迟:

互连路径延迟

● 从端口Y到端口D的互连路径延迟:

器件延迟

● 实例uP的输出SM的器件延迟:

B.5 完整语法

以下是使用BNF格式显示的SDF的完整语法。终端(terminal)名称是大写的,关键字是粗体的,但是不区分大小写。起始的终端是delay_file:

附录C:SPEF

本附录将介绍标准寄生参数提取格式(SPEF),它是IEEE Std 1481标准的一部分。

C.1 基础

SPEF允许以ASCII交换格式描述设计的寄生信息(R,L和C)。用户可以读取和检查SPEF文件中的值,尽管用户永远不会手动创建此文件。它主要用于将寄生信息从一个工具传递到另一个工具。图C-1显示了SPEF可以由诸如布局布线工具或寄生参数提取工具之类的工具生成,然后交由时序分析工具用于电路仿真或执行串扰分析。

图C-1

寄生参数可以在许多不同的层次上表示。SPEF支持分布式(distributed)网络模型、(reduced)简化网络模型和(lumped)集总电容模型。在分布式网络模型(D_NET)中,网络走线的每段都有其自己的R和C。在简化网络模型(R_NET)中,在网络的负载引脚上考虑一个简化的R和C,而在网络的驱动引脚上考虑一个π模型(C-R-C)。在集总电容模型中,仅为整个网络指定一个电容。图C-2显示了物理网络走线的一个示例,图C-3显示了分布式网络模型,图C-4显示了简化的网络模型,图C-5显示了集总电容模型。

图C-2

图C-3

图C-4

图C-5

互连寄生效应取决于工艺,SPEF支持最佳(best-case)、典型(typical)和最差(worst-case)三种情况。允许R、L和C值、端口压摆和负载使用此三种不同情况下的值。

通过提供一个包含网络名称和实例名称映射到索引的一个名称映射(name map),可以有效地减小SPEF文件的大小,更重要的是,所有较长名称仅出现在一个位置。

设计的SPEF文件可以拆分为多个文件,也可以分层。

C.2 格式

SPEF文件的格式如下:

header_definition包含了基本信息,例如SPEF版本号、设计名称以及R,L和C的单位。name_map指定了网络名称和实例名称到索引的映射。power_definition声明了电源网络和地网络。external_definition定义了设计的端口。define_definition中指出了SPEF还在其它文件中进行了描述的那些实例。internal_definition包含的是文件的核心——设计的寄生参数。

图C-6显示了header_definition的示例:

图C-6

SPEF name 指定了SPEF的版本号;

DESIGN name 指定了设计的名称;

DATE string 指定了创建文件时的时间戳;

VENDOR string 指定了用于创建SPEF的供应商工具;

PROGRAM string 指定了用于生成SPEF的程序;

VERSION string 指定了用于创建SPEF的程序的版本号;

DESIGN_FLOW string string string . . . 指定了在什么阶段创建SPEF文件。它描述了有关SPEF文件的信息,这些信息无法通过读取文件来获得。

预定义的字符串值为:

EXTERNAL_LOADS:外部载荷在SPEF文件中完全指定。

EXTERNAL_SLEWS:外部压摆在SPEF文件中完全指定。

FULL_CONNECTIVITY:SPEF中存在逻辑网表连接。

MISSING_NETS:SPEF文件中可能缺少某些逻辑网络。

NETLIST_TYPE_VERILOG:使用Verilog HDL类型命名约定。

NETLIST_TYPE_VHDL87:使用VHDL87命名约定。

NETLIST_TYPE_VHDL93:使用VHDL93网表命名约定。

NETLIST_TYPE_EDIF:使用EDIF类型命名约定。

ROUTING_CONFIDENCE:(正整数)所有网络的默认走线置信度,基本上是寄生精度的水平。

ROUTING_CONFIDENCE_ENTRY:补充走线置信度值。

NAME_SCOPE_LOCAL | FLAT:指定了SPEF文件中的路径是相对于文件还是相对于设计顶层。

SLEW_THRESHOLDS:(low_input_threshold_percent,high_input_threshold_percent)指定了设计的默认输入转换阈值。

PIN_CAP NONE | INPUT_OUTPUT | INPUT_ONLY:指定了作为总电容一部分的引脚电容类型,默认值为INPUT_OUTPUT。

DIVIDER / 指定了层次结构分隔符。可以使用的其它字符是" . " , " : "和" / "。

DELIMITER :指定了实例与其引脚之间的分隔符。可以使用的其它可能字符是" . " , " / " , " : " 或者 "|"。

BUS_DELIMITER [ ] 指定了用于标识总线位的前缀和后缀。可以用于前缀和后缀的其他可能字符是" { " , " ( " , " < " , " : "," ."和" } " , " ) ", " > "。

T_UNIT 正整数 NS | PS 指定了时间单位。

C_UNIT 正整数 PF | FF 指定了电容单位。

R_UNIT 正整数 OHM| KOHM 指定了电阻单位。

L_UNIT 正整数 HENRY | MH | UH 指定了电感单位。

SPEF文件中的注释可以两种形式出现:

图C-7显示了一个名称映射的示例。 它的形式为:

图C-7

名称映射将指定名称到唯一整数值(它们的索引)的映射。名称映射有助于通过索引来对名称进行引用从而减小文件的大小,名称可以是网络名称或实例名称。考虑图C-7中的名称映射,以后可以使用它们的索引在SPEF文件中引用这些名称,例如:

因此,名称映射会通过使用其唯一的整数表示来避免重复长名称及其路径。

power definition部分定义了电源和接地网络:

以下是一些例子:

external_definition包含了设计的逻辑和物理端口的定义。图C-8显示了逻辑端口的示例,逻辑端口可以以下形式描述:

图C-8

其中port_name可以是形式为*正整数的端口索引。方向为I表示输入,O表示输出,B表示双向。连接属性(conn_attribute)是可选的,可以是以下属性:

● *C number number:端口的坐标。

● *L par_value:端口的电容负载。

● *S par_value par_value:定义端口上的波形。

● *D cell_type:定义端口的驱动单元。

可以使用以下命令定义SPEF文件中的物理端口:

define definition部分定义了当前SPEF文件中引用的实例,但其寄生参数在其它SPEF文件中进行了描述:

当实例是物理分区(而不是逻辑层次结构)时,将使用*PDEFINE。以下有些例子:

这意味着将存在另一个带有*DESIGN值ddrphy的SPEF文件,该文件将包含设计ddrphy的寄生参数,其可能具有物理和逻辑层次结构。跨越层次边界的任何网络都必须描述为分布式网络(D_NET)。

internal definition部分包含了SPEF文件的核心,即设计中网络的寄生参数。基本上有两种形式:分布式网络D_NET和简化网络R_NET。图C-9中为一个分布式网络定义的示例:

图C-9

第一行中的*5426是网络的索引号(网络名称请参见名称映射),0.899466是网络上的总电容值。电容值是网络上所有电容的总和,其中包括假定为接地的交叉耦合电容,还包括负载电容。它可能包含也可能不包含引脚电容,具体取决于DESIGN_FLOW定义中的PIN_CAP设置。

connectivity section描述了网络的驱动和负载引脚:

I表示内部引脚( P表示端口),14212:D表示实例14212的D引脚,14212是一个索引号(有关实际名称需参见名称映射)。“ I”表示网络上的负载(输入引脚),“ O”表示网络上的驱动(输出引脚)。C和 D如先前在connection attributes中所定义的那样,C定义了引脚的坐标,D定义了引脚的驱动单元。

capacitance section描述了分布式网络的电容,电容单位在之前已用* C_UNIT指定。

第一个数字是电容标识符。电容规范有两种形式: 第一种到第四种一种形式,第五种是另一种形式。第一种形式(第一至第四种)指定两个网络之间的交叉耦合电容,而第二种形式(id为5)指定接地电容。因此,在电容id1中,网络5426和5290之间的交叉耦合电容为0.217446;在电容id5中,接地电容为0.529736。请注意,第一个节点名称必须是所描述的D_NET的网络名称。网络索引后面的正整数(5426:10278中的10278)指定内部节点或连接点。因此,电容id4表示在内部节点10278的网络5426和内部节点9922的网络*5116之间存在耦合电容,该耦合电容的值为0.113918。

resistance section描述了分布式网络的电阻,电阻单位在之前已用* R_UNIT指定。

第一个字段是电阻标识符。因此,该网络具有三个电阻部分。第一个在内部节点5426:10278与14212上的D引脚之间,电阻值为0.34。使用图C-10中所示的RC网络可以更好地理解电容和电阻部分。

图C-10

图C-11显示了分布式网络的另一个示例。该网络具有一个驱动和两个负载,网络上的总电容为2.69358。图C-12显示了与分布式网络相对应的RC网络。

图C-11

图C-12

通常,内部定义(internal definition)可以包含以下规范:

D_NET:逻辑网络的分布式RC网络形式。

R_NET:逻辑网络的简化RC网络形式。

D_PNET:物理网络的分布式形式。

R_PNET:物理网络的简化形式。

语法如下:

inductance section用于指定电感,其格式类似于电阻部分。 * V用于指定网络寄生参数的准确性。这些可以单独使用网络指定,也可以使用带有ROUTING_CONFIDENCE值的*** DESIGN_FLOW**语句进行全局指定,例如:

它指定了寄生参数是在最终单元布局和最终布线之后提取得到的,并且使用了3d提取。走线置信度的其它可能值为:

● 10:统计线负载模型

● 20:物理线负载模型

● 30:具有位置但没有单元布局的物理分区

● 40:使用基于斯坦纳树(steiner tree)的走线估计的单元位置

● 50:使用全局走线估计的单元位置

● 60:使用斯坦纳走线进行的最终单元布局

● 70:使用全局走线进行的最终单元布局

● 80:最终单元布局,最终走线,2d提取

● 90:最终单元布局,最终走线,2.5d提取

● 100:最终单元布局,最终走线,3d提取

reduced net是从分布式网络形式简化而来的网络。网络上每个驱动都有一个驱动精简部分(driver reduction section)。驱动精简部分的形式为:

C2_R1_C1表示在网络的驱动引脚上使用π模型的寄生参数。 RC结构中的rc_value是指Elmore延迟(R * C)。 图C-13显示了简化后的网络的SPEF示例,图C-14以图形方式显示了RC网络。

图C-13

图C-14

可使用D_NETR_NET结构描述集总电容模型(lumped capacitance model),该结构仅具有总电容而没有其它信息。以下是集总电容声明的示例:

SPEF文件中的值可以采用三元数组的形式来表示工艺变化,例如:

● 0.243 : 0.269 : 0.300

最佳情况下值为0.243,典型情况下值为0.269,最差情况下值为0.300。

C.3 完整语法

本节描述了SPEF文件的完整语法。

可以在字符前面加上反斜杠()来对其进行转义。注释有两种形式://开始注释直到行尾,而/ * . . . * /是多行注释。

在以下语法中,粗体字符如(,[是语法的一部分。所有结构均按字母顺序排列,起始符号为SPEF_file: