2. 时序分析基础与Vivado报告解读
时序收敛的第一步不是改约束,而是能读懂工具给出的时序报告。Vivado 的 report_timing_summary 把建立时间(Setup)、保持时间(Hold)、脉冲宽度(Pulse Width)三类检查汇总在一张表里,但真正决定“能不能收敛”的信息,往往藏在 WNS、TNS、WHS、THS 这几个字段以及它们背后的路径细节中。本节先建立时序分析的基本概念,再逐字段拆解报告,最后给出一个可复用的解读流程。
建立时间与保持时间:两个方向相反的约束
建立时间要求数据在时钟有效沿到来之前已经稳定一段时间。以触发器为例,若时钟上升沿在 t=10ns 到达,数据必须在 10ns − tsu 之前就稳定,其中 tsu 是器件固有的建立时间。保持时间则相反,要求数据在时钟沿之后继续保持稳定至少 th,防止新数据过早冲入。两者共同定义了数据到达窗口:数据到达时间必须落在 [时钟沿 + th, 下一个时钟沿 − tsu] 之内。
在 Vivado 中,建立检查的裕量(Slack)计算为:
Setup Slack = (要求时间 Required Time) − (到达时间 Arrival Time)
= (捕获沿时刻 + 时钟路径延迟 − t_su − 不确定性)
− (发射沿时刻 + 时钟路径延迟 + 数据路径延迟)
保持检查的裕量方向相反:
Hold Slack = (到达时间 Arrival Time) − (要求时间 Required Time)
= (发射沿时刻 + 时钟路径延迟 + 数据路径延迟)
− (捕获沿时刻 + 时钟路径延迟 + t_h + 不确定性)
Slack 为正表示满足,为负表示违例。注意建立与保持的“到达/要求”定义是互换的,这是初学者最容易混淆的地方。
时钟偏斜、抖动与不确定性
时钟偏斜(Skew)是同一时钟到达两个触发器时钟端的延迟差。若发射触发器时钟比捕获触发器早到 Δt,则建立裕量减少 Δt,保持裕量增加 Δt。偏斜本身不是错误,但会同时挤压建立和保持窗口。
抖动(Jitter)是时钟沿相对理想位置的随机偏移,通常用峰峰值或 RMS 描述。Vivado 把抖动、偏斜余量、时钟树延迟等统一折算为 Clock Uncertainty,在约束中通过 set_clock_uncertainty 指定。例如:
set_clock_uncertainty -setup 0.15 [get_clocks clk_pll]
set_clock_uncertainty -hold 0.08 [get_clocks clk_pll]
不确定性越大,可用裕量越小。工程上常把 PLL 输出抖动、板级时钟源抖动和时钟树偏斜余量合并估算,而不是逐项精确建模。
时序路径类型
Vivado 把路径分为四类:Setup(建立)、Hold(保持)、Recovery/Removal(异步复位恢复/移除)、Pulse Width(脉冲宽度)。其中 Setup 和 Hold 占绝大多数。路径的起点和终点可以是端口、触发器、RAM、DSP 等。跨时钟域路径若未做约束,会被归入 Timing Exception 或直接报为未约束路径,这是报告里最需要警惕的“假通过”。
report_timing_summary 关键字段实战解读
执行 report_timing_summary -delay_type min_max -report_unconstrained -check_timing_verbose 后,报告开头是 Design Timing Summary 表。核心字段含义如下:
| 字段 | 含义 | 判读要点 |
|---|---|---|
| WNS | 最差负裕量(Worst Negative Slack) | 所有建立路径中最差的一条;≥0 表示建立全部通过 |
| TNS | 总负裕量(Total Negative Slack) | 所有违例路径裕量之和;反映违例规模 |
| WHS | 最差保持裕量 | 保持检查中最差的一条;≥0 表示保持全部通过 |
| THS | 总保持裕量 | 保持违例路径裕量之和 |
| WPWS | 最差脉冲宽度裕量 | 时钟高/低电平宽度是否满足最小要求 |
| TNS Failing Endpoints | 违例终点数量 | 定位需要修复的寄存器/端口数量 |
实战中先看 WNS 和 WHS 是否都为非负。若 WNS 为负而 WHS 为正,通常是组合逻辑过长或时钟频率过高;若 WHS 为负,则常见于数据路径过短、时钟偏斜过大或保持约束过紧。TNS 的绝对值越大,说明违例路径越多,修复优先级越高。
报告下半部分会列出每条违例路径的详细分解,包括:Source(起点)、Destination(终点)、Path Group(时钟组)、Path Type(Setup/Hold)、Requirement(要求时间)、Data Path Delay(数据路径延迟)、Logic Levels(逻辑级数)、Clock Path Skew(时钟偏斜)。其中 Logic Levels 和 Data Path Delay 是判断“是逻辑太深还是布线太长”的关键。
一个可复用的解读示例
假设某设计在 100MHz 时钟下报告:WNS = −0.312ns,TNS = −1.845ns,WHS = 0.045ns,THS = 0.000ns,违例终点 7 个。这说明建立时间有 7 条路径违例,保持时间刚好通过。打开最差路径,看到 Data Path Delay = 10.42ns,Logic Levels = 14,Requirement = 10.00ns,Clock Path Skew = 0.18ns。计算可知:10.42 + 0.18 − 10.00 ≈ 0.60ns 的差距中,逻辑延迟占了主要部分。此时优先考虑插入流水线寄存器或优化组合逻辑,而不是先动时钟约束。
若同一设计 WHS = −0.02ns,则说明保持裕量不足。常见原因是数据路径过短(例如直连旁路)或时钟偏斜方向不利。可尝试增加数据路径延迟、调整时钟树约束,或在综合/实现策略中启用保持修复选项。注意保持违例通常不能靠降频解决,因为降频会同时放宽建立和保持的要求,但保持违例的根源往往在偏斜和短路径上。
set_false_path/set_clock_groups,这些路径不会计入 WNS,但实际硬件可能失效。务必用 report_unconstrained 和 check_timing 交叉验证。