赞
踩
描述了常用库单元描述中的时序相关信息。本章仅关注与时序、串扰和功率分析相关的属性,尽管库单元包含多个属性。纳米技术中对时序的主要影响是互连。
除了时序信息外,库单元描述还包含几个属性(attributes),如单元面积和功能,这些属性与时序无关,但在RTL合成过程中相关。在本章中,我们只关注与时序和功率计算相关的属性(attributes)。
可以使用各种标准格式来描述库单元。虽然各种格式的内容基本相似,但我们已经使用Liberty语法描述了库单元示例。
本章的开始部分描述了线性和非线性时序模型(linear and the non-linear timing models ),然后是第3.7节描述的纳米技术的高级时序模型。
单元的每个输入和输出都可以指定引脚处的电容。在大多数情况下,电容仅针对单元输入而不是输出指定,即大多数单元库中的输出引脚电容为 0。
- 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_capacitance 和fall_capacitance 值指定为一个范围,并在说明中指定下限和上限值。
单元时序模型旨在为设计环境中单元的各种实例提供准确的时序。时序模型通常是从单元的详细电路模拟中获得,以模拟单元运行的实际场景。为单元的每个时序弧指定时序模型。
让我们首先考虑一个简单的逆变器逻辑单元的时序弧,如图3-1所示,因为它是一个逆变器,在输入端的上升(下降)转变导致输出处的下降(上升)转变。单元的两种延迟特性是:
请注意,延迟是基于单元库中定义的阈值点来测量的(参见第2.4节),通常为50%Vdd。因此,从输入超过其阈值点到输出超过其阈值点,测量延迟。
通过逆变器单元的时序电弧延迟取决于两个因素:
延迟值与负载电容直接相关——负载电容越大,延迟越大。在大多数情况下,延迟随着输入转换时间的增加而增加。在某些情况下,输入阈值(用于测量延迟)与单元的内部开关点有显着差异。在这种情况下,通过单元的延迟可能会表现出相对于输入转换时间的非单调行为 - 较大的输入转换时间可能会产生较小的延迟,尤其是在输出负载较轻的情况下。
单元输出的转换(slew)主要取决于输出电容——输出转换时间随着输出负载的增加而增加。因此,根据单元类型及其输出负载,输入处的大转换(大转换时间)可以改善输出处。图 3-2 显示了单元输出的转换时间可以根据单元输出的负载而改善或恶化的情况。
一个简单的时序模型是线性延迟模型,其中单元的延迟和输出转换时间表示为两个参数的线性函数:输入转换时间和输出负载电容。通过单元的延迟 D 的线性模型的一般形式如下所示。
其中 D0、D1、D2 是常数,S 是输入转换时间,C 是输出负载电容。线性延迟模型在亚微米技术的输入转换时间和输出电容范围内不准确因此,大多数单元库目前使用更复杂的模型,例如非线性延迟模型。
大多数单元库都包含表(table)模型,用于指定单元的各种时序弧的延迟和时序检查。一些用于纳米技术的较新的时序库还提供了基于电流源的高级时序模型(例如 CCS、ECSM 等),本章稍后将对其进行介绍。table型称为 NLDM(非线性延迟模型),用于延迟、输出转换或其他时序检查。
table模型捕获了通过单元输入引脚的输入转换时间和单元输出的总输出电容的各种组合的延迟。
延迟的 NLDM 模型以二维形式呈现,两个独立变量是输入转换时间(input transition time )和输出负载电容(output load capacitance),table中的条目表示延迟。以下是典型逆变器单元的此类table示例:
- 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_rise 和 cell_fall。索引的类型和表查找索引的顺序在查找表模板 delay_template_3x3 中描述。
- 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_fall 和 cell_rise 延迟表中的实际索引值覆盖。指定索引值的另一种方法是在模板定义中指定索引值,而不是在 cell_rise 和 cell_fall 表中指定它们。这样的模板看起来像这样:
- 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 模型不仅用于延迟,还用于单元输出的转换时间,其特征在于输入转换时间和输出负载。因此,有单独的二维表用于计算单元的输出上升和下降转换时间。
- 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 模型的逆变器单元具有下表:
给定这种单元的输入转换时间和输出电容,如图 3-3 所示,从 cell_rise 表中获得 15ps 输入转换时间(下降)和 10fF 负载的上升延迟,从20ps 输入转换时间(上升)和 10fF 负载的 cell_fall 表。
指定单元正在反转的信息在哪里?该信息被指定为时序弧的timing_sense 字段的一部分。在某些情况下,此字段未指定,但应从引脚功能派生。
对于示例反相器单元,时序弧为negative_unate,这意味着输出引脚转换方向与输入引脚转换方向相反(负)。因此,cell_rise 表查找对应于输入引脚的下降转换时间。
本节通过示例说明表模型的查找。如果输入转换时间和输出电容对应于表条目,则表查找是微不足道的,因为时序值直接对应于表中的值。下面的示例对应于查找不对应于表中任何可用条目的一般情况。在这种情况下,使用二维内插来提供结果时序值。为表插值选择每个维度中两个最近的表索引。考虑输入转换时间为 0.15ns 和输出电容为 1.16pF 的下降转换表(上面指定的示例表)。下面再现了与二维插值相关的下降过渡表的相应部分。
- 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
slew(即transition time)值基于库中指定的测量阈值。大多数上一代库(0.25 毫米或更早)使用 10% 和 90% 作为压摆或转换时间的测量阈值。
选择转换阈值以对应于波形的线性部分。随着技术变得越来越精细,实际波形最线性的部分通常在 30% 到 70% 之间。因此,大多数新一代时序库将转换测量点指定为 Vdd 的 30% 和 70%。但是,由于之前测量的转换时间在 10% 到 90% 之间,因此在填充库时测量的转换时间通常在 30% 到 70% 之间加倍。这由通常指定为 0.5 的转换降额系数指定。 30% 和 70% 的转换阈值(转换降额为 0.5)导致等效的测量点为 10% 和 90%。阈值设置示例如下所示。
- /* 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)。
具有一组不同转换阈值设置的另一个示例可能包含:
- /* 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 。
这是单元库中转换阈值设置的另一个示例。
- 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 所示。
指定slew降额时,延迟计算期间内部使用的slew值为:
library_transition_time_value * slew_derate
这是延迟计算工具内部使用的转换,对应于特征转换阈值测量点。
让我们考虑两个输入和单元的时序弧。该单元的两个时序弧都是positive_unate;因此,输入引脚上升对应于输出上升,反之亦然。
对于二输入and单元,有四种延迟:
这意味着对于 NLDM 模型,将有四个表模型用于指定延迟。类似地,也将有四个这样的表模型用于指定输出转换时间。
一个三输入 nand 单元的输入 INP1 到输出 OUT 的时序模型示例如下所示。
- 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_rise 和 cell_fall 以及两个转换表rise_transition 和 fall_transition 来描述从 INP1 到 OUT 的时序弧的特性。输出 max_transition 值也包含在上面的示例中。
Positive or Negative Unate
如第 2.7 节所述,nand 单元示例中的时序弧为negative unate,这意味着输出引脚转换方向与输入引脚转换方向相反(负)。因此,cell_rise 表查找对应于输入引脚的下降转换时间。另一方面,通过and单元格或or单元格的时序弧是positive unate,因为输出转换与输入转换的方向相同。
考虑具有三个输入和两个输出的组合块。
像这样的块可以有许多时序弧。通常,时序弧可以从块的每个输入到每个输出。如果从输入到输出的逻辑路径是non-inverting 或 positive unate,则输出具有与输入相同的极性。如果是反相逻辑路径是negative unate,则输出与输入极性相反;因此,当输入上升时,输出下降。这些时序弧表示通过块的传播延迟。
一些通过组合单元格的时序弧可以是positive unate 也可以是negative unatee。一个例子是通过两输入异或单元的时序弧。两输入异或( xor )单元的输入处的转换 可导致输出转换沿相同或相反的转换方向,具体取决于单元的另一个输入的逻辑状态。这些时序弧可以被描述为non-unate或两组不同的 positive unate 和 negative unate 时序模型,它们依赖于状态。此类依赖于状态的表在第 3.5 节中有更详细的描述。
考虑图 3-8 中所示的时序单元的时序弧。
对于同步输入(synchronous inputs),例如引脚 D(或 SI、SE),有以下时序弧:
对于异步输入(asynchronous inputs),例如 pin CDN,有以下时序弧:
对于触发器的同步输出,例如引脚 Q 或 QN,有以下时序弧:
所有同步时序弧都与时钟的有效边沿有关,时钟的边沿使时序单元捕获数据。此外,时钟引脚和异步引脚等清零,可以进行脉宽定时检查。图 3-9 显示了使用各种信号波形的时序检查。
需要建立和保持同步时序检查,以便通过时序单元正确传递数据。这些检查验证数据输入在时钟的有效边沿是明确的,并且正确的数据在有效边沿被锁存。这些时序检查验证数据输入在活动时钟边沿附近是否稳定。当数据输入必须保持稳定时,激活时钟之前的最短时间称为建立时间(setup time)。从超过阈值的最新数据信号(通常为Vdd的50%)到超过其阈值的活动时钟边缘(通常为Vdd的50%)的时间间隔是setup time。类似地,保持时间(hold time)是数据输入必须在时钟活动边缘之后保持稳定的最短时间。从超过其阈值的活动时钟边缘到超过其阈值的最早数据信号的时间间隔是hold time。如前所述,时序单元时钟的有效边沿是导致时序单元捕获数据的上升沿或下降沿。
建立和保持检查示例(Example of Setup and Hold Checks)
时序单元的同步引脚的setup 和hold constraints通常以二维表格的形式描述,如下所示。下面的示例显示触发器数据引脚的setup 和hold时序信息。
- 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描述为:
- 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是要求数据信号稳定的区域宽度。
对于触发器,在扫描数据输入引脚上有一个负的hold时间是有帮助的。这在时钟偏移(clock skew)方面提供了灵活性,并且可以消除几乎所有缓冲器插入的需要,以便在scan mode中修复hold冲突(scan mode是触发器串行连接形成扫描链的模式-触发器的输出通常串行连接到下一个触发器的扫描数据输入引脚;这些连接用于测试性)。
与同步数据输入上的setup 或 hold check类似,有约束检查控制异步管脚。下面将描述这些。
恢复和去除检查(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 引脚为低电平有效,因此该引脚上的高脉冲宽度没有限制,因此未指定。
- 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");
- }
- }
- }
时序单元的传播延迟是从时钟的有效边沿到输出的上升沿或下降沿。这是负边沿触发的触发器的传播延迟弧示例,从时钟引脚 CKN 到输出 Q。这是一个非同步的时序弧,因为时钟的有效边沿可能导致上升或下降输出 Q 上的边缘。这是延迟表:
- 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。
- timing() {
- related_pin : "CKP";
- timing_type : rising_edge;
- timing_sense : non_unate;
- cell_rise(delay_template_3x3) {
- . . .
- }
- . . .
- }
在许多组合块中,输入和输出之间的时序弧取决于块中其他引脚的状态。输入和输出引脚之间的这些时序弧可以是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 的时序模型指定如下:
- 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 的情况。
- 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 处于活动状态时,另一组在扫描启用引脚处于非活动状态时。
- 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规范的示例:
- leakage_power() {
- when : "A1 !A2";
- value : 259.8;
- }
- leakage_power() {
- when : "A1 A2";
- value : 282.7;
- }
本节介绍黑匣子(任意模块或块)的 IO 接口的时序弧。时序模型捕获黑盒 IO 接口的时序。黑盒接口模型可以具有逻辑组合以及时序单元的时序弧。一般来说,这些时序弧弧也可以是状态相关的。
对于图 3-11 所示的示例,时序弧可以放置在以下类别下:
除了上面的时序弧,还可以对黑匣子的外部时钟引脚进行脉宽检查。也可以定义内部节点并在这些内部节点上定义生成的时钟以及指定进出这些节点的时序弧。总之,黑盒模型可以具有以下时序弧:
时序模型(例如 NLDM)表示通过基于输出负载电容和输入转换时间的时序弧的延迟。实际上,单元输出看到的负载由电容和互连电阻组成。由于 NLDM 方法假设输出负载是纯电容性的,因此互连电阻成为一个问题。即使互连电阻不为零,当互连电阻的影响很小时,也可以使用这些 NLDM 模型。在存在电阻互连的情况下,延迟计算方法通过获得单元输出处的等效有效电容来改进 NLDM 模型。延迟计算工具中使用的“有效”电容方法获得等效电容,该电容在单元的输出端具有与具有 RC 互连的单元相同的延迟。有效电容方法在第 5.2 节中作为延迟计算的一部分进行了描述。
随着特征尺寸的缩小,由于波形变得高度非线性,互连电阻的影响会导致很大的不准确性。各种建模方法为单元输出驱动器提供了额外的精度。从广义上讲,这些方法通过等价电流源驱动的输出状态建模获得更高的精度。
这些方法的示例是 - CCS(Composite Current Source复合电流源)或 ECSM(Effective
Current Source Model有效电流源模型)。例如,CCS 时序模型通过使用随时间变化和电压相关的电流源为单元输出驱动器建模提供了额外的精度。通过指定不同场景下接收器引脚电容和输出充电电流的详细模型来提供时序信息。接下来描述 CCS 模型的细节。
接收器引脚电容对应于为 NLDM 模型指定的输入引脚电容。与 NLDM 模型的引脚电容不同,CCS 模型允许在转换波形的不同部分分别指定接收器电容。由于互连 RC 和等效输入非线性电容(由于来自单元内输入设备的米勒效应),接收器电容值在转换波形上的不同点发生变化。因此,该电容在波形的初始(或前导)部分与波形的尾随部分被不同地建模。
接收器引脚电容可以在引脚级别指定(如在 NLDM 模型中),其中通过该引脚的所有时序弧都使用该电容值。或者,接收器电容可以在时序弧级指定,在这种情况下,可以为不同的时序弧指定不同的电容模型。下面描述这两种指定接收器引脚电容的方法。
在引脚级别指定电容
当在引脚级别指定时,接下来给出接收器引脚电容的一维表规范示例。
- 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 的负载的函数。
- 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 约束的类似定义。
在 CCS 模型中,非线性时序用输出电流表示。输出电流信息被指定为依赖于输入转换时间和输出负载的查找表。
输出电流针对输入转换时间和输出电容的不同组合而指定。对于这些组合中的每一个,都指定输出电流波形。本质上,这里的波形是指指定为时间函数的输出电流值。使用output_current_fall 指定的下降输出波形的输出电流示例如下所示:
- 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 指定的上升输出波形的输出电流的描述类似。
本节介绍用于串扰噪声(或毛刺glitch)分析的 CCS 模型。这些被描述为 CCSN(CCS noise)模型。 CCS noise模型是结构模型,代表单元内不同的 CCB(Channel Connected Blocks通道连接块)。
什么是CCB? CCB是指单元的源漏通道连接部分。例如,单级单元(如反相器、与非单元和非单元)仅包含一个 CCB——整个单元通过使用一个通道连接区域连接。多级单元,例如和单元,或或单元,包含多个 CCB。
CCSN 模型通常指定为由单元输入驱动的第一个 CCB,以及驱动单元输出的最后一个 CCB。这些是使用稳态电流、输出电压和传播噪声模型指定的。
对于单级组合单元,如 nand 和 nor 单元,CCS 噪声模型是为每个时序弧指定的。这些单元只有一个 CCB,因此模型是从单元的输入引脚到输出引脚。
下面描述了一个 nand 单元的示例模型:
- 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 几乎总是true,但对于非功能性单元(例如称重单元和天线单元)的除外。值为 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 输出端的毛刺波形。这些多维表包含:
CCB 输出电压(或通过 CCB 传播的噪声)在表中指定。
两级单元的噪声模型(Noise Models for Two-Stage Cells)
就像单级单元一样,两级单元(例如and cells 和 or cells)的 CCS 噪声模型通常被描述为时序弧的一部分。由于这些单元包含两个单独的 CCB,噪声模型分别为 ccsn_first_stage 和另一个为 ccsn_last_stage 指定。例如,对于双输入and单元,CCS 噪声模型由第一阶段和最后阶段的单独模型组成。这在接下来说明。
- 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 噪声模型。
- 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):抗噪模型指定输入引脚允许的毛刺幅度。这些通常根据以毛刺宽度和输出电容作为两个指标的二维表来描述。表中的值对应于输入引脚允许的毛刺幅度。这意味着任何小于指定幅度和宽度的毛刺都不会通过单元传播。可以指定抗噪模型的不同变体,例如:
单元库包含与单元中的功耗相关的信息。这包括有功功率以及待机或泄漏功率。顾名思义,有功功率与设计中的活动有关,而待机功率是在待机模式下消耗的功率,这主要是由于泄漏造成的。
有功功率与单元输入和输出引脚的活动有关。单元中的有功功率来自输出负载的充电以及内部开关。这两者通常分别称为output switching power 和 internal switching power。
输出开关功率(output switching power)与单元类型无关,仅取决于输出容性负载、开关频率和单元的电源。内部开关功率取决于单元的类型,因此该值包含在单元库中。下面描述库中内部开关电源的约束。
内部开关电源在单元库中称为 internal power。这是当单元的输入或输出有活动时单元内的功耗。对于组合单元,输入引脚转换会导致输出切换,从而产生内部开关电源。例如,只要输入切换(在输入处有上升或下降转换),逆变器单元就会消耗功率。库中的内部电源描述为:
- 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) 为单位的能量)。因此,库中的内部功率实际上指定了每次转换消耗的内部能量。
除了功率表之外,上面的示例还说明了电源引脚、接地引脚和断电功能的约束,该功能指定了单元可以断电的条件。这些构造允许在不同电源可能断电的设计和场景中使用多个电源。下图显示了每个单元的电源引脚约束。
- 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 的输出电容。
- 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");
- }
- }
即使输出或内部状态没有转换,也可以消耗开关功率。一个常见的例子是在触发器的时钟引脚上切换的时钟。触发器在每次时钟切换时消耗功率 - 通常是由于触发器单元内部的反相器的切换。即使触发器输出不切换,时钟引脚切换引起的功率也会耗散。因此,对于时序单元,输入引脚功率是指单元内部的功耗,即输出不转换时的功耗。下面是输入引脚电源约束的示例。
- 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 内部功率的贡献。
上述准则是指应用工具使用功率表的一致性,并确保在功率计算过程中不会重复计算由于时钟输入而指定的内部功率。
大多数标准单元都设计为仅在输出或状态发生变化时才耗散功率。当单元通电但没有活动时消耗的任何功率都是由于非零泄漏电流。泄漏可能是由于 MOS 器件的亚阈值电流或由于通过栅极氧化物的隧道电流。在前几代 CMOS 工艺技术中,漏电功率一直可以忽略不计,在设计过程中也不是主要考虑因素。然而,随着技术的缩小,泄漏功率变得越来越重要,与有功功率相比不再可以忽略不计。
高 Vt 单元是指阈值电压高于工艺技术标准的单元。
上所述,泄漏功率贡献来自两种现象:MOS 器件中的亚阈值电流和栅极氧化物隧穿。通过使用高 Vt 单元,可以降低亚阈值电流;然而,由于高 Vt 单元的速度降低,因此需要进行权衡。高 Vt 单元具有较小的泄漏但速度较慢。类似地,低 Vt 单元具有更大的泄漏但允许更快的速度。通过切换到高(或低)Vt 单元,栅极氧化物隧道效应不会显着改变。因此,控制泄漏功率的一种可能方式是使用高 Vt 单元。与高 Vt 和标准 Vt 单元之间的选择类似,设计中使用的单元强度是泄漏和速度之间的权衡。更高强度的单元具有更高的泄漏功率,但提供更高的速度。与电源管理相关的权衡在第 10.6 节中详细描述。
亚阈值 MOS 泄漏与温度具有很强的非线性相关性。在大多数工艺技术中,随着器件结温从 25C 增加到 125C,亚阈值泄漏会增加 10 到 20 倍。栅极氧化物隧道效应的贡献相对于温度或器件的 Vt 而言是相对不变的。在 100 纳米及以上工艺技术中可忽略不计的栅极氧化物隧道效应,已成为 65 纳米或更精细技术在较低温度下泄漏的重要因素。例如,对于 65nm 或更精细的工艺技术,栅极氧化物隧道泄漏可能等于室温下的亚阈值泄漏。在高温下,亚阈值泄漏仍然是泄漏功率的主要贡献者。
为库中的每个单元指定了泄漏功率。例如,逆变器单元可能包含以下约束:
cell_leakage_power : 1.366;
这是单元中耗散的泄漏功率 - 泄漏功率单位在库的标题中指定,通常以纳瓦为单位。通常,泄漏功率取决于单元的状态,并且可以使用 when 条件指定状态相关值。
例如,INV1 单元可以具有以下约束:
- cell_leakage_power : 0.70;
- leakage_power() {
- when : "!I";
- value : 1.17;
- }
- leakage_power() {
- when : "I";
- value : 0.23;
- }
其中 I 是 INV1 单元的输入引脚。应该注意的是,约束包括一个默认值(在when条件之外),并且默认值通常是在when条件内指定的泄漏值的平均值。
除了时序信息之外,库中的单元描述还指定了时序弧的区域、功能和 SDF 条件。本节简要介绍了这些内容;有关更多详细信息,请参阅 Liberty 手册。
面积约束(Area Specification)
area规范提供了一个单元或单元组的面积。
area : 2.35;
以上指定单元格的面积为 2.35 个面积单位。这可以代表单元使用的实际硅面积,也可以是面积的相对量度。
功能约束(Function Specification)
function规范指定引脚(或引脚组)的功能。
- pin (Z) {
- function: "IN1 & IN2";
- . . .
- }
以上指定了两个输入and单元的 Z 引脚的功能。
SDF条件(SDF Condition)
SDF 条件属性支持标准延迟格式 (SDF) 文件生成和反注释期间的条件匹配。正如when为时序分析的状态相关模型指定条件一样,SDF注释的状态相关时序使用的相应规范由sdf_cond表示。
以下示例说明了这一点:
- timing() {
- related_pin : "A1";
- when : "!A2";
- sdf_cond : "A2 == 1'b0";
- timing_sense : positive_unate;
- cell_rise(delay_template_7x7) {
- . . .
- }
- }
单元库指定了创建库的特征和操作条件。例如,库的标题可能包含以下内容:
- 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-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 因子的使用方法如下:
- Result with derating = Original_value *
- ( 1 + k_process * DELTA_Process
- + k_volt * DELTA_Volt
- + k_temp * DELTA_Temp)
例如,假设一个库在 1.08V 和 125C 下具有慢速过程模型。如果要获得 1.14V 和 100C 的延迟,则慢速工艺模型的单元上升延迟可通过下式获得:
- Derated_delay = Library_delay *
- ( 1 + k_volt_cell_rise * 0.06
- - k_temp_cell_rise * 25)
假设使用了上面概述的 k_factors,则前面的等式映射为:
- Derated_delay = Library_delay * (1 - 0.42 * 0.06 - 0.0012 * 25)
- = Library_delay * 0.9448
降额条件下的延迟计算为原始延迟的 94.48%。
单元描述具有库单位方面的所有值。这些单位是使用 Liberty 命令集在库文件中声明的。电压、时间、电容和电阻的单位声明如下例所示:
- 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),除非明确指定以帮助解释。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。