4、综合入门:Yosys 与 OpenROAD 的集成。运行逻辑综合。查看综合后的网表与报告。

逻辑综合,说白了就是把我们写的 RTL 代码(Verilog/VHDL)翻译成门级网表。这个过程里,工具会做两件大事:一是把行为级描述映射到标准单元库里的具体逻辑门,二是根据你给的时序约束去优化路径。

我个人习惯把综合看作是芯片后端的第一道关卡。这步要是没做好,后面布局布线再怎么折腾也救不回来。今天我们就来走一遍 OpenROAD 里的综合流程,看看 Yosys 是怎么跟 OpenROAD 配合的。

4.1 Yosys 在 OpenROAD 中的角色

OpenROAD 并没有自己重新发明一个综合引擎,它直接集成了 Yosys 作为前端综合工具。Yosys 是一个开源的、可扩展的 Verilog 综合框架,在学术界和工业界都有不少用户。

在 OpenROAD 流程里,Yosys 负责把 RTL 转换成门级网表,然后交给后续的布局布线工具。这个集成做得挺巧妙的——你不需要单独去学 Yosys 的命令行,OpenROAD 的 Tcl 脚本会帮你调用它。

核心流程:

  • 输入:RTL 文件(.v)、时序约束(.sdc)、工艺库文件(.lib)
  • 工具:Yosys(内嵌于 OpenROAD)
  • 输出:门级网表(.v)、综合报告(.rpt)

我曾经在一个项目里遇到过 Yosys 把某个组合逻辑优化过头了,导致功能仿真通过但实际芯片行为不对。后来查了半天,发现是综合时没加 keep 属性。嗯,这里要提醒大家:综合不是越优化越好,功能正确永远是第一位的。

4.2 准备综合环境

在跑综合之前,你得先准备好三样东西:RTL 代码、工艺库、时序约束。OpenROAD 对这三样东西的格式有明确要求。

4.2.1 工艺库文件(.lib)

工艺库是综合的基础。它描述了每个标准单元的延迟、面积、功耗等信息。OpenROAD 使用 Liberty 格式的库文件(.lib)。

对于教学和实验,OpenROAD 官方提供了一个 45nm 的 NangateOpenCellLibrary。你可以在 OpenROAD 的安装目录下找到它。我个人建议初学者先用这个库练手,等熟悉了流程再换自己的工艺库。

文件 说明
NangateOpenCellLibrary_typical.lib 典型工艺角下的库文件
NangateOpenCellLibrary_fast.lib 快速工艺角下的库文件
NangateOpenCellLibrary_slow.lib 慢速工艺角下的库文件

4.2.2 时序约束文件(.sdc)

时序约束告诉综合工具你的设计要跑多快。最基本的约束就是时钟周期。比如你设计的目标频率是 100MHz,那时钟周期就是 10ns。

一个最简单的 SDC 文件长这样:

# 创建时钟
create_clock -name clk -period 10.0 [get_ports clk]

# 设置输入延迟
set_input_delay -clock clk 2.0 [all_inputs]

# 设置输出延迟
set_output_delay -clock clk 2.0 [all_outputs]

你想想看,如果没有时序约束,Yosys 就不知道该怎么优化路径,综合出来的网表可能时序一团糟。我建议你在写约束时,先给一个宽松的周期,等综合通过后再逐步收紧。

4.3 运行综合:Yosys 与 OpenROAD 的集成

在 OpenROAD 里跑综合,你只需要写一个 Tcl 脚本。下面是一个完整的综合脚本示例:

# 读取工艺库
read_liberty /path/to/NangateOpenCellLibrary_typical.lib

# 读取 RTL 文件
read_verilog ./src/top.v
read_verilog ./src/sub_module.v

# 指定顶层模块
link_design top

# 读取时序约束
read_sdc ./constraints/top.sdc

# 运行综合
synth -top top

# 优化
opt

# 写出网表
write_verilog ./results/top_synth.v

# 写出报告
report_area > ./reports/area.rpt
report_timing > ./reports/timing.rpt
report_power > ./reports/power.rpt

这个脚本看起来简单,但每一步都有讲究。我来拆解一下:

  1. read_liberty:加载工艺库。如果有多个工艺角,可以加载多个库文件。
  2. read_verilog:读取你的 RTL 代码。注意要按依赖顺序读取,先读底层模块,再读顶层模块。
  3. link_design:把各个模块连接起来,形成一个完整的设计。
  4. read_sdc:加载时序约束。
  5. synth:这是 Yosys 的综合命令。它会做逻辑综合、技术映射。
  6. opt:优化。Yosys 会做一些简单的优化,比如删除冗余逻辑、合并门单元。
  7. write_verilog:写出综合后的门级网表。
  8. report_*:生成面积、时序、功耗报告。

