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 综合后网表质量检查

综合完,拿到网表,别急着往后端送。先做一轮质量检查,能省下后面大量的调试时间。

我一般会检查以下几项:

  1. 时序违例检查:看setup和hold有没有违例。DC里用report_timing,Genus里用report_timing
  2. DRC检查:看有没有max_transition、max_capacitance违例。这些物理约束如果没满足,布局布线时会出大问题。
  3. 网表完整性检查:看有没有悬空引脚、未连接的线。DC里用check_design,Genus里用check_design -all
  4. 面积报告:看综合出来的面积是否在预期范围内。如果面积比预估大了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_transitionset_max_capacitance
  • 网表有悬空引脚:代码里可能有未连接的信号,或者综合时没处理好。用check_design查一下。

我记得有一次,综合完网表面积比预估大了50%。查了半天,发现是代码里写了一个巨大的case语句,综合工具把它展开成了大量的多路选择器。后来改成优先级编码器,面积就降下来了。

所以,综合不只是工具的事,代码质量也很重要。好的RTL代码,综合出来自然又快又小。

逻辑综合实战知识体系 RTL代码 + 约束 DC / Genus 综合 面积优先 平衡模式 速度优先 门级网表 + SDC 网表质量检查(时序/DRC/面积)

好了,逻辑综合实战的内容就聊到这儿。记住,综合不是一锤子买卖,多跑几次,多对比,才能找到最适合你设计的策略。


公众号:蓝海资料掘金营,微信deep3321