数字电路时序基础:建立时间、保持时间、时钟偏斜

各位好,今天我们来聊几个最基础但也最容易让人栽跟头的概念——建立时间、保持时间和时钟偏斜。你别看它们名字简单,我敢说,80%的时序问题都跟这三个兄弟有关。

我之前带过几个新人,一上来就急着调T_LPX和T_TA,结果调了半天发现根本问题是建立时间没满足。所以咱先别急,把底子打扎实了再说。

建立时间(Tsu)与保持时间(Th)

先说说建立时间。说白了,就是时钟有效沿到来之前,数据信号必须提前稳定下来的那段时间。为什么要有这个要求?你想想看,寄存器内部是由一堆晶体管构成的,输入信号需要时间去"建立"内部的状态。如果数据来得太晚,寄存器还没反应过来,时钟沿就到了——那采到的数据就可能是错的。

保持时间就更简单了:时钟沿过去之后,数据还得再稳定一段时间,不能马上变。因为在时钟触发后的很短时间内,寄存器内部还在"消化"刚采到的值,外部数据一变,内部就乱套了。

我在项目中碰到过这样一个案例:一个接口的保持时间总是不满足,查了半天发现是时钟树综合时给寄存器的时钟偏斜做得太大。这就是一个典型的例子,两个概念是互相影响的。

参数 定义 检查时刻
建立时间 (Tsu) 时钟沿到来前数据必须稳定的最小时间 时钟沿之前
保持时间 (Th) 时钟沿到来后数据必须稳定的最小时间 时钟沿之后

从公式看时序裕量

判断一条路径是不是走得通,实际上就是在算两个数:建立时间裕量和保持时间裕量。公式不复杂,但很多人容易记混。

  • 建立时间检查公式:
    Tclk + Tskew - Tcq - Tcomb - Tsu >= 0
    或者写成:Tclk + Tskew >= Tcq + Tcomb + Tsu
  • 保持时间检查公式:
    Tcq + Tcomb - Th - Tskew >= 0
    也就是:Tcq + Tcomb >= Th + Tskew

你看,两个公式里都出现了Tskew(时钟偏斜),但它的作用方向正好相反。在建立时间检查里,Tskew是有利的;在保持时间检查里,Tskew是有害的。嗯,这里要注意,同一个参数,在两条检查路径里唱的是反调。

经验之谈:我们做时序收敛时,有时候会特意在时钟路径上加一点缓冲,让Tskew变大,从而改善建立时间。但你加的时候一定要同时算算保持时间还能不能过。我之前就见过一个项目,建立时间好了,保持时间却炸了——结果是ECO改了一整版。

时钟偏斜(Clock Skew)

时钟偏斜啥意思?简单说,就是同一个时钟信号到达不同寄存器的时间不一样。为什么会不一样?因为时钟树不是完美的。每个时钟路径上的缓冲器数量和走线长度都有细微差异,这些差异累积起来就造成了偏斜。

小技巧:在place之后先看一下clock skew的粗略估计。如果发现某条路径的skew值超出预期,最好先调整一下clock tree的约束,其他地方优化再多也白搭。

有了偏斜之后,时序分析就变成了源寄存器和目标寄存器之间的比较。源寄存器的时钟晚到一点,数据就晚发出一点,但目标寄存器的时钟也偏了,所以需要重新对齐。

// 一个简单的触发器建模,展示Tsu和Th
module dff (
    input  clk,
    input  d,
    output q
);
    reg q_reg;
    // 这里的时间参数在实际STA中由库文件定义
    // setup time: 0.2ns
    // hold time:  0.1ns
    // clk-to-q delay: 0.3ns
    always @(posedge clk) begin
        q_reg <= d;  // 数据必须满足Tsu和Th要求
    end
    assign q = q_reg;
endmodule

综合来看三者的关系

为了让你更直观地理解这三个概念是怎么串在一起的,我画了一张图。它展示了从源寄存器发出数据,经过组合逻辑,再到目标寄存器捕获的完整过程。

时序路径与Tsu / Th / Tskew 关系图 源寄存器 组合逻辑 延时: Tcomb 目标寄存器 时钟源 时钟偏斜 Tskew1 时钟偏斜 Tskew2 保持时间检查点 建立时间检查点 注:Tskew1与Tskew2的差值会影响建立时间的Tclk有效长度,同时影响保持时间的检查窗口。 实际STA中会用最差情况的Tskew,即Tskew2 - Tskew1的值。

图中左侧是时钟源,分成两条路径分别往源寄存器和目标寄存器送时钟。如果两条路径的延时不一样,时钟沿到达的时间就差了一个Tskew。这个差值,就是你算建立和保持裕量时必须考虑进去的。

我的一点建议

做时序分析时,有一个习惯我一直在用:拿到一个违例路径,先不看具体的delay值是多少,而是先把Tskew的值标出来。能标多少标多少,这样你一眼就能看出违例到底是因为路径太长,还是因为时钟偏斜太大,还是因为库里的setup/hold本身就很紧。这个判断很重要——因为修复路径太长的做法是插缓冲器、修时钟偏斜的做法是改时钟树约束,两个方向的方案差别非常大。

注意:如果一条路径同时出现建立时间和保持时间违例,不要慌。这种情况往往不是因为"路径太长"导致的,而大概率是时钟偏斜和组合逻辑的延时分布不合理造成的。我曾经接手过一个ECO,就是两条路径的Tskew刚好把建立和保持裕量都吃光了。解决思路不是一味加缓冲或删缓冲,而是重新平衡时钟树。

小结

建立时间、保持时间、时钟偏斜这三板斧,是数字时序分析的基石。弄清楚它们的关系,后面所有的调试工作才有方向。简单总结几点:

  • 建立时间——数据必须先到,不能迟到。
  • 保持时间——数据到了之后不能马上跑,得留一会儿。
  • 时钟偏斜——加在建立时间上有好处,加在保持时间上有坏处。

这几个道理听起来简单,但在实际项目中,往往就是这些基础概念没吃透才出了问题。所以我也是一直跟自己讲:别觉得基础的东西不用深究,真到了流片回来的那天,后悔都来不及。