第三章:建立时间与保持时间

各位同学,今天我们来聊聊时序分析里最核心的两个概念——建立时间和保持时间。说实话,我见过不少工程师,写RTL代码一把好手,但一提到setup和hold就含糊其辞。这不行,因为时序违例的后果,轻则芯片降频,重则直接报废。

3.1 建立时间(Setup Time)定义与约束

建立时间,说白了就是数据在时钟有效沿到来之前,必须提前稳定下来的最短时间。为什么要有这个要求?因为寄存器内部是个模拟电路,数据需要时间来完成电平转换和锁存。你想想看,如果数据在时钟沿来的前一纳秒还在跳变,那寄存器采到的值到底是0还是1?谁也不知道。

建立时间的本质:数据必须在时钟沿之前稳定,且稳定时间 ≥ 建立时间。

我在项目中遇到过这样一个案例:一个高速接口的设计,综合后时序报告显示setup slack为负。当时年轻,觉得差个几十皮秒应该没事。结果呢?芯片回来,接口在高温低压下频繁出错。从那以后,我对setup time再也不敢马虎。

建立时间的约束公式很简单:

数据到达时间 + 建立时间 ≤ 时钟到达时间 + 时钟周期

用更直观的方式表达:

T_data + T_setup ≤ T_clk + T_period

其中:

  • T_data:数据从起点到终点寄存器的总延迟
  • T_setup:终点寄存器的建立时间要求
  • T_clk:时钟从起点到终点寄存器的延迟(时钟偏斜)
  • T_period:时钟周期

嗯,这里要注意,时钟偏斜(clock skew)有时候能帮我们满足setup,有时候却会害了我们。如果时钟到达终点寄存器比起点晚,那相当于给了数据更多时间——这是好事。反过来,如果时钟先到终点,那就麻烦了。

3.2 保持时间(Hold Time)定义与约束

保持时间,则是数据在时钟有效沿之后,必须保持稳定的最短时间。为什么需要这个?因为时钟沿过去之后,寄存器内部的锁存器还需要一点时间来完成数据捕获。如果数据在时钟沿后立刻变化,那捕获到的值可能还是上一拍的数据。

重要提醒:保持时间违例比建立时间违例更难调试。建立时间违例通常可以通过降频来临时解决,但保持时间违例是功能性的,降频也没用!

我曾经接手过一个项目,前同事留下的代码,综合后hold slack全是负的。我问他怎么回事,他说「没事,跑慢点就行」。我当时就笑了——保持时间违例跟频率无关,你跑1Hz它照样出错。最后我们不得不重新插入大量buffer来修复,芯片面积增加了15%。

保持时间的约束公式:

数据到达时间 ≥ 时钟到达时间 + 保持时间

即:

T_data ≥ T_clk + T_hold

这里T_hold是终点寄存器的保持时间要求。注意,这个公式里没有时钟周期——所以我说保持时间跟频率无关,就是这个道理。

3.3 建立时间与保持时间的矛盾关系

有意思的是,setup和hold有时候是矛盾的。你想满足setup,希望数据路径延迟小一点;但想满足hold,又希望数据路径延迟大一点。这怎么办?

我个人习惯的做法是:先保证setup,再检查hold。因为setup决定了芯片能跑多快,而hold可以通过插入延迟来修复。但要注意,插入延迟不能太多,否则又会破坏setup。

时序约束 数据路径延迟要求 修复方法
建立时间 延迟尽量小 优化逻辑深度、使用高速单元
保持时间 延迟尽量大 插入buffer、增加路径延迟

3.4 时序违例的后果

时序违例的后果,我按严重程度排个序:

  1. 功能错误:寄存器采到错误的数据,整个逻辑功能崩溃。这是最严重的。
  2. 亚稳态:数据在时钟沿附近变化,寄存器输出进入亚稳态,可能持续振荡或输出不确定值。
  3. 性能下降:setup违例可以通过降频来规避,但代价是芯片跑不到目标频率。
  4. 良率降低:有些芯片在典型条件下能工作,但在极端温度或电压下就失效,导致良率下降。

避坑指南:我曾经遇到过一个设计,综合后setup slack只有10ps。我觉得「差不多」,就送去流片了。结果回来一测,只有60%的芯片能通过测试。那40%的芯片,在高温下全部失效。教训就是:setup slack至少要留出10%的时钟周期余量,别卡着极限做设计。

另外,保持时间违例还有个隐蔽的危害——它会导致数据串扰。什么意思呢?就是上一拍的数据还没稳定,下一拍的数据就来了,两个数据在寄存器输入端打架。这种问题在仿真里很难发现,因为仿真模型通常不考虑这种微小的时序重叠。

3.5 实际项目中的检查方法

在STA工具中,我们通常这样检查:

# 建立时间检查
setup_slack = T_clk + T_period - T_data - T_setup

# 保持时间检查
hold_slack = T_data - T_clk - T_hold

slack为正,说明满足约束;slack为负,说明违例。我个人习惯在项目中设置一个「安全阈值」——setup slack至少留50ps,hold slack至少留30ps。这样即使工艺波动,芯片也能正常工作。

好了,这一章的内容就到这里。建立时间和保持时间是时序分析的基础,也是面试中必问的知识点。下一章我们会讲时钟偏斜和时钟抖动,这两个概念跟setup/hold关系密切,到时候再深入聊。