书接上回,Multi-bit的实现方法和应用 (上),闲言少叙,ICer GO!
In-place MBFF实现
相较于仅基于逻辑连接的MBFF封装,如果考虑到布局的实际情况,那么就有physical aware的in-place的MBFF封装实现,这种思路可以应用在常见的DCT/DCG/genus_PLE 等综合流程。
和in-compilre相比,这种in-place的MBFF封装,最大的优势,就是physical aware。譬如如下示意图:
可见,工具将距离较近的SBFF封装成了MBFF,简单而言,工具的在封装MBFF时候会更为谨慎(严苛),相应的MBFF的封装比率也自然会下降。
这里以DCT为例,它提供了一种in-place的MBFF实现方式:一种基于综合结果的MBFF封装方法。具体实现方法如下
set_multibit_options -mode none
compile_ultra -gate_clock -scan -spg
identify_register_banks
source MBFF_SCR
compile_ultra -gate_clock -scan -incremental -spg
和In-compile相比,这里需要注意两个地方
- 在compile命令中,跳过MBFF封装步骤
- 使用spg模式运行compile命令
- 基于综合结果使用命令identify_register_banks,完成MBFF的in-place体交换。效果见下图:
PS:封装后的MBFF的坐标,是在原始SBFF的中间位置 - MBFF优化后,需要使用compile -incremental进行进一步增量优化,来平抑MBFF带来的QoR影响
这种in-place的MBFF替换有下列好处
- 基于实际物理布局的情形进行MBFF有效替换:
- 相较常规的MBFF有了物理布局影响的考量,可以有针对性地进行MBFF封装,这个对于最终的物理实现有很好的帮助
- 传统的in-compilre的MBFF封装,先做封装,在做优化,这样很有可能导致优化受限
- 可选择的基于WNS的封装方式,可以有效控制MBFF封装对WNS的影响
综上可以看出,如果是使用了in-place方式进行MBFF优化,那么这个布局的结果,一定是要传递给后端版图工具,所以需要SYN和APR联动起来,S家的流程如下:
# SYN flow:
dc_shell> set hdlin_infer_multibit never\|default_none
dc_shell> compile_ultra -gate_clock -scan -spg
dc_shell> identify_register_banks
dc_shell> compile_ultra -gate_clock -scan -incremental -spg
dc_shell> write_file -format ddc -hierarchy top.ddc
#APR flow:
icc_shell> create_mw_lib ...
icc_shell> read_ddc
icc_shell> ......
icc_shell> place_opt_design -spg ......
可以看到。S家是通过SPG flow将此信息紧密联动的,所以说,如果用户使用了in-place的MBFF的流程,那么需要使用SPG流程完成这个信息的有效传递。相较传统的in-compile的MBFF流程,MBFF的对APR实现的挑战会变小。
APR阶段的MBFF封装
从上述的描述可以看到,综合里边可以有效地处理MBFF的封装实现。对应的,基于MBFF的封装原理,除过上述SPG的MBFF流程外,APR阶段也可以自己对MBFF进行封装,以实现PPA的优化。
市面上常见的APR工具是S家ICC/ICC2和C家的innovus,这两个工具都可以对MBFF进行封装,原理是类似的,具体描述见下:
- ICC flow
基于对place 步骤的拆结,这里可以分为三个方法
- Flow1:SPG flow,参见上述综合的In-place MBFF封装方法
- Flow2:coarse placement MBFF flow
icc_shell> create_mw_lib ...
icc_shell> read_verilog
icc_shell> ......
icc_shell> set_banking_guidance_strategy \
-input_map_file MBFF_map.file \
-register_group_file MBFF_reg_grp.rpt \
-output_file MBFF_assembly.tcl
icc_shell> create_placement ......
icc_shell> source ./MBFF_assembly.tcl
icc_shell> place_opt_design -skip_initial_placement ......
先配置MBFF的应用策略,再创建粗布局(coarse placement),工具这个时候会根据粗布局的结果,构建MBFF封装方式,这个和in-place的MBFF封装流程类似,然后用户将导出的文件MBFF_assembly.tcl读入,完成MBFF的封装动作。最后使用place_opt_desing
进行增量式优化,完成MBFF的封装实现。上述的两个输入文件:MBFF_map.file
和MBFF_reg_grp.rp
t都是在DC工具通过命令write_multibit_guidance_files
来导出,以便指导ICC的MBFF封装方方式。
- Flow3:place_opt MBFF flow
icc_shell> place_opt
icc_shell> set_banking_guidance_strategy \
-input_map_file MBFF_map.file \
-output_file MBFF_assembly.tcl
icc_shell> create_banking_guidance
icc_shell> source MBFF_assembly.tcl
icc_shell> psynopt
基于SBFF的网表,完成正常的place_opt,然后基于物理布局结果,进行MBFF的封装实现,最后再做一次增量优化,即可完成MBFF的优化实现过程。如下图示例:
- INVS flow
相较于S家的多个流程的选择,C家的流程比较简单,这个也符合两家一贯的风格,S家细致贴心,C家直接高效。
C家除过对MBFF的封装(merge)以外,也会支持对MBFF打散(split),这些只需要在place阶段进行直接配置就好
invs_shell> setOptMode \
-multiBitFlopOpt {true| false | mergeOnly | splitOnly} \
-multiBitFlopOptIgnoreSDC {true | false}
其中:
multiBitFlopOpt==true: timing_driven 下的MBFF封装和打散
multiBitFlopOpt==false: 禁止MBFF操作,数据库里边以有的MBFF不受影响
multiBitFlopOpt==mergeOnly: timing_driven 下的做MBFF的封装操作
multiBitFlopOpt==splitOnly: timing_driven 下的做MBFF的打散操作
任何阶段设置了setOptMode
配置,任何阶段使用place_opt_design | optDesign
等命令,都会根据这个设定进行相应的优化,这个选项也会被完整地保存在invs的数据库中。
在invs的任何优化后的数据库中,可以使用命令reportMultiBitFFs -statistics
对MBFF的替换结果进行统计报告:
这个评价系统和DC有一些相似之处,但是对于MBFF替换比率的表达,这里采用了Bit Per Flop:平均计算下,单个FF可以承担的FF bit数量。这个值越高,说明MBFF的替换比率就越高,反之亦然。
Invs还提供了一个pin map的报告文件,(PS:这个需要在invs的session里边导出),命令是:dumpMultiBitFlopMappingFile
。这个可以生成
- MBFF的封装(merge)和打散(splie)的动作细节;
- 原先的SBFF(D/Q)和MBFF(D*/Q*)的pin mapping的对应关系
MBFF的命名
基于上述MBFF的实现方法和流程,MBFF的产生通常分为四种
- DC的in-compile 封装MBFF
- DC的in-place封装MBFF
- ICC的in-place封装MBFF
- Invs的in-place封装MBFF
- 手册给出的示范如下
但是经过测试,得到的是类似下列的封装方式:
这种命名方式可能会对formal的mapping有一定挑战,需要注意一下
- 第二种和第三种都是in-place的方式,也是使用工具导出的命令进行MBFF的封装,这样如果命名不是很友好,用户可以通过调整脚本进行命名维护,对用户后期的工作较为友好
这个默认模式就是简单的将FF的名字使用”_”进行连接。
- 第四种是invs是在in-place步骤进行封装的,用户对命名不能干预,
Invs的方法比较友好,前边使用了CDN_MBIT作为MBFF的引示,中间每一个SBFF都用MB进行引示,这个命名规则比较好理解,formal也比较容易区分。常言道,简洁即简单,看来invs不让用户干预命名,还是对自己的处理很有自信的。
流程梳理和推荐
基于上述陈述,对于MBFF的优化方式已经有了比较全面的理解,这里提供一些具体的数据供各位参考:
- DCT采用in-place的MBFF封装流程:
stage | with_MBFF | WO_MBFF |
---|---|---|
SYN_area | 1 | 0.95 |
SYN timing | Meet | Meet |
- invs基于netlist,进行的MBFF封装流程
stage | with_MBFF | WO_MBFF |
---|---|---|
invs_area | 1 | 0.975 |
timing | Meet | Meet |
Short | Clean | Clean |
- invs基于DCT in-place的netlist,进行的MBFF封装流程
stage | with_MBFF | WO_MBFF |
---|---|---|
invs_area | 1 | 0.99 |
timing | WNS; -0.4 | WNS: -0.3 |
Short | Clean | Clean |
结合上述结果,和各个流程的特点,这里有一些建议和推荐
- MBFF可以在三个步骤进行封装实现:RTL,SYN,APR
- 综合阶段通常只作封装,不做打散,
- APR阶段需要基于时序进行封装和打散,timing driven依赖
- MBFF的封装对SBFF的布局有严重依赖:这点符合timing driven的目的
基于此,这里推荐两个flow供大家选择
- SYN-APR MBFF flow
- SYN 打开MBFF优化流程
- APR需要加载SYN吐出的initial placement DEF或者ddc。
- APR 使用skip_initial_placement 的place_opt命令,完成对MBFF的APR实现
- APR MBFF flow
- 基于SBFF的综合数据,在APR的place_opt阶段开始实现MBFF
- 时序驱动模式下,工具可以自动实现后续步骤的MBFF的封装和打散操作
【敲黑板划重点】
MBFF的流程贯穿在整个设计实现,最终的服务对象还是APR和时序分析。通过理解其流程,可以很好的做出最适用于自身设计的方案选择,有效利用其优势,让MBFF助力设计实现,
参考资料
Synopsys Design Compiler® User Guide
Synopsys Multibit Register Synthesis and Physical Implementation Application Note
艾思考后端实现 芯片设计里的Multi-Bit FF探究
艾思考后端实现 Multi-bit的实现方法和应用 (上)