4. 逻辑综合(Yosys):Yosys 基本命令、综合策略与脚本编写、面积与时序的初步评估
逻辑综合,说白了就是把我们写的 RTL 代码(Verilog/VHDL)翻译成门级网表。这个过程有点像把建筑设计图纸变成实际的钢筋水泥结构。Yosys 是 OpenROAD 流程里的综合工具,开源、免费,而且功能一点不弱。
我个人习惯把综合看作后端流程的“入口”。入口质量好不好,直接决定了后面布局布线的难度。所以这一章,咱们把 Yosys 的基本命令、综合策略和脚本编写讲透。
4.1 Yosys 基本命令
Yosys 的命令行交互模式非常直观。你可以在终端里敲 yosys 进入交互环境,也可以写一个 .tcl 脚本批量执行。我刚开始用的时候,最喜欢的就是它的 help 命令——几乎每个命令都有详细的说明。
下面这张表列出了最常用的几个命令,建议你记下来:
| 命令 | 功能 | 常用选项 |
|---|---|---|
read_verilog |
读入 Verilog 文件 | -sv 支持 SystemVerilog |
hierarchy |
展开模块层次结构 | -check 检查未定义模块 |
proc |
处理 always 块,转换为逻辑 | -noopt 跳过优化 |
opt |
逻辑优化(常数传播、死逻辑消除) | -full 全量优化 |
techmap |
工艺映射到目标库 | -map 指定库文件 |
dfflibmap |
映射触发器到工艺库 | -liberty 指定 Liberty 文件 |
abc |
调用 ABC 进行逻辑综合与优化 | -liberty -constr |
stat |
统计面积、单元数量 | -top 指定顶层模块 |
write_verilog |
写出综合后的网表 | -noattr 去掉属性 |
ls 查看当前设计中的模块列表,用 show 图形化显示模块结构。我个人习惯先用 show 看一眼模块连接,确认读入正确再往下走。
4.2 综合策略与脚本编写
综合策略说白了就是“怎么让 Yosys 把 RTL 变成又快又小的网表”。不同的项目侧重点不一样——有的要面积小,有的要速度快,有的要功耗低。我遇到过最头疼的情况是:面积压下来了,时序却崩了;时序修好了,面积又超标了。
下面是一个典型的综合脚本框架,我把它拆成几个阶段来讲:
# ========== 阶段1:读入设计 ==========
read_verilog -sv ./rtl/top.sv
read_verilog -sv ./rtl/sub_module.v
# ========== 阶段2:层次展开与检查 ==========
hierarchy -check -top top
# ========== 阶段3:逻辑处理 ==========
proc
opt_expr
opt_clean
check
# ========== 阶段4:工艺映射 ==========
techmap -map /path/to/techlib.v
dfflibmap -liberty /path/to/lib/slow.lib
# ========== 阶段5:ABC 综合与优化 ==========
abc -liberty /path/to/lib/slow.lib \
-constr /path/to/constraints.sdc \
-script +strash;scorr;ifraig;retime;strash;dch,-f;map,-M,1,-D,500
# ========== 阶段6:统计与输出 ==========
stat -top top
write_verilog -noattr ./output/top_synth.v
这里有几个关键点:
- 阶段1-2: 读入文件后一定要做
hierarchy -check,它会报出所有未定义的模块引用。我曾经因为漏了一个子模块的 .v 文件,浪费了半天 debug。 - 阶段3:
proc把 always 块转换成逻辑门,opt_expr和opt_clean做初步优化。这一步能去掉很多冗余逻辑。 - 阶段4:
techmap把通用逻辑映射到工艺库的单元,dfflibmap专门处理触发器。注意:工艺库的 .v 文件必须和 Liberty 文件对应。 - 阶段5: ABC 是真正的“重武器”。
-constr指定时序约束,-script后面的字符串是 ABC 的内部命令。我一般会调-D参数(延迟目标)来平衡面积和时序。
abc 命令里忘了加 -liberty,结果综合出来的网表全是通用门,面积大了 3 倍。记住:ABC 必须知道目标库的时序信息才能做有效优化。
4.3 面积与时序的初步评估
综合完成后,第一件事就是看面积和时序。Yosys 的 stat 命令会给出详细的单元统计:
=== top ===
Number of cells: 12543
$_AND_ 2341
$_OR_ 1567
$_NOT_ 892
$_DFF_P_ 4321
... (其他单元)
Chip area for module '\top': 156789.432 um^2
这个数字能告诉你:
- 用了多少组合逻辑(AND/OR/NOT)
- 用了多少时序单元(DFF)
- 总面积是多少
时序评估呢?Yosys 本身不直接做 STA,但 ABC 在综合过程中会报告关键路径的延迟。你可以在 ABC 脚本里加 print_stats 来查看:
abc -liberty /path/to/lib/slow.lib \
-script "strash; ifraig; retime; map; print_stats"
输出类似这样:
Delay = 2.34 ns (critical path length = 12 gates)
Area = 12345.67 um^2
这个延迟是 ABC 估算的,不是精确的 STA 结果,但足够你判断综合策略是否合理。如果延迟超标,你可以:
- 收紧
-D参数(比如从 500 降到 300) - 增加
retime重定时优化 - 检查约束文件是否合理
4.4 综合策略对比
不同的项目需要不同的综合策略。我整理了一个对比表,方便你根据需求选择:
| 策略 | 适用场景 | ABC 脚本关键参数 | 典型效果 |
|---|---|---|---|
| 面积优先 | 成本敏感、低速设计 | -D, 1000 share |
面积小 15%,延迟大 30% |
| 时序优先 | 高性能、高频设计 | -D, 200 retime dch,-f |
延迟小 25%,面积大 20% |
| 平衡策略 | 大多数通用设计 | -D, 500 map,-M,1 |
面积和时序折中 |
嗯,这里要注意:-D 的单位是皮秒(ps),不是纳秒。如果你设 -D, 500,那就是目标延迟 500ps = 0.5ns。设得太小,ABC 会拼命优化时序,面积会暴涨;设得太大,优化力度不够,时序可能不满足。
我个人习惯的做法是:先用平衡策略跑一轮,看 stat 和 ABC 的延迟报告。如果面积超标,就调大 -D 或者去掉 retime;如果时序超标,就调小 -D 或者增加 dch,-f(分解高扇出网络)。
-D 从 400 调到 350,面积只涨了 5%,但时序余量多了 80ps。这个 trade-off 非常划算。