第2章:静态时序分析(STA)基础:建立时间与保持时间的概念,时序路径的分类
各位好,我是老陈。今天咱们聊聊STA的基础。
静态时序分析,说白了就是检查你的芯片能不能跑在目标频率上。我刚开始做设计时总觉得这步可有可无,直到有一次流片回来芯片死活上不了高频……嗯,从那以后我再也不敢跳过STA了。
2.1 建立时间与保持时间:两个绕不开的概念
先问大家一个问题:为什么寄存器会采错数据?
原因很简单——数据到达的时间不对。要么来得太晚,要么走得太平。
2.1.1 建立时间(Setup Time)
建立时间,就是时钟有效沿到来之前,数据必须提前稳定下来的最短时间。说白了,数据得“提前站好队”,等时钟来点名。
核心公式:
数据到达时间 + 建立时间 ≤ 时钟周期 + 时钟偏斜
我在项目中遇到过这样一个案例:一个高速接口的建立时间违例,查了半天发现是时钟树不平衡导致的。你想想看,时钟偏斜大了,数据路径又长,setup自然就崩了。
2.1.2 保持时间(Hold Time)
保持时间,是时钟有效沿之后,数据必须保持稳定的最短时间。嗯,这里要注意——保持时间违例比建立时间违例更难修,因为它跟时钟频率无关。
避坑指南:
我曾经在28nm项目上遇到一个保持时间违例,修了整整两周。原因是综合时没加足够的hold margin,结果后端修起来特别痛苦。记住:保持时间违例,加buffer就能修,但加多了会破坏setup。
2.2 时序路径的分类:四种路径,四种脾气
STA把时序路径分成四类。我个人习惯把它们记成“两内两外”——内部两条,外部两条。
| 路径类型 | 起点 | 终点 | 典型场景 |
|---|---|---|---|
| 输入到寄存器 | 输入端口 | 寄存器D端 | 片外信号进入片内 |
| 寄存器到寄存器 | 寄存器CK端 | 寄存器D端 | 核心逻辑路径 |
| 寄存器到输出 | 寄存器CK端 | 输出端口 | 片内信号输出到片外 |
| 输入到输出 | 输入端口 | 输出端口 | 纯组合逻辑路径 |
2.2.1 寄存器到寄存器路径(Reg2Reg)
这是最核心的路径,也是我们花时间最多的路径。说白了,就是两个寄存器之间的组合逻辑延迟。
// 典型的Reg2Reg路径
always @(posedge clk) begin
reg2 <= reg1 + data_in; // 组合逻辑在中间
end
我建议新手先盯死Reg2Reg路径。为什么?因为这类路径占了芯片90%以上的时序问题。修好了它,其他路径基本就顺了。
2.2.2 输入到寄存器路径(Input2Reg)
这类路径受片外延迟影响很大。我记得有个项目,客户给的input delay设得太紧,结果我们后端怎么修都修不出来。后来跟客户沟通,发现是他们的约束写错了。
小技巧:
处理Input2Reg路径时,我习惯先跟前端确认input delay的合理性。别闷头修,有时候问题不在你这边。
2.2.3 寄存器到输出路径(Reg2Output)
输出路径的难点在于——你不仅要管片内,还要管片外。output delay设得太大,内部路径就紧;设得太小,外部又可能不满足。
2.2.4 输入到输出路径(Input2Output)
这类路径最特殊——它没有寄存器,纯组合逻辑。说实话,我在实际项目中很少遇到纯组合的输入输出路径,因为现在芯片设计基本都带寄存器了。但如果你遇到了,记住:它只受组合逻辑延迟影响,跟时钟频率无关。
2.3 知识体系总览
下面这张图,是我自己总结的STA基础框架。你把它记熟了,后面学起来会轻松很多。
2.4 实际项目中的经验总结
说了这么多理论,最后分享几点实战经验:
- 先看setup,再看hold——我习惯先跑一遍setup分析,把大的违例修掉,再回头修hold。因为hold违例通常加buffer就能解决,但加多了会影响setup。
- 关注最差路径——别被几百条违例吓到。通常最差的10条路径代表了90%的问题。先修它们。
- 时钟偏斜是把双刃剑——正偏斜对setup有利,对hold有害。负偏斜则相反。我建议在时钟树综合阶段就控制好偏斜,别等到后端再修。
个人习惯:
我每次跑完STA,都会先看一份“时序违例汇总报告”。重点关注那些slack小于-100ps的路径。如果发现某条路径slack特别差,我会先检查是不是约束写错了——这种事我遇到过不止一次。
好了,STA基础就聊到这儿。记住:建立时间和保持时间是STA的基石,四种路径分类是分析问题的框架。把这些搞清楚了,后面学起来会轻松很多。