主要讲述如何为静态时序分析设置环境,STA包括设定时钟、指定IO时序特性、指定false path和multicycle path。
1、STA环境是什么
大多数的数字电路设计是同步的,假定DUA会与其他同步设计交互,这意味着DUA会从前一级DFF接收数据,并将数据发送到DUA后一级DFF。为了对这种设计执行STA,需要设定DFF的时钟、进入DUA和退出DUA的所有路径上的约束。
2、设定时钟creat_clock
定义时钟需要提供:clock source、period、duty cycle、edge time
creat_clock -name SYSCLK -period 20 -waveform{0 5} [getports SCLK]
定义的时钟名称为SYSCLK,周期为20ns(默认是ns为单位),上升沿在0ns,下降沿在5ns,时钟是在端口SCLK上定义的。
其中,如果没有指定waveform,默认waveform{0,period/2}。例如:creat_clock -period 5 [get_ports SCAN_CLK],没有指定-name,因此时钟名称与端口名称相同。
create_clock -name BDYCLK -period 15 -waveform {5 12} [get_ports GBLCLK]
create_clock -period 125 -waveform {100 150} [get_ports ARMCLK]
可以看出,若waveform中的参数在一个周期内就不用推算,不在一个周期需要推算。
create_clock -period 1.2 -waveform {0.3 0.4 0.8 1.0} [get_ports JTAG_CLK]
2.1 时钟不确定度 set_clock_uncertainty
用不确定度来建模那些会降低有效时钟周期的因素。
set_clock_uncertainty -setup 0.2 [get_clocks CLK_CONFIG]
set_clock_uncertainty -hold 0.05 [get_clocks CLK_CONFIG]
对于setup check,设置时间不确定度会减少可用的有效时钟周期;对于hold check,设置时间不确定度会被用作需要满足的额外时序裕度。也就是说,为了保证数据传输时的正确性,在进行数据传输时,应当避开clock uncertainty的范围,也就是数据在这段时间内最好保持不变。
set_clock_uncertainty -from VIRTUAL-SYS_CLK -to SYSCLK -hold 0.05
set_clock_uncertainty -from VIRTUAL-SYS_CLK -to SYSCLK -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
该电路为两个不同的clock domain SYS_CLK和CFG_CLK之间的path,根据上面约束可知,setup check的uncertainty是100ps,hold check的uncertainty是50ps。
2.2 时钟延迟 set_clock_latency
set_clock_latency 1.8 -rise [get_clocks MAIN_CLK]
# MIN_CLK的上升沿延迟是1.8ns
set_clock_latency 2.1 -fall [all_clocks]
# 所有时钟的下降沿延迟是2.1ns
-rise和-fall指的是 时钟在DFF的clock pin上的延迟
时钟延迟有两种:network latency 和 source latency
network latency是从时钟定义点到dff clock pin的delay
source latency是从时钟源到时钟定义点的delay
DFF clock pin上的delay等于二者之和。
set_clock_latency 0.8 [get_clocks CLK_CONFIG]
set_clock_latency 1.9 -source [get_clocks SYS_CLK]
set_clock_latency 0.851 -source -min [get_clocks CFG_CLK]
set_clock_latency 1.322 -source -max [get_clocks CFG_CLK]
# 没有给出 -source 选项,表明是 network latency
# 没有给出 -fall和-rise选项,表明fall和rise是相同的
# 没有给出 -min和-max选项,表明min和max是相同的
当clock tree建立后,network latency可以忽略,source latency不可以忽略。
3. 生成时钟creat_clock
generated clock是有master clock衍生而来,当基于master clock生成一个新的clock时,可以将这个新的clock定义为generated clock。
CLKP在经过UFF0后,后续电路的时钟周期发生了更改,但STA并不知道后续电路的时钟发生了变化,更不知道新的clock的周期是多少,因此需要定义generated clock,让STA知道后续电路的clock已经发生了更改以及新的clock周期是多少。
create_clock -name CLKP 10 [get_pins UPLL0/CLKOUT]
create_generated_clock -name CLKPDIV2 -source UPPL0/CLKOUT -divide_by 2 [get_pins UFF0/Q]
定义master clock会创建一个新的clock domain,而定义generated clock则不会创建新的clock domain。generated clock与master clock同相,并且不需要进行额外的约束,所以应当尽量将内部的新clock定义为generated clock。
master clock的source是时钟定义点,generated clock的source是master clock,因此在时钟路径报告中,clock path的起点是master clock的定义点,master clock的latency也会直接作用于generated clock(也就是说在定义generated clock时不需要再指定latency)
SYS_CLK由触发器的输出进行门控,由于触发器的输出可能并不是恒定的,因此处理这种情况的一种方式是在UAND1的输出端定义一个generated clock,并且让新的clock与SYS_CLK相同。
created_clock 0.1 [get_ports SYS_CLK]
created_generated_clock -name CORE_CLK -divide_by 1 -source SYS_CLK [get_pins UAND1/Z]
create_clock -period 10 -waveform {0 5} [get_port PCLK]
create_generated_clock -name PCLKx2 -source PCLK -multiply_by 2
[get_pins UCLKMULTREG/Q]
门控单元输出端的master clock
UAND2的两个输入端分别是两个不同的clock,此时我们可以在UAND2的输出端定义一个master clock,因为UAND2的输出与这个输入的clock不大可能具有相位关系
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]
使用Edge和Edge_shift 定义generated clock
edge指的是DCLK的每一个边沿(既包括posedge,也包括negedge),从1开始,每遇到一个边沿,增加1。
-edge{posedge negedge posedge},
因为通过这三个边沿我们就可以确定generated clock的high duration和low duration。在-edge_shift {}中,三个参数指的是下图下面那排,也就是时间。
create_clock 2 [get_ports DCLK]
create_generated_clock -name DCLKDIV2 -edges {2 4 6} -source DCLK [get_pins UBUF2/Z]
CLKDIV2的posedge在DCLK的第2个边沿,negedge在DCLK的第4个边沿,下一个posedge在DCLK的第6个边沿。
-edge {}中的第一个参数是上升沿,那么如果generated clock的第一个边沿是下降沿,那么则需要进行推断。
-edges{}单独使用时:
create_generated_clock -name G3CLK -edges {5 7 10} -source DCLK [get_pins UAND0/Z]
-edges{}与-edges_shift一起使用时:
create_generated_clock -name MIIDIV2 -source MIICLK -edges {1 1 5}
-edge_shift {0 5 0} [get_pins UMIIDIV/Q]
第一个沿偏移0ns,第一个沿偏移5ns,第五个沿偏移0ns
使用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]
生成时钟的时钟延迟:
可以为生成时钟指定时钟延迟。
到DFF clk pin的总时钟延迟:主时钟的源延迟+生成时钟的源延迟+生成时钟的网络延迟
典型的时钟生成场景:
主时钟在芯片的输入端定义参考时钟,在PLL的输出处定义第二个主时钟。PLL输出时钟与参考时钟没有相位关系。因此,输出时钟不应该是参考时钟的生成时钟。最有可能的情况是,由时钟分频器逻辑生成的所有时钟都被指定为在PLL输出处的主时钟的生成时钟。
4.约束输入时钟
由于STA不能检查不受约束路径上的时序约束,因此需要约束所有路径来进行时序分析。
UFF0和UFF1都是由时钟CLKA驱动的,了解过建立时间和保持时间的应该知道,在第一个时钟上升沿UFF0发送数据,UFF1在下一个时钟上升沿接收数据,因此CLKA的周期应该是数据从UFF0到UFF1的时间
对于外部设计,从UFF0到端口INP1时间的是UFF0需要的时间Tclk2q(CK端 -> Q端的时间)+ C1所需的时间Tc1
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的周期是2ns,那么端口INP1只剩下500ps(2ns - 1.5ns)的时间可以在设计内部传播,UFF1要想在下一个时钟上升沿捕获UFF0发送的稳定的数据,Tc2 + UFF1 setup时间必须小于500ps。
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 的延迟,最大和最小延迟分别指最长和最短路径延迟。在给定外部输入延迟的情况下,设计内部的可用建立时间为15-6.7与15-3的最小值也就是8.3ns。在时钟上升沿来之后的3-6.7ns之间数据都可以开始改变。此外部输入延迟是相对于时钟CLKP的上升沿指定的(如果输入延迟是相对于时钟的下降沿指定的,则必须使用-clock_fall选项)
5.约束输出时钟
示例a
端口OUTB到UFF1的传播时间(Tc2 + UFF1的setup time)是输出路径的约束
set Tc2 3.9
set Tsetup 1.1
set_output_delay -clock CLKQ -max [expr Tc2 + Tsetup] [get_ports OUTB]
这指定相对于时钟边沿的最大外部延迟为 Tc2 加 Tsetup
示例b
最大路径延迟为 7.4ns(= 最大 Tc2 加上 Tsetup = 7 0.4)。最小路径延迟为 -0.2ns(= 最小 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]
图中显示了何时 OUTC 必须稳定才能被外部触发器可靠地捕获。这描述了数据必须在所需的稳定区域开始之前在输出端口准备好,并且必须保持稳定直到稳定区域结束。这映射到 DUA 内部输出端口 OUTC 的逻辑时序要求。
示例c
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]
6.时序路径组
有效的时序路径包括:
- 从输入端口到输出端口
- 从输入端口到触发器或存储器的数据输入引脚
- 从一个触发器或存储器的时钟引脚到另一个触发器或存储器的数据输入引脚
- 从一个触发器或存储器的时钟引脚到输出端口
时序路径可以根据与路径终点相关的时钟分为不同时序路径组,每个时钟都有一组与之相关的时序路径。还有一个默认时序路径组(default path group),其中包括了所有non-clocked(异步)路径
时序路径分组为:
- CLKA组:输入端口A到触发器UFFA的D引脚
- CLKB组:触发器UFFA的CK引脚到触发器UFFB的D引脚
- 默认组:输入端口A到输出端口Z、触发器UFFB的CK引脚到输出端口Z
对每个路径组分别执行静态时序分析。
6.外部属性建模
虽然 create_clock、set_input_delay 和 set_output_delay 足以约束设计中的所有路径以执行时序分析,但这些不足以为模块的 IO 引脚获得准确的时序。
对于输入,需要指定输入的转换
set_drive(此命令已过时,不推荐使用。)
set_driving_cell
set_input_transition
对于输出,需要指定输出引脚看到的容性负载
set_load
6.1 驱动强度建模
set_drive和set_driving_cell约束用于对驱动模块输入端口的外部单元的驱动强度进行建模。在没有这些约束的默认情况下,假定所有输入都具有无限的驱动强度,即输入引脚的过渡时间为0。
set_drive明确指定了DUA输入引脚上的驱动电阻值,该电阻值越小,驱动强度越高,电阻值为0表示无限的驱动强度。
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 互连时从输入端口到第一个单元的延迟。
Delay_to_first_gate = (drive * load_on_net) + interconnect_delay
延迟值 = (驱动强度 * 网络负载) + 互连线延迟
set_driving_cell 可用于指定驱动输入端口的单元。
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_input_transition 命令提供了一种在输入端口表达转换的便捷方式。可以选择指定参考时钟
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.
6.2 容性负载建模
set_load约束在输出端口上设置了电容性负载,以模拟由输出端口驱动的外部负载。默认情况下,端口上的电容性负载为0。可以将负载显式地指定为电容值或某个单元的输入引脚电容。
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.
7.设计规则检查
检查设计中的所有端口和引脚是否满足过渡时间和电容的规定约束。这些规则可以使用以下命令指定:
set_max_transition
set_max_capacitance
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负载再加上网络上的任何互连电容的总和计算得出的
网络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
UBUF2的A引脚过渡时间 = 2 * 网络N2的总电容 = 2 * 0.07 = 0.14ns = 140ps
输出端口OUTP过渡时间 = UBUF2的Z引脚的驱动电阻 * 网络N1的总电容 = 1 * 0.17 = 0.17ns = 170ps
8.虚拟时钟
虚拟时钟是存在但不与设计的任何引脚或端口相关联的时钟。它用作 STA 分析中的参考,以指定相对于时钟的输入和输出延迟。
DUA从 CLK_CORE 获取时钟,但驱动输入端口 ROW_IN 的时钟是 CLK_SAD。在这种情况下,如何指定输入端口 ROW_IN 上的 IO 约束?同样的问题发生在输出端口 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}
create_clock -period 10 [get_ports CLK_CORE]
定义了这些虚拟时钟后,可以相对于该虚拟时钟指定 IO 约束。
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]
上图显示了输入路径上的时序关系,这将DUA中的输入路径限制为 5.3ns 或更小。
上图显示了输出路径上的时序关系,这将DUA中的输出路径限制为 3.5ns 或更小。
9.完善时序分析
用于约束分析的四个常用命令是:
- set_case_analysis :在单元的引脚或输入端口上指定常量值。
- set_disable_timing :中断单元的时序弧。
- set_false_path :指定实际不存在的路径,这意味着在STA中不需要检查这些路径。
- set_multicycle_path :指定可能花费超过一个时钟周期的路径。
9.1
例如,如果芯片中具有DFT(可测性设计)逻辑,则在正常功能模式下,芯片的TEST引脚将一直为0。
如果未将TEST引脚设置为常数,则可能会存在一些奇怪的长路径,而这些长路径在功能模式下永远不会存在
9.2
在某些情况下,单元中的一条路径可能无法发生。例如可能有这样一种情况,其中时钟连接到多路复用器的选择端,而多路复用器的输出是数据路径的一部分。在这种情况下,中断多路复用器选择引脚和输出引脚之间的时序弧可能很有用。图7-37为一个示例,通过多路复用器选择端的路径不是有效的数据路径。可以使用set_disable_timing命令来中断这种时序弧。
10
该约束将覆盖所有默认的单周期时序路径以及此类路径的任何多周期路径约束
set_max_delay约束了指定路径的最大延迟,而set_min_delay约束了指定路径的最小延迟。
11
时序路径具有起点和终点,可以使用set_input_delay和set_output_delay命令在时序路径上创建其它起点和终点。
为SYSCLK定义时钟后,待分析的时序路径即为从UFF0 / CK到UFF1 / D。如果仅对报告从UAND2 / Z到UAND6 / A的路径延迟感兴趣,则可以使用以下两个命令: