OpenSTA read_sdf 标注失败:实例路径与设计名不匹配排查
OpenSTA read_sdf 标注失败最容易被一份“看起来正常”的 report_checks 掩盖:SDF 已报实例不存在,后续报告却仍给出 MET。问题不在 slack 计算,而在标注根本没有落到目标弧上。本篇用同一网表对照实例名、SDF 设计头与修复结果;时钟尚未建立导致的空报告另见 OpenSTA no clocks found 排查。
本文要回答的问题
instance ... not found指向网表实例、SDF 实例,还是 Liberty 单元?- 为什么
read_sdf已报错,report_checks仍能输出路径和正的 slack? - SDF 的
DESIGN与link_design顶层不一致时,OpenSTA 2.0.17 实际怎样处理? - 修复后如何用弧延迟而不是退出码确认标注生效?
读这张图要抓住“定位对象”和“验收延迟”两处。蓝色是加载过程,红色是两种名称不一致,橙色强调必须查实际弧值,绿色才是修复动作。尤其不要把 DESIGN 当成所有工具都会强制校验的顶层选择器;下面的真实输出会展示本版的差异。
一、OpenSTA read_sdf 标注失败的直接证据
实验顶层是 top,数据路径经过 u_stage 和 u_buf。错误 SDF 把缓冲实例写成 u_buffer,并在 IOPATH A Y 上给出 0.800ns;Liberty 中同一弧的原始延迟是 0.300ns。这个差值让“是否标注成功”可以直接从路径报告中读出。
第 14 行是根因:wrong_instance.sdf 第 8 行的 u_buffer 不在当前网表。可是后面 u_buf/Y 仍显示 0.300ns,数据到达时间 0.500ns,slack 8.500ns,最后 CASE_EXIT wrong_instance=0。这份 MET 报告使用的是库延迟,不是 SDF 中的 0.800ns;退出码 0 也只说明脚本走到了末尾。
二、实例路径为何比单元名更关键
SDF(Standard Delay Format,标准延迟格式)的 CELLTYPE 指明单元类型,INSTANCE 指明要标注的网表对象。BUF_X1 在 Liberty 中存在,只能证明单元定义可解析;它不能替代 u_buf 这个实例。层次设计中还要按 SDF 的 DIVIDER 写完整路径,例如子模块内的缓冲可能是 u_core/u_buf,不能只凭 RTL 信号名猜测。
| 名称 | 本例正确值 | 常见错法 | 失败后的表现 |
|---|---|---|---|
link_design 顶层 | top | 链接了旧顶层或包装层 | 后续实例作用域整体错位 |
CELLTYPE | BUF_X1 | 与 Liberty 单元名不一致 | 单元类型解析或匹配异常 |
INSTANCE | u_buf | 写成 u_buffer、漏层次前缀 | instance ... not found |
IOPATH | A Y | 引脚名与库定义不符 | 目标时序弧无法对应 |
正确修复不是把错误警告忽略,也不是另建一个叫 u_buffer 的空实例,而是让 SDF 的实例作用域与当前链接网表一致。名称来自逻辑综合、布局布线或层次展平流程时,应沿生成链核对转义、层次分隔符和重命名结果。若 Liberty 本身没读进来,应先修复库路径与解析问题,再判断 SDF 是否匹配。
三、DESIGN 不一致不一定触发报错
第二组只把 SDF 头改为 DESIGN "chip_top",INSTANCE u_buf 保持正确。直觉上它应被拒绝,但 OpenSTA 2.0.17 没有输出 mismatch 错误,弧延迟却从 0.300ns 变成了 0.800ns。
CASE: wrong SDF DESIGN chip_top; linked design is top
Startpoint: u_stage (rising edge-triggered flip-flop clocked by clk)
Endpoint: q (output port clocked by clk)
0.200 0.200 ^ u_stage/Q (DFF_P)
0.800 1.000 ^ u_buf/Y (BUF_X1)
1.000 data arrival time
9.000 data required time
8.000 slack (MET)
CASE_EXIT wrong_design=0这说明本版的实际定位依据是已经 link_design top 的网表及可匹配的实例,而不是用 SDF DESIGN 字段重新选择顶层。因此“DESIGN 名不同”不能解释所有标注失败,更不能拿它替代实例检查。工程文件仍应把设计头改对:其他工具可能严格校验,一致的名称也能避免读错旧 SDF。
四、修复与验收要同时看名称和弧值
修复文件同时采用 DESIGN "top"、CELLTYPE "BUF_X1"、INSTANCE u_buf,read_sdf fixed.sdf 后再执行 report_checks。关键片段如下:
CASE: fixed DESIGN top and INSTANCE u_buf
Startpoint: u_stage (rising edge-triggered flip-flop clocked by clk)
Endpoint: q (output port clocked by clk)
0.200 0.200 ^ u_stage/Q (DFF_P)
0.800 1.000 ^ u_buf/Y (BUF_X1)
1.000 data arrival time
9.000 data required time
8.000 slack (MET)
CASE_EXIT fixed=00.200ns 的寄存器弧未变,u_buf/Y 精确采用 SDF 的 0.800ns,到达时间由错误实例组的 0.500ns 变为 1.000ns,slack 相应由 8.500ns 变为 8.000ns。四组数字彼此闭合,才证明指定弧已反标。若只有退出码变为 0,或只看到 slack (MET),仍不能区分“标注成功”和“错误后继续使用 Liberty”。
自动化流程还应让 read_sdf 错误直接中止,而不是无条件续跑报告。可用 Tcl catch 包住读取命令,打印 SDF 文件名与错误后 exit 1;验收日志则保留目标实例弧的延迟。这样既能拦住实例错名,也能防止下游把一份未反标的报告归档成签核结果。
五、从最小复现回到真实工程
真实设计的实例数量很多,不适合逐行肉眼比对整份 SDF。可取一条已知包含目标单元的路径,在读取 SDF 前后各跑一次相同的 report_checks,固定路径起终点、分析类型和显示精度。若目标弧前后的数值完全相同,同时日志又有 not found,优先查实例作用域;若数值已经改变,就说明至少这条弧完成了标注,不必因其他无关警告推翻结论。
| 排查顺序 | 要核对的对象 | 能排除的误判 |
|---|---|---|
| 链接后 | link_design 的顶层名称 | 把旧顶层当成当前作用域 |
| 读取前 | Liberty 弧延迟与引脚方向 | 把库解析问题误当成 SDF 错名 |
| 读取时 | CELL 的完整实例路径 | 只看 CELLTYPE,漏掉实例错误 |
| 读取后 | 同一弧的增量与到达时间 | 用 MET 或退出码代替标注验收 |
层次路径不匹配常出现在网表被重新生成之后。同一块逻辑在 RTL 里叫 buffer_inst,综合或物理实现后可能变成 u_buf;父模块被展平、复制或插入包装层,也会改变实例前缀。因此修复应落到 SDF 生成端或网表交付端,而不是长期维护一张手工改名表。临时改一份 SDF 可以验证根因,但下一轮网表仍可能让同样的问题回来。
还要区分“某条弧已标注”与“整份 SDF 完整标注”。本例只有一个缓冲弧,0.800ns 足以证明这条路径;大型设计则应统计并保存所有读取错误,抽查关键路径,再检查未标注对象。不能因一条路径从 0.300ns 变为 0.800ns,就默认其余寄存器、互连和条件弧也全部成功。反过来,某个可选实例在裁剪后消失,也应确认它是否本应存在,不能简单删除警告。
一个稳妥的读取骨架如下。它把失败变成非零退出,避免后续命令继续消费旧延迟;具体文件名和顶层仍由外层流程传入。
if {[catch {read_sdf fixed.sdf} msg]} {
puts stderr "SDF annotation failed: $msg"
exit 1
}
report_checks -path_delay max -format full_clock_expanded -digits 3最终交付日志至少应包含网表顶层、SDF 文件名、读取是否成功和一条可核对的弧值。审查者据此能重建对象对应关系,不需要从一张 slack 汇总反推过程。若名称映射必须由脚本完成,也应把映射规则和输入网表版本一起保存,避免用无法追溯的手工编辑通过检查。
代码获取:最小 Liberty、网表、三份 SDF、Tcl 与运行脚本位于 geek-doc.cn/experiments/ts-opensta-sdf-annotation-fail,安装 OpenSTA 后在目录内执行 bash run.sh 即可复现三组对照。
实验环境
- 机器/系统:本地 Docker 容器,Ubuntu 24.04;宿主为 macOS。
- 工具版本:OpenSTA 2.0.17,Debian 官方独立二进制包。
- 日期:2026-10-31。
- 完整命令:在实验目录执行
bash run.sh,依次运行wrong_instance.tcl、wrong_design.tcl、fixed.tcl,合并标准输出和标准错误并记录各组退出码。 - 实验边界:
experiment.lib仅含教学用 DFF/BUF 时序弧;文中数值只用于判别标注是否生效,不代表任何工艺的签核结果。
这一篇在知识体系里的位置
本篇处理的是 SDF 已经进入 STA 流程后的对象匹配问题。库路径或 Liberty 解析失败属于前置加载问题;若标注已生效、接下来要判断建立时间是否真正满足,可转到 OpenSTA 负 slack 排查。若弧延迟正确但报告没有路径,则按 OpenSTA read_sdf 标注失败之外的时钟排查 检查 create_clock 与端点覆盖,不要反复修改 SDF。
总结
OpenSTA read_sdf 标注失败的核心是确认延迟有没有落到目标实例弧。instance u_buffer not found 后仍可能输出 8.500ns 的 MET 和退出码 0,那是 Liberty 的 0.300ns 在起作用;DESIGN "chip_top" 与顶层 top 不同,本版却仍能完成标注,说明设计头不是可靠的匹配依据。修正 DESIGN 与 INSTANCE 后,u_buf/Y 应变为 0.800ns、到达时间 1.000ns、slack 8.000ns,并配合错误即退出的脚本,才算真正修复。