第2章 建立时间与保持时间基本概念

做时序分析绕不开两个最基础的概念——建立时间(Setup Time)和保持时间(Hold Time)。说白了,它们就是寄存器对数据信号提出的“入场券”要求。我在刚接触数字电路时总觉得这两个概念太理论化,直到第一次调试FPGA设计遇到时序违例,才真正明白它们有多重要。

咱们先抛开公式,从一个最直观的角度理解:寄存器靠时钟沿来“拍快照”。数据信号必须在时钟沿前稳定一段时间,时钟沿后也要稳定一段时间,这样寄存器才能正确地把数据存进去。前一段叫建立时间,后一段叫保持时间。你想想看,如果数据在时钟沿附近还在跳变,寄存器读到什么?有可能是上一次的值,也可能是新值,甚至是不确定的亚稳态。嗯,这就是所有时序问题的根源。

核心定义
建立时间:数据在时钟有效沿到来之前必须保持稳定的最小时间窗口。
保持时间:数据在时钟有效沿到达之后必须保持稳定的最小时间窗口。

为什么要有这两个时间窗口?

寄存器内部电路其实是一串比较器、锁存器和驱动级。数据进来后需要时间让内部节点充放电、翻转。如果时钟沿来临时数据还没稳定,或者刚过时钟沿数据就开始乱变,内部状态就会进入“薛定谔”状态——既不是0也不是1,或者两者来回振荡。这就是亚稳态。我在一个DDR接口项目中就遇到过这种问题,高速信号在接收端经常出现毛刺,最后发现是保持时间不够,数据在时钟沿后没多久就被下一个数据冲掉了。

所以,建立时间和保持时间就是寄存器给予的安全裕量。它们并不需要你手动“设置”,而是芯片工艺本身决定的参数,在Datasheet里能找到。你要做的是确保你的设计满足这些参数。

时序路径的基本模型

要理解建立时间和保持时间的计算,先得清楚一条时序路径上发生了什么。看这张图:

建立时间与保持时间示意图 建立时间与保持时间——数据在时钟沿附近的稳定要求 CLK 时钟有效沿 DATA 数据进入窗口 数据离开窗口 建立时间 (Tsu) 保持时间 (Th) 说明 数据必须在时钟沿前 Tsu 时间内稳定,并在时钟沿后 Th 时间内保持稳定。 如果数据变化点侵入蓝色窗口(建立时间)或绿色窗口(保持时间),就会发生时序违例。

路径模型中有两个关键角色:发起寄存器(Launch Flip‑Flop)和捕获寄存器(Capture Flip‑Flop)。数据从发起寄存器输出,经过组合逻辑和布线,最终到达捕获寄存器的数据输入引脚。捕获寄存器在下一个时钟沿采样。这中间的时间关系就是计算的核心。

  • 发起沿(Launch Edge):启动数据发送的时钟沿。
  • 捕获沿(Capture Edge):后续的时钟沿,用于采样数据。
  • 时钟周期(Clock Period, Tclk):两个沿之间的时间差,通常就是一个时钟周期。
  • 数据路径延迟(Tdata):从发起寄存器输出到捕获寄存器输入的全部延迟,包括组合逻辑、走线等。

建立时间约束公式

建立时间保证数据在捕获沿之前已经到达并稳定。它的基本不等式是:

Tclk + Tskew + Thold_setup ? 等一下,咱们先按标准走。
实际上,建立时间检查要求:数据到达时间 ≤ 捕获时间 − 建立时间需求。
数据到达时间 = Tclk_launch + Tco + Tdata
捕获时间 = Tclk_capture + Tclk_period
满足要求:(Tclk_launch + Tco + Tdata) ≤ (Tclk_capture + Tclk_period - Tsu)
其中 Tco 是寄存器时钟到输出的延迟,Tsu 是寄存器要求的建立时间。

如果时钟有偏差(Clock Skew,即两个寄存器接收到的时钟沿有时间差),公式里还要加上 Tskew 的修正。我个人习惯把公式写成:Tdata ≤ Tclk_period − Tsu + Tskew − Tco。这样看起来更直白——数据路径能允许的最大延迟就是时钟周期减去建立时间再减去其他开销。如果Tdata太大,就占用建立时间裕量,甚至导致违例。

建立时间与保持时间核心参数一览
参数含义通常由谁提供
Tsu寄存器要求的建立时间芯片Datasheet
Th寄存器要求的保持时间芯片Datasheet
Tco时钟到输出延迟芯片Datasheet
Tdata数据路径总延迟(组合逻辑+布线)设计者通过STA工具得到
Tskew时钟到达两个寄存器的偏差时钟树分析
Tclk_period时钟周期用户约束

保持时间约束公式

保持时间保证数据在捕获沿之后不会立刻变化。它的基本不等式是:

数据保持时间要求:数据必须在捕获沿之后继续稳定至少 Th 长的时间。
数据等待时间 = Tclk_launch + Tco + Tdata
下一个数据到达时间 = Tclk_capture + Tco_next + Tdata_next
满足要求:(Tclk_launch + Tco + Tdata) ≥ (Tclk_capture + Th)
简化后:Tdata ≥ Th − Tskew(不考虑复杂情况)。

你可能已经注意到了,保持时间约束和时钟周期本身没有直接关系——它只关心数据变化的相对顺序。我曾经在一个低速设计中以为保持时间肯定没问题,结果因为时钟树做得太“匀”,导致Tskew很小,而数据路径却因为多余的缓冲器延迟不够大,反而触发了保持时间违例。嗯,所以保持时间检查有时比建立时间更隐蔽。

实战小技巧:在FPGA中,如果遇到保持时间违例,可以尝试在路径中插入一些延迟单元(比如LUT配置成反相器链),或者增加布线路径长度。但要注意,增加延迟会同时降低建立时间裕量,所以要在两者之间平衡。
重要提醒:保持时间违例不能通过降低频率来解决!因为保持时间与时钟周期无关。如果你发现设计无论如何都跑不上高频,检查一下是不是保持时间在捣乱。我曾经吃过这个亏,花了整整两周才意识到是保持时间不足,而不是频率太高。

建立时间与保持时间的关系图解

用一个对比表格来收个尾,帮你快速分清这两个参数:

特性建立时间 (Setup)保持时间 (Hold)
检查对象数据是否早到数据是否晚走
与频率关系直接相关,频率越高裕量越小基本无关,只与路径延迟有关
违反后果寄存器采样到错误值或亚稳态寄存器采样到错误值或亚稳态
常见修复手段降低频率、优化组合逻辑、增加流水线增加路径延迟、调整时钟树偏斜
在STA中优先级通常先检查,因为更常见同样重要,但容易被忽略

建立时间和保持时间就像是电路的两个“呼吸阀门”——一个管吸气时间,一个管呼气时间。任何一边出问题,电路都没法正常工作。理解了这两个概念,你就能看懂时序报告里的关键路径分析了。下节咱们会真正搭建一个完整的RMII时序计算模型,把这些概念用到具体的设计中去。