10.1 片上变化

通常,工艺和各环境参数在芯片的不同部分上可能不一致。由于工艺差异,芯片上不同部分的相同 MOS 晶体管可能没有相似的特性,这些差异是由于芯片内部的工艺差异引起的。请注意,多个制造批次中的工艺参数差异可能会覆盖慢工艺到快工艺(2.10 节中所介绍)。在本节中,我们讨论的是对一个芯片上可能存在的工艺差异(称为局部工艺差异)的分析,该差异远小于多个制造批次之间的差异(称为全局工艺差异)。

 

除了工艺参数的变化之外,设计中不同部分可能还会存在不同的电源电压和温度。因此,同一芯片的两个区域可能不在相同的 PVT 条件下。这些差异可能是由许多因素引起的,包括:

 

会影响局部电源电压的沿芯片区域的 IR 压降变化;

 

PMOS 或 NMOS 器件的电压阈值变化;

 

PMOS 或 NMOS 器件的沟道长度变化;

 

由于局部热点造成的温度变化;

 

互连金属刻蚀或厚度变化会影响互连电阻或电容。

 

上述的 PVT 变化被称为片上变化(OCV),这些变化会影响芯片不同部分的走线延迟和单元延迟。如上所述,OCV 建模并不是要对芯片与芯片之间可能的 PVT 变化进行建模,而是要对单个芯片内局部可能的 PVT 变化进行建模。OCV 带来的影响通常在时钟路径上更为明显,因为时钟路径在芯片中传播的距离更长。解决局部 PVT 变化的一种方法是在 STA 期间包含 OCV 分析。前面各章中所介绍的静态时序分析能够获得特定时序角(timing corner)的时序,但没有对芯片上的变化进行建模。由于时钟和数据路径可能受到不同 OCV 的影响,因此时序验证可以通过使数据发起路径和捕获路径的 PVT 条件稍有不同来对 OCV 的影响进行建模。通过降额(derate)特定路径的延迟就可以对 OCV 带来的影响进行建模,即首先使这些路径更快或更慢,然后通过这些变化来验证设计的性能。可以降额单元延迟或走线延迟,或同时降额两者,以模拟 OCV 的影响。

 

现在,我们来讨论如何完成 OCV 降额处理以进行建立时间检查。考虑图 10-1 中所示逻辑,其中 PVT 条件可能随芯片的不同区域而变化。当发起时钟路径和数据路径的 OCV 条件导致延迟最大、而捕获时钟路径的 OCV 条件导致延迟最小时,此时的建立时间检查最为严格。请注意,此处最小和最大延迟是由于芯片上局部 PVT 的变化。

 

图 10-1

 

对于此示例,以下是建立时间检查,注意此处还不包括任何用于降额延迟的 OCV 设置:

 

LaunchClockPath + MaxDataPath <= ClockPeriod + CaptureClockPath - Tsetup_UFF1

 

Minimum clock period = LaunchClockPath + MaxDataPath - CaptureClockPath + Tsetup_UFF1

 

LaunchClockPath = 1.2 + 0.8 = 2.0

 

MaxDataPath = 5.2

 

CaptureClockPath = 1.2 + 0.86 = 2.06

 

Tsetup_UFF1 = 0.35

 

Minimum clock period = 2.0 + 5.2 - 2.06 + 0.35 = 5.49ns

 

以上路径延迟对应于没有任何 OCV 降额的延迟值,我们可以使用 set_timing_derate 命令来对单元和网络延迟进行降额处理。比如以下命令:

 

set_timing_derate -early 0.8

 

set_timing_derate -lata 1.1

 

上述命令将最小 / 最短 / 最早路径的延迟降低了 20%,并将最大 / 最长 / 最迟路径的延迟增加了 10%。长路径的延迟(例如,用于建立时间检查的数据路径和发起时钟路径或用于保持时间检查的捕获时钟路径)将乘以使用 -late 选项指定的降额值,而短路径的延迟(例如,用于建立时间检查的捕获时钟路径或用于保持时间检查的数据路径和发起时钟路径)将乘以使用 -early 选项指定的降额值。如果未指定降额系数,则假定值为 1.0。

 

降额系数将统一应用于所有网络延迟和单元延迟,如果某个应用场景中需要保证单元和网络的降额系数不同,则可以在 set_timing_derate 命令中使用 -cell_delay 和 -net_delay 选项。

 

set_timing_derate -cell_delay -early 0.9

 

set_timing_derate -cell_delay -late 1.0

 

set_timing_derate -net_delay -early 1.0

 