小技巧:如果你在综合时遇到奇怪的错误,可以试试在 synth 命令后面加 -verbose 参数,Yosys 会输出更详细的日志,方便你定位问题。

4.4 综合后的网表长什么样?

综合完成后,你会得到一个门级网表。这个网表不再是 always @(posedge clk) 这样的行为级描述,而是由具体的标准单元组成的结构级描述。

举个例子,一个简单的 D 触发器在综合后的网表里可能是这样的:

DFF_X1 u_dff0 (
  .D(net_data),
  .CK(clk),
  .Q(net_q),
  .QN(net_qn)
);

这里的 DFF_X1 就是工艺库里的一个标准单元,X1 表示它的驱动能力。你想想看,同样的功能,用 X1 和 X4 的单元,面积和功耗差别很大。综合工具会根据你的约束自动选择合适的驱动强度。

我曾经在一个低功耗项目里,发现综合工具给所有路径都选了最小尺寸的单元,结果时序完全跑不过。后来加了时序约束,工具才乖乖地给关键路径换上大驱动单元。所以说,约束的质量直接决定了综合结果的好坏。

4.5 解读综合报告

综合完成后,一定要仔细看报告。报告里藏着很多信息,能帮你判断综合结果是否合理。

4.5.1 面积报告

面积报告会告诉你设计用了多少标准单元、组合逻辑面积、时序逻辑面积、总芯片面积。比如:

=== Area Report ===
Combinational area: 12345.67 um^2
Sequential area:   8765.43 um^2
Total area:        21111.10 um^2
Number of cells:   1234

这个数字能帮你判断设计规模。如果面积比你预期的大很多,可能是综合时没加合适的约束,或者 RTL 代码写得不合理。

4.5.2 时序报告

时序报告会列出所有路径的建立时间和保持时间检查结果。重点关注最差的 slack(时序裕量)。如果 slack 是负数,说明这条路径时序不满足。

=== Timing Report ===
Startpoint: u_reg0/CK
Endpoint:   u_reg1/D
Path type:  setup
Slack:      0.12 ns
Data path delay: 9.88 ns
Clock period:    10.00 ns

这个例子里 slack 是 0.12ns,是正的,说明时序满足。如果 slack 是负的,比如 -0.5ns,那就说明这条路径慢了 0.5ns,需要优化。

4.5.3 功耗报告

功耗报告会给出动态功耗、静态功耗和总功耗。对于低功耗设计,这个报告尤其重要。

=== Power Report ===
Dynamic power:  12.34 mW
Static power:    0.56 mW
Total power:    12.90 mW

注意:综合阶段的功耗估算比较粗略,因为它还没有考虑布局布线的寄生参数。但你可以用它来做相对比较,比如对比不同综合策略下的功耗差异。

4.6 综合流程知识图谱

下面这张图总结了 Yosys 与 OpenROAD 集成的综合流程,以及各阶段的输入输出关系:

Yosys 与 OpenROAD 综合流程 RTL 代码 (.v) 时序约束 (.sdc) 工艺库 (.lib) Yosys 综合引擎 逻辑综合 + 技术映射 + 优化 门级网表 (.v) 综合报告 (.rpt) 时序/面积/功耗数据 后续流程:布局 → 时钟树综合 → 布线 → 签核 关键检查点: • 检查综合报告中的 slack 是否为正 • 确认网表功能与 RTL 一致(形式验证) • 对比面积、功耗是否在预期范围内

4.7 常见问题与避坑指南

综合这一步看着简单,实际跑起来坑不少。我把自己踩过的坑整理了一下:

  • 库文件路径问题:OpenROAD 对库文件路径很敏感,建议用路径。我曾经因为用了相对路径,结果换了个目录就跑不通了。
  • RTL 代码风格:Yosys 对某些 Verilog 语法支持有限。比如 for 循环里的变量声明,有些版本会报错。我建议写 RTL 时尽量用可综合的风格。
  • 时序约束不完整:如果忘了加 set_input_delay 和 set_output_delay,综合工具会默认端口延迟为 0,这会导致综合结果过于乐观。
  • 综合时间过长:如果设计很大,综合可能会跑很久。可以试试用 synth -flatten 选项,把层次结构打平,有时能加快速度。

我的习惯:每次综合完,我都会先看一眼面积报告里的 cell count。如果这个数字跟预期差太多,我会先怀疑是不是 RTL 代码有问题,而不是急着调约束。

好了,综合这一步我们就讲到这里。你只要按照上面的步骤走一遍,应该能顺利跑通 Yosys 和 OpenROAD 的集成流程。拿到网表和报告后,多看看、多想想,慢慢就能积累出感觉来。