OpenSTA no clocks found:create_clock 缺失与端口名写错排查
OpenSTA no clocks found 常见为两类约束事故:根本没有执行 create_clock,或 [get_ports ...] 写错了网表端口名。二者都可能以 No paths found、未约束端点告终,且进程退出码仍可为 0。本篇用同一网表做三组对照;与 unconstrained endpoint 排查 重点讨论的“下游引用了不存在的时钟对象”和 false path 不同,这里专查时钟是否创建、是否真正附着到端口。
本文要回答的问题
read_verilog、link_design都成功,为什么没有数据时序路径?- 完全没有
create_clock时,哪些报告能证明时钟域没有建立? - 端口名写错后,为什么
report_clock_properties仍可能列出时钟? - 修复后要看哪些输出,而不能只看进程退出码?
这张漏斗把“库和网表能读”与“有时序图”分开:LINK_OK 只能走到第二层,不能当作约束通过。两条根因的验证终点也不只是列出 clk,而是端点覆盖和路径报告同时恢复。
一、OpenSTA no clocks found 的原始诊断
实验网表只有一个 DFF 和输出缓冲,真实端口是 clk、d、q。第一组故意不读任何 SDC;OpenSTA 版本为 2.0.17。下面保留了链接成功、未约束端点、空时钟表、No paths found 和退出码。
LINK_OK 后面马上出现 u_stage/C 未挂时钟、q 与 u_stage/D 两个未约束端点;时钟表只有表头,随后没有路径。最后的 CASE_EXIT no_clock=0 很关键:对 OpenSTA 来说脚本正常执行完毕,并不等价于设计完成了时序检查。自动化若只判断退出码,会把这次“没检查”当成成功。
二、根因:链接网表与建立时序图是两步
read_verilog 建立层次和连接关系,link_design 解析实例引用;create_clock 则在指定端口上创建带周期、波形的时钟对象,并把它传播到寄存器时钟引脚。少了后一步,DFF 在网表里真实存在,STA 仍不知道用哪个边沿和周期检查它。
红色是两列根因,蓝色是读取与诊断,橙色是修复,绿色才是通过。特别注意错名分支:对象“被创建”与对象“附着到真实端口”不是一回事,因此 report_clock_properties 不能单独作为验收依据。
三、两类原因的判别清单
| 检查项 | 完全缺 create_clock | get_ports 端口名写错 |
|---|---|---|
| SDC 加载 | 没有时钟定义可执行 | 执行时出现 port 'clck' not found |
| 时钟属性表 | 只有表头,无 clk 行 | 本版仍列出 clk、10ns 和波形 |
| 寄存器时钟脚 | u_stage/C unclocked | 仍是 unclocked |
| 端点覆盖 | q、u_stage/D 未约束 | 仍有两个未约束端点 |
| 修复位置 | 增加时钟定义 | 只改对象选择,不盲目再建一个时钟 |
错名组的原始摘录如下。Startpoint 不再带 clocked by clk,同时 unclocked 与 unconstrained 警告仍在;后面即使出现输出路径和 MET,也不能覆盖这些失败证据。
LINK_OK: read_verilog and link_design completed
CASE: wrong port name clck
Warning: wrong_port.sdc, 1 port 'clck' not found.
Warning: There is 1 unclocked register/latch pin.
u_stage/C
Warning: There are 2 unconstrained endpoints.
q
u_stage/D
Clock Period Waveform
----------------------------------------------------
clk 10.00 0.00 5.00
Startpoint: u_stage (rising edge-triggered flip-flop)所以排查顺序应是:先看 port not found,再查 unclocked 和未约束端点,最后才看 slack。已有 OpenSTA no clocks found 端点审计方法 可用于更大设计的覆盖统计。
为什么错名后还有一段看似正常的路径报告?本版 OpenSTA 对空的对象选择结果只给警告,仍继续创建名为 clk 的时钟对象;后续 set_output_delay -clock clk 又能引用这个对象,于是输出端有了相对该时钟的 required time。可是 clk 没有附着到任何真实端口,DFF 的 u_stage/C 没有发射时钟,起点描述便退化为不带 clocked by 的寄存器。这样的报告不是完整寄存器到输出检查,不能拿其中的 8.500 MET 当作修复证据。
这个差异也决定了命令组合:report_clock_properties 回答“是否存在时钟对象及其周期”,check_setup -verbose 回答“寄存器时钟脚和端点是否被覆盖”,report_checks 回答“具体路径如何到达、如何要求”。三条命令互不能替代。只执行第一条,会把错名误判为成功;只执行第三条,又可能因碰巧存在 I/O 路径而漏掉未约束的寄存器数据端。
四、修复代码与复跑 PASS
正确 SDC 把时钟附着到真实 clk 端口,再给输入、输出 1ns 预算:
create_clock -name clk -period 10.0 [get_ports clk]
set_input_delay 1.0 -clock clk [get_ports d]
set_output_delay 1.0 -clock clk [get_ports q]若当前文件是错名对照,只把 [get_ports clck] 改为 [get_ports clk],不要同时新增另一个同名时钟。复跑脚本保留 report_clock_properties、check_setup -verbose 和 report_checks;本例验收标准是:时钟为 10ns、未约束警告消失、起点标注 clocked by clk、路径组为 clk、slack 为 MET。
Clock Period Waveform
----------------------------------------------------
clk 10.00 0.00 5.00
Startpoint: u_stage (rising edge-triggered flip-flop clocked by clk)
Endpoint: q (output port clocked by clk)
Path Group: clk
0.500 data arrival time
9.000 data required time
8.500 slack (MET)
CASE_EXIT fixed=0这组输出才构成修复 PASS:不只是有时钟名,也不只是退出码为 0,而是时序图从时钟端口延伸到了寄存器和输出端点。若时钟存在但端点仍漏约束,还应继续按 OpenSTA no clocks found 与约束 lint 检查,而不是用一条 set_false_path 把警告消掉。
代码获取:完整网表、实验 Liberty、三份 Tcl、SDC 与运行脚本位于 geek-doc.cn/experiments/ts-opensta-no-clocks-found,安装 OpenSTA 后执行 bash run.sh 可复现三组对照。
实验环境
- 机器/系统:本地 Docker 容器,Ubuntu 24.04;宿主为 macOS。
- 工具版本:OpenSTA 2.0.17,Debian 官方独立二进制包;未使用 OpenLane。
- 日期:2026-10-30。
- 完整命令:在实验目录执行
bash run.sh,依次运行no_clock.tcl、fixed.tcl、wrong_port.tcl,合并 stdout/stderr 并记录各组退出码。 - 实验边界:
experiment.lib仅为含 DFF/BUF 最小时序弧的教学库;未跑物理实现,本文数值不能外推为任何工艺的签核结论。
这一篇在知识体系里的位置
本篇处于 SDC 数据格式与生命周期 之后的故障定位层,专门处理“设计已链接、时钟却未附着”的入口问题。后续端点覆盖审计见 OpenSTA no clocks found 端点审计方法;若缺的是下游 -clock 引用或路径被例外豁免,则转到 unconstrained endpoint 排查。
总结
OpenSTA no clocks found 要区分完全没写 create_clock 与 get_ports 端口名写错。前者时钟表为空,后者在 OpenSTA 2.0.17 中仍可能列出时钟对象,却留下 port not found、unclocked 和未约束端点。read_verilog/link_design 成功与退出码 0 都不代表完成时序检查;正确修复后必须同时看到真实端口上的 10ns 时钟、clocked by clk、Path Group: clk 和 slack (MET),才算建立并检查了时序路径。