本章节介绍了如何为静态时序分析配置环境。正确的约束对于分析STA结果很重要,只有准确指定设计环境,STA分析才能够识别出设计中的所有时序问题。STA的准备工作包括设置时钟、指定IO时序特性以及指定伪路径和多周期路径。在继续学习下一章的时序验证之前,请务必全面了解本章节。
大部分数字设计是同步的,从前一个时钟周期计算出的数据在时钟有效沿上被锁存在触发器中。考虑图7-1中的典型同步设计。假定待分析设计(Design Under Analysis, DUA)会与其他同步设计交互。这意味着DUA从一个时钟触发器获取数据并将数据输出至DUA外的另一个时钟触发器。
为对这种设计执行STA,需要指定触发器的时钟,且需要进入和退出设计的所有路径的时序约束。
图7-1中的例子假定这里只有一个时钟和 C 1 C1 C1, C 2 C2 C2, C 3 C3 C3, C 4 C4 C4,和 C 5 C5 C5表示组合逻辑块,其中 C 1 C1 C1和 C 5 C5 C5在设计之外。
在一个典型设计中,可以有多个时钟,且存在多个路径从一个时钟域到另一个时钟域。以下部分描述了在这个场景下如何配置STA环境。
定义一个时钟,需要以下信息:
基本定义如图7-2所示。通过定义时钟,所有的内部时序路径(所有触发器到触发器的路径)均受到约束;这意味着所有的内部路径可仅使用时钟约束(clock specification)来分析。时钟约束指定触发器到触发器的路径必须占用一个周期。我们将介绍占用一个周期时间的要求怎样可以放宽。
这里有一个基本时钟约束/规范(specification和contraint在SDC规格中是同义词):
create_clock \
-name SYSCLK \
-period 20 \
-waveform {0 5} \
[get_ports2 SCLK]
该时钟名为SYSCLK
,并在端口SCLK
上定义。SYSCLK
的周期指定为
20
20
20个单位,如果未指定,默认时间单位为纳秒(通常,时间单位会在技术库中进行指定)。waveform
中的第一个自变量指定出现上升沿的时刻,第二个自变量指定出现下降沿的时刻。
waveform
选项中可以指定任意数量的边沿。但是,所有边沿必须在一个周期内。边沿时刻从零时刻之后的第一个上升沿开始,然后是下降沿,然后再是上升沿,以此类推,这意味着waveform
列表中的所有时刻值必须单调增加。
-waveform {time_rise time_fall time_rise time_fall ...}
另外,必须指定偶数个边沿时刻。waveform
选项将指定一个时钟周期内的波形,然后不断重复。如果未指定任何waveform
选项,则默认值为:
-waveform {0, period/2}
如下图7-3所示是一个没有指定waveform
选项的时钟约束的示例:
create_clock -period 5 [get_ports SCAN_CLK]
在此约束中,由于未指定-name
选项,因此时钟的名称与端口的名称相同,即SCAN_CLK
。
下图7-4是时钟约束的另一个示例,其中波形的边沿在一个周期的中间位置。
create_clock -name BDYCLK -period 15 \
-waveform {5 12} [get_ports GBCLK]
所创建时钟的名字为BDYCLK
且其被定义在端口GBLCLK
上。实际上,将时钟名和端口名保持一致最好。
以下是更多的时钟约束示例:
# 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.
# 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.
除了上述属性外,还可以在时钟源处指定过渡时间/压摆(transition_time/slew)。在某些情况下,例如顶层的输入端口或某些PLL的输出端口,工具无法自动计算出过渡时间。在这种情况下,在时钟源处显式地指定过渡时间很有用,这可以使用set_clock_transition
命令来指定。
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节)来约束时钟的压摆。
可以使用set_clock_uncertainty
约束来指定时钟周期的时序不确定度(uncertainty),该不确定度可用于对可能会减少有效时钟周期的各种因素进行建模。 这些因素可能是时钟抖动(jitter)以及可能需要在时序分析中考虑的任何其它悲观因素。
set_clock_uncertainty -setup 0.2 [get_clocks CLK_CONFIG]
set_clock_uncertainty -hold 0.05 [get_clocks CLK_CONFIG]
注意,建立时间检查的时钟不确定度将减少可用的有效时钟周期,如图7-7所示。对于保持时间检查,时钟不确定度将用作需要满足的额外时序裕量。
以下命令可用于指定跨时钟边界路径上的时钟不确定度,称为时钟间不确定度(inter-clock uncertainty)。
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
之间的路径。根据上述时钟间不确定度的约束,将
100
p
s
100ps
100ps用作建立时间检查的不确定度,将
50
p
s
50ps
50ps用作保持时间检查的不确定度。
可以使用set_clock_latency命令指定时钟的延迟。
# 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),触发器时钟引脚上的总时钟延迟是源延迟和网络延迟之和:
以下是一些指定源延迟和网络延迟的命令示例:
# 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)之前对时钟树延迟的估计值。在时钟树综合完成后,从时钟源到触发器时钟引脚的总时钟延迟是源延迟加上时钟树从时钟定义点到触发器的实际延迟。
下一节将介绍衍生时钟(generated clocks),7.9节将介绍虚拟时钟(virtual clocks)。
衍生时钟是从主时钟(master clock)所派生出来的。主时钟使用create_clock
命令来定义指定。
当在一个设计中基于主时钟产生一个新的时钟时,新时钟被定义为衍生时钟。例如,如果有一个时钟的三分频电路(divide-by-3 circuitry),则将在该电路的输出处定义一个衍生时钟。由于STA不知道分频逻辑输出的时钟周期已更改,更重要的是新的时钟周期是多少,因此需要定义衍生时钟。图7-10给出了衍生时钟示例,该时钟是主时钟的 C L K P CLKP CLKP的二分频(divide-by-2)。
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会报告出 T C L K TCLK TCLK和 T C L K D I V 5 TCLKDIV5 TCLKDIV5之间的路径。注意,这样的路径是不可能存在的,因为选择信号只能选择一个多路复用器的时钟输入。在这种情况下,可能需要设置伪路径或指定这两个时钟之间的互斥(exclusive)关系,以避免报告出错误的路径。当然,这假定设计中其它部分的 T C L K TCLK TCLK和 T C L K D I V 5 TCLKDIV5 TCLKDIV5之间没有路径。
如果多路复用器选择信号不是静态不变的并且在运行期间会发生变化,这样会发生什么呢? 在这种情况下,会对多路复用器输入端进行时钟门控(clock gating)检查,时钟门控检查将在第 10 10 10章中介绍,这些检查可确保多路复用器输入端的时钟相对于多路复用器选择信号能够安全地切换。
图7-12给出了一个示例,其中时钟 S Y S _ C L K SYS\_CLK SYS_CLK由触发器的输出进行门控。由于触发器的输出可能不是恒定的,因此处理这种情况的一种方法是在与门单元的输出处定义一个衍生时钟,该时钟与输入时钟相同。
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所示:
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
(分频)选项指定了衍生时钟的频率。
考虑图7-14中所示的时钟门控示例,两个时钟分别输入至一与门单元中,问题是与门单元的输出是什么?如果与门单元的输入均为时钟,则可以安全地在与门单元的输出端定义一个新的主时钟,因为单元的输出不太可能与任何一个输入时钟有任何相位关系。
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.
在内部引脚上创建时钟的一个缺点是:它会影响路径延迟计算,并迫使设计人员手动计算源延迟。
图7-15给出了一个衍生时钟的示例,除两个不同相的时钟外,还会生成一个二分频时钟。各时钟的波形也显示在图中。
该例的时钟定义如下。衍生时钟定义说明了-edge
选项是定义衍生时钟的又一方式。该选项采用源主时钟
{
r
i
s
e
,
f
a
l
l
,
r
i
s
e
}
\{rise,fall,rise\}
{rise,fall,rise}列表的方式来形成新的衍生时钟。主时钟的第一个上升沿是第一个沿(
f
i
r
s
t
e
d
g
e
first\, edge
firstedge),第一个下降沿是第二个沿(
e
d
g
e
2
edge\, 2
edge2),下一个上升沿是第三个沿(
e
d
g
e
3
edge\,3
edge3),以此类推。
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.
如果衍生时钟的第一个边沿是下降沿怎么办?考虑如图7-16所示的衍生时钟 G 3 C L K G3CLK G3CLK。可以通过指定边沿 5 5 5、 7 7 7和 10 10 10来定义这种衍生时钟,如以下时钟约束所示。注意, 1 n s 1ns 1ns时刻的下降沿将被自动推断出来。
create_generated_clock -name G3CLK -edges {5 7 10} \
-source DCLK [get_pins UAND0/Z]
-edge_shift
选项可与-edges
选项一起使用,以指定相应边沿的任何偏移以形成新的衍生波形。它指定边沿列表中每个边沿的偏移量(以时间单位)。以下是使用此选项的示例:
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
1
1移位
0
n
s
0ns
0ns获得了衍生时钟的第一个边沿,通过将源时钟的边沿
1
1
1偏移
5
n
s
5ns
5ns获得了衍生时钟的第二个边沿,而通过将源时钟的边沿
5
5
5移位
0
n
s
0ns
0ns获得了衍生时钟的第三个边沿。下图7-17显示了上述波形:
这里是衍生时钟的另一个例子;该例使用了invert
选项。在所有其它衍生时钟选项都被使用后,-invert
选项将会对衍生时钟进行反向。图7-18给出了产生这种反向时钟的原理图。
create_clock -period 10 [get_ports CLK]
create_generated_clock -name NCLKDIV2 -divide_by 2 -invert \
-source CLK [get_pins UINVQ/Z]
也可以为衍生时钟指定时钟延迟,在衍生时钟上指定的源延迟还包括了从主时钟定义点到衍生时钟定义点的延迟。因此,由衍生时钟驱动的触发器的时钟引脚的总时钟延迟是主时钟源延迟、衍生时钟源延迟和衍生时钟网络延迟的总和。如下图7-19所示:
衍生时钟可以将另一个衍生时钟作为其时钟源,即一个衍生时钟也可以具有衍生时钟,以此类推。但是,衍生时钟只能有一个主时钟。在后面的章节中将介绍更多衍生时钟的示例。
图7-20给出了在典型ASIC设计中如何进行时钟分配(clock distribution)的情形。晶振(Oscillator)在芯片外部产生低频(典型值为 10 − 50 10-50 10−50MHz)时钟,片上PLL将其用作参考时钟,以生成高频低抖动时钟(典型值为 200 − 800 200-800 200−800MHz)。然后,该PLL的输出时钟被输入到时钟分频器逻辑中,该逻辑产生ASIC所需的时钟。
在时钟分配的某些分支上,可能有时钟门控(clock gates)用于在设计的无效部分关闭时钟,以在必要时节省功耗。在PLL的输出端也可以接一个多路复用器,以便在必要时可以绕过PLL。
在进入设计的芯片输入端口处为参考时钟定义了一个主时钟,在PLL的输出处定义了第二个主时钟。PLL的输出时钟与参考时钟没有任何相位关系。因此,PLL的输出时钟不应是参考时钟的衍生时钟。很有可能的是,由时钟分频器逻辑生成的所有时钟都将被指定为PLL输出处主时钟的衍生时钟。
本节将介绍输入路径的约束。这里需要注意的一点是,STA无法检查不受约束的路径上的任何时序,因此需要约束所有路径以进行时序分析。在后面的章节中会介绍一些示例,其中一些示例可能并不关心某些逻辑,因而这些输入路径可能可以不用约束。例如,设计人员可能并不在乎一些输入控制信号的时序,因此可能并不需要进行本节中将要介绍的时序检查。但是,本节假定我们要约束全部的输入路径。
图7-21中为待分析设计(DUA)的输入路径。触发器 U F F 0 UFF0 UFF0在设计的外部,并向设计内部的触发器 U F F 1 UFF1 UFF1提供数据。数据通过输入端口 I N P 1 INP1 INP1连接两个触发器。
C L K A CLKA CLKA的时钟定义指定了时钟周期,这是两个触发器 U F F 0 UFF0 UFF0和 U F F 1 UFF1 UFF1之间可用的总时间。外部逻辑所需的时间为 T c l k 2 q Tclk2q Tclk2q(数据发起触发器 U F F 0 UFF0 UFF0的 C K CK CK至 Q Q Q延迟)加上 T c 1 Tc1 Tc1(通过外部组合逻辑的延迟),因此输入引脚 I N P 1 INP1 INP1上的延迟定义指定了 T c l k 2 q Tclk2q Tclk2q加上 T c 1 Tc1 Tc1的外部延迟。并且这个外部延迟是相对于一个时钟指定的,在本例中为时钟 C L K A CLKA CLKA。
下面是输入延迟约束:
set Tclk2q 0.9
set Tc1 0.6
set_input_delay -clock CLKA -max [expr Tclk2q + Tc1] \
[get_ports INP1]
该约束指定输入端口 I N P 1 INP1 INP1的外部延迟为 1.5 n s 1.5ns 1.5ns,且这是相对于时钟 C L K A CLKA CLKA而言的。假设 C L K A CLKA CLKA的时钟周期为 2 n s 2ns 2ns,则 I N P 1 INP1 INP1引脚的逻辑只有 500 p s ( = 2 n s − 1.5 n s ) 500ps(=2ns-1.5ns) 500ps(=2ns−1.5ns)可以在设计内部中传播。此输入延迟定义意味着输入约束为: T c 2 Tc2 Tc2加上触发器 U F F 1 UFF1 UFF1的 T s e t u p Tsetup Tsetup必须小于 500 p s 500ps 500ps,才可以确保可靠地捕获到触发器 U F F 0 UFF0 UFF0发起的数据。请注意,上述外部延迟值被指定为了最大值(max)。
让我们同时考虑最大和最小延迟情况,如图7-22所示。以下是此示例的约束:
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]
I N P A INPA INPA的最大和最小延迟是从 C L K P CLKP CLKP到 I N P A INPA INPA的延迟中得出的,最大和最小延迟分别是最长和最短路径延迟,这些通常也可以对应于最坏情况(worst-case)下的慢速(最大时序工艺角)和最佳情况(best-case)下的快速(最小时序工艺角)。因此,最大延迟对应于最大时序工艺角下的最长路径延迟,最小延迟对应于最小时序工艺角下的最短路径延迟。在我们的示例中, 1.1 n s 1.1ns 1.1ns和 0.8 n s 0.8ns 0.8ns是 T c k 2 q Tck2q Tck2q的最大和最小延迟值。组合逻辑路径延迟 T c 1 Tc1 Tc1的最大延迟为 5.6 n s 5.6ns 5.6ns,最小延迟为 2.2 n s 2.2ns 2.2ns。 I N P A INPA INPA上的波形显示了数据到达设计输入端的时间窗口,以及预计达到稳定状态的时间。从 C L K P CLKP CLKP到 I N P A INPA INPA的最大延迟为 6.7 n s ( = 1.1 n s + 5.6 n s ) 6.7ns(= 1.1ns + 5.6ns) 6.7ns(=1.1ns+5.6ns),最小延迟为 3 n s ( = 0.8 n s + 2.2 n s ) 3ns(= 0.8ns + 2.2ns) 3ns(=0.8ns+2.2ns),这些延迟是相对于时钟有效沿指定的。在给定外部输入延迟的情况下,设计内部的可用建立时间是慢角(slow corner)下的 8.3 n s ( = 15 n s − 6.7 n s ) 8.3ns(= 15ns-6.7ns) 8.3ns(=15ns−6.7ns)和快角(fast corner)下的 12 n s ( = 15 n s − 3.0 n s ) 12ns(= 15ns-3.0ns) 12ns(=15ns−3.0ns)中的最小值。因此, 8.3 n s 8.3ns 8.3ns是用来可靠地捕获DUA内部数据的可用时间。
以下是输入约束的更多示例:
set_input_delay -clock clk_core 0.5 [get_ports bist_mode]
set_input_delay -clock clk_core 0.5 [get_ports sad_state]
由于未指定max或min选项,因此
500
p
s
500ps
500ps这个值将同时用于最大延迟和最小延迟。此外部输入延迟是相对于时钟clk_core
的上升沿指定的(如果输入延迟是相对于时钟的下降沿指定的,则必须使用-clock_fall
选项)。
本节将借助下面的三个例子来介绍输出路径的约束:
例子A:图7-23为一条通过待分析设计输出端口的路径示例,其中 T c 1 Tc1 Tc1和 T c 2 Tc2 Tc2是通过组合逻辑的延迟。
时钟 C L K Q CLKQ CLKQ的周期定义了触发器 U F F 0 UFF0 UFF0和 U F F 1 UFF1 UFF1之间的总可用时间。外部逻辑的总延迟为 T c 2 Tc2 Tc2加上 T s e t u p Tsetup Tsetup,此总延迟 T c 2 + T s e t u p Tc2 + Tsetup Tc2+Tsetup必须作为输出延迟约束的一部分来指定。注意,输出延迟是相对于捕获时钟指定的,数据必须及时到达外部触发器 U F F 1 UFF1 UFF1才能满足其建立时间要求。
set Tc2 3.9
set Tsetup 1.1
set_output_delay -clock CLKQ -max [expr Tc2 + Tsetup] \
[get_ports OUTB]
这指定了相对于时钟边沿的最大外部延迟为 T c 2 Tc2 Tc2加上 T s e t u p Tsetup Tsetup,即 5 n s 5ns 5ns的延迟。最小延迟可以类似地指定。
例子B:图7-24给出了同时具有最小和最大延迟的示例。
最大路径延迟为 7.4 n s ( = m a x { T c 2 } + T s e t u p = 7 + 0.4 ) 7.4ns(=max\, \{Tc2 \}\,+\,T_{setup} = 7 + 0.4) 7.4ns(=max{Tc2}+Tsetup=7+0.4),最小路径延迟为 − 0.2 n s ( = m i n { T c 2 } − T h o l d = 0 − 0.2 ) -0.2ns(=min\{Tc2\}-T_{hold} = 0-0.2) −0.2ns(=min{Tc2}−Thold=0−0.2)。因此,输出约束为:
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中的波形显示了 O U T C OUTC OUTC必须保持稳定状态的时间,以确保外部触发器能够可靠地捕获它。这说明在所需的稳定区域开始之前,数据就必须在输出端口准备就绪,并且必须保持稳定,直到稳定区域结束为止。这同样反映了DUA内部对输出端口 O U T C OUTC OUTC逻辑的时序要求。
例子C:这是另一个输入约束和输出约束的示例。该模块具有两个输入端口 D A T A I N DATAIN DATAIN和 M C L K MCLK MCLK,以及一个输出端口 D A T A O U T DATAOUT DATAOUT。图7-25显示了预期的波形。
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]