设计约束文件SDC,全称Synopsys design constraints
主要包括以下内容
Units(Time,capacitance,Resistance,Voltage,Current,Power)单位(时间,电容,电阻,电压,电流,功率)
System interface(Driving cell load) 系统接口(驱动单元,负载)
Design rule constraint(max fanout,max transition)
Timing constraints(Clock definitions, clock latency, clock uncertainty, input/output delay)
Timing exceptions (Multi-cycle and false paths)
按照用途大致分为以下几类:
#1、描述芯片的工作速度,即时钟的频率,包括create_clock,create_generated_clock等
#2、描述芯片的边界约束,包括set_input_delay,set_output_delay等
#3、描述芯片的一些设计违反rule(DRV),包括set_max_fanout,set_max_capacitance,set_max_transition等
#4、描述设计中一些特殊的路径。包括set_false_path,set_multicycle_path等
#5、描述设计中一些需要禁止的timing arc例如set_disable_timing
时钟 sdc
任何sdc首先定义的都是时钟,对于一个同步电路而言,缓存器间的路径延迟时间必须小于一个clock周期(Period),clock三要素:Waveform、Uncertainty和clock group
Crate_clock:主要定义一个Clock的source远端、周期、占空比(时钟高电平与周期的比例)及信号上升沿及下降沿的时间点。
|------------------------------------------------------------------|
| create_clocks -name clk_name -period 10 [get_ports clk_in] |
这是最基本的时钟约束语句,为时钟管脚创建一个时钟,综合工具会根据创建的时钟进行布局布线,并给出时序分析报告,若发生时序违例,则需要对设计进行优化修改。
这个时钟描述成sdc语句就是
|------------------------------------------------------------------------------|
| create_clock -name SYSCLK -period 20 -waveform {0 5} [get_ports2 SCLK] |
waveform后面跟上升沿和下降沿的时间 -waveform {time_rise time_falltime }如果没指定-period,默认的waveform为{0,period/2}
create_generated_clock( 分频时钟)
generated clock是从master clock中取得的时钟定义。Master clock是指create_clock命令指定的时钟长生节点。如图所示:
#定义master clock
|-----------------------------------------------------------------------------------------|
| create_clock -name CLKP -period 10 \ -waveform {0 5} [get_pins UPLL0/CLKOUT] |
#在Q点定义generated clock
|--------------------------------------------------------------------------------------------------------------------------|
| create_generated_clock -name CLKPDIV2 -source UPLL0/CLKOUT \ master_clock CLKP -divide_by 2 [get_pins UFF0/Q] |
-source设定生成时钟的源引脚
divide_by 3:3分频
divide_by:表示生成时钟通过分频生成
multiply_by:表示生成时钟通过倍频生成。
Edges:占空比设置
一般我们把时钟的源头定义为create_clock,而分频时钟则会定义为create_generated_clock。两者的主要区别在CTS步骤,generated clock并不会产生新的clock domain(时钟域),而且定义generated clock后,clock path的起点始终位于master clock,这样source latency并不会重新计算。
Virtual clock (虚拟时钟):
设计中的某个时钟实际存在,但其时钟源不是来自设计中任何引脚和端口;由于虚拟时钟和设计中的任何引脚和端口无直接关系,故定义虚拟时钟时并不指定时钟端口。
虚拟时钟用于作为输入输出延时约束的时钟源。
#定义虚拟时钟
|--------------------------------------------------------|
| create_clock -name VCLK -period 10 -waveform {0 5} |
通常把input/output delay挂在virtual clock上,因为input/output delay约束就是指片外的时钟,挂在虚拟时钟上较为合理。
set_clock_uncertainty :定义了clock信号到时序器件的clock端可能早到或晚到的时间。主要用来降低jitter对有效时钟周期的影响。在setup check中,clock uncertainty是代表着降低了时钟的有效周期,在hold check中,clock uncertainty 是代表这hold check所需要满足的额外margin。
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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 -setip 0.1 set_clock_uncertainty 0.5 [get_clocks CLK1] |
对于不同时钟不确定度建模时,源时钟可用from,目的时钟可用to
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #c1 到c2 的建立时间和保持时间不确定度 set_clock_uncertainty -from C1 to C2 -setup 0.5 set_clock_uncertainty -from C1 to C2 -hold 0.5 #C1 上升沿到C2 下降沿的不确定度 set_clock_uncertainty -rise_from C1 fall_to C2 0.5 #C1 和C2 之间的不确定度 set_clock_uncertainty -from C1 to C2 0.5 set_clock_uncertainty -from C2 to C1 0.5 |
时钟延迟 set_clock_latency
时钟信号从时钟源输出端到达时序单元时钟输入端(如触发器)所需要的时间,称为时钟延迟;
时钟延迟包括源延迟和网络延迟,源延迟是指源时钟到达时钟定义的端口的延迟;
网路延迟是指时钟定义的端口到时序单元时钟输入端的延迟;
·-source设定源延迟
|-----------------------------------------------------|
| set_clock_latency -source 0.5 [get_clocks C1] |
最长路径可以用-late或者max,最短路径可以用-early或者min
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| set_clock_latency -source -early 0.5 [get_clocks C1] set_clock_latency -source -late 1.0 [get_clocks C1] set_clock_latency -source -min 0.5 [get_clocks C1] set_clock_latency -source -max 1.0 [get_clock C1] |
当为设定-source时,表示网络延迟;
|------------------------------------------------------------------------------------------------------------------------|
| # 上下降沿网络延迟 Set_clock_latency 0.5 -rise [get_clocks C1] Set_clock_latency 0.3 -fall [get_clocks C1] |
时钟网络延迟和时钟源延迟的区别:
时钟网络延迟时时钟树生成前的设置,当实际时钟树生成后,时钟网络延迟将通过set_propagated_clock被时钟树的实际结果所替代;而时钟源延迟则会一直存在。
时钟分组set_clock_groups
同步时钟:时钟存在固定的相位关系,来自同一个时钟;异步时钟:不存在固定的相位关系;为了让时序工具忽略异步时钟之间的时序分析或串扰分析,SDC提供了set_clock_groups命令,表明时钟组之间的时序路径不必考虑;
asynchronous 代表两个异步的clock group
physically_exclusive 代表两个clock group在物理上相互排斥,比如在一个source pin上定义两个时钟
logically_exclusive 代表两个clock group在逻辑上相互排斥,比如两个clock经过MUX选择器。例如
|----------------------------------------------------------------------------------|
| set_clock_groups -physically_exclusive -group {CLK1 CLK2} -group {CLK3 CLK4} |
input/output delay IO 边界上的约束。
STA并不能去检查一条没有被约束的路径,因此所有的端口都必须被赋予边界约束。set_input_delay和set_output_delay都是对外部时延信息的描述。
set_input_delay :
输入延迟:在一个时钟周期内,外部逻辑的输出数据到达设计输入端口所需的时间。即输入信号是在时钟沿后多长时间到达模块port上的。
用如下命令表示:
|--------------------------------------------------|
| set_input_delay 1.0 -clock ck [all_inputs] |
set_output_delay :
输出延迟:在一个时钟周期内,设计输出端口数据到达外部逻辑所需的时间。信号在后级模块中需要在时钟沿之前提前多长时间准备好。
用如下命令表示:
|-------------------------------------------------------|
| set_output_delay 2.5 -clock ck [get_ports out1] |
一般来说,IO的timing优先级较低,我们应该关注与芯片内部的timing path。Input/output_delay设置的越大,就给PCB板级电路留有更大余量;input/output_delay设置的越小,对板级电路的限制越大,一般情况下设置为时钟周期的70%,如果综合后时序不满足,则可降至时钟周期的50%。
IO 环境建模
输入驱动建模:默认情况下,如果没有外部输入驱动,时序分析工具则默认外部输入驱动为无穷大;
set_drive:
设置外部驱动信息,通过该命令定义驱动该引脚的输入驱动电阻值,通过该驱动电阻值计算出驱动端的转换时间,并计入时序路径延时信息。该值越小,驱动能力越强。
|-------------------------------------|
| set_drive 2.0 [get_ports in1] |
注意: 不能使set_drive值为0,为0时,这样输入就具有无限大的驱动能力,意味着transition time为0.
|-------------------------------------------------------------------------------|
| set_drive -rise 0.4 [all_inputs] set_drive -fall 0.3 [all_inputs] |
上述命令定义所有输入的驱动值,上拉驱动电阻为0.4,下拉驱动电阻为0.3
·-min指定最小电阻,用于保持时间分析
·-max指定最大电阻,用于建立时间分析
·如果不指定-max和-min,那么指定的值即用于建立时间分析,也用于保持时间分析;
set_driving_cell :这个约束其实和set_drive实现的是同一个功能,指使用设计库的某一个单元来驱动输入端口,然后按照该单元的输入电阻来计算tranition time,从而得到输入端口的延迟。通常要比set_drive使用更多,一般用在block level上,因为会考虑OCV等因素,会更加准确一点。
|-----------------------------------------------------------|
| set_driving_cell -lib_cell AND -from -pin B -pinY IN1 |
|------------------------------------------------------|
| set_driving_cell -lib_cell INVX1M [all_inputs] |
上述命令定义设计所有驱动力等价于单元库中INVX1M单元的驱动力;
-lib_cell:指定驱动引脚的单元;
set_input_transition:
通过set_input_transition 定义驱动该引脚的输入驱动端转换时间,设置的转换时间越大驱动能力越小,当定义为0时,其代表输入端驱动力无穷大。
|------------------------------------------------------|
| set_input_transition 0.8 [get_ports DATA_IN*] |
输出驱动负载建模:默认情况下,如果没有设置外部负载,时序分析工具则默认外部输出负载为0
1.set_load: 设置输出电路的负载。由于外部电路的负载将会影响到接到端口上单元的延迟,因此需要对端口的带负载能力做限制。为了比较精确地计算输出电路的延迟,需要知道输出电路的所有负载。电路负载电容越大,延时时间越大。
|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| set_load 1.5 -min -pin_load [get_ports in1] set_load 10 [all_outputs] set_load [expr[load_of $LIB_NAME/AND2X1M/A]*3] [all_outputs] |
注意: 不能使负载电容为0,这样1输出端口就具有无穷大的驱动能力。上述命令定义所有输出负载等效为库中与门AND2X1M的引脚A的电容值的3倍。
负载类型:-pin_load,-wire_load可以指定负载类型时引脚负载还是线负载。
2.set_port_fanout_number value port_list
指定输出的扇出数(如果已知外部寄生负载并且已经通过set_load指定了外部寄生负载,则这个命令没有具体含义)
3.set_fanout_load value port_list
指定扇出负载(根据标准负载指定负载值)
时序特例 sdc
时序特例sdc即Path exception。针对一些路径需要的一些特殊设定,常用的有set_flase_path,set_multicycle_path,set_max_delay,set_min_delay等
伪路径set_false_path :
false path是指在正常环境下,并不真实存在或者经过的路径,比如一些静态输入信号产生的path。像这样的path,我们可以指定set_false_path。这样在计算timing时就不会去分析它。
|--------------------------------------------------------------------------------------------------------------------------------|
| set_false_path -from ff1/CK -through {u1/Y} -to ff2/D set_false_path -from [get_clocks CLK1] -to [get_clocks CLK2] |
多周期路径set_multicycle_path:
指的是两个寄存器之间的数据要经过多个时钟才能稳定的路径,一般出现在组合逻辑较大的那些路径,也有可能是一些慢时钟去踩快时钟的路径。对于这些路径,我们可以设置multicycle path。同样的设置multicycle path时,也要非常谨慎,需要提前知道1该条path要设几个cycle,start还是end也要理解清楚,而且默认的hold的multicycle比setup少一个。
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| set_multicycle_path 2 -setup -from ff1/CP -to ff2/D set_multicycle_path 1 -hold -from ff1/CP -to ff2/D set_multicycle_path -from [get_pins DFF1/Q] -to [get_clocks DFF2/D] -setup 5 set_multicycle_path -from [get_pins DFF1/Q] -to [get_clocks DFF2/D] -hold 4 |
最大最小延迟set_max_delay ,set_min_delay
当需要点对点对某些电路进行约束时,可通过最大最小延迟实现。
异步电路之间
输入信号直接通过组合逻辑后输出
当约束定义的时时序路径中的节点时,则约束的仅在两个节点之间;
|---------------------------------------------------------------------------------------------------------------------------------|
| set_max_delay -from [get_ports A1] -to [get_ports A2] 8 set_min_delay -from [get_ports A1] -to [get_ports A2] 5 |
上述定义A1到A2之间的时序路径的约束最大延时8ns最小延时6ns。
当约束定义是时钟树,最大最小延时将应用于该时钟源所控制的所有路径
|---------------------------------------------------------------------------------------------------------------------------------------------|
| Set_max_delay -from [get_clocks CLK1] -to [get_clocks CLK2] 8 Set_min_delay -from [get_clocks CLK1] -to [get_clocks CLK2] 5 |
上述定义表示从时钟域CLK1到CLK2之间的所有时序路径的约束最大延时为8ns,最小延时为6ns
|---------------------------------------------------------------------------------------------------|
| set_max_delay 8.0 -from {ff1/CP} -to {ff2/D} set_min_delay 4.0 -from {ff1/CP} -to {ff2/D} |
设计规则约束 sdc
设计规则约束sdc即drv,主要包括set_max_capacitance,set_min_capacitance,
set_max_fanout,set_max_transition.一般情况下lib库里面会有这些约束,但是为了时序更好,会在sdc里面更加严格的去约束它。
set_max_capacitance,set_min_capacitance : 设定了某一端口所互连线的最大和最小负载电容,负载电容是互连线自身电容和扇出电容之和。
|------------------------------------------------|
| set_max_capacitance 150 [current_design] |
set_max_fanout: 约束了某条net上驱动的所有cell的个数的总和,而这条net可以由input port驱动,也可以是内部的任何一条net。需要注意的是,max_fanout并不是用来约束output port的,因为一个输出端口可能会连有很多条net
|------------------------------------------|
| set_max_fanout 80 [current_design] |
set_max_transition: 设定端口信号的最大转移时间,需要注意区分data transition和clock transition time,一般clock的transition time要小一点。
|----------------------------------------------------------------------------------------------------|
| set_max_transition 150 [current_design] set_max_transition -clock_path 80 [all_clocks] |
逻辑赋值约束 sdc
常用的逻辑约束命令就是set_case_analysis。它的作用是对电路端口置0,置1的操作。根据设计中不同模式的需要,通过设置恒定状态约束来定义时钟选择端口的对应状态值,在多个模式中选择的时候,设定指定单一模式(相当于mux选择器)
如上图,假如CLK_SEL为0时,选择PLLdiv6_input,CLK_SEL为1时,选择PLLdiv2_input,则可设set_case_analysis 0 [get_pins {mux.CLK_SEL}]
上述定义模式端口mux.CLK_SEL恒定状态为0;可以是0,1,rising,falling
时钟转换时间set_clock_transition
时钟在高低电平状态下切换所需要的延时;
·-rise提供时钟上升沿的转换时间
·-fall提供时钟下降沿的转换时间
·-max和-min设置转换时间的最大最小条件
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| set_clock_transition -rise 0.2 [get_clock CLK] set_clock_transition -fall -min 0.2 [get_clocks CLK] set_clock_transition -fall -max 0.4 [get_clocks CLK] |
该命令仅用于预布局阶段,即时钟树综合完成之前,在时钟树生成之后,该命令不应用于任何布局时序分析;
SDC 命令
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 时序约束命令包括指定时钟特性,端口延迟,引脚和路径命令 create_clock create_generated_clock set_clock_groups set_clock_uncertainty set_clock_latency set_clock_transition set_input_delay set_output_delay set_propagated_clock set_clock_gating_check set_ideal_latency set_ideal_network set_ideal_transition set_max_time_borrow set_resistance set_time_derate set_data_check group_path set_load set_drive set_input_transition set_fanout_load |
面积与功率约束
|-------------------------------------------------------------------------------------------------------------------------------------|
| set_max_area create_valtage_area set_level_shifter_threshold set_level_shifter_strategy set_max_dynamic_power set_max_leakage_power |
设计规则约束
|-------------------------------------------------------------------------------------------|
| set_max_transition set_max_capacitance set_min_capacitance set_max_fanout |
接口约束
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| set_load set_drive set_driving_cell set_fanout_load set_port_fanout_number set_input_transition set_input_delay set_output_delay |
特定模式和配置约束
|-----------------------------------------------------------------|
| set_case_analysis set_logic_dc set_logic_zero set_logic_one |
时序例外
|-------------------------------------------------------------------------------------------------------|
| set_false_path set_multicycle_path set_max_delay set_min_delay set_disable_timing |
其他命令
|-------------------------------------------------------------------------------------------------------------------------------------------------|
| set_wire_load_model set_wire_load_mode set_wire_load_selection_group set_wire_load_min_block_size set_units set_operating_condition sdc_version |
SDC查询命令
|----------------------------------------------------------------------------------------------------------------------------------------------------|
| get_cells get_ports get_pins get_nets get_clocks all_inputs all_output all_registers all_clocks get_libs get_lib_cells get_lib_pins current_design |