一:工作环境属性约束
工作环境约束一方面是设置DC的工作环境,也就是DC要从在什么样的环境下对你的设计进行约束,举个例子,比如你的芯片要在恶劣的环境中进行工作,DC如果在优质的环境中对你的设计进行约束,你的芯片生产出来,就很有可能工作不了。因此一般就要告诉DC,使用恶劣的模型对设计进行约束。另一方面是为了保证电路的每一条时序路径延时计算的精确性,特别是输入/输出路径的精确性,单单靠外部的输入延时和输出延时的约束是不够,还要提供设计的环境属性。
1:包括
*输入端口,激励驱动
*输出端口,驱动负载
*PVT
*集成参数影响
2:电路图
输入管脚:驱动能力,input transition time
输出管脚:RC模型,loading模型
PVT conditions
parasitic RC:寄生RC
3:输出管脚 loading模型
默认情况下,DC假设端口上的外部电容负载为0,我们可以指定电容负载为某些之,也可以使用load_of选项明确说明电容负载的值为工艺库中某一单元引脚的负载(一般是选择输入引脚)
例如:
*set_load [expr 30.0/1000] [get_ports B]
*
左图:set_load [load of my_lib/AN2/A] [get_ports B] ;#采用工艺库my_lib里的AN2,A是cellAN2的pin脚
右图:set_load {expr[load of my_lib/inv1a0/A]*3} [get_ports B] ;#采用工艺库my_lib里的inv1a0,三个并联
4:input或者inout端口设置驱动强度
默认情况下,激励是理想的,没有transition
*set_input_transition 0.12 [get_ports A];#直接设置输入端口的转换时间
*当不知道输入转换时间时,可使用下面命令调用库器件模型
set_driving_cell -lib_cell OR3B [get_ports A] ;#调用库lib_cell里的OR3B
set_driving_cell -lib_cell FD1 -pin Qn [get_ports A] ;#调用库lib_cell里的FD1的管脚Qn
5:PVT(process,voltage,temperature)
工艺库单元通常用“nominal”电压和温度来描述其默认特性;库文件中,包含对各种不同条件的具体描述,如slow,fast,typical等;可以通过使用命令set_operating_conditions命令把工作条件加入到设计上。综合时,原来按“nominal”环境计算出的单元延迟和连线延迟,将按工作条件作适当比例调整。
如下图为为延迟与工作条件的关系:
list_libs ;#查看当前工艺库
report_lib libname;#查看libname的PVT等信息
设置工作条件可用下面命令:
set_operating_conditions -max $OPERA_CONDITION -max_library $LIBNAME
set_operating_conditions -max "wccom" ;#有wccom,typical,bccom选项
7:集成参数互联(设置线负载模型)
在计算时序路径延迟时,除了需要知道门单元延迟,还需要知道连线的延迟。
连线延迟目前用线负载模型(wire load model,简称WLM),WLM是厂商根据多种以及生产出来芯片的统计结果,在同样的工艺下,计算出某个设计规模范围内负载扇出为1的连线平均长度,负载扇出为2的连线平均长度,负载扇出为3的连线平均长度等。WLM根据连线的扇出进行估算连线的RC寄生参数。
线负载模型为DC提供统计性估算的线网负载信息,随后DC使用这些线网负载信息,以负载的大小为函数来模拟线上的延迟;如果DC遇到连线的扇出大于模型中列出的最大扇出值,它将使用外推斜率来计算连线的长度。具体格式由工艺库决定(下)(也可使用report_lib $lib_name 查看格式):
上图格式中,若连线扇出为7,而连线最大扇出为5,连线的长度计算如下:
232.68 + 50.3104*(7-5) = 333.3008;这条连线的电容和电阻分别为 333.3008*0.00017=0.0566pf,333.3008*0.000217=0.0903千欧
关于WLM的命令如下
DC自动选择线负载模型:set auto_wire_load_selection false
手动选择线负载模型:set_wire_load_model -name $WIRE_LOAD_MODEL -library $LIB_NAME
如果连线穿越层次边界,连接两个不同的模块,那么有三种方式对这种跨模块线连接的类型进行建模,set_wire_load_mode命令用于设置连线负载模型的模式。有三种模式供选择:top、segment和enclosed。三种模式的示意图如下所示:
由图可见, 该设计的顶层设计(top)包括一个子模块, 该子模块又包括两个更小的模块。 顶层设计对应的连线负载模型为50×50; 子模块对应的连线负载模型为40×40;更小的两个模块对应的负载模型为20×20和30×30。
假设有一个连线贯穿两个小模块, 但没有超出子模块的范围。 对于这种连线, 在三种模式下, 所用的连线负载模型是不同的,下面是介绍:
比较悲观的形式:这时,top为顶层设计,电路的规模比SUB模块大,连线负载模型最悲观。在top模式下, 采用top层的连线负载模型, 即50×50;因此,连线的延迟最大。我们一般选用这种方式,命令如下:
set_wire_load_mode top
比较不悲观方式:用enclosed的方式选择WLM,该W LM对应的设计完全地包住这条连线,这时DC将选择SUB模块对应的连线负载模型。在enclosed模式下, 采用子模块的连线负载模型, 即40×40;因SUB模块比较TOP设计小,所以连线的延迟比较短(不悲观,就是连线延时小)。对应的命令为:
set_wire_load_mode enclosed
在segmented模式下, 位于两个小模块中的部分采用这两个小模块对应的连线负载模型, 中间部分采用子模块的连线负载模型。
二:输入驱动,输出负载预算
1:预算规则
*输入驱动选择弱cell,但不能过弱
*输入端口电容限制set_max_capacitance
*输出端口load个数估算
例如:(只是举例)对于下面的电路图:
其规格为:模块输入端口驱动的负载不大于10个“AND2”门的输入引脚的负载,模块输出端口最多允许连接3模块,如果某个输出端需要连接多于3个模块,我们要在代码中复制该输端口。
2:example
三:环境变量例子
环境约束举例如下所示:
语法中,设置(定义变量时),如上面的:
Set ALL_IN_EXCEPT_CLK [remove_from_collection [all_inputs] [get_ports “$CLK_NAME”]]中,后面的remove_from_collection是移除设计物集对象的意思,我们知道,DC可以将设计识别成多个对象,比如输入端口、输出端口等等,然后这个就是从all_inputs这个对象集合中,移除掉CLK_NAME这些代表的端口;如果命令之中有命令时,需要用[]来括起来。
然后是expr是表达式求值的意思,因为load_of取出了一个端口的负载值(因为哟load_of这个命令,即命令中有命令,因此需要加[]),这个值*10 是个表达式,因此用expr来指出求值,求值是一个命令,因此用[]括了起来。
上面中,LIB_NAME、WIRE_LOAD_MODEL、DRIVE_CELL 、DRIVE_PIN、OPERA_CONDITION这些变量的内容都不是随便定义的,需要根据综合库书写,下面进行解释,库的具体内容参考综合库那一节。
LIB_NAME:库的名字,这里使用的恶劣的情况:
WIRE_LOAD_MODEL:线负载模型,打开slow.lib这文件,可以找到各种线负载模型:
约束中选的是w150的。
DRIVE_CELL:驱动单元,也就是用来模拟驱动输入端的驱动单元,这要选择库中有的单元,比如反相器:
DRIVE_PIN:驱动管脚,为单元的输出管脚,也就是“Y”了。
OPERA_CONDITION:这个操作环境也是要填写库里面有的:
设置完这些变量之后,还设置了ALL_IN_EXCEPT_CLK和MAX_LOAD变量,其中ALL_IN_EXCEPT_CLK变量代表了除了时钟之外的输入管脚。MAX_LOAD变量就表示了最大的负载,代表的是库中某个单元的输入负载值。
四:面积约束
1:面积的单位
·2输入与非门(2-input-NAND-gate)
·晶体管数目(Transistors)
·平方微米(Square microns)
2:我们用set_max_area命令为设计作面积的约束。例如:
set_max_area 10000
当设计不是很大的时候,根据上面的描述,我们就可以使用下面的命令进行面积约束:
set_max_area 0
让DC做最大的面积优化约束。
五:其他命令
1:约束加完后检查
report_port -verbose ;#检查端口约束
report_clcok;#检查clock约束
2:重定向
重定向输出脚本并且输出到一个log文件里
redirect -tee -file precompile.rpt
3: help
help *clcok
help -verbose create_clock
create_clock -help
man create_clock
六:实战
由于种种原因,这里只有环境属性的约束的实战,其他的约束也可以通过上面的讲解和下面的这个实战进行设计。
首先,我们来看看设计约束规格:
(设计原理图)
(设计规范)
在前面一节的基本时序约束规范上加上下面的规范:
·DC启动环境的设置我们根据设计原理图和设计规范开始进行实践:
(跟上一节一样,这里不再重复)
·约束文件的编写
基本的时序路径约束和上一节一样,不进行改动,下面进行工作环境的约束:
-->输入端口的驱动设置:
1.要我们使用库里面的bufbd1来驱动除了clk和Cin*之外的所有输入端口:
这里是直接使用库里面的单元来驱动的,根据前面的讲解,我们很容易得到约束的命令为:
set_driving_cell -lib_cell bufbd1 -library cb13fs120_tsmc_max [remove_from_collection [all_inputs] [get_ports "clk Cin*"]]
(命令的格式为)set_driving_cell -lib_cell 单元的名字 -library 单元所在库的名字 要设置约束的对象
注意:当一条命令太长,要进行分割时,使用反斜杠\作为分隔符,且反斜杠后面不能加空格。
2.Cin*是芯片级的端口,需要加上120ps的最大转化时间,这是直接设置转换时间,因此可以这样约束:
set_input_transition 0.12 [get_ports Cin*]
-->输出负载的约束:
1.除了cout输出,其它输出驱动值都是库单元bufbd7的引脚I负载值的两倍,也就是用单元的端口进行约束,因此有:
set_load [expr 2 * {[load_of cb13fs120_tsmc_max/bufbd7/I]}] [get_ports out*]
2.cout驱动最大值为25pf的负载,因此可以这样设置:
set_load 0.025 [get_ports Cout*]
-->操作环境的设置:
由于用到了库里面的单元,我们还在最好设置一下操作环境,虽然DC可以从启动环境里面找到单元所在的位置库,但是我也要设置操作环境,如下所示:
set_operating_conditions -max cb13fs120_tsmc_max
下面的步骤跟前面的一样,这里就不展开描述了:
·启动DC,设计读入前的检查
·读入设计和检查设计
·执行约束和检查约束
·进行综合