3、逻辑综合实战:DC/Genus综合流程、综合策略(面积vs速度)、综合后网表质量检查
逻辑综合,说白了就是把我们写的RTL代码,翻译成门级网表。这一步是后端设计的起点,也是决定芯片成败的关键。我见过太多项目,因为综合没做好,后面布局布线再怎么折腾也救不回来。
今天咱们就聊聊DC和Genus这两大工具的综合流程,以及怎么在面积和速度之间做取舍。最后,我会分享一些网表质量检查的实战经验。
3.1 DC与Genus综合流程
DC是Synopsys家的老牌工具,Genus是Cadence家的。虽然两家工具的命令和脚本略有不同,但核心流程是相通的。我个人习惯用DC,但Genus在大型设计上有时更快。
先看一个典型的综合流程:
# DC综合脚本示例
read_verilog {top.v sub1.v sub2.v}
current_design top
link
source constraints.tcl
compile_ultra
write -f verilog -o top_netlist.v
write_sdc top.sdc
嗯,这里要注意,link这一步很多人会忘。它负责把设计中调用的标准单元库、宏单元库链接起来。如果漏了,综合出来的网表可能全是空的。
Genus的流程类似,但命令不同:
# Genus综合脚本示例
read_hdl {top.v sub1.v sub2.v}
elaborate top
read_sdc constraints.sdc
syn_generic
syn_map
syn_opt
write_hdl > top_netlist.v
我曾经在项目中遇到过,用Genus综合时,syn_generic这一步跑得特别慢。后来发现是代码里写了一个巨大的组合逻辑,拆成流水线后,速度就上来了。
3.2 综合策略:面积 vs 速度
综合策略的核心,就是面积和速度的博弈。你想想看,芯片面积越小,成本越低,但速度可能上不去。速度要快,就得堆更多的逻辑门,面积自然就大了。
DC里控制这个平衡的参数是compile_ultra的选项:
| 策略 | 命令/选项 | 适用场景 |
|---|---|---|
| 面积优先 | compile_ultra -area_high_effort |
成本敏感、速度要求不高的设计 |
| 速度优先 | compile_ultra -timing_high_effort |
高性能CPU、GPU等 |
| 平衡模式 | compile_ultra(默认) |
大多数通用设计 |
Genus里对应的策略是:
- 面积优先:
set_db syn_global_effort high+set_db syn_area_effort high - 速度优先:
set_db syn_global_effort high+set_db syn_timing_effort high
我个人建议,新手先跑一次平衡模式,看看时序和面积的数据。如果时序有违例,再切到速度优先。如果面积超标,再切到面积优先。不要一上来就选极端策略。
核心原则:综合时,先满足时序,再优化面积。时序不满足,芯片就是废的。面积大了,至少还能用。
3.3 综合后网表质量检查
综合完,拿到网表,别急着往后端送。先做一轮质量检查,能省下后面大量的调试时间。
我一般会检查以下几项:
- 时序违例检查:看setup和hold有没有违例。DC里用
report_timing,Genus里用report_timing。 - DRC检查:看有没有max_transition、max_capacitance违例。这些物理约束如果没满足,布局布线时会出大问题。
- 网表完整性检查:看有没有悬空引脚、未连接的线。DC里用
check_design,Genus里用check_design -all。 - 面积报告:看综合出来的面积是否在预期范围内。如果面积比预估大了30%以上,说明代码或约束有问题。
避坑指南:我曾经有一次,综合完网表直接送后端,结果布局布线时发现大量DRC违例。查了两天才发现,是综合时忘了设set_max_transition约束。从那以后,我每次综合完都会跑一遍完整的DRC检查。
下面是一个网表质量检查的脚本片段:
# DC网表质量检查
redirect -tee check_design.rpt {check_design}
redirect -tee timing.rpt {report_timing -max_paths 100}
redirect -tee area.rpt {report_area}
redirect -tee qor.rpt {report_qor}
Genus的检查命令:
# Genus网表质量检查
report timing > timing.rpt
report area > area.rpt
report power > power.rpt
check_design -all > check_design.rpt
嗯,这里还要注意,网表里的标准单元名称,要和库里的完全一致。如果名字对不上,后端工具会报错。我习惯在综合脚本里加一句set_name_style,统一命名风格。
3.4 综合策略的实战选择
实际项目中,面积和速度的取舍不是非黑即白的。我分享一个我常用的策略:
- 关键路径:用速度优先,多花点面积也值得。
- 非关键路径:用面积优先,能省则省。
- 时钟网络:用速度优先,时钟抖动和偏斜必须控制好。
- 数据通路:看情况,如果数据通路很宽(比如128位),面积优先更划算。
DC里可以用group_path来指定不同路径的优化策略:
group_path -name critical -from [all_inputs] -to [all_outputs] -weight 2.0
group_path -name non_critical -from [all_inputs] -to [all_outputs] -weight 0.5
Genus里用set_db path_group实现类似功能。
小技巧:综合时,可以先把所有路径设成速度优先,跑一次看看哪些路径真的紧张。然后只对紧张路径做速度优化,其他路径切回面积优先。这样既保证了时序,又控制了面积。
3.5 综合后的常见问题
综合完,你可能会遇到这些问题:
- 时序违例太多:可能是约束设得太紧,或者代码本身有逻辑深度问题。先检查约束,再优化代码。
- 面积爆炸:可能是代码里用了太多重复逻辑,或者综合策略太激进。试试面积优先模式。
- DRC违例:通常是忘了设物理约束,或者库的驱动能力不够。加
set_max_transition和set_max_capacitance。 - 网表有悬空引脚:代码里可能有未连接的信号,或者综合时没处理好。用
check_design查一下。
我记得有一次,综合完网表面积比预估大了50%。查了半天,发现是代码里写了一个巨大的case语句,综合工具把它展开成了大量的多路选择器。后来改成优先级编码器,面积就降下来了。
所以,综合不只是工具的事,代码质量也很重要。好的RTL代码,综合出来自然又快又小。
好了,逻辑综合实战的内容就聊到这儿。记住,综合不是一锤子买卖,多跑几次,多对比,才能找到最适合你设计的策略。
公众号:蓝海资料掘金营,微信deep3321