3. 建立时间与保持时间:时序收敛的核心

各位同学,今天我们来聊聊时序分析里最基础、也最绕不开的两个概念——建立时间(setup time)和保持时间(hold time)。

说实话,我刚入行那会儿,总觉得这俩东西就是背公式。直到有一次,我负责的一个28nm项目,前仿真全过,后仿真也没问题,结果芯片回来就是跑不到目标频率。排查了整整两周,最后发现是一段关键路径的setup slack只剩了2ps。嗯,从那以后,我再也不敢小看这两个“时间”了。

3.1 建立时间检查原理

建立时间,说白了就是数据在时钟有效沿到来之前,必须提前稳定下来的那段时间。

你想想看,寄存器内部是由一堆晶体管组成的。数据要写入,需要先给内部节点充放电。如果数据来得太晚,还没来得及锁存,时钟沿就来了——那结果就是不确定的,可能是0,可能是1,也可能是中间态。

建立时间检查的公式很简单:

Data Arrival Time + Setup Time ≤ Clock Arrival Time + Clock Period

或者换个写法:

Launch Clock + Tclk1 + Tcq + Tcomb + Tsetup ≤ Capture Clock + Tclk2 + Tperiod

这里我解释一下每个参数:

  • Launch Clock:发射时钟沿的时间
  • Tclk1:时钟到发射寄存器的延迟
  • Tcq:寄存器时钟到输出的延迟
  • Tcomb:组合逻辑延迟
  • Tsetup:接收寄存器的建立时间要求
  • Capture Clock:捕获时钟沿的时间
  • Tclk2:时钟到接收寄存器的延迟
  • Tperiod:时钟周期

核心要点:建立时间检查关注的是数据能不能在下一个时钟沿之前准备好。如果slack为负,就是setup violation。

3.2 保持时间检查原理

保持时间呢,刚好反过来。它要求数据在时钟有效沿之后,还要再稳定一段时间。

为什么需要这个?因为时钟沿过去之后,寄存器内部的锁存器还需要一点时间来完成数据的真正锁存。如果数据变化得太快,刚锁进去又被冲掉了——那同样是不确定态。

保持时间检查的公式:

Data Arrival Time ≥ Capture Clock + Thold

展开写就是:

Launch Clock + Tclk1 + Tcq + Tcomb ≥ Capture Clock + Tclk2 + Thold

注意看,这里没有时钟周期Tperiod。为什么?因为保持时间检查发生在同一个时钟沿,跟周期没关系。

我个人习惯:做hold分析时,我会特别关注时钟偏斜(clock skew)。如果时钟偏斜太大,hold violation几乎跑不掉。我曾经在一个项目中,就因为时钟树没做好,hold violation修了整整一周。

3.3 Setup与Hold Violation的成因

搞清楚了原理,我们来看看实际项目中,violation到底是怎么来的。

Setup Violation的常见原因

  1. 组合逻辑路径太长——这是最常见的。比如你用了太多级的逻辑门,或者fanout太大导致驱动能力不足。
  2. 时钟频率太高——说白了就是目标频率定得太激进,留给数据的时间不够。
  3. 时钟偏斜(clock skew)太大——如果捕获时钟比发射时钟晚太多,相当于变相缩短了可用时间。
  4. 片上工艺偏差(OCV)——不同位置的管子速度不一样,最差情况下路径延迟会变大。

Hold Violation的常见原因

  1. 路径太短——你没看错,路径太短也会出问题。比如两个寄存器直接相连,没有组合逻辑,数据跑得太快。
  2. 时钟偏斜反向——如果捕获时钟比发射时钟早,数据还没到就被要求锁存了。
  3. 时钟树不平衡——这是后端工程师的噩梦。我曾经遇到过一个项目,时钟树做了三版才把hold修干净。
  4. 低功耗设计引入的额外延迟——比如电源关断、多电压域切换,这些都会影响时序。

注意:setup和hold有时候是矛盾的。修setup要减少路径延迟,修hold要增加路径延迟。所以实际项目中,我们通常先保证setup收敛,再回头修hold。因为setup影响的是功能能不能跑在目标频率,而hold影响的是功能正不正确。

3.4 知识体系图

下面这张图,是我自己总结的时序检查核心逻辑。你看一遍,应该就能把setup和hold的关系理清楚。

时序检查核心逻辑 时序检查 建立时间 (Setup) 保持时间 (Hold) 组合逻辑太长 时钟频率太高 时钟偏斜大 路径太短 时钟偏斜反向 时钟树不平衡 先修Setup,再修Hold Setup影响能否跑到目标频率 | Hold影响功能是否正确

3.5 实际项目中的避坑指南

最后,分享几个我在项目中踩过的坑:

  • 不要只看最差路径——我曾经只盯着最差的那条路径修,结果修完发现另一条路径又冒出来了。建议用分布图看整体情况。
  • 注意多时钟域交互——异步时钟域之间的路径,setup和hold分析要特别小心。我建议用专门的同步器来处理。
  • 修hold要留余量——因为OCV的影响,hold在芯片实际工作时可能比仿真更差。我个人习惯留10%的余量。
  • 别忽视复位路径——很多人只关心数据路径,但复位信号的时序同样重要。我见过一个项目,复位释放时序没做好,芯片上电就死机。

一个小技巧:在做时序收敛时,我习惯先把所有路径的setup slack和hold slack分别列出来,画成柱状图。这样一眼就能看出哪些路径是瓶颈,哪些路径还有优化空间。比盯着数字看效率高多了。

好了,关于建立时间和保持时间,今天就聊到这里。这两个概念是时序分析的地基,地基打不牢,后面盖再高的楼也白搭。希望各位在实际项目中,能少走一些我当年走过的弯路。

可可精品资料库