数字逻辑综合工具-DC-06
——综合优化过程
编译的策略:Top-down
(做设计有两种策略:top-down 和 bottom-up)
设计一定是一种层次化的结构,一层一层地去例化
Top-down只有一层的约束,针对某些模块,可能会有一些特殊的约束
在一个soc系统里面,会有一些真正的工作模块,和一些管理模块,这些工作模块跟clk、rst不会放到一起去做综合,clk、reset这些模块一般会做一些特殊的约束,比如clock gating,会放在额外的脚本里面做
如果采用bottom-up的综合顺序,当出现了glue logic(胶合逻辑),即如果在顶层模块里,并不是只有模块与模块的连接,而是由一个与门连接而成。如果采用bottom-up的顺序,下层模块保持don’t touch,那么还需要针对top层写一个额外的约束(要把glue logic也放进去编译)。
如果这样做的话,一个Soc项目里的顶层会有四五十个模块,针对每一个模块都写一个约束,这个工作量会非常大,而且效果不一定好,所以一般采用top-down的方式。
【compile_ultra】
用在时序约束紧张的时候。相当于打开了很多的开关。
这个命令在compile命令上做了更强的一些优化功能,会把整个模块给打散。
全部打散会有些问题,对于后仿而言,最后只能看到一个顶层,如果后仿有问题,没法确定是哪个模块产生的!
针对一些关键路径会优化,尝试做多次,直到所有的方法都没法满足约束。
这个命令做的一些优化:
1、 结构级优化:比如做了一个加法器(行波进位加法器、超前加法器等等)(比较大的优化)
2、 逻辑级优化
3、 门级优化:局部上的一些优化
DC会尝试着在满足时序约束的同时,将面积达到最小。
如果不满足要求,DC会找出critiical path,对其进行resynthesis
【DesignWare Library】
这是一个soft IP库:加减乘大于等于小于
FIFO、shiftreg、div_seq、ram……
(自己写的没有人家写的可靠)
在设计都进来的时候,link check保存为unmapped .ddc,这个格式里面主要是一些DW开头的器件。
【一些常见的算术优化方法:】
1、 折叠
2、 公共表达式——资源分享
3、 少用乘法
4、 乘以某个常数——把这个常数拆成2的多少次放,做移位相加,替代乘法器
【逻辑复制】
单元的延迟跟两个因素有关:输入的转换时间和扇出负载。
上图有一个关键路径,它的组合逻辑延时比较长,为了减小这个时间,把输入门的负载减小:将逻辑一分为二,对于关键路径,不让它驱动过多的单元,对于约束比较松的路径,可以安排large fanout(以面积换速度)。
【库分析】
等效表达式:DC会针对同一个表达式做不同的表达方式。预先建立好逻辑。
说实话不是很懂。
【边界优化】
有的时候会借助一些常数,可以被优化掉,比如用DFF的QB端,优化过后的信号会出现_BAR的后缀。
问题:做形式验证(把网表跟rtl代码作数学表达式上的等价校验)的时候,需要把DC产生的default.svf文件(一般在工作目录下)交给formality工具,告诉formality这些结构发生了一些改变。否则Formality会不认识这些优化的地方。
【Auto-ungrouping】
这是compile ultra默认的,如果不希望打散,加上命令set_ungroup <references_or_cells> false 命令
例子:
【扫描链-scan】(DFT)哪些地方短路了,哪些地方开路了给扫描出来。一般用这种带选择的触发器来代替一般的触发器,作为扫描链。扫描链的插入必然会带来更大的面积和更长的组合路径。
在综合的时候一般要加入-scan选项,让DC把里面普通的触发器替代成这种带MUX的触发器,看看能不能完成。
在没有做DFT的时候,-scan选项只是插入一个MUX,并没有形成一个链!
【timing_high_effort_script选项】
对时序做最好的优化。
会把时序的优先级提升到超过DRC(Design Rule Check)的优先级!
DRC是工艺厂商的要求,不满足DRC可能会出错。
【-timing】
【-retime】
上图:前面的不满足,后面的有点余量
下图:把前面的一部分组合逻辑挪到后面去,这样前一级就得到了很大的改善。后面一点点的violation可以通过把时钟稍微往后挪一点来改善掉。
Retiming的基本思想:这几个在功能和时序上是等效的
如果不希望这种retiming发生在一些特定的寄存器或者design中,可以通过命令设置
retiming的结果也需要放在.svf文件里告诉Formality
【路径分组】
在一个设计里面可能会有很多的clock,DC会把这些路径根据时钟进行分组
【亚关键路径被忽略的问题】
如果最长路径不能满足是需要求,那么DC会放弃对其它逻辑的一些优化。
(假设COMBO不满足时序要求,中间那个reg-to-reg路径就不优化了。)
——重新分组:这个组的最差的一个挂了,那这个组么得救了,其他组的还能抢救一下。
比如这里,分成Inputs Outputs Reg-to-Reg和COMBO四个组
命令:(既然是路径,就要指定从哪来到哪去(from to))
【critical range】
这个组里,最差的已经提高不了了,现在设置一个范围,在这个范围里面的,都尽量去做一些优化。
【给分定的组指定一个权重】
发现某些组是特别重要的,就把权重提高一点。
三个建议的值:1 2 5 默认的是1。5的重要程度最高。
weight的另外一个例子:
这里换了一种实现DFF的方式,Tsetup变长了,但Tc2q变短了,即提高了CLK路径的优先级,牺牲了别的路径,改善了该路径。
【【操作部分】】
(官方建议critical_range不超过时钟周期的百分之十)
这些值设好了之后要查看一下,report_path_group
license没有compile_ultra,用-map_effort high(发现综合结果不满足要求,回过头来做优化,注意,这种不会做结构级的优化) -area_effort high来代替
把综合之后的网表保存为ddc格式
脚本运行完了之后看时序
report_timing -delay_type max(看最差的那条)
(这是在脚本里把路径分组注释掉之后的结果)
注意,现在只报告了一个路径。而且这个路径属于clk_i路径组。
通过report_path_group来查看分组的情况
(此时没有任何分组)
ungroup之前的电路图:
(此时的设计是分级的)
敲入命令:ungroup -flatten -all之后,只能看到一个顶层了
compile没加-scan选项时的ddc网表:
(在mapped里面,top.ddc)
这是一个普通的D触发器
敲入命令:compile -map_effort high -area_effort high -scan
==>综合出来这样的DFF
这些DFF并没有连成一个链,需要用DFT Compiler去做。(不是所有的芯片都一定要做DFT的)。
【设置了路径组之后的综合】
report_path_group
再执行report_timing -delay_type max
(这边不存在COMBO的路径,所以没有报)