为了定义一个时钟,我们需要提供以下信息:
通过定义时钟, 所有内部时序路径 ( 触发器到触发器路径 )都将受到约束,这意味着可以仅使用时钟约束来分析所有内部路径。时钟约束指定受该clock控制的相邻的触发器到触发器的路径之间的延时 必须占用一个周期 ,稍后我们将介绍如何放宽这一要求(一个周期时间)。
create_clock -name SYSCLK -period 20 -waveform {0 5} [get_ports SCLK]
该时钟名(-name)为SYSCLK,并在端口SCLK上定义( [get_ports SCLK])。SYSCLK的周期(-period)指定为20个单位,如果未指定,默认时间单位为纳秒(通常,时间单位会在技术库中进行指定)。waveform中的第一个自变量指定出现上升沿的时刻,第二个自变量指定出现下降沿的时刻。
如果未指定任何waveform选项,则默认值为: -waveform { 0,period/2 }。
waveform选项中可以指定 任意偶数个边沿 。但是, 所有边沿必须在一个周期内 。边沿时刻从零时刻之后的 第一个上升沿开始 ,然后是下降沿,然后再是上升沿,以此类推,这意味着waveform列表中的 所有时刻值必须单调增加 。 -waveform {time_rise time_fall time_rise time_fall ...}。另外, 必须指定偶数个边沿时刻 。waveform选项将指定一个时钟周期内的波形,然后不断重复。
例:
上图的时钟约束为: create_clock -period 125 -waveform {100 150} [get_ports ARMCLK],因为waveform中的边沿必须从上升沿开始。
如果未指定-name选项,时钟的名称与端口的名称相同。
例:create_clock -period 5 [get_ports SCAN_CLK] ,该时钟的名称将为 SCAN_CLK
最好将时钟名称与端口名称保持一致 。
除了上述特性外,还可以在时钟源处指定transition time (slew)。
术语“slew”和“transition time”在本文中可互换使用。
在数字威廉希尔官方网站 中,当输入信号发生变化时,输出信号并不会立即响应,而需要一定的时间来完成状态的转换。这个状态转换所需的时间就是 transition time。
这个约束 仅适用于理想时钟 , 一旦构建了时钟树就将其忽略 ,因为此时将会使用时钟引脚上的实际transition time。如果在输入端口上定义了时钟,也可以使用set_input_transition命令来约束。
可以使用set_clock_uncertainty约束来指定时钟周期的timing uncertainty,该不确定度可用于对可能会减少有效时钟周期的各种因素进行建模。 这些因素可能是 时钟抖动(clock jitter) 以及可能需要在时序分析中考虑的任何其它悲观度。
set_clock_uncertainty -setup 0.2 [get_clocks CLK_CONFIG]
set_clock_uncertainty -hold 0.05 [get_clocks CLK_CONFIG]
set_clock_uncertainty -from SYS_CLK -to CFG_CLK -hold 0.05
set_clock_uncertainty -from SYS_CLK -to CFG_CLK -setup 0.1
根据上述时clock uncertainty的约束,将100ps用作建立时间检查的不确定度,将50ps用作保持时间检查的不确定度。
Network Latency是指从clock definition point到触发器时钟引脚的延迟。
clock definition point: create_clock的点。
Source Latency 也称为(insertion delay),是指从时钟源到时钟定义点的延迟。
Source Latency 可能是片上的延迟也可能是片外的延迟。 示例:
对于max,min,rise,fall,指定了一个0.8ns的network latency (因为没有-source选项),
指定了一个max 的 source latency。
一旦为设计 建立了时钟树 ,就可以 忽略network latency (假设指定了set_propagated_clock命令)。但是,即使在建立时钟树之后, source latency也会保留 。
因为network latency是在进行时钟树综合(Clock Tree Synthesis)之前对时钟树延迟的估计值,有了时钟树之后就可以使用实际值。
在有了时钟树综合完成后:
从时钟源到触发器的时钟引脚的总延迟 = source latency + 时钟树上的从clock definition point 到触发器时钟引脚的实际延迟值。
Generated clock 是指从主时钟(master clock) 派生而来的时钟,主时钟(master clock)是指用create_clock指令创建的时钟。
create_clock -name CLKP 10 [get_pins UPLL0/CLKOUT]
(创建了一个名字是 “CLKP” 的master clock,它的周期为10ns,占空比(duty_cycle)为50%(默认值),clock definition point 是UPLL0的CLKOUT pin )
create_generated_clock -name CLKPDIV2 -source UPLL0/CLKOUT -divide_by 2 [get_pins UFF0/Q]
(在flip-flop 的UFF0的Q端创建了一个派生时钟(generated clock),名字是CLKDIV2,它的master clock是 在UPLL0上的CLKOUT pin,它的频率是它的master clock 的1/2,因此它的时钟周期是它的master clock 的两倍,为20ns)
示例 :
示例:
其中时钟SYS_CLK由触发器的输出进行门控。由于触发器的输出可能不是恒定的,因此处理这种情况的一种方法是 **在与门单元的输出处定义一个衍生时钟** ,该时钟与输入时钟相同。
示例:
如图所示,与门单元的两个输入均为时钟,那么与门单元的输出是什么呢?如果与门单元的输入均为时钟,则可以安全地在与门单元的****输出端定义一个新的主时钟,因为该单元的输 出与任何一个输入时钟有相位关系的可能性很小 。
注意:
在内部引脚上创建一个master clock 会 影响路径延迟计算 ,并 迫使设计人员手动计算source latency 。
用法:定义generated clock时,加上-edges选项,并在{ 上升,下降,上升 }中填上generated clock的第一个上升沿的edge,第一个下降沿的edge,第二个上升沿的edge,这个edge是依据source clock的边沿列表的:主时钟的第一个上升沿是edge1,第一个下降沿是edge2,下一个上升沿是edge3,依此类推。##### 示例:
(创建一个周期为2ns的名叫DCLK的主时钟,它的上升沿在0ns,下降沿在1ns)
create_generated_clock -name DCLKDIV2 -edges {2 4 6} -source DCLK [get_pins UBUF2/Z]
(在UBUF2的输出端Z端定义了一个名叫DCLKDIV2的generated clock,它在source clock的edge 2 有一个上升沿,在source clock 的 edge 4 有一个下降沿,并且下一个上升沿在source clock 的edge 6)
create_generated_clock -name PH0CLK -edges {3 4 7} -source DCLK [get_pins UAND0/Z]
create_generated_clock -name PH1CLK -edges {1 2 5} -source DCLK [get_pins UAND1/Z]
考虑如图7-16所示的衍生时钟G3CLK。可以通过指定边沿5、7和10来定义这种generated clock,如以下时钟约束所示:
create_generated_clock -name G3CLK -edges {5 7 10} -source DCLK [get_pins UAND0/Z]
-edge_shift选项可以与-edges选项一起使用,指定相应边的任何移位,以形成新生成的generated clock。它指定了边列表中每条边的移动量(以时间单位计算)。下面是一个使用该选项的示例。
● 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_generated_clock -name MIIDIV2 -source MIICLK -edges {1 1 5} -edge_shift {0 5 0} [get_pins UMIIDIV/Q]
(在edge1 -edge_shift 参数指定时钟边沿向右移动了5ps 的效应。)
在所有其它generated clock的选项都被使用后,-invert选项将会对generated clock进行反相。
示例:
create_clock -period 10 [get_ports CLK]
create_generated_clock -name NCLKDIV2 -divide_by 2 **-invert ** -source CLK [get_pins UINVQ/Z]
可以为generated clock指定时钟延迟,在generated clock上指定的source latency还包括了从master clock definition point到generated clock definition point的延迟。因此,由generated clock驱动的触发器的时钟引脚的总时钟延迟 = master clock source latency + generated clock source latency +generated clock network latency。
STA无法检查不受约束的路径上的任何时序,因此需要约束所有路径以进行时序分析。实际情况中,设计人员可能并不在乎一些输入控制信号的时序,因此可能并不需要进行本节中将要介绍的时序检查。但是,本节假定我们要约束全部的输入路径。
CLKA的时钟定义指定了 时钟周期 , 这是两个触发器UFF0和UFF1之间可用的总时间 。
External logic 所需要的总时间 = Tclk2q(数据launch的触发器UFF0的CK端到Q端的延时) + Tc1(通过外部组合逻辑威廉希尔官方网站 的延迟)。
因此需要在输入引脚INP1上定义外部延迟,外部延迟的值为 Tclk2q+Tc1 ,并且该外部延迟是相对于时钟CLKA指定的。
指令如下:
● set Tclk2q 0.9
● set Tc1 0.6
● set_input_delay -clock CLKA** -max** [expr Tclk2q + Tc1] [get_ports INP1]
该约束指定输入端口INP1的外部延迟为1.5ns (Tclk2q + Tc1),且这是相对于时钟CLKA而言的。假设CLKA的时钟周期为2ns,则INP1引脚的逻辑只有500ps(= 2ns-1.5ns)可以在设计内部中传播。此输入延迟定义意味着输入约束为 :Tc2加上触发器UFF1的Tsetup必须小于500ps,才可以确保可靠地捕获到触发器UFF0发起的数据 。请注意,上述外部延迟值被指定为了最大值(max)。(max 对应 setup,min 对应hold)。
指令:
● set Tc2 3.9
● set Tsetup 1.1
● set_output_delay -clock CLKQ -max [expr Tc2 + Tsetup] [get_ports OUTB]
时钟CLKQ的周期定义了 触发器UFF0和UFF1之间的总可用时间 。外部逻辑的总延迟 = Tc2 + Tsetup,此总延迟必须作为输出延迟约束的一部分来指定。
Output ** delay是相对于capture clock指定的** ,数据必须及时到达外部触发器UFF1才能满足其建立时间要求。
Input ** delay 是相对于launch clock 指定的** 。
上图中给出同时具有最大延迟和最小延迟的示例。
最大路径延迟 = Tc2max + Tsetup = 7ns + 0.4ns = 7.4ns
最小路径延迟 = Tc2min + Thold = 0 - 0.2ns = -0.2ns
指令如下:
● 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]
在STA中,时序路径是根据有效的起点和终点来划分的。
对上面的有效起点与有效终点进行两两组合即可得到有效的路径,如下:
上图中的有效路径有:
时序路径可以根据与路径终点相关的时钟进行分类,因此每个时钟都有一组与之相关的 时序路径 。静态时序分析和报告通常分别在每个时序路径组中单独执行。
上图中的时序路径组有: ● CLKA组:输入端口A到触发器UFFA的D引脚
● CLKB组:触发器UFFA的CK引脚到触发器UFFB的D引脚
● 默认组:输入端口A到输出端口Z、触发器UFFB的CK引脚到输出端口Z
尽管上述的create_clock, set_input_delay和set_output_delay已经足够约束设计中用于执行时序分析的所有路径。但是只有这些还不足以获取模块IO引脚上的准确时序,因此为了准确对设计环境进行建模,还需要一下外部属性。
在静态时序分析中,使用transition time来测量波形上升或下降的快慢 (slew rate) ,也就是信号在两个电平之间转换所花费的时间。 transition time是slew rate的倒数 。
对于输入,需要指定slew,这个信息可以通过以下指令指定:
• set_drive (该命令已过时,不推荐使用)
• set_driving_cell
• set_input_transition
对于输出,需要对output pin指定capacitive load(负载电容),可以通过以下指令指定:
• set_load
对驱动模块的输入端口的外部单元的驱动强度进行建模可以使用set_drive 和 set_driving_cell指令。如果没有使用这些指令进行约束,则 默认驱动强度无限大, 输入引脚的transition time = 0。
输入端口的驱动强度用于计算第一个单元的transition time。
**示例:**
● set_drive 100 UCLK
(在UCLK上指定了一个100 的drive resistance )
● set_drive -rise 3 [all_inputs]
● set_drive -fall 2 [all_inputs] 指定的驱动强度可以用于计算在任何 RC interconnect情况下计算从 **输入端口到第一个单元的延迟值** :
延迟值 = (驱动强度 * 网络负载) + 互连线延迟
(Delay_to_first_gate = (drive * load_on_net) + interconnect_delay)
set_driving_cell约束提供了一种更方便更准确的方法来描述端口的驱动能力。
set_driving_cell可用于指定驱动输入端口的单元类型
示例: set_driving_cell -lib_cell INV2 -library tech13g [all_inputs]
指定了library tech13g中的cell INV2是所有inputs的driving cell。
与set_drive约束一样,set_driving_cell也可用于计算第一个单元的transition time,并在任何RC interconnect情况下计算从输入端口到第一个单元的延迟值。
注意:
使用set_driving_cell会造成: 由于输入端口上的电容性负载而导致的驱动单元的增量延迟会被视作输入上的附加延迟而将其包括在内。
set_input_transition约束指令提供了一种在输入端口表示transition time 的快捷方式, 并且可指定参考时钟。
示例:
set_input_transition 0.6 [all_inputs]
(在所有input ports上指定一个600 ps 的transition time)
总之,需要指定输入端的slew value来确定输入路径中的 第一个单元的延迟 。若没有用该约束,则transition time 则为0,这是不符合实际情况的。
set_load约束在输出端口上设置电容性负载,以模拟输出端口驱动的外部负载。
默认情况下,端口上的电容性负载为0,可以将负载显式地指定为 电容值(下图左侧) 或 某个单元输入引脚电容(下图右侧) 。
示例:
(在output port OUTX的电容负载置为5pF)
set_load -pin_load 0.007 [get_ports {shift_write[31]}]
(将7fF的pin load 置于特定的output port shift_write[31] 上)
注意:
连接port的net上的电容负载可以用**-wire_load**选项指定,如果 -pin_load 和 -wire_load选项都没有被加上 , 则默认是-pin_load。
指定输出上的负载很重要,因为这会影响驱动单元输出的单元延迟,如果没有指定,则默认为0,这不符合实际情况。
set_load还可以指定设计中 内部网络(internal net) 的电容负载。
例: set_load 0.25 [**get_nets **UCNT5/NET6]
STA中常用的设计规则检查有:-max_transition 最大过渡时间 和** -max_capacitance** 最大电容。它们
会检查设计中的所有ports和所有pins是否满足transition time 和 capacitance的检查。
这些限制可以通过下述指令指定:
作为静态时序分析的一部分,任何对这些设计规则的违反都会以slack的形式被报告出来。
● set_max_transition 0.6 IOBANK
● set_max_capacitance 0.5 [current_design]
网络上的电容 = 所有引脚电容 + 任何IO负载+网络上的任何互连电容
示例:
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
Transition time 是延迟计算的一部分,对于上图:
Transition time on pin UBUF2/A = drive of 2 * 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
RC: 电阻乘以电容是一个物理学上的量,通常用来表示一个威廉希尔官方网站 中的时间常数,记作 RC 。这个量的单位是秒。在一个威廉希尔官方网站 中,电容会存储电荷,而电阻会阻碍电流的流动。当一个威廉希尔官方网站 中有一个电容和一个电阻时,它们的乘积 RC 表示了电容器充电或放电的时间常数。这个时间常数决定了电容器充电或放电的速度。
除了set_max_transition与set_max_area,还可以为设计指定其他的设计规则,如:set_max_fanout(指定设计中所有引脚的fanout 约束) 与 set_max_area等。但是这些检查是应用于synthesis而不是STA的。
一个 Virtual clock 是指一个已经存在但是没有与设计中的任何一个pin或port相连的时钟。虚拟时钟通常用于在指定input delay 和 output delay 时作为参考。
在上图中,待分析设计(DUA)的时钟端为CLK_CORE,但是输入端口ROW_IN的驱动时钟为CLK_SAD。
同理,输出端口STATE_O上也会有同样的问题。
为了处理这种情况,可以在不指明端口或引脚的情况下来定义虚拟时钟。
针对上图,可以为CLK_SAD和CLK_CFG定义虚拟时钟: ● create_clock -name VIRTUAL_CLK_SAD -period 10 -waveform {2 8}
● create_clock -name VIRTUAL_CLK_CFG -period 8 -waveform {0 4}
定义时钟CLK_CORE: ● create_clock -period 10 [get_ports CLK_CORE]
在定义了虚拟时钟后,就可以根据这些虚拟时钟定义IO约束了。* set_input_delay -clock VIRTUAL_CLK_SAD -max 2.7 [get_ports ROW_IN]
使用虚拟时钟只是约束输入和输出(IO),设计人员还可以选择其他方法来约束IO。
用于约束分析空间的四条常见指令有:
在设计中,某些信号在芯片的特定模式下具有恒定值。例如:如果芯片中有DFT(可测性设计)逻辑,则在正常功能模式下,芯片的TEST引脚将一直为0。因此,为STA指定这样的常量值很有必要,有助于减少分析空间,避免报告不相关的路径。
指令示例:
set_case_analysis 0 TEST
set_case_analysis 1 UCORE/UMUX0/CLK_SEL[0]
(选择了PLLdiv16被用于MIICLK,PLLdiv8的时钟路径被阻塞并且不会通过多路复用器传播。因此最后的时序分析报告中也就没有使用时钟PLLdiv8分析任何时序路径)
每个单元都有从其输入到输出的时序弧,并且时序路径可能会通过这些时序弧中的其中一个。在某些情况下, 单元中的一条路径可能无法发生 。例如可能有这样一种情况,其中时钟连接到多路复用器的 选择端 ,而多路复用器的 输出是数据路径的一部分 。在这种情况下,中断多路复用器选择引脚和输出引脚之间的时序弧可能很有用。
示例:
使用指令 set_disable_timing -from S -to Z [get_cells UMUX0] 中断UMUX0中从S到Z的时序弧。
可以通过使用set_min_delay和set_max_delay命令来约束点对点路径,这将from-pin到to-pin之间的路径延迟限制在了命令指定值内。该约束将覆盖所有默认的单周期时序路径以及此类路径的任何多周期路径约束。
set_max_delay约束了指定路径的最大延迟,而set_min_delay约束了指定路径的最小延迟。
(从UFF2/Q到UFF3/D的最大延迟为600ps)
set_max_delay 1.2 -from [get_clocks SYS_CLK] -to [get_clocks CFG_CLK]
(指定从一个时钟到另一个时钟的点对点约束)
路径分段(path segmentation)是指将时序路径分解为可以进行时序分析的较小路径。
时序路径具有起点和终点,可以使用set_input_delay和set_output_delay命令在时序路径上创建其它起点和终点。通常在单元的输出引脚上指定set_input_delay来定义 新起点 ,而通常在单元的输入引脚上指定set_output_delay来定义 新终点 。这些约束定义了新的时序路径,它是原始时序路径的子集。
定义这些约束会导致从UFF0 / CK到UFF1 / D的原始时序路径被分段,并分别在UAND2 / Z和UAND6 / A处创建内部起点和内部终点。现在,时序报告将明确显示此新路径。
请 注意 ,还会自动创建另外两条时序路径, 一条从UFF0 / CK到UAND2 / Z , 另一条从UAND6 / A到UFF1 / D 。因此,原始的时序路径已被分为了三个部分, 每个部分分别进行时序分析 。
更多回帖