第五章综合的约束与优化.docx
《第五章综合的约束与优化.docx》由会员分享,可在线阅读,更多相关《第五章综合的约束与优化.docx(42页珍藏版)》请在冰豆网上搜索。
第五章综合的约束与优化
第五章综合的约束与优化
综合的一个很重要的概念就是:
单纯的映射是远远不够的,更重要的是设计的整体优化。
一方面设计工程师为综合规定必要的约束,例如对面积、速度、功耗的要求等,从而使优化有所依据;另一方面选择合适的综合器是优化程度的决定性因素。
同一个设计使用不同的综合器所得到的优化结果可以相差3~5倍。
第一节综合约束
5-1-1概述
综合约束是对可测量的电路特性所定义的设计目标,比如面积、速度和电容等。
如果没有这些约束,DesignCompiler工具将不能有效地对你的设计进行最优化。
在对设计进行优化时,DesignCompiler支持两种类型的约束:
●设计规则约束(Designruleconstraints)
●最优化约束(Optimizationconstraints)
设计规则约束是固有的,在工艺库里定义;这些约束条件是为了保证设计
的功能正确性,适用于使用工艺库的每一个设计;可以使这些约束比最优化约束更为严格。
最优化约束是外在的,由设计者自己定义;最优化约束描述设计指标,在整个dc_shell工作期间应用于当前设计;它们必须接近于现实情况。
DesignCompiler试图同时满足设计规则约束和最优化约束,但设计规则约束必须首先被满足。
设计者可以以命令行形式交互式的指定约束或者在一个约束文件里指令约束。
图5.1显示了主要的设计规则约束和最优化约束,以及如何用dc_shell界面命令来设置这些约束。
图5.1MajorDesignCompilerConstraints
第二节设置设计规则约束
这一节将讨论最常用的设计规则约束:
•转换时间(Transitiontime)
•扇出负载(Fanoutload)
•电容(Capacitance)
DesignCompiler给设计对象赋予属性来表示这些设计规则约束。
表5.1列出了每一个设计规则约束对应的属性名。
表5.1设计规则属性
DesignRuleConstraint
AttributeName
Transitiontime
max_transition
Fanoutload
max_fanout
Capacitance
max_capacitance
min_capacitance
Celldegradation
cell_degradation
Connectionclass
connection_class
设计规则约束是工艺库里指定属性,你也可以明确地、随意地指定这些约束。
如果工艺库里定义了这些属性,在进行设计编译和生成约束报告时,DesignCompiler暗中将它们应用于使用那个库的任何设计。
你不能移走工艺库里定义的设计规则约束,因为它们是工艺的特定要求,但你可以使它们更为严格来适应你的设计。
如果内在的和外在的设计规则约束同时应用于一个设计或一条线,更为严格的值拥有优先权。
5-2-1设置转换时间约束
线的转换时间约束是对它的驱动管脚改变逻辑值的时序要求。
转换时间是以工艺库数据为基础。
对于非线性延迟模型(NLDM),输出转换时间是输入转换和输出负载的函数。
通过对一个单元的每一个输出管脚赋予max_transition属性,DesignCompiler和LibraryCompiler模拟转换时间约束。
在最优化过程中,DesignCompiler试图使每一条线的转换时间都小于max_transition属性值。
命令set_max_transition用来改变工艺库里指定的最大转换时间约束。
通过对指定的对象设置max_transition属性,这条命令给设计中所有线或与确定端口相连的线设置了最大转换时间。
比如,对设计adder中的所有线设置最大转换时间3.2,输入:
dc_shell>set_max_transition3.2find(design,adder)
利用remove_attribute命令来取消set_max_transition命令,比如,输入:
dc_shell>remove_attributefind(design,adder)\max_transition
5-2-2设置扇出负载约束
线的最大扇出负载是指这条线所能驱动的最大数目的负载。
通过赋予每一个输入管脚fanout_load属性和一个单元的每一个输出管脚max_fanout属性,DesignCompiler和LibraryCompiler模拟扇出限制。
扇出负载值不表示电容;它表示对整个扇出负载的数字上的贡献。
强加于一个输入管脚的扇出负载不必是1.0。
库的开发者可以指定更高的扇出负载值来模仿内在的单元负载效果。
将有那个管脚驱动的所有输入的fanout_load值相加,DesignCompiler计算一个驱动管脚的扇出。
为确定这个管脚是否满足最大扇出负载约束,DesignCompiler将计算的扇出负载值和管脚的max_fanout值相比较。
图5.2显示了一个小电路。
其中管脚X驱动两个负载,管脚A和管脚B。
如果管脚A的fanout_load值为1.0,管脚B的fanout_load为2.0,那管脚X的整个扇出负载为3.0。
如果管脚X有一个大于3.0的最大扇出,比如说16.0,那管脚X符合扇出约束。
图5.2扇出约束实例
在最优化时,DesignCompiler试图满足每一个驱动管脚的扇出负载限制。
如果一个管脚违反了扇出负载限制,DesignCompiler会尽力改正这个问题(比如通过改变这个元件的驱动能力)。
工艺库可能对整个库指定默认的扇出约束,或对库描述的一个单独的单元里特定的管脚指定扇出约束。
为确定你的工艺库是否为扇出计算而模拟,你可以对单元的输入管脚搜索fanout_load属性:
dc_shell>get_attributefind(pin,my_lib/*/*)fanout_load
用set_max_fanout命令对设计或输入管脚设置比工艺库里指定的更为保守的扇出约束(用set_fanout_load命令对输出端口设置预期的扇出负载值)。
set_max_fanout命令通过对指定对象设置max_fanout属性对设计中的所有线或指定的输入端口设置最大扇出负载。
比如,要对设计adder中的所有线设置max_fanout为16,输入:
dc_shell>set_max_fanout16find(design,adder)
如果你用set_max_fanout命令和存在库的max_fanout属性,DesignCompiler会尽力满足更小的扇出限制。
用remove_attribute命令来取消set_max_fanout命令,比如,输入:
dc_shell>remove_attributefind(design,adder)max_fanout
5-2-3设置电容约束
转换时间约束并没有提供一个直接的方式来控制线的真实电容。
如果你想要直接控制电容,利用set_max_capacitance命令来设置最大电容约束。
这个约束是完全独立的,因此除了转换时间约束外,你还可以使用它。
通过给一个单元的输出端口或管脚赋予max_capacitance属性,DesignCompiler和LibraryCompiler模拟电容约束。
把线电容和管脚电容相加,DesignCompiler来计算输出线的电容。
为确定线是否满足电容约束,DesignCompiler把计算出的电容值与输出管脚的max_capacitance值相比较。
比如,对设计adder中的所有线设置最大电容为3,输入:
dc_shell>set_max_capacitance3find(design,adder)
用remove_attribute命令来取消set_max_capacitance命令,如,输入:
dc_shell>remove_attributefind(design,adder)\max_capacitance
你也可以用set_min_capacitance命令对输入端口或管脚设置最小电容。
第三节设置最优化约束
这一节中将讨论最常用的指定的最优化约束:
•时序约束(Timingconstraints)
•面积约束(Areaconstraints)
DesignCompiler也支持功耗约束。
图5.3解释了定义最优化约束的一些常
用的命令。
图5.3CommandsUsedtoDefinetheOptimizationConstraintsforSequentialBlocks
5-3-1设置时序约束
时序约束指定了设计所要求的性能。
为设置时序约束,
1.定义时钟。
2.定义与时钟相关的I/O的时序要求。
3.指定组合路径延迟要求。
4.指定时序异常。
表5.2列出了设置时序约束的命令。
表5.2设置时序约束的命令
Command
Description
create_clock
Definestheperiodandwaveformfortheclock.
set_clock_latency
set_propagated_clock
set_clock_uncertainty
Definestheclockdelay.
set_input_delay
Definesthetimingrequirementsforinputports
relativetotheclockperiod.
set_output_delay
Definesthetimingrequirementsforoutputportsrelativetotheclockperiod.
set_max_delay
Definesmaximumdelayforcombinationalpaths.
(Thisisatimingexceptioncommand.)
set_min_delay
Definesminimumdelayforacombinationalpaths.
(Thisisatimingexceptioncommand.)
set_false_path
Specifiesfalsepaths.
(Thisisatimingexceptioncommand.)
set_multicycle_path
Specifiesmulticyclepaths.
(Thisisatimingexceptioncommand.)
下面的部分将详细介绍三个步骤。
5-3-1-1定义一个时钟
对于一个同步设计,时钟周期是最重要的约束,因为它对设计中所有寄存器到寄存器的路径加以约束。
1.定义时钟的周期和波形
利用create_clock来定义时钟的周期(-period选项)和波形(-waveform选项)。
如果你没有指定时钟的波形,DesignCompiler使用50%的占空循环。
比如,对端口clk指定25兆赫和50%的占空循环,输入:
dc_shell>create_clockclk-period40
当你的设计包含多时钟时,密切注意这些时钟共同的基本周期。
共同的基本周期是所有时钟周期最小的共同的倍数。
比如,如果你有10,15,20的时钟周期,那共同的基本周期就为60。
定义你的时钟以使这个共同的基本周期是每一个时钟周期的最小的整数倍数。
这个共同的基本周期的要求是定性的,不存在硬性限制。
如果这个基本周期大于最小周期的十倍,那结果是要求更长的运行时间和更大的内存。
一个极端的情况是如果你有一个寄存器到寄存器的路径,其中一个寄存器的周期为10,而另一个寄存器的周期为10.1,那么共同的基本周期就为1010.0。
通过指定不带小数点的时钟周期,插入不确定的时钟来调整时钟周期,你可以解决这个问题。
dc_shell>create_clock-period10clk1
dc_shell>create_clock-period10clk2
dc_shell>set_clock_uncertainty-setup0.1clk2
用report_clock命令来显示设计中所有时钟资源的信息,用remove_clock命令来移走时钟的定义。
2.创建虚拟时钟
许多情况下,一个模块里可能不存在系统时钟。
你可以用create_clock-name来创建一个虚拟时钟,模拟系统中表现的时钟信号。
通过创建一个虚拟时钟,你可以描述模块外的与时钟相关的延迟。
dc_shell>create_clock-period30-waveform{1025}\-namesys_clk
3.指定时钟网络延迟
默认情况下,DesignCompiler假设时钟网络没有延迟(完美的时钟)。
用set_clock_latency和set_clock_uncertainty命令来指定关于时钟网络延迟的时序信息。
你也可以用这些命令来指定估计的或真实的延迟信息。
用set_propagated_clock命令来指定通过时钟网络传播的时钟等待,比如:
dc_shell>set_propagated_clockclk
考虑到由于布局导致的时钟网络的变化,利用set_clock_latency命令的-setup或-hold选项增加少许的错误富余。
比如,对于先期提到的20兆赫的时钟,在时钟边缘的每一边增加0.2的富余,输入:
dc_shell>set_clock_uncertainty-setup0.2clk
dc_shell>set_clock_uncertainty-hold0.2clk
使用report_clock命令的-skew选项来显示时钟网络的时滞信息。
DesignCompiler用这些时钟信息来确定一条路径是否满足建立和保持时间。
5-3-1-2指定I/O时序要求
如果你没有对一个输入端口指定时序要求,DesignCompiler假设信号在零时刻到达输入端口。
绝大多数情况下,输入信号在交错时间到达。
用命令set_input_delay定义输入端口的到达时间。
你定义相对于系统时钟和其他输入端口的输入延迟约束。
如果你没有对一个输出端口指定时序要求,DesignCompiler不会对任何一个以该输出端口结束的路径加以约束。
用set_output_delay命令来定义要求的输出到达时间。
你定义相对于系统时钟的输出延迟约束。
如果一个输入或输出端口有多重的时序要求(因为多重路径),用-add_delay来指定额外的时序要求。
用report_port命令来列出与端口相关的输入或输出的延迟。
用remove_input_delay命令移走输入延迟约束。
用remove_output_delay命令移走输出延迟约束。
图5.4显示了延迟和有效的时钟沿之间的关系(如图中的上升沿)。
图5.4RelationshipBetweenDelayandActiveClockEdge
图中,模块A有输入DATA_IN和输出DATA_OUT。
从波形图中可以看到,DATA_IN在时钟上升沿后稳定20ns;DATA_OUT必须在时钟上升沿前15ns有效。
在你用create_clock命令设置时钟约束后,用set_input_delay和set_output_delay命令来指定这些额外的要求。
比如,输入:
dc_shell>set_input_delay20-clockCLKDATA_IN
dc_shell>set_output_delay15-clockCLKDATA_OUT
下面是一个加以约束的设计模块的实例:
图5.5解释了设计模块my_block的时序要求,下面的命令行是用来定义这些时序要求的。
图5.5my_block的时序要求
create_clock-period20-waveform{515}clka
create_clock-period30-waveform{1025}clkb
set_input_delay10.4-clockclkain1
set_input_delay6.4-clockclkb-add_delayin1
set_output_delay1.6-clockclka-minout1
set_output_delay4.8-clockclka-maxout1
5-3-1-3指定组合路径延迟要求
对于不被时钟周期限制的完全的组合延迟,命令set_max_delay和set_min_delay定义指定路径的最小和最大延迟。
在HDL代码中产生异步逻辑,一种普通的方法就是对锁存器和触发器使用异步置位或复位。
因为复位信号跨越几个模块,在顶层约束这个信号。
比如,要对复位信号定义最大延迟为5,输入:
dc_shell>set_max_delay5-fromRESET
对从IN1到OUT1的路径指定最小延迟为10,输入:
dc_shell>set_min_delay10-fromIN1-toOUT1
用report_timing_requirements命令列出对你的设计所要求的最大和最小延迟。
5-3-1-4指定时序异常
时序异常是对一个或更多的违反默认的单循环时序关系的路径指定时序关系。
利用时序异常来对那些不遵循默认的单循环行为的路径或异步路径加以约束或使其失去作用。
指定众多的时序异常会增加编译时间。
然而,很多设计需要许多的时序异常。
DesignCompiler只承认有正确参考点的时序异常。
•设计中的有效起点是指时序单元的主要的输入端口和时钟管脚。
•有效的结束点是指设计的主要输出端口和时序单元的数据管脚。
如果你指定了一个无效的参考点,DesignCompiler不会发出警告信息。
你必须用命令report_timing_requirements中的-ignored选项来查明被DesignCompiler忽视的时序异常。
你可以利用时序异常命令来指定下列条件:
•错误路径(Falsepaths(set_false_path))
•最小延迟要求(Minimumdelayrequirements(set_min_delay))
•最大延迟要求(Maximumdelayrequirements(set_max_delay))
•多循环路径(Multicyclepaths(set_multicycle_path))
用report_timing_requirements命令列出设计中的时序异常。
1.指定错误路径
DesignCompiler在时序报告中不报告错误路径,或在时序优化时不照顾它们。
用命令set_false_path指定错误路径。
用这个命令来忽视那些非关键路径,它们可能掩盖其他一些在优化时必须考虑的路径;或者是那些在正常操作中从不会发生。
比如,图5.6显示了一个寄存器的外形,它从双向总线(DATA)进行读写。
图5.6ConfigurationRegister
这个电路有这些时序路径:
1.DATAtoU1/D
2.RDtoDATA
3.U1/GtoCONFIG(withpossibletimeborrowingatU1/D)
4.U1/GtoDATA(withpossibletimeborrowingatU1/D)
5.U1/GtoU1/D(throughDATA,withpossibletimeborrowing)
前面四条路径都是有效的,而第五条是一条功能错误的路径,因为正常的操作不可能要求对寄存器同时进行读和写。
在这个设计里,你可以用这个命令来使这条路径失效:
dc_shell>set_false_path-fromU1/G-toU1/D
利用reset_path命令和相同的选项取消set_false_path命令,输入:
dc_shell>set_false_path-setup-fromIN2-toFF12/D
dc_shell>reset_path-setup-fromIN2-toFF12/D
创建一条错误路径不同于使时序弧失效。
使时序弧失效表示一条路径的中断。
定义一个错误路径并不中断路径,它只是阻止在优化时,这条路径被考虑。
2.指定最小和最大延迟要求
你可以用set_min_delay和set_max_delay来指定路径延迟要求,它们远比DesignCompiler根据时钟时序得到的保守。
利用reset_path命令取消set_min_delay和set_max_delay命令。
(1)寄存器到寄存器的路径
DesignCompiler利用下列方程式得到寄存器到寄存器路径的最小和最大路径延迟的约束:
min_delay=(Tcapture-Tlaunch)+hold
max_delay=(Tcapture-Tlaunch)-setup
你可以利用set_min_delay和set_max_delay命令而不考虑得到的路径延迟(Tcapture–Tlaunch)。
比如,假设你有一条路径,时间20时从一个寄存器开始,在时间35到达一个寄存器,此时是时钟的下一个有效沿:
dc_shell>create_clock-period40waveform{020}clk1
dc_shell>create_clock-period40-waveform{1535}clk2
DesignCompiler自动地得到一个最大路径延迟约束:
(35-20)-(终点库的寄存器的建立时间)。
指定一个最大路径延迟为10,输入:
dc_shell>set_max_delay10-fromreg1-toreg2
DesignCompiler以10-(终点库的寄存器的建立时间)来计算最大路径延迟约束,没有考虑最初得到的最大路径延迟约束。
(2)寄存器到端口的路径
DesignCompiler利用下列方程式得到寄存器到端口路径的最小和最大路径延迟的约束:
min_delay=period-output_delay
max_delay=period-output_delay
如果你用set_min_delay或set_max_delay命令,这些命令中定义的值将代替约束计算中的周期值。
比如,假设你有一个时间时钟周期为20的设计,输出OUTPORTA的输出延迟为5:
dc_shell>create_clock-period20CLK
dc_shell>set_output_delay5-clockCLKOUTPORTA
DesignCompiler自动地得到最大路径延迟约束15(20-5)。
指定你想要的最大路径延迟10,输入:
dc_shell>set_max_delay10-toOUTPORTA
DesignCompiler计算最