4. 保持时间冲突分析
保持时间,英文叫 hold time。很多新手觉得它比建立时间简单,其实不然。
我个人习惯把保持时间叫做「数据的刹车距离」。你想想看,时钟沿来了,数据不能马上变,得稳稳地保持住一段时间。这个时间就是保持时间。
4.1 保持时间公式详解
先看标准公式:
T_hold + T_skew ≤ T_co + T_logic
拆开来看:
- T_hold:触发器的保持时间要求。这是工艺库给的,你改不了。
- T_skew:时钟偏斜。这里要注意,保持时间公式里的 skew 和建立时间公式里的 skew,符号是反的。
- T_co:时钟到输出的延迟。数据从时钟沿到 Q 端输出,需要时间。
- T_logic:组合逻辑延迟。数据路径上的门延迟。
说白了,这个公式在检查什么?它在检查:上一级的数据,能不能在下一级需要保持的时候,还没被新数据冲掉。
核心要点:保持时间违例,本质上是「数据跑得太快了」。和建立时间违例正好相反。
4.2 数据保持时间要求
每个触发器都有自己固定的保持时间要求。比如某个工艺库的 DFF,保持时间可能是 0.2ns。这意味着时钟沿之后,数据输入必须稳定至少 0.2ns。
我在项目中遇到过一件事。有个模块综合后时序报告全是绿的,但后仿就是出错。查了半天,发现是某个库单元的保持时间标注错了。嗯,这种坑很隐蔽。
数据保持时间要求,主要取决于:
- 工艺节点:越先进的工艺,保持时间通常越小,但也不
- 触发器结构:主从触发器和边沿触发器的保持时间不同
- 工作条件:PVT(工艺、电压、温度)会影响保持时间
我的经验:做保持时间分析时,一定要用最差条件(slow corner)。因为保持时间在 slow corner 下要求最严格。
4.3 时钟偏斜对保持时间的影响
时钟偏斜对保持时间的影响,和建立时间正好相反。
你想想看:
- 建立时间:希望时钟偏斜是正的(目的时钟晚到),这样数据有更多时间准备
- 保持时间:希望时钟偏斜是负的(目的时钟早到),这样数据能更快被采到
但问题是,时钟偏斜你控制不了那么精确。我曾经在一个项目中,因为时钟树做得太「平衡」,导致某些路径的保持时间反而出了问题。
为什么会这样?因为时钟偏斜如果太大,目的时钟比源时钟晚到太多,源数据可能已经变了,但目的时钟还没来。等目的时钟来了,采到的已经是新数据了。
避坑指南:我曾经吃过一次亏。在时钟树综合时,为了追求零偏斜,插了很多 buffer。结果保持时间违例一大堆。后来我学乖了,保持时间分析时,要检查最坏情况的时钟偏斜。
4.4 保持时间违例的典型场景
保持时间违例,说白了就是数据路径太短了。我总结了几种常见场景:
| 场景 | 原因 | 解决方法 |
|---|---|---|
| 短路径直连 | 两个触发器之间几乎没有组合逻辑 | 插入 buffer 或延迟单元 |
| 时钟偏斜过大 | 目的时钟比源时钟晚太多 | 优化时钟树,减少偏斜 |
| 扫描链路径 | 测试模式下,数据路径变短 | 扫描链插入延迟单元 |
| 异步时钟域 | 跨时钟域路径,保持时间难满足 | 使用双级同步器或 FIFO |
我印象最深的是扫描链的保持时间违例。有一次做 DFT,扫描链综合完后,保持时间违例几百条。原因是扫描模式下,数据路径被 bypass 了,组合逻辑变少,数据跑得太快。
解决方法是:在扫描链上插入专门的延迟单元。嗯,这个操作叫 scan hold fixing。
重要提醒:保持时间违例不能通过降低频率来解决。因为保持时间检查的是时钟沿之后的数据稳定性,和时钟周期无关。你频率再低,数据该冲还是会冲。
最后说一个我自己的习惯。做保持时间分析时,我会同时检查 setup 和 hold。因为有时候为了修 hold 插了 buffer,反而把 setup 搞坏了。这是个 trade-off,需要平衡。
总结一下:保持时间分析,关键是理解「数据不能跑太快」这个本质。修 hold 违例,就是给数据路径加延迟。但别忘了,加延迟可能会影响 setup。这是个平衡的艺术。