set_timing_derate -net_delay -late 1.2

 

可以使用 -cell_check 选项来对单元检查(例如建立时间和保持时间)的延迟进行降额。使用此选项时,使用 set_output_delay 指定的任何输出延迟也将被降额,因为此约束也是输出建立时间要求的一部分。但是,对于使用 set_input_delay 指定的输入延迟,是不会被降额的。

 

set_timing_derate -early 0.8 -cell_check

 

set_timing_derate -late 1.1 -cell_check

 

-clock 选项仅将降额应用于时钟路径。同样,-data 选项仅将降额应用于数据路径。

 

set_timing_derate -early 0.95 -clock

 

set_timing_derate -late 1.05 -data

 

现在,我们将以下降额约束应用于图 10-1 的示例:

 

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

 

Minimum clock period = 2.4 + 6.24 - 1.854 + 0.385 = 7.171ns

 

在上面的建立时间检查中,由于时钟树的公共时钟路径(图 10-1)具有 1.2ns 的延迟,而发起时钟和捕获时钟路径上的降额有所不同,因此存在差异。时钟树的这一部分对于发起时钟和捕获时钟路径都是通用的,因此不应进行不同的降额。对发起和捕获时钟路径应用不同的降额是过于悲观的,因为在实际上时钟树的这一部分实际上仅处于一个 PVT 条件下,即最大路径或最小路径(或介于两者之间),但绝不会同一时间处在两种不同 PVT 条件下。由于对时钟树的公共部分应用了不同降额系数而引起的悲观被称为“公共路径悲观度”CPP(Common Path Pessimism),在分析过程中应将其消除。CPPR(Common Path Pessimism Removal)表示“公共路径悲观度消除”,通常在路径报告中作为单独的条目列出,它也被标记为时钟收敛悲观度消除 CRPR(Clock Reconvergence Pessimism Removal)。

 

CPPR 消除了时序分析中发起时钟路径和捕获时钟路径之间的人为悲观情绪。如果同一个时钟既驱动捕获触发器又驱动发起触发器,那么时钟树很可能会在分支之前共享一条公共路径。CPP 本身是沿时钟树公共路径的延迟之差,这是由于发起和捕获时钟路径的降额系数不同所致。时钟信号在公共点的最小到达时间和最大到达时间之间的差即为 CPP。公共点(Common Point)的定义为时钟树公共部分中最后一个单元的输出引脚。

 

  • CPP = LatestArrivalTime @CommonPoint - EarliestArrivalTime @CommonPoint

 

上述分析中的“最晚时间”和“最早时间”是指在特定工艺角(Corner)下的 OCV 降额值,例如最坏情况下的慢速(Worst-Case-Slow)或最佳情况下的快速(Best-Case-Fast)。对于图 10-1 的示例:

 

LatestArrivalTime @CommonPoint = 1.2 * 1.2 = 1.44

 

EarliestArrivalTime @CommonPoint = 1.2 * 0.9 = 1.08

 

CPP = 1.44 - 1.08 = 0.36ns

 

Minimum clock period = 7.171 - 0.36 = 6.811ns

 

对于前面的设计示例,应用 OCV 降额会把最小时钟周期从 5.49ns 增加到 6.811ns,这说明了通过这些降额系数建模的 OCV 变化会降低设计的最大工作频率。

 

最差 PVT 条件下的 OCV 分析

如果在最差情况(worst-case)的 PVT 条件下执行建立时间检查,则在较晚路径(late path)上就无需降额了,因为它们已经是最差的情况了。但是,可以通过将特定的降额系数应用于较早路径(early path)来使那些路径更快,例如使较早路径加速 10%。在最差情况下,降额约束可能如下所示:

 

set_timing_derate -early 0.9

 

set_timing_derate -late 1.0

 

上述降额约束可用于在最差情况的慢速工艺角下进行最大路径(或建立时间)检查。因此,较晚路径的 OCV 降额系数设置为 1.0,以使其不会超出最差情况的慢速工艺角。

 

接下来介绍在最差情况的慢速工艺角下进行建立时间检查的示例。为捕获时钟路径指定了以下降额约束:

 

  • set_timing_derate -early 0.8 -clock

 

以下是在最差情况的慢速工艺角下执行的建立时间检查路径报告。较晚路径使用的降额系数在报告中为 Max Data Paths Derating Factor 和 Max Clock Paths Derating Factor,而较早路径使用的降额系数在报告中为 Min Clock Paths Derating Factor。

 

 

