4. 保持时间违例分析
保持时间违例,说实话,是时序分析里最让人头疼的问题之一。建立时间违例你还能通过降频、加流水线来补救,但保持时间违例一旦出现,基本就是动电路结构了。我刚开始做后端时,就被一个保持时间违例折腾了两周,最后发现是时钟偏斜搞的鬼。
4.1 保持时间公式推导
先来推公式。保持时间检查,说白了就是看数据能不能稳定地待在触发器里。
对于发射触发器(launch flop)和捕获触发器(capture flop),保持时间要满足:
数据到达时间 > 数据要求时间
数据到达时间:
Data_arrival = T_clk_launch + T_ck2q + T_data_path
数据要求时间:
Data_required = T_clk_capture + T_hold
保持时间余量:
Hold_slack = Data_arrival - Data_required
= (T_clk_launch + T_ck2q + T_data_path) - (T_clk_capture + T_hold)
这里有个关键点——时钟偏斜。我们把时钟偏斜定义为:
T_skew = T_clk_capture - T_clk_launch
代入公式:
Hold_slack = T_ck2q + T_data_path - T_hold - T_skew
核心结论:保持时间违例和时钟周期无关!它只取决于数据路径延迟、时钟偏斜和触发器的保持时间要求。
嗯,这里要注意。建立时间检查看的是最慢路径,保持时间检查看的是最快路径。为什么?因为数据到达得越早,越容易破坏上一个数据的保持时间要求。
4.2 违例原因分析
我在项目中遇到过三种最常见的保持时间违例原因,一个一个说。
4.2.1 时钟偏斜
时钟偏斜对保持时间的影响,说白了就是「成也萧何,败也萧何」。
如果捕获时钟比发射时钟晚到(正偏斜),保持时间余量会变小:
Hold_slack = T_ck2q + T_data_path - T_hold - T_skew
你看,T_skew 越大,余量越小。我曾经在一个项目中,时钟树综合没做好,导致两个相邻触发器之间的时钟偏斜达到了 200ps。结果保持时间违例一片一片的,修得我头皮发麻。
避坑指南:我曾经遇到过一种情况——时钟偏斜看起来不大,但数据路径几乎为零(两个触发器背靠背放置),结果保持时间还是违例了。所以,时钟偏斜要结合数据路径一起看。
4.2.2 数据路径过短
这是保持时间违例最常见的原因。数据路径太短,数据嗖的一下就过去了,捕获触发器还没准备好。
什么情况下数据路径会过短?
- 两个触发器直接相连——中间没有任何组合逻辑
- 使用了低驱动强度的单元——但路径长度本身很短
- 扫描链上的保持时间违例——扫描链通常路径很短
我记得有一次做低功耗设计,用了很多低阈值电压的单元。结果保持时间违例报表一出来,好家伙,几百条。原因就是低阈值单元速度太快,数据路径延迟太小。
个人经验:我建议在综合阶段就检查保持时间。虽然保持时间通常在布局布线后修,但综合阶段可以提前发现那些「数据路径过短」的极端情况,提前插入缓冲器。
4.2.3 工艺角影响
工艺角对保持时间的影响,和建立时间正好相反。
| 工艺角 | 对建立时间的影响 | 对保持时间的影响 |
|---|---|---|
| 慢工艺角(SS) | 最差(路径延迟最大) | 最好(路径延迟最大) |
| 快工艺角(FF) | 最好(路径延迟最小) | 最差(路径延迟最小) |
| 典型工艺角(TT) | 中等 | 中等 |
所以,保持时间分析要在最快工艺角下做。你想想看,芯片在低温、高电压下,晶体管开关速度最快,数据路径延迟最小,这时候保持时间最容易违例。
我有个血的教训。一次流片回来,芯片在常温下跑得好好的,一到低温就出问题。查了半天,就是保持时间在低温工艺角下违例了。从那以后,我每次做保持时间分析,都会把快工艺角作为重点检查对象。
关键点:保持时间违例的修复,通常是在数据路径上插入缓冲器(buffer)或延迟单元(delay cell)。但要注意,插入缓冲器会增加功耗和面积,而且可能影响建立时间。所以,这是一个权衡的过程。
4.3 保持时间违例的典型场景
我总结了几种常见的保持时间违例场景,你在实际项目中大概率会遇到:
- 扫描链保持时间违例——扫描链路径短,而且通常跨模块,时钟偏斜大
- 时钟门控单元的保持时间违例——时钟门控使能信号路径短
- 异步复位同步器的保持时间违例——复位信号和时钟之间的时序关系复杂
- 多bit总线之间的保持时间违例——不同bit的路径延迟差异大
嗯,这里要特别说一下扫描链。我做过一个项目,扫描链上有上千个触发器,保持时间违例占了三分之一。最后怎么修的?在扫描链上逐级插入延迟单元,每修一条就重新跑一遍STA,折腾了整整一周。
实用技巧:我建议在布局布线阶段,对保持时间违例的路径设置较高的权重。这样布线工具会自动在数据路径上插入缓冲器,减少后续的手动修复工作。
4.4 保持时间违例的修复策略
修复保持时间违例,说白了就是让数据走慢一点。常用的方法有:
- 插入缓冲器——在数据路径上串入缓冲器,增加延迟
- 使用延迟单元——专门的延迟单元,延迟大、面积小
- 调整时钟偏斜——让捕获时钟提前到达(负偏斜),但这会影响建立时间
- 优化工艺角——在快工艺角下修复,确保在所有工艺角下都满足
我个人习惯是优先使用延迟单元。为什么?因为延迟单元的延迟大,插入一个就能解决很多问题,而且对功耗的影响比缓冲器小。
但要注意,延迟单元也有坑。我曾经用过一种延迟单元,在慢工艺角下延迟太大,反而导致了建立时间违例。所以,修复保持时间违例时,一定要同时检查建立时间。
重要提醒:修复保持时间违例后,一定要重新做STA验证。而且要在所有工艺角、所有温度、所有电压下都验证一遍。不要只盯着快工艺角看。
保持时间违例的分析,说白了就是一场和时间的赛跑。数据不能跑得太快,也不能跑得太慢。我做了这么多年芯片设计,最大的体会就是:时序分析没有捷径,只有踏踏实实地理解每一个公式、每一个工艺角的影响,才能在项目中出现问题时快速定位、快速修复。