相关阅读
Design Compiler
https://blog.csdn.net/weixin_45791458/category_12738116.html?spm=1001.2014.3001.5482
简介
其实在下面两篇关于Formality的文章中,笔者已经介绍了不可读(unread)的概念,但仅提了一句"当Design Compiler识别到不可读触发器后,它会将其从设计中移除",本文旨在详细讨论Design Compiler对不可读单元的优化方式。
Formality:不可读(unread)的概念
https://chenzhang.blog.csdn.net/article/details/145242304Formality:时序变换(二)(不可读触发器移除)
https://chenzhang.blog.csdn.net/article/details/145329194 首先回顾一下不可读的概念:不可读是一种状态,单元(触发器、组合逻辑门)都可能位于这种状态,简单来说,不可读就是单元直接或间接没有驱动任何输出端口。
下面以图1为例介绍不可读的概念,其中单元x2的输出悬空,导致单元x2、t2_reg、t1_reg、x1都被视为不可读(其中后三个单元的扇出中只有不可读单元,所以被认定为是间接不可读状态)。

图1 综合前设计
默认情况下,Design Compiler在综合过程中会将所有不可读单元删除,因为删除它们对设计的功能没有影响,并提示以下信息。
Information: The register 't2_reg' will be removed. (OPT-1207)
Information: The register 't1_reg' will be removed. (OPT-1207)
优化控制
如果用户出于一些设计原因,想要保留不可读单元,可以通过一些控制变量和命令完成,下面将依次介绍,首先介绍的是compile_delete_unloaded_sequential_cells变量和set_compile_directives命令,它们很早就存在于Design Compiler中了,而set_unloaded_register_removal命令较新,因此最后介绍。
compile_delete_unloaded_sequential_cells变量
如果把compile_delete_unloaded_sequential_cells变量(默认值为true)设置为false,则综合工具会保留不可读触发器,并将其认定为是可读状态(这样做的话,触发器扇入的逻辑锥也就不会被认定为是间接不可读状态从而删除了),图2展示了将compile_delete_unloaded_sequential_cells变量设置为false后的综合结果。从图中可以看出,组合逻辑门x2被删除了,而其余单元都得以保留。

图2 综合后设计
综合时会提示以下信息,需要注意的是,只有一个触发器没有驱动任何扇出,才会出现OPT-109警告,也就是说该警告由删除组合逻辑门x2后的触发器t2_reg触发,而不是触发器t1_reg。
Warning: In design dff_100_flat, there are sequential cells not driving any load. (OPT-109)
Information: Use the 'check_design' command for
more information about warnings. (LINT-98)
set_compile_directives命令
除了保留不可读触发器,不可读组合逻辑门也可以被保留,set_compile_directives命令提供了-delete_unloaded_gate选项,当compile_delete_unloaded_sequential_cells变量设置为true时,如果-delete_unloaded_gate选项指定为false,则可以阻止删除不可读单元(触发器、组合逻辑门),并将其认定为是可读状态,下面展示了该命令的用法。
dcnxt_shell> set_app_var compile_delete_unloaded_sequential_cells true
dcnxt_shell> set_compile_directives -delete_unloaded_gate false [get_cells x2]
图3展示了这种情况下的综合结果。

图3 综合后设计
需要注意的是,该命令只能用于阻止删除不可读单元,而不能用于指定删除不可读触发器,当compile_delete_unloaded_sequential_cells变量设置为false时,即使-delete_unloaded_gate选项指定为true也无法删除不可读触发器,如下所示。
dcnxt_shell> set_app_var compile_delete_unloaded_sequential_cells false
dcnxt_shell> set_compile_directives -delete_unloaded_gate true [get_cells t2_reg]
图4展示了这种情况下的综合结果。

图4 综合后设计
set_unloaded_register_removal命令
Design Compiler在2019版本推出了set_unloaded_register_removal命令,该命令可以在指定触发器上设置remove_unloaded_register属性,用于控制当该触发器不可读时是否删除,下面展示了该命令的用法。
dcnxt_shell> set_unloaded_register_removal [get_cells t2_reg] true
当remove_unloaded_register属性设置为false时,其优先级大于compile_delete_unloaded_sequential_cells变量和set_compile_directives命令;当remove_unloaded_register属性设置为true时其优先级大于compile_delete_unloaded_sequential_cells变量,但小于set_compile_directives命令。下面展示了一些例子。
dcnxt_shell> set_app_var compile_delete_unloaded_sequential_cells true
dcnxt_shell> set_compile_directives -delete_unloaded_gate true [get_cells t2_reg]
dcnxt_shell> set_unloaded_register_removal [get_cells t2_reg] false
图5展示了这种情况下的综合结果。

图5 综合后设计
dcnxt_shell> set_app_var compile_delete_unloaded_sequential_cells false
dcnxt_shell> set_compile_directives -delete_unloaded_gate true [get_cells t2_reg]
dcnxt_shell> set_unloaded_register_removal [get_cells t2_reg] true
图6展示了这种情况下的综合结果。

图6 综合后设计
dcnxt_shell> set_app_var compile_delete_unloaded_sequential_cells false
dcnxt_shell> set_compile_directives -delete_unloaded_gate false [get_cells t2_reg]
dcnxt_shell> set_unloaded_register_removal [get_cells t2_reg] true
图7展示了这种情况下的综合结果。

图7 综合后设计
需要注意的是,以上所说的不可读单元删除的前提是该单元没有被设置dont_touch、size_only属性。
边界优化
正如Design Compiler:边界优化(Boundary Optimization)一文中所说的,不可读信息是否能跨越层次结构传播取决于是否开启了边界优化,下面给出了一个例子。

图8 综合前设计
如果使用compile_ultra -no_boundary_optimization命令进行综合(禁止边界优化),则不可读信息无法从层次外部传播到内部,也就是说out1_reg及其扇入的逻辑锥不会被删除,如果使用compile_ultra -no_autoungroup命令进行综合(禁止自动解组),则综合结果如图9所示。

图9 综合后设计
如果想在禁用边界优化时依旧删除不可读单元,可以将compile_optimize_unloaded_seq_logic_with_no_bound_opt变量(默认值为false)设置为true,此时不可读信息可以跨越层次结构传播。