4. 逻辑综合(Yosys):Yosys 基本命令、综合策略与脚本编写、面积与时序的初步评估

逻辑综合,说白了就是把我们写的 RTL 代码(Verilog/VHDL)翻译成门级网表。这个过程有点像把建筑设计图纸变成实际的钢筋水泥结构。Yosys 是 OpenROAD 流程里的综合工具,开源、免费,而且功能一点不弱。

我个人习惯把综合看作后端流程的“入口”。入口质量好不好,直接决定了后面布局布线的难度。所以这一章,咱们把 Yosys 的基本命令、综合策略和脚本编写讲透。

Yosys 逻辑综合核心流程 RTL 读入 (read_verilog) 高层次综合 (hierarchy) 工艺映射 (techmap) 逻辑优化 (opt) 面积/时序评估 网表写出 (write_verilog) 💡 核心思路: 读入 RTL → 展开层次 → 优化逻辑 → 映射到工艺库 → 评估面积/时序 → 输出网表 每一步都可以加约束、调参数,反复迭代直到满足目标。

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 重定时优化
  • 检查约束文件是否合理
⚠️ 注意: ABC 报告的延迟是“理想版图”下的延迟,没有考虑互连线负载。实际布局布线后,延迟通常会比这个值大 20%~50%。所以综合阶段的目标延迟要比最终目标更紧一些。

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(分解高扇出网络)。

💡 实战经验: 我在一个 AI 加速器项目里,综合阶段花了整整一周调参数。最后发现,把 -D 从 400 调到 350,面积只涨了 5%,但时序余量多了 80ps。这个 trade-off 非常划算。