yosys 网表接 OpenSTA 的衔接流程:从 write_verilog 到 report_checks 的文件交接清单
更新时间:2026-11-03。综合是什么 讲过综合把 RTL 翻译成门级网表,OpenSTA 第一次静态时序分析 讲过 STA 要吃库、网表、约束三个文件。这两篇之间有一段实际工程里最容易掉链子的接缝:Yosys 吐出来的网表,凭什么能被 OpenSTA 正确吃下去?本篇专门讲这段 yosys 网表接 OpenSTA 的衔接流程,用 Yosys 0.33 与 OpenSTA 2.0.17 把同一份最小库从头真跑到 slack 报告。
本文要回答的问题
- 从 RTL 到时序报告,Yosys 侧和 STA 侧各自要跑哪几条命令,交接物具体是哪几个文件?
dfflibmap、abc -liberty、write_verilog -noattr各自解决什么问题,漏跑一条网表里会混进什么?- OpenSTA 里到底是
set_top_module还是link_design,顶层名写错、库里查无此单元时 2.0.17 实际报什么? - 怎么在交接前自查网表「干净」:残留的
$单元、层次、属性分别怎么处理?
先给一张交接流水线卡,本篇全部内容就是把这张卡里的每一格展开:
读这张卡抓住一条主线:前三步在 Yosys 里把内建单元全部换成库单元,第四步落盘成交接件,后三步在 OpenSTA 里把同一份库和网表重新拼回时序图。
一、这一步在流程里的位置:交接的是「承诺」
综合器和 STA 工具是两个独立程序,它们之间没有数据库直连,唯一的契约就是落盘文件:Yosys 承诺网表里出现的每个单元名都能在某份 liberty 里查到,OpenSTA 则拿这同一份 liberty 去解析功能与延迟。契约的另一半是 SDC 时钟约束,它由人维护,综合和 STA 共用。
绿色是三个输入,橙色是本篇主角交接件,蓝色是两个工具。注意库文件画了两条边:它既是 Yosys 的映射依据,又是 OpenSTA 的延迟来源,必须是同一份——综合用 A 版本库、STA 用 B 版本库,单元对得上名字、延迟却完全错位,是真实项目里极难排查的一类问题。本篇容器里没有 PDK,按 OpenSTA 第一次静态时序分析 同样的办法自写一个只有 DFF/NAND/INV/BUF 的教学库把流程跑通;产线替换为 sky130 这类 PDK 库。
二、命令逐段解读:两侧脚本拆给你看
Yosys 侧脚本 synth.ys 一共八条:
read_liberty -lib teaching.lib
read_verilog rtl.v
synth -flatten -top top
dfflibmap -liberty teaching.lib
abc -liberty teaching.lib
clean
stat
write_verilog -noattr -noexpr netlist.vread_liberty -lib:让 Yosys 先认识库。后面dfflibmap与abc各自还要再给一次-liberty,三处缺一不可;开头这次读库让通用优化阶段就知道单元引脚和功能。synth -flatten -top top:跑到通用门级为止,产物是$_DFF_P_、$_NAND_这类 Yosys 内建单元。-flatten展平层次,本篇 RTL 里故意写了一个gating子模块,展平后网表只剩top一个模块;不展平也能交接,但子模块必须随顶层一起写进同一个文件,且会留下\u_g.a这类转义层次网名。dfflibmap -liberty:把内建触发器映射成库里的DFF_P。这一条与abc分工明确:abc 只管组合逻辑,触发器必须由 dfflibmap 单独映射。abc -liberty:把组合逻辑映射成库门。教学库里要显式提供反相器INV_X1,不能指望全靠 NAND 两输入短接;本环境实测库里只有 BUF/NAND 时,abc 在映射含反相网络时会直接段错误,报Can't open ABC output file,补上 INV 后正常。clean/stat:清理悬空网线并打印账单。交接前必看stat:单元清单里只能出现库单元名。write_verilog -noattr -noexpr:-noattr去掉(* ... *)属性注释,-noexpr保证门以实例形式出现而不是折成 assign 表达式,两件事都为下游工具的兼容性。
STA 侧分两个脚本,setup 与 hold 各自独立进程跑:
read_liberty teaching.lib
read_verilog netlist.v
link_design top
read_sdc constraints.sdc
report_checks -path_delay max -digits 3前三行的顺序即依赖:先有库,网表里的 DFF_P 才不是无意义名字;先读网表,link_design 才有东西可连。link_design top 的参数是顶层模块名,必须和 Yosys 侧 -top top 以及网表里的 module top 三处一致。这里按 2.0.17 实测澄清一个常见混淆:OpenSTA 没有 set_top_module 命令(那是 Yosys 的词),敲进去直接报 invalid command name "set_top_module";link_design 不带参数则报 missing top_cell_name argument and no current_design。
还有一个本环境实测到的执行细节:同一个 tcl 会话里先出 max 再出 min 两份报告时,第一份 setup 报告的门延迟会被随后 min 分析的转换时间传播带偏,标量库门下出现 0.105/0.132 这类插值数字(独立跑应是 0.100/0.120)。教学与回归脚本里 setup/hold 拆成两次 sta 进程跑,数字稳定可复现;容器外调用形如 sta -no_init -exit sta_setup.tcl,-exit 保证跑完即退,便于塞进 Makefile。
三、交接文件长什么样
被交接的网表是一份合法但枯燥的结构 Verilog,综合本篇两级流水加两级 NAND 门控的 RTL 后,stat 给出四个单元,落盘网表如下:
module top(clk, d, en, en2, q);
wire _0_;
input clk; wire clk;
input d; wire d;
input en; wire en;
input en2; wire en2;
output q; wire q;
wire s1;
NAND2_X1 _1_ ( .A(en), .B(s1), .Y(_0_) );
NAND2_X1 _2_ ( .A(en2), .B(_0_), .Y(n1) );
DFF_P _3_ ( .C(clk), .D(n1), .Q(q) );
DFF_P _4_ ( .C(clk), .D(d), .Q(s1) );
endmodule三个特征说明它是合格交接件:没有 always、没有运算符,全是实例和连线;四个实例名 NAND2_X1/DFF_P 全部来自 teaching.lib;顶层模块名就是 top。文件里那几行 \u_g.a 式零延迟 assign 是展平残留,不影响 STA。
库侧 teaching.lib 是标量延时的最小库,单元的关键描述长这样(完整文件见代码仓):DFF 用 ff(IQ, IQN) { clocked_on : "C"; next_state : "D"; } 声明打拍关系,D 端写 setup/hold 约束(0.10/0.02ns),Q 端写 rising_edge 弧给出 0.20ns 的 Tco;NAND 用 function : "((A B)')" 声明功能,每个输入一组 combinational 延时弧(rise 0.12 / fall 0.10ns)。库写法的完整解读见 OpenSTA 第一次静态时序分析,本篇只强调一点:这一份文件被两个工具共读,改库要两边一起重跑。
SDC 仍然只有一行时钟:create_clock -name clk -period 1.0 [get_ports clk]。没有时钟的网表 link 能过,但所有寄存器端点都是 unconstrained,报告不出路径。
四、常见错与检查点
下面四个错全部在本环境实测触发,前两个还保留在实验 log 的反例段:
| 现象 | 检查点 | 纠正 |
|---|---|---|
Error: top_wrong is not a verilog module. | link_design 参数与网表 module 名、Yosys -top 是否三处一致 | 改成真实顶层名 |
Warning: module $_DFF_P_ not found. Creating black box,随后 No paths found. | 漏了 dfflibmap;网表里残留 $ 开头的内建单元 | 补 dfflibmap -liberty 重综合,stat 只见库单元再交接 |
abc 报 Can't open ABC output file,Yosys 中止 | 教学库里没有独立 INV,abc 映射反相网络时段错误 | 库里补 INV_X1 再跑 |
| 零告警退出但端点 unconstrained / 无路径 | SDC 没读或时钟名与端口不符 | 确认 read_sdc 执行、get_ports clk 命中 |
第二行最有迷惑性:OpenSTA 遇到不认识的模块不硬失败,而是默默建一个黑盒继续 link,直到出报告时才表现为 No paths found.。所以「link 没报错」从来不是交接成功的充分条件,stat 与 grep 网表里的 $ 单元才是——grep '\$_' netlist.v 应当零命中。黑盒问题的更多形态见 OpenSTA link 缺单元 与 Yosys blackbox cell unknown,缺时钟的系统排查见 OpenSTA no clocks found。
五、真实跑一遍:从综合到两份报告
一键脚本 run.sh 依次执行综合、打印网表、两个独立 STA 进程与两个反例。先看 stat 的交接账单:四个单元、两个 DFF 两个 NAND,没有任何 $ 残留,这是放行网表的依据。setup 报告如下:
逐行对账:_4_/C → _4_/Q 是发射触发器 Tco 0.200;_1_/Y 的 0.100 是 NAND fall 标量延时,_2_/Y 的 0.120 是下一级 NAND rise——注意报告里的 v/^ 标记电平在反相门后翻转,fall 对 0.10、rise 对 0.12,与库表一致。到达 0.420,要求 1.000 − setup 0.100 = 0.900,slack 0.480 MET。hold 取最短路径同法算:
同一沿捕获,要求时间只有库内 hold 0.020,最早到达 0.420,hold slack 0.400 MET。两个反例的真实输出也在同一条 log 里:顶层名写错时 STA 直接拒绝;漏掉 dfflibmap 时网表第 31、36 行是 \$_DFF_P_ 实例,STA 建黑盒后只回一句 No paths found.:
此时网表中没有任何布线信息,延迟只含门延迟与引脚电容,线延迟为零;真实签核还要在布局布线后反标 SPEF 再重跑同一套脚本,数字会明显变大,负 slack 的处置见 OpenSTA slack (VIOLATED) 负裕量解读。
实验环境
- 机器/系统:本地 Docker 容器,Ubuntu 24.04;宿主为 macOS。
- 工具版本:Yosys 0.33(
yosys -V实测Yosys 0.33 (git sha1 2584903a060))、OpenSTA 2.0.17(镜像 geek-eda:0.3-sta,sta -version实测 2.0.17)。 - 日期:2026-11-03。
- 完整命令:
bash run.sh,依次执行yosys -s synth.ys综合出netlist.v、sta -no_init -no_splash -exit sta_setup.tcl与sta_hold.tcl两个独立进程,外加顶层名写错、漏dfflibmap两个反例,stdout/stderr 合并记录。 - 实验边界:
teaching.lib是教学用最小库,标量延时自洽但不对应任何真实工艺;产线请替换为 sky130 等 PDK 库,结论不能外推为签核依据。
代码获取:完整的 rtl.v、teaching.lib、synth.ys、sta_setup.tcl、sta_hold.tcl、run.sh 与 Makefile 位于 geek-doc.cn/experiments/flow-opensta-from-yosys-netlist,有 docker 镜像 geek-eda:0.3-sta 的机器上执行 make run 即可复现综合、两份报告与两个反例。
这一篇在知识体系里的位置
本篇是「综合之后、签核之前」的接缝操作页:上游综合命令的完整拆解见 Yosys 综合命令 anatomy,网表三种落盘格式(Verilog/JSON/BLIF)怎么选见 Yosys 网表输出流程;下游第一次 STA 的命令逐行读法在 OpenSTA 第一次静态时序分析,setup/hold 与 slack 的概念直觉见 静态时序分析 STA 入门。交接后出问题按症状跳报错页:OpenSTA link 缺单元、OpenSTA no clocks found、OpenSTA slack (VIOLATED) 负裕量解读。
总结
yosys 网表接 OpenSTA 的衔接流程本质是一份文件契约:Yosys 侧 synth -flatten → dfflibmap → abc → stat → write_verilog -noattr,把内建单元全部换成库单元后落盘;OpenSTA 侧 read_liberty → read_verilog → link_design <顶层名> → read_sdc → report_checks,用同一份库把网表拼回时序图。2.0.17 里没有 set_top_module,定顶只用带参数的 link_design。交接前三道自查:stat 只见库单元、grep '$_' netlist.v 零命中、顶层名三处一致;漏 dfflibmap 时 STA 会把 $_DFF_P_ 建成黑盒且不硬报错,只在报告时回 No paths found.。实测 1.0ns 周期下 Tco 0.200 加两级 NAND 0.100/0.120,setup slack 0.480、hold slack 0.400 均 MET;setup/hold 拆独立进程跑数字才可复现,教学库产线必须换 PDK 并反标布线 RC。