2. 建立时间与保持时间基础

在 TimeQuest 中做时序约束与签核,第一步不是急着写 create_clock 或 set_input_delay,而是把“建立时间”和“保持时间”这两个概念从物理层面理解清楚。因为所有约束命令、所有 Slack 报告、所有违例分析,最终都归结为同一个问题:数据信号到达触发器时,是否在时钟有效沿附近的一个稳定窗口内保持不动。这个稳定窗口,就是 setup 与 hold 共同定义的。

一、setup 与 hold 的物理含义

触发器在时钟有效沿采样数据,但数据并不是在时钟沿那一瞬间才被“读取”的。芯片内部的采样电路需要数据在时钟沿之前提前稳定一段时间,这段时间叫建立时间(setup time,tsu);同时还需要在时钟沿之后继续保持稳定一段时间,这段时间叫保持时间(hold time,th)。两者合起来,构成了一个以时钟有效沿为中心的“禁止数据跳变窗口”。

可以这样理解:时钟沿是“拍照时刻”,setup 要求被拍的对象在快门按下前已经摆好姿势,hold 要求快门按下后姿势还不能马上变。如果数据在 setup 窗口内还在跳变,触发器可能采到旧值或亚稳态;如果数据在 hold 窗口内过早变化,触发器可能把新值误锁进来。因此 setup 违例通常表现为“数据来得太晚”,hold 违例通常表现为“数据变得太早”。

方向约定:本文统一以“数据从源触发器经组合逻辑到达目的触发器”为正向路径。setup 检查关注数据到达时间是否早于时钟到达时间减去 tsu;hold 检查关注数据到达时间是否晚于时钟到达时间加上 th。全文及图示均采用这一参照系。

二、一条完整时序路径由什么组成

在 FPGA 内部,一条典型的寄存器到寄存器(reg-to-reg)时序路径包含以下环节:

  • 源触发器:在源时钟沿把数据从 D 端锁存到 Q 端,Q 端变化存在时钟到输出延迟 tco。
  • 组合逻辑:数据从源 Q 出发,经过 LUT、进位链、布线等,产生组合逻辑延迟 tcomb。
  • 目的触发器:数据到达目的 D 端,等待目的时钟沿采样,需要满足 tsu 和 th。
  • 时钟网络:源时钟和目的时钟各自从时钟源经过时钟树到达触发器时钟端,存在时钟延迟和可能的偏斜(skew)。

因此,数据到达时间(data arrival time)和时钟到达时间(clock arrival time)是两条并行的“赛跑路径”。setup 检查的是数据路径是否跑得太慢,hold 检查的是数据路径是否跑得太快。

三、数据到达时间与时钟到达时间的关系

以目的触发器为观察点,定义:

  • 数据到达时间 = 源时钟沿 + tco + tcomb(再加上源时钟到源触发器的延迟)。
  • 时钟到达时间 = 目的时钟沿 + 目的时钟网络延迟。

setup 关系可以写成:数据到达时间 ≤ 时钟到达时间 + 时钟周期 − tsu。移项后得到 setup slack = (时钟到达时间 + 周期 − tsu) − 数据到达时间。slack 为正表示满足,为负表示违例。

hold 关系则相反:数据到达时间 ≥ 时钟到达时间 + th。hold slack = 数据到达时间 − (时钟到达时间 + th)。注意 hold 检查通常针对同一个时钟沿,不跨周期,因此时钟周期不参与 hold 计算。

下面这张图把上述关系集中表达出来:左侧是数据路径,右侧是时钟路径,中间在目的触发器处汇合,分别标出 setup 窗口和 hold 窗口。

数据到达时间与时钟到达时间的关系 源触发器 Q 端输出 t_co 组合逻辑 LUT / 进位 / 布线 t_comb 目的触发器 D 端采样 t_su / t_h 数据 数据 时钟源 PLL / 全局时钟 时钟网络 时钟树延迟 / skew 时钟 时钟 时钟到达 时间 时钟有效沿 t_su t_h 数据到达 检查关系 setup:数据到达 ≤ 时钟到达 + T − t_su hold:数据到达 ≥ 时钟到达 + t_h setup slack = 时钟到达 + T − t_su − 数据到达 hold slack = 数据到达 − 时钟到达 − t_h

四、用一组示例参数走一遍计算

假设某 FPGA 工程中,时钟周期 T = 10 ns,源触发器 tco = 1.2 ns,组合逻辑延迟 tcomb = 5.5 ns,目的触发器 tsu = 0.3 ns,th = 0.1 ns。为简化,先假设源时钟和目的时钟的网络延迟相同,即时钟到达时间差为 0。

数据到达时间 = t_co + t_comb = 1.2 + 5.5 = 6.7 ns
setup 要求   = T - t_su = 10 - 0.3 = 9.7 ns
setup slack  = 9.7 - 6.7 = 3.0 ns  → 满足

hold 要求    = t_h = 0.1 ns
hold slack   = 6.7 - 0.1 = 6.6 ns  → 满足

这组参数下 setup 和 hold 都有较大余量。但如果把 tcomb 增大到 9.8 ns,setup slack 就变成 9.7 − 9.8 = −0.1 ns,出现 setup 违例。此时 TimeQuest 的 Setup Summary 中该路径会显示负 slack,需要优化组合逻辑或降低时钟频率。反过来,如果 tcomb 小到 0.05 ns,hold slack = 0.05 − 0.1 = −0.05 ns,出现 hold 违例,通常需要插入延迟或调整布局布线。

注意:hold 违例与时钟频率无关,降低频率不能修复 hold。这是初学者最容易混淆的一点。hold 问题只能通过增加数据路径延迟、减少时钟偏斜或使用专用 hold 修复手段来解决。

五、时钟偏斜对 setup/hold 的影响

实际工程中,源时钟和目的时钟到达各自触发器的延迟往往不同,这个差值就是时钟偏斜(skew)。设目的时钟比源时钟晚到 Δt,则:

  • setup 可用时间变为 T + Δt − tsu,正偏斜对 setup 有利。
  • hold 要求变为 Δt + th,正偏斜对 hold 不利。

因此时钟偏斜是一把双刃剑:它放松了 setup,却收紧了 hold。TimeQuest 在分析时会自动从时钟树中提取实际插入延迟,计算源和目的时钟的到达时间差,再代入上述公式。这也是为什么约束时钟时不仅要定义周期,还要保证时钟树被正确识别和传播。

六、在 TimeQuest 中观察这些量

完成时钟约束和综合布局布线后,在 TimeQuest 中执行 Report Timing,选择 Setup 或 Hold 分析,可以看到每条路径的详细报告,包括:Launch Clock、Latch Clock、Data Arrival Time、Clock Arrival Time、Setup/Hold Relationship、Slack。把这些字段与本文的公式一一对应,就能把抽象概念落到具体数值上。

例如报告中 Data Arrival Time = 6.700、Clock Arrival Time = 0.000、Setup Relationship = 9.700、Slack = 3.000,正好对应前面的示例计算。理解这些字段的来源,是后续写 set_max_delay、set_multicycle_path、set_clock_groups 等约束的基础。

总结来说,setup 和 hold 不是两个孤立的数字,而是数据路径与时钟路径在目的触发器处的一次“时间对账”。数据到达时间、时钟到达时间、时钟周期、tsu、th 这五个量决定了 slack 的正负。把这五个量的关系画清楚、算清楚,TimeQuest 的约束与签核就有了稳固的起点。