OpenSTA report_checks 报告解读:Startpoint、Path Type、Incr/Path 与 slack 逐字段读
更新时间:2026-11-03。静态时序分析是什么 讲过,STA 不仿真波形,而是把每条路径的到达时间与要求时间做一次减法。OpenSTA 把这次减法完整打印出来的命令就是
report_checks。本篇不写自动化脚本(那属于 STA 时序报告提取 TCL 脚本 的范畴),只做一件事:拿一份真实报告,从上到下逐字段讲人话。全部数字来自 OpenSTA 2.0.17 对一份最小教学设计的真实运行。
本文要回答的问题
- 报告头的 Startpoint、Endpoint、Path Group、Path Type 各自怎么确定,看错了会怎样?
- 表格里 Delay 与 Time 两列(老资料常写作 Incr 与 Path)有什么区别,为什么每一行都有两个数?
clock network delay (ideal)、clock reconvergence pessimism、library setup time这些行分别是谁的账?- data arrival time 与 data required time 怎么算出来,slack 的 MET/VIOLATED 由哪两个数相减得到?
- 同一条路径把时钟频率提高,报告里哪些字段变、哪些字段不变?
这张卡就是全篇的阅读路线:报告头回答「这是哪两个触发器之间的什么检查」,上下两个半区各做一次时间累加,末区只做一次减法。任何一个字段对不上,都比单纯看到红字 VIOLATED 更能定位问题。
一、这一步在流程里的位置
report_checks 是 STA 流程的读数动作,本身不改设计、不改约束。它的上游是三个输入文件经 Tcl 加载进内存:时序库(liberty)、网表(Verilog)、约束(SDC 风格的时钟与例外命令);下游是人读报告做收敛决策,或把数字喂给脚本做回归判定。
读图抓住一点:report_checks 只是把内存里已经算好的时间打印出来,所以报告数字不对时,要回到三个输入和 Tcl 命令本身排查,而不是怀疑打印格式。本篇三个输入都刻意保持最小:教学 liberty 只有一个 DFF_P(CLK→Q 0.20ns、setup 0.10ns、hold 0.00ns)和一个 BUF_X1(延时 0.30ns),网表是 u_a → BUF → u_b 两级流水线,教学库不对应任何真实工艺,产线需替换为 PDK 签核库。
二、命令逐段解读:从加载到出报告
完整脚本只有六行,以基线场景 met.tcl 为例:
read_liberty teaching.lib
read_verilog top.v
link_design top
create_clock -name clk -period 2.0 [get_ports clk]
report_checks -path_delay max
report_checks -path_delay min前三行把库、网表读进来并把顶层 top 链接成完整设计;create_clock 在 clk 端口定义周期 2.0ns 的时钟,发射沿默认在 0.00、占空比 50%;最后两行分别出 setup 与 hold 报告。report_checks 常用选项如下:
| 选项 | 作用 | 不写会怎样 |
|---|---|---|
-path_delay max | 做 setup 检查,捕获沿取最晚(下一个周期) | 默认就是 max,显式写更清楚 |
-path_delay min | 做 hold 检查,捕获沿取最早(同一沿) | 不写就看不到 hold,hold 违例会漏检 |
-from/-through/-to | 收窄起点/经过点/终点 | 默认报全设计最差路径,长设计里翻不到目标路径 |
-path_group clk | 只报某个路径组 | 默认所有组,输出可能很长 |
-fields {slew capacitance input_pin} | 多打印转换时间、负载电容、输入引脚列(合法字段名为 slew/capacitance/input_pin/net) | 默认只有 Delay/Time/Description 三列 |
-endpoint_count 2 -group_count 10 | 每个端点保留路径数、每组报告条数(2.0.17 没有 -nworst,写错会报 not a known keyword) | 默认每个端点只留最差一条 |
-digits 4 | 小数位数 | 默认两位,微小违例会被四舍五入掩盖 |
两个版本坑要提醒:其一,OpenSTA 2.0.17 里 -setup/-hold 不是合法旗标,写了会告警并仍按 max 出报告,查 hold 必须用 -path_delay min;其二,想加列看 slew/capacitance 时字段名写在 -fields 的集合里(注意是 capacitance 不是 cap),不是独立开关。旗标不生效但退出码仍是 0 的问题,在 OpenSTA clock uncertainty 未生效排查 里有同类实测。
三、输入输出文件:报告长什么样
输入三件套的体量都很小:teaching.lib 约 1.9KB,定义两个单元的标量延时;top.v 是 9 行结构化网表;met.tcl 六行命令。输出是纯文本报告,下面终端卡是基线场景 setup 报告的真实输出(周期 2.0ns):
逐字段读这张卡。报告头四行是「路径身份」:Startpoint u_a 是发射数据的触发器,Endpoint u_b 是捕获触发器,括号注明二者都是 clk 上升沿触发;Path Group 是 clk——OpenSTA 默认按捕获触发器的时钟给路径分组;Path Type max 说明这是 setup 检查(取最大延时路径),换成 min 就是 hold。
正文分上下两个半区。发射半区(上半张表)回答「数据几点到」:clock clk (rise edge) 0.00 是发射沿时刻;clock network delay (ideal) 0.00 是时钟网络延迟,标着 ideal 表示时钟还在理想模式、没有传播延时;u_a/C 0.00 → u_a/Q 0.20 → u_x/Y 0.50 → u_b/D 0.50 是数据路径逐站累加,0.50 即 data arrival time。这里要分清两列:左列 Delay 是这一行本级的增量(老资料常叫 Incr),右列 Time 是从发射沿起的累计值(常叫 Path)——BUF 那行左列 0.30、右列 0.50,差的正是前级的 0.20。
捕获半区(下半张表)回答「数据必须几点到」:捕获沿在 2.00ns(一个周期之后);clock reconvergence pessimism(CRPR,时钟共同路径悲观折中)这里是 0.00;library setup time −0.10 把库里的建立时间从捕获沿里扣掉,得到 data required time 1.90ns。最底部三行做减法:1.90 要求 − 0.50 到达 = 1.40 slack (MET)。hold 报告结构完全相同,只有两处不同:Path Type 是 min,捕获沿停在 0.00(同一沿捕获),library hold time 为 0.00,于是 slack = 0.50 到达 − 0.00 要求 = 0.50 MET。setup 检查的物理含义见 STA setup 检查原理(OpenSTA 实操)。
四、常见错与检查点
| 现象 | 先查什么 | 纠正 |
|---|---|---|
| 报告尾部是 MET,但流片后 hold 出问题 | 是否只看了默认 max 报告 | hold 必须显式 report_checks -path_delay min |
| slack 显示 0.00 却怀疑有小违例 | 默认两位小数四舍五入 | 加 -digits 4 复跑确认 |
| 网络延迟一行全是 0.00 就认为时钟树完美 | 行尾是否标着 ideal | 理想时钟不算线延迟,传播后要用 set_propagated_clock |
| 改了半天违例,报告数字纹丝不动 | 是否改错路径组/路径 | 先核对报告头 Startpoint/Endpoint/Path Group 再动手 |
第四个是新人最高频的浪费:拿着 u_a→u_b 的报告去优化别的路径。读报告的正确顺序永远是先报告头、再两个半区、最后才看 slack。负 slack 的物理含义和分级见 OpenSTA slack (VIOLATED) 负裕量解读;时钟网络延迟从理想值到传播值的完整语义见 STA 时钟延迟:source latency 与 network latency。
五、真实跑一遍:提频制造违例,再加网络延迟对照
同一份网表与库,只把周期从 2.0ns 改成 0.5ns(2GHz),数据路径延时 0.50ns 分毫不变,报告立刻变色:
对照两份报告,变化只有三处:捕获沿从 2.00 变成 0.50,required time 从 1.90 变成 0.40,slack 从 1.40 MET 变成 −0.10 VIOLATED;发射半区 0.20/0.30/0.50 三个数字一字未动——数据跑得再快也没用,是时钟给的预算少了。这正是读字段的价值:违例时先看是到达变大还是要求变小,优化方向完全不同。
第三个场景把周期改回 2.0ns,加一条 set_clock_latency 0.20 [get_clocks clk],观察网络延迟字段:
0.00 0.00 clock clk (rise edge)
0.20 0.20 clock network delay (ideal)
0.20 0.40 ^ u_a/Q (DFF_P)
...
2.00 2.00 clock clk (rise edge)
0.20 2.20 clock network delay (ideal)
1.40 slack (MET)发射沿与捕获沿各平移 0.20ns(到达 0.70、要求 2.10),减法结果仍是 1.40——共同时钟路径的延迟对两个半区同增同减,这也是 CRPR 存在的原因。三组用例退出码均为 0(注意:路径 VIOLATED 时 sta 进程退出码仍是 0,不能用退出码判时序,要读 slack 数字)。
实验环境
- 机器/系统:本地 Docker 容器,Ubuntu 24.04;宿主为 macOS(Apple Silicon)。
- 工具版本:
sta -version输出2.0.17(镜像 geek-eda:0.3-sta,Debian 独立二进制包)。 - 日期:2026-11-03。
- 完整命令:
docker run --rm -v "$PWD":/work -w /work geek-eda:0.3-sta bash run.sh,依次执行met.tcl、fast.tcl、latency.tcl三个场景(等价于make run)。 - 实验边界:教学 liberty 只有两个单元、标量延时,数值用于演示字段读法,不能外推为任何工艺的签核结论。
代码获取
完整教学库、网表、三个场景 Tcl 与运行脚本位于 geek-doc.cn/experiments/flow-opensta-report-checks-reading,克隆后进入该目录执行 make run 即可在 geek-eda:0.3-sta 容器中复现 MET、VIOLATED 与网络延迟三份对照报告,本机装有 OpenSTA 时也可用 STA_BIN=sta bash run.sh 直接运行。
这一篇在知识体系里的位置
本篇讲「人怎么逐字段读懂一份报告」:想先建立 setup/hold 的整体概念,读 静态时序分析是什么 与 OpenSTA 建时钟与第一份时序报告;字段已经会读、要把判定接进回归脚本,读 STA 时序报告提取 TCL 脚本;报告里的约束数字不随设定变化时,读 OpenSTA clock uncertainty 未生效排查。
总结
OpenSTA report_checks 报告解读的关键是按区块读数:报告头四行(Startpoint、Endpoint、Path Group、Path Type)确认路径身份,max 是 setup、min 是 hold;表格左列 Delay 是本级增量、右列 Time 是累计值;发射半区从 0.00 发射沿累加时钟网络延迟、CLK→Q 与组合逻辑得到 data arrival time,捕获半区从下一周期沿扣掉 CRPR 与库 setup 时间得到 data required time;底部 required 减 arrival,非负即 MET,为负即 VIOLATED。提频实验证明违例只改捕获沿一侧的预算、数据路径数字不变,而时钟网络延迟对两侧同增同减不影响 slack;另外路径违例时退出码仍为 0,时序判定必须读数字而不是看退出码。