1. 不可读单元的概念与识别机制
在数字IC设计中,不可读(unread)单元是指那些不直接或间接驱动任何输出端口的逻辑单元。这个概念不仅适用于触发器(flip-flop),也适用于组合逻辑门。理解不可读状态对于优化设计面积和功耗至关重要。
1.1 不可读状态的判定标准
一个单元被判定为不可读需要满足以下条件:
- 该单元的输出端口未连接任何负载(直接不可读)
- 该单元仅驱动其他不可读单元(间接不可读)
以图1所示电路为例:
- x2门输出悬空,属于直接不可读
- t2_reg仅驱动x2门,由于x2不可读,因此t2_reg也变为不可读
- 同理,t1_reg和x1门也因为扇出链上的单元全部不可读而被判定为不可读
1.2 Design Compiler的优化策略
Design Compiler在综合过程中会执行以下优化步骤:
- 扫描整个设计,识别所有不可读单元
- 根据当前设置决定是否移除这些单元
- 生成优化后的网表
默认情况下,Design Compiler会移除所有不可读单元,并输出类似如下的提示信息:
code复制Information: The register 't2_reg' will be removed. (OPT-1207)
Information: The register 't1_reg' will be removed. (OPT-1207)
注意:这种优化是安全的,因为被移除的单元不会影响设计的逻辑功能。实际上,保留这些单元只会浪费芯片面积和功耗。
2. 不可读单元保留控制方法
在某些特殊情况下,设计者可能需要保留不可读单元。Design Compiler提供了三种主要的控制方法,各有不同的优先级和适用范围。
2.1 compile_delete_unloaded_sequential_cells变量
这是最基础的控制方式:
- 默认值:true(删除不可读时序单元)
- 设置为false时:保留所有不可读触发器
当设置为false时:
- 所有触发器都会被保留,无论是否可读
- 组合逻辑门仍可能被移除
- 会收到OPT-109警告,提示存在不驱动任何负载的时序单元
示例设置:
tcl复制set_app_var compile_delete_unloaded_sequential_cells false
2.2 set_compile_directives命令
这个命令提供了更精细的控制:
tcl复制set_compile_directives -delete_unloaded_gate false [get_cells x2]
主要特点:
- 可以针对特定单元进行设置
- 适用于所有类型的逻辑单元(时序和组合)
- 优先级高于compile_delete_unloaded_sequential_cells
重要限制:
- 不能单独用于删除触发器
- 当compile_delete_unloaded_sequential_cells为false时,即使-delete_unloaded_gate设为true也无法删除触发器
2.3 set_unloaded_register_removal命令
这是较新的控制方法(2019版本引入):
tcl复制set_unloaded_register_removal [get_cells t2_reg] true
属性优先级规则:
- remove_unloaded_register=false > compile_delete_unloaded_sequential_cells
- remove_unloaded_register=true < set_compile_directives
3. 边界优化与层次结构影响
不可读状态的传播会受到层次边界的影响,这涉及到边界优化(Boundary Optimization)的概念。
3.1 默认情况下的层次传播
在启用边界优化时(默认):
- 不可读状态可以跨层次传播
- 高层模块的不可读信号会导致底层模块对应单元被移除
禁用边界优化的方法:
tcl复制compile_ultra -no_boundary_optimization
此时:
- 不可读状态不会跨层次传播
- 底层模块的单元即使不被高层使用也会保留
3.2 特殊控制变量
compile_optimize_unloaded_seq_logic_with_no_bound_opt变量(2016版本引入):
- 默认值:false
- 设置为true时:即使禁用边界优化,也允许不可读状态跨层次传播
示例:
tcl复制set_app_var compile_optimize_unloaded_seq_logic_with_no_bound_opt true
4. 其他相关注意事项
4.1 属性冲突处理
当多个属性冲突时,优先级如下:
- dont_touch/size_only属性(最高优先级)
- set_compile_directives
- set_unloaded_register_removal
- compile_delete_unloaded_sequential_cells
4.2 调试与报告工具
Design Compiler NXT(2022版本)提供了新的报告命令:
tcl复制report_transformed_registers
这个命令可以详细显示所有寄存器变换操作,包括不可读单元移除。
4.3 RTL阶段的优化
需要注意的是,部分不可读单元可能在RTL编译阶段就被HDL Compiler移除,与综合阶段的优化是独立的。相关控制变量包括:
- hdlin_preserve_sequential
- preserve_sequential综合指令
5. 实际应用建议
基于多年项目经验,对于不可读单元处理的最佳实践包括:
- 默认采用自动移除策略
- 可以显著减少面积和功耗
- 对功能没有影响
- 需要保留的特殊情况
- 调试需要保留的观测点
- 某些特殊的功耗管理电路
- 需要保持对称性的布局考虑
- 调试技巧
- 使用check_design命令查看警告详情
- 结合report_unloaded_ports分析不可读源头
- 对于复杂设计,可以分层次逐步验证优化效果
经验分享:在实际项目中,我曾遇到一个案例:一个大型SOC设计中有约5%的触发器被识别为不可读单元。通过合理设置优化策略,最终节省了约3%的芯片面积和相应比例的静态功耗。关键在于确保这些移除确实不会影响功能,这需要完备的验证流程支持。
