4、综合(Synthesis)实战:Yosys与ABC工具链、逻辑综合策略、面积与时序的权衡
综合,说白了就是把我们写的 RTL 代码,翻译成门级网表。这一步很关键,它直接决定了你的芯片最终能跑多快、占多大面积、功耗怎么样。我刚开始接触 OpenROAD 的时候,觉得综合就是跑个脚本完事,后来踩了不少坑才明白——综合的学问深着呢。
4.1 Yosys 与 ABC 工具链:开源综合的黄金搭档
在 OpenROAD 流程里,综合这活儿主要由 Yosys 和 ABC 两个工具配合完成。Yosys 负责前端处理,把 Verilog 解析、展开、优化;ABC 则负责后端逻辑综合与工艺映射。
我个人习惯把 Yosys 看作「翻译官」,把 ABC 看作「工匠」。翻译官把高级语言转成内部表示,工匠再根据你给的工艺库,把它雕琢成真正的门级电路。
Yosys 的基本流程
一个典型的综合脚本长这样:
# 读取设计文件
read_verilog my_design.v
read_verilog -sv my_interface.sv
# 读取工艺库(Liberty 格式)
read_liberty -lib my_tech.lib
# 层次化展开
hierarchy -check -top my_top
# 逻辑综合与优化
proc; opt; fsm; opt; memory; opt
# 技术映射到工艺库
techmap; opt
# 输出网表
write_verilog synth_netlist.v
这里面的 proc、fsm、memory 这些命令,分别处理过程块、状态机和存储器。每次 opt 都是一轮优化。我在项目中遇到过,有人一口气把所有优化跑完,结果综合出来的面积大得离谱。后来发现,优化要分步走,每一步都看看中间结果,这样更容易定位问题。
ABC 的介入时机
Yosys 做完技术映射后,会调用 ABC 做更精细的逻辑优化。ABC 的核心是 strash(结构化哈希)和 resyn2(重综合)等命令。你可以通过 Yosys 的 abc 命令来调用它:
# 调用 ABC 进行逻辑优化
abc -liberty my_tech.lib -script +strash;scorr;ifraig;retime;strash;dch,-f;map,-M,1,-F,2
# 或者使用预定义的脚本
abc -liberty my_tech.lib -script my_abc_script.abc
4.2 逻辑综合策略:面积与时序的博弈
综合策略说白了就是怎么在面积和时序之间找平衡。你想想看,一个电路想跑得快,就得用更大的驱动单元,面积自然就上去了。反过来,想省面积,就得用小单元,但时序可能就崩了。
我总结了几种常见的策略:
| 策略名称 | 核心思路 | 适用场景 | 风险点 |
|---|---|---|---|
| 面积优先 | 使用最小面积的单元,减少逻辑深度 | 成本敏感、频率要求不高的设计 | 时序容易违规 |
| 时序优先 | 使用大驱动单元,优化关键路径 | 高频设计、性能关键模块 | 面积膨胀严重 |
| 平衡策略 | 关键路径用大单元,非关键路径用小单元 | 大多数通用设计 | 需要精细调参 |
| 低功耗策略 | 使用低功耗单元,减少翻转活动 | 电池供电、IoT 设备 | 时序和面积都可能变差 |
在 Yosys 里,你可以通过 setattr 命令给特定模块或路径设置不同的综合策略。比如:
# 对关键路径模块使用时序优先
select -module critical_path_module
setattr -mod -set keep_hierarchy 1
abc -liberty my_tech.lib -script +strash;ifraig;retime;map,-M,1,-F,4
# 对非关键路径模块使用面积优先
select -module non_critical_module
abc -liberty my_tech.lib -script +strash;dch,-f;map,-M,0,-F,1
4.3 面积与时序的权衡:实战中的取舍
做综合最头疼的就是面积和时序的权衡。这里我分享几个实战经验。
4.3.1 从时序报告入手
综合完成后,第一件事就是看时序报告。Yosys 可以生成详细的时序信息:
# 生成时序报告
report_timing -path end -max_paths 10 -nworst 5 > timing_report.rpt
# 查看面积报告
stat -liberty my_tech.lib > area_report.rpt
拿到报告后,我一般会关注三点:
- 最差负时序裕量(WNS):负值越大,说明时序越差
- 总负时序裕量(TNS):所有违规路径的裕量总和,反映整体情况
- 面积利用率:当前面积占目标面积的百分比
4.3.2 迭代优化的思路
我不会指望一次综合就搞定所有问题。我的做法是:
- 第一次综合:用默认策略,拿到基线数据
- 分析关键路径:找出 WNS 最差的 10 条路径,看看是什么原因导致的
- 调整策略:对关键路径模块使用时序优先,其他模块保持面积优先
- 再次综合:对比面积和时序的变化
- 重复 2-4 步:直到满足约束
核心原则:不要试图一次把所有路径都修好。每次只修最差的几条,看看面积变化,再决定下一步。我曾经在一个项目中,花了三天时间反复迭代,最终在面积只增加 5% 的情况下,把 WNS 从 -0.5ns 修到了 +0.1ns。
4.3.3 使用 retime 进行时序重分配
ABC 的 retime 命令是个好东西。它可以在不改变逻辑功能的前提下,重新分配寄存器之间的组合逻辑,从而改善时序。
# 在 ABC 脚本中使用 retime
retime -o 1 # 向后移动寄存器
retime -i 1 # 向前移动寄存器
嗯,这里要注意,retime 会改变寄存器的位置,可能会影响仿真和验证。我一般会在综合完成后,用形式验证工具确认功能一致性。
4.4 综合后的检查清单
综合跑完后,别急着往下走。我习惯做一遍检查:
- 网表完整性:有没有悬空引脚、未连接的线网?
- 时序收敛性:所有路径的 setup/hold 都满足了吗?
- 面积合理性:和预估的差距大不大?有没有异常大的模块?
- 功耗预估:用
report_power看看动态功耗和静态功耗 - DRC 检查:有没有扇出过大、过渡时间过长的问题?
4.5 本章知识体系
下面这张图总结了综合阶段的核心流程和决策点:
综合不是一锤子买卖,而是一个反复迭代、不断调优的过程。掌握了 Yosys 和 ABC 的工具链,理解了面积与时序的权衡,你就能在开源流程中做出不输商业工具的结果。
可可精品资料库