请注意,捕获时钟路径的延迟已被降低了 20%:可参考时序报告中的单元 UCKBUF0,在发起路径中它有 56ps 的延迟,而在捕获路径中仅有 45ps 的延迟。单元 UCKBUF0 处在公共时钟路径上,也就是既在捕获时钟路径上又在发起时钟路径上。由于公共时钟路径不能有不同的降额系数,因此该公共路径的延迟差 56ps-45ps = 11ps 将会被补偿校正,这可以从 clock reconvergence pessimism 那行中看出。总而言之,如果要比较此路径报告降额与不降额的差别的话,则可能会注意到只有捕获时钟路径的单元和网络延迟被降低了。

 

保持时间检查的 OCV

现在,我们将介绍如何对保持时间检查进行降额处理。考虑如图 10-2 所示的逻辑,如果整个芯片上的 PVT 条件不同,则当发起时钟路径和数据路径具有导致延迟最小的 OCV 条件(即最早的发起时钟),且保持时钟路径具有导致延迟最大的 OCV 条件(即最晚的捕获时钟)时,保持时间检查的最差情况就会发生。

 

图 10-2

 

以下表达式即为此示例所要执行的保持时间检查:

 

  • LaunchClockPath + MinDataPath - CaptureClockPath - Told_UFF1 >= 0

 

将图 10-2 中的延迟值应用于上述表达式,我们可得(不应用任何降额系数):

 

LaunchClockPath = 0.25 + 0.6 = 0.85

 

MinDataPath = 1.7

 

CaptureClockPath = 0.25 + 0.75 = 1.00

 

Thold_UFF1 = 1.25

 

这意味着检查结果如下:

 

  • 0.85 + 1.7 - 1.00 - 1.25 = 0.3ns >= 0

 

因此可得结论:保持时间没有违例。

 

应用以下降额约束:

 

set_timing_derate -early 0.9

 

set_timing_derate -late 1.2

 

set_timing_derate -early 0.95 -cell_check

 

重新计算的结果如下:

 

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.765 + 1.53 - 1.2 - 1.1875 + 0.075 = -0.0175ns

 

结果小于 0,因此表明对路径应用了 OCV 降额系数之后保持时间违例了。

 

通常,保持时间检查是在最佳情况的快速 PVT 角下执行的。在这种情况下,较早路径无需降额,因为这些路径已经是最快的路径了。但是,可以通过将特定的降额系数应用于较晚路径来使那些路径更慢,例如使较晚路径变慢 20%。在最佳情况下,降额约束可能如下所示:

 

set_timing_derate -early 1.0

 

set_timing_derate -late 1.2

 

对于图 10-2 中的示例:

 

LatestArrivalTime @CommonPoint = 0.25 * 1.2 = 0.30

 

EarliestArrivalTime @CommonPoint = 0.25 * 1.0 = 0.25

 

因此此时公共路径悲观度为:

 

  • 0.30 - 0.25 = 0.05ns

 

这是使用此降额约束的设计示例的保持时间检查路径报告:

 

 

请注意,较晚路径的延迟增加了 20%,而较早路径保持不变。来看一下单元 UCKBUF0 的延迟,其在发起时钟路径上的延迟为 56ps,而在捕获时钟路径上的延迟为 67ps,增加了 20%。UCKBUF0 是公共时钟树上的单元,因此由于此公共时钟树上的降额系数不同而引入的悲观度为 67ps-56ps = 11ps,这在 clock reconvergence pessimism 一行中得到了补偿校正。

 

10.2 时间借用

时间借用(Time Borrowing)技术(也称为周期窃取 cycle stealing 技术)发生在锁存器(Latch)上。在锁存器中,时钟的一个边沿会使锁存器透明,即这个沿打开了锁存器,使得锁存器的输出与数据输入相同,该时钟沿被称为打开沿(opening edge)。时钟的另一个沿会关闭锁存器,也就是说,输入数据的任何改变在锁存器的输出处都无效,此时钟沿被称为关闭沿(closing edge)。

 

通常,应在时钟有效沿之前就在锁存器输入处准备好数据。但是,由于锁存器在时钟处于有效状态时是透明的,因此数据可以晚于有效时钟沿到达,也就是说,它可以从下一个周期借用时间。如果这样借用了时间,则会减少可用于下一级(锁存器到另一个时序单元)的时间。

 

