OpenSTA 最小脉宽违规:时钟波形与 Liberty 约束对照排查
OpenSTA 最小脉宽违规表示时钟某个高电平或低电平区间太短,不满足时序单元时钟引脚的 Liberty 约束。它不是建立时间或保持时间不足,也不能用数据路径上的正 slack 抵消。本篇用同一网表、同一库和两份 SDC 得到一组违规与一组满足报告;若报告里连时钟都没有,应先按 OpenSTA no clocks found 排查 处理时钟创建问题。
本文要回答的问题
min_pulse_width_high和min_pulse_width_low分别检查哪一段时间?- 周期不变时,为什么调整
-waveform仍可能消除或引入违规? - 怎样用
report_pulse_width_checks读出要求值、实际值与 slack? - 为什么出现
VIOLATED时,OpenSTA 进程的退出码仍可能是 0?
读这张图要把左右两类输入分开:SDC 决定实际波形,Liberty 决定单元能接受的底线,OpenSTA 在二者交汇处做减法。只看周期或只看频率都缺少占空比信息;只看库约束又不知道当前时钟是否真的满足。
一、OpenSTA 最小脉宽违规检查的是什么
最小脉宽检查落在寄存器或锁存器的时钟引脚上。高脉宽从本次有效上升沿量到随后的下降沿,低脉宽从下降沿量到下一次上升沿。对常见的上升沿触发 DFF,若 SDC 写 create_clock -period T -waveform {r f},则高电平宽度为 f-r,低电平宽度为 T-(f-r)。这里的 r、f 必须与周期使用相同单位,本例 Liberty 的时间单位是 1ns。
第一行在一个 4ns 周期里只保留 1ns 高电平,低电平为 3ns;第二行是 10ns、50% 占空比,高低各 5ns。可见“周期更长”不是唯一修法:只要总周期足够,移动下降沿也能重新分配高、低两段宽度。反过来,周期达标但波形过窄仍会失败。
| 对照项 | 违规组 | 满足组 |
|---|---|---|
| 时钟周期 | 4ns | 10ns |
-waveform | {0 1} | {0 5} |
| 实际高 / 低脉宽 | 1ns / 3ns | 5ns / 5ns |
| 库要求高 / 低脉宽 | 均为 2ns | 均为 2ns |
| 报告结论 | 高脉宽 VIOLATED | 高、低脉宽均 MET |
占空比通常指高电平时间占整个周期的比例,但检查不能只看这个百分数。同样是 25% 占空比,4ns 周期的高电平只有 1ns,20ns 周期则有 5ns;比例相同,绝对脉宽不同,判定也可能不同。低电平检查还会迫使设计者同时照顾另一段:在固定周期里增加高电平,就会等量减少低电平,因此不能把下降沿无限后移。对于双数据率或同时使用正负边沿的设计,这种此消彼长尤其重要。
还要注意最小脉宽与最大频率不是同一张约束。最大频率关心完整周期能否容纳数据到达和建立要求,最小脉宽关心单个半周期是否足够寄存器可靠采样。一个设计可以拥有很大的建立时间余量,同时因高电平过窄而失败;把 report_checks 中的数据路径 slack 抄到脉宽问题上,会掩盖真正的失败对象。
库里的两行约束是检查阈值,不是让 OpenSTA 自动修改时钟的参数。本文实验库在 DFF_P 的 C 引脚声明如下:
pin(C) {
direction : input;
clock : true;
min_pulse_width_high : 2.0;
min_pulse_width_low : 2.0;
}二、最小实验与真实违规报告
网表只有一个 DFF_P,时钟直接连接到 u_stage/C。违规组 SDC 只含一行时钟定义,避免输入输出延迟和多余时钟干扰结论:
create_clock -name clk -period 4.0 -waveform {0.0 1.0} [get_ports clk]加载库、网表并 link_design 后读取该 SDC,再执行 report_pulse_width_checks。这个命令直接面向脉宽检查;本文使用的 OpenSTA 2.0.17 不支持把 min_pulse_width 当作 report_checks -path_delay 的参数。
报告把两行结果放在同一个引脚下:高电平 Required Width 为 2ns,Actual Width 为 1ns,所以 slack 是 1-2=-1ns;低电平实际为 3ns,余量为 1ns,因此同一时钟可以一项失败、一项通过。不能看到第二行 MET 就忽略第一行 VIOLATED。
Pin 列也提供排查入口。这里失败的是 u_stage/C,不是顶层 clk 端口,更不是数据引脚 D。实际设计可能有多个寄存器挂在同一时钟上,报告会按各单元库的阈值分别计算;同名时钟在不同单元上并不必然得到相同的 Required Width。若只有一个实例失败,应比较它的单元型号和库,若整片同时失败,再优先回看上游时钟波形。传播路径、生成时钟和主时钟的波形关系也应保持一致,不能只改报告末端的一条派生约束。
CASE_SDC: violation.sdc
Clock Period Waveform
----------------------------------------------------
clk 4.00 0.00 1.00
MIN_PULSE_WIDTH_CHECKS
Required Actual
Pin Width Width Slack
------------------------------------------------------------
u_stage/C (high) 2.00 1.00 -1.00 (VIOLATED)
u_stage/C (low) 2.00 3.00 1.00 (MET)
CASE_EXIT violation=0末尾退出码为 0 也值得注意。它表示 Tcl 脚本执行到了结尾,不表示所有时序检查通过。自动化使用本版本时,应检查报告中的 VIOLATED 或负 slack,不能把进程状态当作脉宽验收条件。相反,如果命令本身拼错,本版本也可能打印 Error 后继续到脚本末尾,所以日志审计还要排除命令错误,确认表格确实由 report_pulse_width_checks 产生。一张只有时钟属性、没有脉宽表格的日志不能算检查通过。
三、满足组与排查顺序
满足组保持库和网表完全不变,只把 SDC 换成 10ns 周期、50% 占空比。这样可以明确说明差异来自时钟定义,而不是某条数据路径恰好变快。
create_clock -name clk -period 10.0 -waveform {0.0 5.0} [get_ports clk]CASE_SDC: pass.sdc
Clock Period Waveform
----------------------------------------------------
clk 10.00 0.00 5.00
MIN_PULSE_WIDTH_CHECKS
Required Actual
Pin Width Width Slack
------------------------------------------------------------
u_stage/C (high) 2.00 5.00 3.00 (MET)
u_stage/C (low) 2.00 5.00 3.00 (MET)
CASE_EXIT pass=0两组数字只证明这份教学约束下的判定变化,不代表真实芯片把时钟改成 10ns 就能获得 3ns 签核余量。实际项目应读取对应工艺角、电压和温度的库,并确认 SDC 单位与库单位一致。report_clock_properties 中的周期和波形只是约束输入的复核,真正的通过依据仍是后面的逐引脚检查表。
修复也要区分约束错误与硬件能力错误。如果 SDC 的下降沿写错,改正 -waveform 是恢复真实意图;如果约束准确而时钟源输出的窄脉冲确实低于单元要求,就要降低频率、调整占空比或更换时钟产生方案。随意把库里的 2ns 改小只是删除告警,并未改变硬件极限。对生成时钟,还应检查主时钟修改后派生波形是否同步更新,避免主时钟通过而分频时钟仍失败。
遇到 OpenSTA 最小脉宽违规,可按这个顺序定位:先确认报告引脚和 (high)、(low) 类型;再用 report_clock_properties 对拍周期与波形;随后回到 Liberty 查该引脚阈值;最后检查时钟源、分频器或占空比整形电路是否真能提供所需波形。若问题其实是端点未覆盖,则应转到 unconstrained endpoint 排查,不要混用修复手段。
代码获取:完整网表、实验 Liberty、两份 SDC、Tcl 和运行脚本位于 geek-doc.cn/experiments/ts-opensta-min-pulse-width,安装 OpenSTA 后执行 bash run.sh 可复现两组对照。
实验环境
- 机器/系统:本地 Docker 容器,Ubuntu 24.04;宿主为 macOS。
- 工具版本:OpenSTA 2.0.17,Debian 官方独立二进制包;未使用 OpenLane。
- 日期:2026-10-31。
- 完整命令:在实验目录执行
bash run.sh,依次以SDC_FILE=violation.sdc和SDC_FILE=pass.sdc运行sta -no_init -exit check.tcl,合并 stdout/stderr 并记录退出码。 - 实验边界:
experiment.lib仅含一个 DFF 的最小时序弧与 2ns 脉宽约束;未跑物理实现,数值不可外推为任何工艺的签核结论。
这一篇在知识体系里的位置
本篇属于静态时序分析的约束检查层,重点是把 SDC 波形与 Liberty 单元限制放在同一张报告中对拍。时钟未创建或未附着时,先看 OpenSTA no clocks found:create_clock 缺失与端口名写错排查;端点覆盖异常则看 OpenSTA unconstrained endpoint 排查。
总结
OpenSTA 最小脉宽违规要分别看高、低电平:实际脉宽来自 create_clock 的周期和 -waveform,要求值来自 Liberty 时钟引脚,slack 为二者之差。本例 4ns 周期配 {0 1} 波形时,高脉宽 1ns 小于要求 2ns,得到 -1ns VIOLATED,而低脉宽仍 MET;换成 10ns、{0 5} 后两项均为 3ns MET。排查应落到具体引脚和电平类型,且不能用退出码 0 或其他路径的正 slack 掩盖脉宽失败。