2023.4.10 天气晴
2023.4.11
STA存在在逻辑综合后的每个步骤,非常重要,且STA只针对同步电路,异步电路的时序无法分析。
概念:遍历电路存在的所有时序路径(测试覆盖率基本达到100%),根据给定工作条件(PVT
)下的时序库.lib文件
计算信号在这些路径上的传播延时
,检查信号的建立和保持时间
是否满足约束要求,根据最大路径延时和最小路径延时找出违背时序约束的错误。
本质:满足每个寄存器的建立时间和保持时间
关键路径:时序路径中最长的一条,决定系统的最快工作速度
内部会划分为不同的时序路径,去分析每条路径的建立时间和保持时间
两种时序起点:clock pin
、input port
两种时序终点:data input pin
、output port
路径分类:
pin2reg
(input-D)reg2reg
(clk-D)reg2pin
(clk-output)pin2pin
(input-output)前三类要确保数据信号在时钟锁存沿的建立时间和保持时间内是稳定不变的。
最后一个路径的信号传输通常不通过时钟,一般直接约束pin2pin的延时范围
STA
:不需要输入激励就可以穷尽所有路径,且运行速度快,占用内存较少。不仅对芯片的时序进行检查,同时根据时序结构来进行优化设计。动态仿真
:需要输入激励,难以穷尽所有可能,覆盖率难以达到100%,且运行速度较慢,占用内存较多。PVT
:Process
工艺、Voltage
电压、Temperature
温度
三种模式
:Typical(平均值)、Fast、Slow(晶体管驱动电流是最小值)
五种情况
:TT、FF、SS、FS、SF(第一个代表NMOS,第二个代表PMOS)
分析建立时间:高温+低压+工艺慢速(延时最大)ss
分析保持时间:低温+高压+工艺快速(最好情况)ff
大多数SOC都是全局异步、局部同步,STA只对同步电路进行分析。
set_false_path -from [get_clocks USBCLK] -to [get_clocks MEMCLK]
建立时间Tsu
(set up time):时钟上升沿来临之前,数据保持稳定的时间,使得触发器能够锁存住数据保持时间Th
(hold time):时钟上升沿来临之后,数据保持稳定的时间输出延迟时间Tco
(clock output delay):clk触发到输出信号有效之间的最大延迟时间主要针对控制信号来说:
Trecovery(恢复时间)
:控制信号在下一个时钟沿到来之前,变无效的最小时间长度
Tremoval(移除时间)
:在“有效时钟沿”之后变无效的最小时间长度
Tmet
:亚稳态振荡时间
当异步复位信号的撤销时间在Trecovery(恢复时间)和Tremoval(移除时间)之间时,输出结果就会出现亚稳态,造成复位失败
释放沿必须在时钟沿前面提前recovery time释放,或者在时钟沿后removal time之后释放
lib、db(打不开)格式,内容是相同的
输入转换时间
,C为输出负载电容
(下面描述的是INP1引脚到OUT引脚的上升沿和下降沿延时)
压摆值(slew)基于的是在库中指定的测量阈值点,大多数上一代的库(0.25um或更旧的库)都使用10%和90%作为压摆
(或称过渡时间
)的测量阈值点。
压摆阈值点的选择对应的是波形的线性部分。
压摆测量阈值点为30%和70%且压摆降额系数为0.5,等效于测量阈值点为10%和90%。
通俗的说,就是判断波形翻转的电平阈值,转换时间的阈值是多少。
这个库原本表征的是0-100%,但实际使用测出来的是20-80%
包括时钟、IO以及一些特殊的约束指令,这些最终都会写到SDC的脚本里面。
Clock source
,可以是设计的端口,也可以是设计内部某个单元的引脚(通常是时钟生成逻辑的一部分)(很重要,用来确定路径)Period
,时钟的周期Duty
,高电平在整个周期中的比例。Edge Times
上升沿和下降沿翻转时间create_clock -name SYSCLK -period 20 -waveform {0 5} [get_ports SCLK] //时钟名字SYCLK,周期20ns,0是上升沿,5是下降沿,时钟端口SCLK
时钟不确定性来源于:时钟偏移
、时钟抖动
、时钟延时
对setup和hold time添加时钟不确定性的约束,使得时序约束更加严格,使得输入数据应该到达更早,时钟沿后应该保持更久的时间。
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 CFC_CLK -setup 0.1
时钟源延时 + 时钟网络延时
set_clock_latency 0.8 [get_clocks CLK_CONFIG] //时钟网络延时
set_clock_latency 1.9 -source [get_clocks CLK_CONFIG] //时钟源延时
set_clock_latency 1.9 -source -min [get_clocks CLK_CONFIG] //时钟源延时,最大值和最小值,用来去分析建立时间和保持时间
set_clock_latency 1.9 -source -max [get_clocks CLK_CONFIG]
由主时钟分频或者倍频得到的新时钟,就是生成时钟。
相同相位
的,是同步时钟
。create_clock -name CLKP 10 [get_pins UPLL0/CLKOUT]
create_generated_clock -name CLKPDIV2 -source UPLL0/CLKOUT -divide_by 2 [get_pins UFF0/Q] //生成的时钟要指定source,2表示生成时钟是源时钟周期的两倍
生成时钟的source latency:定义为主时钟定义点到生成时钟定义点之间的延时
寄存器clk端的时钟延时:主时钟的source latency + 生成时钟的source latency + 生成时钟的network latency
下图是两个时钟逻辑相与生成一个新的时钟,可以看到新的时钟和源时钟之间没有太多的关系,此时建议定义一个新的时钟。
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]
这里描述的是INP1端口的输入延时,Tclk2q+Tc1(时钟沿有效到数据送到输入端口的时间
)
起点是CLKA,终点是输入端口INP1
set Tclk2q 0.9
set Tc1 0.6
set_input_delay -clock CLKA -max [expr Tclk2q + Tc1] [get_ports INP1] //指定时钟域,这里变量的引用是否需要加$,视频里面没有加
也可以定义输入延时的最大值和最小值
create_clock -period 15 -waveform {5 12} [get_ports CLKP]
set_input_delay -clock CLKP -max 6.7 [get_ports INPA] //第一个时钟沿有效到DUA输入端口的时间,clk2q+Comb
set_input_delay -clock CLKP -min 3.0 [get_ports INPA]
输出延时指输出端口到下一个寄存器的D端,Tc2+Tsu(输出数据送到下一个寄存器D端的时间
)
set Tc2 3.9
set Tsetup 1.1
set_output_delay -clock CLKQ -max [expr Tc2 + Tsetup] [get_ports OUTB]
也可以定义输出延时的最大值和最小值
create_clock -period 20 -waveform {0 15} [get_ports CLKQ]
set_output_delay -clock CLKP -max 7.4 [get_ports OUTC]
set_output_delay -clock CLKP -min 0.4 [get_ports OUTC]
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]
看每条时序路径的终点位于哪个时钟组,路径终点位于同一个时钟域的是同一个组。
对输入转换时间和输出负载电容进一步约束,使得更贴近实际情况
输入端口:
set_drive
:给输入端口设定驱动阻抗值set_driving_cell
:同第一种set_input_transition
:直接指定输入端口的转换时间,以上三种任意选一种即可set_drive 100 UCLK //指定输入引脚的驱动电阻,值越小,驱动能力越强。设置为0的话表示驱动能力无穷大,是不存在的
set_drive -rise 3 [all_inputs]
set_drive -fall 3 [all_inputs] //也可以上升沿下降沿单独设置
set_driving_cell -lib_cell INV3 -library slow [get_ports INPB] //可以从库slow里面取出一个cell,把它设定为输入驱动单元
set_input_transition 0.85 [get_ports INPC] //直接设置转换时间,感觉更简单,上面那些还需要去进行计算
输出端口:
set_load
:指定输出负载电容,默认值为0set_load 5 [get_ports OUTX] //设置为5pF
set_load -pin_load 0.007 [get_ports{shift_write[31]}] //在输出端口添加一个7fF的负载电容
检查所有端口是否满足要求,前两个用于STA,后两个主要用于综合的时候约束
set_max_transition
set_max_capacitance
set_max_transition 0.6 IOBANK
set_max_capacitance 0.5 [current_design]
虚拟时钟存在但是不和设计中的端口和引脚相连接。
它在STA分析中用作参考,以指定相对于时钟的输入和输出延迟。
下图就是添加了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] //真实的时钟定义要写端口,不指定waveform就是50%
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]
set_case_analysis
:声明单元引脚上的固定值,或者输入端口的固定值;set_disable_timing
:断开单元时序弧;set_false_path
:STA不需要进行分析检查的路径,伪路径约束set_multicycle_path
:声明可能耗费超过一个周期的路径。set_case_analysis 1 UCORE/UMAX0/CLK_SEL[0]
set_disable_timing -from S -to Z [get_cells UMUXO] //认为这条没有时序,不需要进行分析,减小PT的运行时间
set_false_path -from [get_clocks USBCLK]-to [get_clocks MEMCLK] //从USBCLK到MEMCLK的路径都不进行分析,该指令也用来排除一些不可能发生的时序路径,需要具体分析
//输入到输出有多周期路径,如果在一个clk的时候去检查,肯定不对,可以设置在第三个周期的时候去检查
create_clock -name CLKM -period 10 [get _ports CLKM]
set_multicycle_path 3 -setup -from [get_pins UFFO/Q]-to [get_pins UFF1/D]