图 10-3 给出了使用有效上升沿借用时间的示例。如果在锁存器 10ns 处的 CLK 上升沿(打开沿)之前的时间 A 处数据 DIN 就已经准备好了,则数据在锁存器打开时会流向锁存器的输出。如果数据 DIN 在时间 B 处(延迟)到达,则它将借用时间 Tb。但是,这减少了从锁存器到下一个触发器 UFF2 的可用时间,只有时间 Ta 可用,而不再是完整的时钟周期。

 

图 10-3

 

锁存器的时序的第一条规则是:如果数据在锁存器的打开沿之前到达,则寄存器行为将与触发器完全一样。在打开沿捕获数据,而同一时钟沿又将发起数据,作为下一条时序路径的起点。

 

第二条规则适用的情况是:数据在锁存器为透明状态时(在打开沿和关闭沿之间)到达。锁存器的输出将被用作下一级时序路径的起点,而不是时钟引脚。在锁存器处结束的时序路径所借用的时间将决定下一级的发起时间。

 

在锁存器的关闭沿之后到达的数据信号是时序违例的。图 10-4 显示了正裕量、零裕量和负裕量(即发生违例时)所分别对应的数据到达时序区域。

 

图 10-4

 

图 10-5(a)中为锁存器到下一级触发器的半周期路径,图 10-5(b)描绘了时间借用的波形,时钟周期为 10ns。UFF0 在 0 时刻发起数据,但数据路径需要 7ns。锁存器 ULAT1 在 5ns 时打开。因此,向 ULAT1 到 UFF1 的路径借用了 2ns,而 ULAT1 到 UFF1 的可用时间仅为 3ns(5ns-2ns)。

 

图 10-5

 

接下来,我们将介绍图 10-5(a)锁存器示例的三组不同时序报告,以说明从下一级路径借用的不同时间量。

 

没有借用时间

若从触发器 UFF0 到锁存器 ULAT1 的数据路径延迟小于 5ns,则建立时间检查的路径报告如下:

 

 

在这种情况下,由于数据在锁存器打开之前及时到达了锁存器 ULAT1,因此无需借用时间。

 

借用了时间

若从触发器 UFF0 到锁存器 ULAT1 的数据路径延迟大于 5ns,则建立时间检查的路径报告如下:

 

 

在这种情况下,由于锁存器透明时数据是可用的,因此会从后续路径借用所需的 1.81ns,然后仍能满足时序要求。以下是后续路径的路径报告,其中显示了前一条路径借用的 1.81ns:

 

 

时序违例的例子

在这种情况下,数据路径延迟要大得多,并且数据在锁存器关闭之后才能到达,这显然是时序违例的。

 

 

10.3 数据引脚到数据引脚检查

建立时间和保持时间检查也可以在任意两个数据引脚之间进行,这两个都不是时钟引脚。一个引脚为约束引脚(constrained pin),其作用类似于触发器的数据引脚,而另一个引脚为相关引脚(related pin),其作用类似于触发器的时钟引脚。关于触发器建立时间检查的一个重要区别是,数据到数据的建立时间检查是在与发起沿相同的沿上执行的(不同于触发器的常规建立时间检查,其中捕获时钟边沿通常会距离发起时钟沿一个周期)。因此,数据到数据的建立时间检查也称为零周期检查(zero-cycle checks)或同周期检查(same-cycle checks)。

 

使用 set_data_check 命令可以指定数据到数据的检查,SDC 约束命令示例如下:

 

set_data_check -from SDA -to SCTRL -setup 2.1

 

set_data_check -from SDA -to SCTRL -hold 1.5

 

参见图 10-6,SDA 是相关引脚,而 SCTRL 是约束引脚。建立时间数据检查规定 SCTRL 应该在相关引脚 SDA 的边沿之前至少 2.1ns 到达,否则即为数据到数据的建立时间检查违例。保持时间数据检查规定 SCTRL 应该在 SDA 之后至少 1.5ns 到达,如果约束引脚的信号早于该时刻到达,即为数据到数据的保持时间检查违例。

 

图 10-6

 

此检查在定制设计的模块中很有用,在定制设计的模块中很有可能会要去约束一个信号相对于另一个信号的到达时间。一种常见情况是由使能信号选通的数据信号,此时需要确保当数据信号到达时使能信号保持稳定。

 

考虑图 10-7 中所示的与门单元。我们假设要求是确保 PNA 在 PREAD 上升沿之前 1.8ns 到达,并且在 PREAD 上升沿之后 1.0ns 内不应发生改变。在此示例中,PNA 是约束引脚,而 PREAD 是相关引脚,对应的波形如图 10-7 所示。

 

图 10-7

 

对于这样的时序要求,可以使用数据到数据的建立时间和保持时间检查:

 

set_data_check -from UAND0/A1 -to UAND0/A2 -setup 1.8

 

set_data_check -from UAND0/A1 -to UAND0/A2 -hold 1.0

 

以下是建立时间检查路径报告:

 

 

建立时间在报告中显示为 data check setup time。以上时序违例的报告表明 PREAD 至少需要延迟 1.72ns,以确保 PNA 在 PREAD 之前 1.8ns 能够到达,这是我们的建立时间要求。

 

数据到数据建立时间检查很重要的一点是,约束引脚和相关引脚的发起时钟沿都来自同一时钟周期。因此,在报告中请注意,捕获沿(UDFF0 / CK)的起始时间为 0ns,而不是一个周期之后的时钟沿(通常在报告中看到的都是这种情况)。

 

零周期(zero-cycle)建立时间检查会导致保持时间检查与其它保持时间检查有所不同,保持时间检查将不再位于同一时钟沿。以下是 CLKPLL 的时钟定义,将用于下面的保持时间路径报告:

 

  • create_clock -name CLKPLL -period 10 -waveform {0 5} [get_ports CLKPLL]

 

 

注意,在保持时间检查中,相关引脚的发起沿比约束引脚的发起沿要早一个周期。这是因为根据定义,通常在建立时间捕获沿之前的一个周期执行保持时间检查。由于数据到数据建立时间检查的约束引脚和相关引脚的时钟沿相同,因此会在发起沿之前一个周期执行保持时间检查。

 

在某些情况下,设计人员可能要求在同一时钟周期上执行数据到数据的保持时间检查。相同周期的保持时间要求意味着要将用于相关引脚的时钟沿移回约束引脚的时钟沿处。可以通过指定多周期保持时间为 -1 来实现:

 

  • set_multicycle_path -1 -hold -to UAND0/A2

 

以下是带有多周期约束的上述示例的保持时间检查路径报告:

 

 

现在,保持时间检查是在约束引脚和相关引脚相同时钟沿上执行的。在同一周期中执行数据到数据保持时间检查的另一种方法是:将其指定为相反方向上的引脚之间的数据到数据建立时间检查。

 

  • set_data_check -from UAND0/A2 -to UAND0/A1 -setup 1.0

 

数据到数据的检查在对数据不改变进行检查(no-change data check)时也很有用。通过在上升沿处指定建立时间检查,在下降沿处指定保持时间检查,从而有效地定义了数据不变窗口,如图 10-8 所示。

 

图 10-8

 

这种情况的约束如下:

 

set_data_check -rise_from D2 -to D1 -setup 1.2

 

set_data_check -fall_from D2 -to D1 -hold 0.8

 

10.4 非时序检查

单元或宏(macro)的库文件可以将时序弧指定为非时序(non-sequential)检查,例如两个数据引脚之间的时序弧。非时序检查是指两个引脚之间的检查,两者都不是时钟。一个引脚是约束引脚,其作用类似于数据,而第二个引脚是相关引脚,其作用类似于时钟。该检查指定了在相关引脚上的数据改变前后,约束引脚上的数据必须保持稳定多长时间。

 

请注意,此检查被指定为单元库规范的一部分,并且不需要显式的数据到数据检查约束。以下是这种时序弧在单元库中的表示形式:

 

 

setup_rising 指相关引脚的上升沿,固有(intrinsic)上升值和下降值是指约束引脚的上升和下降建立时间。可以为 hold_rising、setup_falling 和 hold_falling 定义类似的时序弧。

 

非时序检查类似于 10.3 节中介绍的数据到数据检查,但是有两个主要区别。在非时序检查中,建立时间和保持时间的值是从标准单元库中获得的,可以使用 NLDM 表格模型或其它高级时序模型来描述建立时间和保持时间模型。而在数据到数据检查中,只能为数据到数据的建立时间或保持时间检查指定一个值。第二个区别是,非时序检查只能应用于单元的引脚,而数据到数据的检查可以应用于设计中的任意两个引脚。

 

非时序建立时间检查指定了约束信号必须相对于相关引脚多早到达,如图 10-9 所示。单元库中包含了建立时间弧 D0-> WEN,它被指定为了非时序弧。如果在建立时间窗口内出现 WEN 信号,则非时序建立时间检查将失败。

 

图 10-9

 

非时序保持时间检查指定了约束信号必须相对于相关引脚多晚到达,如图 10-9 所示。如果 WEN 在保持时间窗口中改变了,则非时序保持时间检查将失败。

 

 

 

贝塔的微信❞

 

MOMO 的微信❞