第二章:时序分析基础——建立时间与保持时间,时序路径类型

各位同学,欢迎来到时序收敛实战指南的第二讲。今天咱们聊聊时序分析最核心的两个概念:建立时间和保持时间。嗯,这两个词你肯定听过,但真正吃透的人不多。我见过不少工程师,跑STA时看到violation就慌,其实说白了,就是没搞懂这两个时间到底在约束什么。

2.1 建立时间与保持时间——芯片的“心跳”规则

先问大家一个问题:一个寄存器到底怎么才能正确采集到数据?

答案很简单:数据必须在时钟沿到来之前稳定下来,并且在时钟沿之后继续保持稳定。前者叫建立时间(Setup Time),后者叫保持时间(Hold Time)。

我个人习惯把建立时间想象成“提前到场”,保持时间就是“别急着走”。你想想看,寄存器内部是由一堆晶体管组成的,它需要时间把数据“读进去”。如果数据来得太晚,或者走得太多,内部状态就会出错。

核心公式(务必记住):

  • 建立时间检查:T_launch + T_clk2q + T_data_path + T_setup ≤ T_capture + T_cycle
  • 保持时间检查:T_launch + T_clk2q + T_data_path ≥ T_capture + T_hold

我在项目中遇到过一件事:有个模块在低频下跑得好好的,一上高频就随机出错。查了三天,最后发现是保持时间违例。因为综合工具默认优化建立时间,保持时间被忽略了。嗯,从那以后,我每次做完综合都会手动检查保持时间。

避坑指南:

我曾经犯过一个低级错误——把建立时间和保持时间搞反了。建立时间违例可以通过降频临时解决,但保持时间违例是功能性的,降频也没用。所以,流片前一定要跑一遍完整的STA,别偷懒。

2.2 时序路径的四种类型

搞清楚了建立时间和保持时间,咱们再来看看时序路径。STA里把路径分成四类,我画了张图帮你理解:

时序路径类型总览 reg2reg(寄存器到寄存器) 起点:寄存器时钟端 终点:寄存器数据端 最核心、最常见的路径 占芯片中90%以上的时序路径 reg2out(寄存器到输出) 起点:寄存器时钟端 终点:芯片输出端口 受输出延迟约束影响 需要设置set_output_delay in2reg(输入到寄存器) 起点:芯片输入端口 终点:寄存器数据端 受输入延迟约束影响 需要设置set_input_delay in2out(输入到输出) 起点:芯片输入端口 终点:芯片输出端口 纯组合逻辑路径 通常需要约束最大/最小延迟

这张图把四种路径的关系讲得很清楚。我建议你把它存下来,以后分析时序报告时对照着看。

2.3 深入理解reg2reg路径

reg2reg是STA的“主战场”。为什么?因为芯片里绝大多数逻辑都是寄存器到寄存器的传输。你写的每个always块,综合后都会变成一条或多条reg2reg路径。

我举个例子:

// 一个简单的reg2reg路径
always @(posedge clk) begin
  data_out <= data_in + 1'b1;
end

这条路径的起点是data_in对应的寄存器时钟端,终点是data_out对应的寄存器数据端。中间经过了一个加法器。STA会检查:从时钟沿到数据到达data_out寄存器的时间,是否满足建立时间和保持时间。

个人经验:

我建议你在做floorplan时,就把reg2reg路径的物理距离控制好。如果两个寄存器隔得太远,走线延迟会吃掉大量时序裕量。我曾经在一个项目中,就因为两个关键寄存器放得太远,导致setup violation修了整整两周。

2.4 reg2out与in2reg——芯片的“边界”路径

这两种路径涉及芯片的输入输出端口,需要配合外部器件的时序来约束。

对于reg2out路径,你要设置set_output_delay。这个值代表外部器件需要多少时间才能采集到你的输出数据。我一般会留10%~20%的裕量,防止工艺偏差。

对于in2reg路径,你要设置set_input_delay。这个值代表外部器件的数据到达你的输入端口需要多长时间。嗯,这里有个坑:输入延迟通常包含时钟偏斜,别忘了算进去。

避坑指南:

我曾经在设置输入延迟时,忘了考虑时钟的jitter。结果芯片回来后,某些极端情况下输入数据采集出错。从那以后,我每次都会在输入延迟里加上0.1ns的jitter裕量。

2.5 in2out路径——纯组合逻辑的“直通”路径

in2out路径比较特殊,它不经过任何寄存器。这种路径通常用于异步接口或简单的组合逻辑输出。

约束in2out路径时,我习惯用set_max_delay和set_min_delay。比如:

set_max_delay -from [get_ports in_data] -to [get_ports out_data] 5.0
set_min_delay -from [get_ports in_data] -to [get_ports out_data] 1.0

这样做的目的是确保组合逻辑的延迟在可控范围内。如果延迟太大,外部器件可能来不及响应;如果延迟太小,又可能产生毛刺。

2.6 四种路径的优先级

在实际项目中,这四种路径的优先级是不一样的。我一般这样排:

优先级 路径类型 原因
1(最高) reg2reg 数量最多,影响芯片最高频率
2 in2reg 影响输入数据采集的正确性
3 reg2out 影响输出数据的时序
4 in2out 通常数量少,约束相对宽松

你想想看,如果reg2reg路径没修好,芯片根本跑不到目标频率。但in2out路径如果有点小问题,有时候可以通过调整外部器件的时序来弥补。所以,资源有限时,先集中精力修reg2reg。

2.7 本章小结

好了,今天的内容就到这里。总结一下:

  • 建立时间要求数据提前到来,保持时间要求数据不要过早变化
  • 四种路径类型各有特点,reg2reg是核心
  • 边界路径需要配合外部约束,别漏了jitter和裕量
  • 优先级排序:reg2reg > in2reg > reg2out > in2out

嗯,这些概念看起来简单,但真正用好需要大量实践。我建议你找个项目,打开STA工具,对着时序报告一条条分析。看多了,自然就熟了。

可可精品资料库