相关阅读
Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm=1001.2014.3001.5482
简介
其实在下面这篇关于Formality的文章中,笔者已经介绍了常量触发器的移除,但仅提了一句“当Design Compiler识别到常量触发器后,它会将其从设计中移除并直接传播常量逻辑”,本文旨在详细讨论Design Compiler对常量触发器的优化方式。
Formality:时序变换(一)(常量触发器移除)https://chenzhang.blog.csdn.net/article/details/145312557首先回顾一下常量触发器的概念:设计中的某些触发器可能永远不会改变其状态,因为它们的一个或多个输入引脚上有常量值。这些常量值可能是直接出现在输入端,也可以是通过优化扇入的逻辑锥而最终导致触发器的常量输入,移除这些触发器可以显著改善面积。
下面以图1为例介绍常量触发器的概念,其中t1_reg是不带复位/置位端的触发器,而t2_reg是带异步复位的触发器。
图1 综合前设计
为了固定输入端口的值为常量,可以使用set_logic_one命令(注意:不可以使用set_case_analysis命令),如下所示。
dcnxt_shell> set_logic_one [get_ports d]默认情况下,Design Compiler在综合过程中会将所有常量触发器移除,如图2所示,因为移除它们对设计的功能没有影响,并提示以下信息。
Information: The register 't1_reg' is a constant and will be removed. (OPT-1206)图2 综合后设计(对应图1)
需要注意的是,常量传播到触发器t2_reg的数据输入端就停止了,这是因为触发器t2_reg拥有异步复位功能,其状态可以通过异步复位改变,因此没有被认定为是常量触发器。
表1列出了所有可以被移除的常量触发器类型(假设表中的复位/置位都是高电平有效)。
表1 常量触发器类型
| 触发器类型 | 数据输入 | 置位 | 复位 |
| 简单触发器 | 常量1或0 | 无 | 无 |
| 带置位的触发器 | 常量1 | 无要求 | 无 |
| 带置位的触发器 | 无要求 | 常量1 | 无 |
| 带复位的触发器 | 常量0 | 无 | 无要求 |
| 带复位的触发器 | 无要求 | 无 | 常量1 |
| 带复位/置位的触发器 | 常量1 | 无要求 | 常量0 |
| 带复位/置位的触发器 | 常量0 | 常量0 | 无要求 |
优化控制
如果用户出于一些设计原因,想要保留常量触发器,可以通过一些控制变量和命令完成,下面将依次介绍,首先介绍的是compile_seqmap_propagate_constants变量、compile_seqmap_propagate_high_effort变量和set_compile_directives命令,它们很早就存在于Design Compiler中了,而set_constant_register_removal命令较新,因此最后介绍。
compile_seqmap_propagate_constants变量
如果把compile_seqmap_propagate_constants变量(默认值为true)设置为false,则综合工具会保留常量触发器,并将其认定为是非常量状态,图3展示了将compile_seqmap_propagate_constants变量设置为false后的综合结果。从图中可以看出,常量触发器t1_reg得以保留。
图3 综合后设计(对应图1)
compile_seqmap_propagate_high_effort变量
默认情况下,Design Compiler会尝试寻找那些无法逃脱其复位状态的触发器,并将这些触发器视为常量触发器后移除,图4展示了一个例子,其中带异步复位的触发器t2_reg一旦进入复位状态(即输出0),就会因为反馈路径导致数据输入端为0。
图4 综合前设计
需要注意的是,只有开启了常量触发器的识别后(通过compile_seqmap_propagate_constants变量或set_constant_register_removal命令),compile_seqmap_propagate_high_effort变量(默认值为true)才能控制是否进行这种优化。
set_compile_directives命令
set_compile_directives命令提供了-constant_propagation选项,如果-constant_propagation选项指定为false,则可以阻止常量传播及常量触发器的识别,并将其认定为是非常量状态,下面展示了该命令的用法。
dcnxt_shell> set_app_var compile_seqmap_propagate_constants true dcnxt_shell> set_compile_directives -constant_propagation false [get_cells t1_reg] dcnxt_shell> set_logic_one [get_ports d]图5展示了这种情况下的综合结果。
图5 综合后设计(对应图1)
dcnxt_shell> set_app_var compile_seqmap_propagate_constants true dcnxt_shell> set_app_var compile_seqmap_propagate_high_effort true dcnxt_shell> set_compile_directives -constant_propagation false [get_cells t2_reg]图6展示了这种情况下的综合结果。
图6 综合后设计(对应图4)
该命令可能会影响触发器扇入的逻辑锥优化,图7给出了一个例子。
图7 综合前设计
dcnxt_shell> set_app_var compile_seqmap_propagate_constants true dcnxt_shell> set_compile_directives -constant_propagation false [get_cells x1] dcnxt_shell> set_logic_zero [get_ports d]图8展示了这种情况下的综合结果。
图8 综合后设计(对应图7)
需要注意的是,该命令只能用于阻止移除常量触发器,而不能用于指定移除常量触发器,当compile_seqmap_propagate_constants变量设置为false时,即使-constant_propagation选项指定为true也无法移除常量触发器,如下所示。
dcnxt_shell> set_app_var compile_seqmap_propagate_constants false dcnxt_shell> set_compile_directives -constant_propagation true [get_cells t1_reg] dcnxt_shell> set_logic_one [get_ports d]图9展示了这种情况下的综合结果。
图9 综合后设计(对应图1)
set_constant_register_removal命令
Design Compiler在2019版本推出了set_constant_register_removal命令,该命令可以在指定触发器上设置set_constant_register_removal属性,用于控制是否移除常量触发器,下面展示了该命令的用法。
dcnxt_shell> set_constant_register_removal [get_cells t1_reg] true当set_constant_register_removal属性设置为false时,其优先级大于compile_seqmap_propagate_constants变量和set_compile_directives命令;当set_constant_register_removal属性设置为true时其优先级大于compile_seqmap_propagate_constants变量,但小于set_compile_directives命令。下面展示了一些例子。
dcnxt_shell> set_app_var compile_seqmap_propagate_constants true dcnxt_shell> set_compile_directives -constant_propagation true [get_cells t1_reg] dcnxt_shell> set_constant_register_removal [get_cells t1_reg] false dcnxt_shell> set_logic_one [get_ports d]图10展示了这种情况下的综合结果。
图10 综合后设计(对应图1)
dcnxt_shell> set_app_var compile_seqmap_propagate_constants false dcnxt_shell> set_compile_directives -constant_propagation true [get_cells t1_reg] dcnxt_shell> set_constant_register_removal [get_cells t1_reg] true dcnxt_shell> set_logic_one [get_ports d]图11展示了这种情况下的综合结果。
图11 综合后设计(对应图1)
dcnxt_shell> set_app_var compile_seqmap_propagate_constants false dcnxt_shell> set_compile_directives -constant_propagation false [get_cells t1_reg] dcnxt_shell> set_constant_register_removal [get_cells t1_reg] true dcnxt_shell> set_logic_one [get_ports d]图12展示了这种情况下的综合结果。
图12 综合后设计(对应图1)
需要注意的是,以上所说的常量触发器移除的前提是该单元没有被设置dont_touch、size_only属性。这些属性会影响常量触发器移除,但不会影响常量传播。
常量时钟
默认情况下,如果触发器的时钟输入端为常量,该触发器不会被认定为是常量触发器,但如果将compile_seqmap_propagate_constant_clocks变量(默认值为false)设置为true,则会被认定为是常量触发器(前提是通过compile_seqmap_propagate_constants变量或set_constant_register_removal命令开启了常量触发器的识别),常量值由Design Compiler决定,下面给出了一个例子。
图13 综合前设计
dcnxt_shell> set_app_var compile_seqmap_propagate_constants true dcnxt_shell> set_app_var compile_seqmap_propagate_constant_clocks true dcnxt_shell> set_logic_one [get_ports clk1]图14 综合后设计(对应图13)
特殊属性
compile_seqmap_propagate_constants_size_only变量
一般情况下,被设置dont_touch、size_only属性的触发器不会被认定为是常量触发器,常量也无法穿过这些触发器,但如果compile_seqmap_propagate_constants_size_only变量(默认值为false)设置为true,则常量会穿过拥有size_only属性的触发器(即使该触发器不会被移除)(前提是通过compile_seqmap_propagate_constants变量或set_constant_register_removal命令开启了常量触发器的识别),下面给出了一个例子。
dcnxt_shell> set_app_var compile_seqmap_propagate_constants true dcnxt_shell> set_app_var compile_seqmap_propagate_constants_size_only true dcnxt_shell> set_logic_zero [get_ports d] dcnxt_shell> set_size_only [get_cells t1_reg]图15展示了这种情况下的综合结果。
图15 综合后设计(对应图7)
边界优化
常量是否能跨越层次结构传播与边界优化有关,关于更详细信息,请参考下面博客中的“对于禁止“跨层次结构常量和等价与反向等价信息传播”的特殊处理”一节。
Design Compiler:边界优化(Boundary Optimization)https://chenzhang.blog.csdn.net/article/details/145666047
写在最后
Design Compiler NXT在2022版本推出了report_transformed_registers命令,该命令可以报告工具在优化过程中对寄存器(包括触发器和锁存器)进行的所有变换,详细内容可以参考下面的博客。
SDC命令详解:使用report_transformed_registers命令进行报告https://blog.csdn.net/weixin_45791458/article/details/158101563?sharetype=blogdetail&sharerId=158101563&sharerefer=PC&sharesource=weixin_45791458&spm=1011.2480.3001.8118