第二章 时序路径分析:建立时间与保持时间

各位好,我是老李。做FPGA这行十几年了,今天咱们聊聊时序分析里最核心的东西——建立时间和保持时间。说白了,这两个概念搞不清楚,你的设计跑不跑得稳,心里就没底。

我记得刚入行那会儿,带我的师傅跟我说过一句话:「时序分析不是算数学题,是看你的数据能不能在正确的时间点被正确抓住。」这句话我到现在都记得。

2.1 建立时间与保持时间——寄存器的「脾气」

每个寄存器都有两个关键参数:建立时间(Tsu)保持时间(Th)。你想想看,数据从D端到Q端,不是瞬间完成的。寄存器需要数据在时钟沿到来之前稳定一段时间,这就是建立时间;时钟沿之后还要稳定一段时间,这就是保持时间。

建立时间(Tsu):时钟有效沿到来之前,数据必须保持稳定的最短时间。

保持时间(Th):时钟有效沿到来之后,数据必须保持稳定的最短时间。

我在项目中遇到过这样一个坑:某次做高速ADC接口,采样率跑到200MHz。仿真一切正常,上板子就偶尔丢数据。查了三天,最后发现是保持时间违例。数据在时钟沿之后抖动了一下,寄存器没抓住正确的值。嗯,从那以后我养成了习惯——任何高速接口,先看保持时间。

注意:建立时间和保持时间是由寄存器本身的物理特性决定的,不是你能改的。你只能通过调整逻辑和布线来满足它们。

2.2 时序路径的组成——从源到目的

一条典型的时序路径,说白了就是三个部分:源寄存器 → 组合逻辑 → 目的寄存器。我习惯叫它「发射-传输-捕获」路径。

源寄存器 (发射端) 组合逻辑 (传输路径) 目的寄存器 (捕获端) 时钟网络(含时钟偏斜) 数据路径 数据路径

这张图我画了很多次了。你看,数据从源寄存器的Q端出发,经过组合逻辑的延迟,最终到达目的寄存器的D端。时钟信号同时驱动两个寄存器,但到达时间可能不一样——这就是后面要说的时钟偏斜。

我个人的习惯是,在写RTL之前先画这种路径图。尤其是复杂设计,画清楚了再写代码,能省一半的调试时间。

2.3 建立时间分析——数据要「早到」

建立时间分析,说白了就是检查数据能不能在时钟沿之前稳定下来。公式很简单:

数据到达时间 = T_clk1 + T_co + T_logic
数据要求时间 = T_clk2 + T_period - Tsu

建立时间余量 = 数据要求时间 - 数据到达时间
             = (T_clk2 + T_period - Tsu) - (T_clk1 + T_co + T_logic)

其中:

  • T_clk1:时钟到达源寄存器的延迟
  • T_co:寄存器时钟到输出的延迟
  • T_logic:组合逻辑的传播延迟
  • T_clk2:时钟到达目的寄存器的延迟
  • T_period:时钟周期
  • Tsu:目的寄存器的建立时间要求

余量必须大于0,否则就是建立时间违例。我曾经遇到一个设计,组合逻辑路径太长,导致建立时间余量只有0.02ns。虽然仿真能过,但温度一高就出问题。后来我加了一级流水线,问题就解决了。

小技巧:如果建立时间违例,优先考虑:1) 插入流水线;2) 优化组合逻辑;3) 降低时钟频率(最后的选择)。

2.4 保持时间分析——数据不能「早变」

保持时间分析,很多人容易忽略。它检查的是数据在时钟沿之后能不能保持稳定。公式:

数据保持时间 = T_clk1 + T_co + T_logic
数据要求保持时间 = T_clk2 + Th

保持时间余量 = 数据保持时间 - 数据要求保持时间
             = (T_clk1 + T_co + T_logic) - (T_clk2 + Th)

注意看,保持时间分析跟时钟周期没关系!它只跟路径延迟和时钟偏斜有关。这就是为什么你降频也解决不了保持时间违例。

我记得有一次,一个同事跟我说:「我降频了,保持时间违例怎么还在?」我笑了笑说:「保持时间不看频率,看的是路径延迟差。」他恍然大悟。

重要提醒:保持时间违例通常只能通过修改逻辑或约束来解决。加流水线、降频率都没用。我见过最坑的情况是,保持时间违例导致芯片在不同批次之间表现不一致——有的能跑,有的不能。

2.5 时钟偏斜——时钟到达的时间差

时钟偏斜(Clock Skew),说白了就是同一个时钟信号到达不同寄存器的时间差。公式:

T_skew = T_clk2 - T_clk1

时钟偏斜对建立时间和保持时间的影响是相反的:

偏斜方向 对建立时间的影响 对保持时间的影响
正偏斜(T_clk2 > T_clk1) 有利(数据有更多时间到达) 不利(数据需要保持更久)
负偏斜(T_clk2 < T_clk1) 不利(数据到达时间变短) 有利(数据保持要求降低)

你想想看,如果时钟先到目的寄存器,后到源寄存器(正偏斜),那数据就有更多时间从源跑到目的——建立时间变好了。但反过来,数据在时钟沿之后需要保持更久——保持时间变差了。

我在做DDR3接口的时候,遇到过时钟偏斜导致的问题。PCB走线长度差了几毫米,结果保持时间就违例了。后来在FPGA内部做了时钟相位调整才解决。

核心要点:时钟偏斜不是越小越好,而是要「可控」。好的设计会利用正偏斜来改善建立时间,同时确保保持时间不违例。

2.6 实战中的常见问题

说了这么多理论,我总结几个实际项目中容易踩的坑:

  1. 跨时钟域路径没约束——我曾经有个设计,两个异步时钟域之间的路径没做约束,结果STA报了几百条违例。后来加了同步器才解决。
  2. 组合逻辑太深——一个always块里写了十几级组合逻辑,建立时间肯定过不了。我建议组合逻辑不超过5级。
  3. 忽略时钟偏斜——尤其是全局时钟网络,偏斜通常很小,但局部时钟(比如门控时钟)偏斜可能很大。
  4. 只看建立时间不看保持时间——保持时间违例在低速设计中不常见,但高速设计(>200MHz)必须检查。

嗯,今天就聊到这儿。这些概念是时序分析的基础,搞清楚了,后面的内容就好理解了。


公众号:蓝海资料掘金营,微信deep3321