6、重构时序分析:重构过程时序约束、动态区域时序收敛、静态区域时序隔离

时序分析,说白了就是检查你的设计能不能在目标频率下稳定工作。我刚开始接触动态部分重构时,觉得这玩意儿跟普通时序分析没啥区别。结果第一次跑PR flow,静态区域的时序全乱了,动态区域更是惨不忍睹。嗯,从那以后我再也不敢小看重构时序分析了。

这一章,咱们就聊聊重构过程中的时序约束怎么写、动态区域怎么收敛、静态区域怎么隔离。说白了,就是让重构区域和静态区域各玩各的,互不干扰。

核心观点:动态部分重构的时序分析,本质上是“分而治之”的思想。动态区域和静态区域需要独立约束、独立分析,最后再统一验证。

6.1 重构时序分析的挑战

为什么重构时序分析这么特殊?我遇到过不少工程师,上来就用普通STA流程去跑重构设计,结果一塌糊涂。原因其实很简单:

  • 动态区域可替换:同一个动态区域,可能加载不同的重构模块。每个模块的时序特性都不一样。
  • 静态区域必须稳定:不管动态区域换成什么模块,静态区域的时序都不能受影响。
  • 跨区域路径复杂:信号从静态区域进入动态区域,或者从动态区域回到静态区域,这些路径的时序约束需要特殊处理。

你想想看,如果静态区域和动态区域混在一起分析,那每次换一个重构模块,整个设计的时序都要重新跑一遍。这不现实,也没必要。

6.2 重构过程时序约束

时序约束,是时序分析的基础。我个人的习惯是,先把约束分成三类:静态区域约束、动态区域约束、跨区域约束。

6.2.1 静态区域约束

静态区域的约束,跟普通设计的约束没什么两样。你需要定义时钟、输入延迟、输出延迟、虚假路径等等。但有一点要注意:

注意:静态区域的时钟约束,必须包含动态区域边界上的时钟信息。因为动态区域可能会用到静态区域的时钟,或者产生新的时钟。

举个例子,静态区域有一个100MHz的时钟,动态区域内部可能用这个时钟,也可能用分频后的时钟。那静态区域的约束里,就要把这两个时钟都定义清楚。

# 静态区域时钟约束示例
create_clock -name clk_static -period 10.000 [get_ports clk]
create_generated_clock -name clk_dyn_div2 -source [get_ports clk] \
  -divide_by 2 [get_pins u_dyn_region/clk_div_reg/Q]

6.2.2 动态区域约束

动态区域的约束,就比较麻烦了。因为同一个动态区域,可能加载不同的重构模块。每个模块的时钟、IO、时序路径都不一样。

我建议的做法是:为每个重构模块单独写约束文件。然后在PR flow中,根据当前加载的模块,选择对应的约束文件。

重构模块 约束文件 时钟频率 IO延迟
模块A rm_a.sdc 100MHz 输入2ns, 输出3ns
模块B rm_b.sdc 150MHz 输入1.5ns, 输出2.5ns
模块C rm_c.sdc 80MHz 输入3ns, 输出4ns

这样做的好处是,每个模块的约束都是独立的,互不干扰。而且,如果某个模块的时序不满足,你只需要修改那个模块的约束,不会影响其他模块。

6.2.3 跨区域约束

跨区域路径,是重构时序分析中最容易出问题的地方。我曾经在一个项目中,因为跨区域路径的约束没写对,导致静态区域和动态区域之间的信号延迟过大,整个设计跑不起来。

跨区域约束的核心是:定义好动态区域边界上的时序模型。说白了,就是把动态区域当成一个黑盒子,只关心它的输入输出延迟。

# 跨区域约束示例
# 从静态区域到动态区域的路径
set_input_delay -clock clk_static -max 2.0 [get_ports dyn_region_inputs]
set_input_delay -clock clk_static -min 0.5 [get_ports dyn_region_inputs]

# 从动态区域到静态区域的路径
set_output_delay -clock clk_static -max 3.0 [get_ports dyn_region_outputs]
set_output_delay -clock clk_static -min 1.0 [get_ports dyn_region_outputs]

小技巧:跨区域约束的延迟值,最好留一些余量。我一般会在计算值的基础上再加10%~20%的余量,这样即使动态区域内部有变化,静态区域也能扛得住。

6.3 动态区域时序收敛

动态区域的时序收敛,说白了就是让每个重构模块都能在自己的约束下跑通。我个人的经验是,动态区域的时序收敛比静态区域难得多,因为动态区域的资源有限,而且布局布线受到静态区域的限制。

6.3.1 动态区域的时序优化策略

动态区域的时序优化,跟普通设计的优化差不多,但有一些特殊的地方:

  • 资源利用率控制:动态区域的资源利用率不能太高,一般建议控制在70%以下。否则布局布线会很困难,时序很难收敛。
  • 时钟树平衡:动态区域内部的时钟树,需要单独平衡。我建议在动态区域内部使用专用的时钟缓冲器,不要依赖静态区域的时钟树。
  • 关键路径优化:动态区域的关键路径,往往在边界附近。因为信号从静态区域进入动态区域,或者从动态区域回到静态区域,都会经过边界上的逻辑单元。

我记得有一次,一个重构模块的时序怎么都收敛不了。后来发现,是因为动态区域边界上的IO逻辑太多,导致信号延迟过大。解决办法是,把一部分IO逻辑移到静态区域,减少动态区域的负担。

6.3.2 动态区域的时序验证

动态区域的时序验证,需要分两步走:

  1. 独立验证:每个重构模块单独做STA,确保模块内部的时序满足约束。
  2. 联合验证:把重构模块放到动态区域中,跟静态区域一起做STA,确保跨区域路径的时序也满足。

我建议,独立验证和联合验证都要做。独立验证可以快速发现模块内部的问题,联合验证可以发现跨区域的问题。两者缺一不可。

6.4 静态区域时序隔离

静态区域时序隔离,是重构时序分析中最关键的一环。说白了,就是让静态区域的时序不受动态区域变化的影响。

6.4.1 隔离的原理

静态区域时序隔离的原理,其实很简单:在动态区域边界上插入隔离逻辑。这样,不管动态区域内部怎么变,静态区域看到的都是固定的延迟和时序。

隔离逻辑通常包括:

  • 输入隔离:在静态区域到动态区域的路径上,插入寄存器或锁存器,把信号锁存住。
  • 输出隔离:在动态区域到静态区域的路径上,插入寄存器或锁存器,把信号锁存住。
  • 时钟隔离:在动态区域的时钟路径上,插入时钟门控或时钟缓冲器,确保时钟的稳定。

关键点:隔离逻辑必须放在静态区域中,不能放在动态区域中。因为动态区域是可替换的,隔离逻辑如果放在动态区域中,换模块时隔离逻辑也会变,那就起不到隔离的作用了。

6.4.2 隔离的实现方法

隔离逻辑的实现方法,主要有两种:

方法 优点 缺点 适用场景
寄存器隔离 延迟可控,时序稳定 增加延迟,占用资源 高速设计,对时序要求高的场景
锁存器隔离 延迟小,资源占用少 时序分析复杂,容易出问题 低速设计,对资源要求高的场景

我个人更倾向于使用寄存器隔离。虽然会增加一些延迟和资源,但时序分析简单,不容易出问题。我曾经在一个项目中尝试使用锁存器隔离,结果时序分析搞得一团糟,最后还是换回了寄存器隔离。

6.4.3 隔离的时序约束

隔离逻辑的时序约束,需要特别注意。因为隔离逻辑是静态区域的一部分,但它的输入输出跟动态区域有关。

# 隔离逻辑的时序约束示例
# 输入隔离寄存器
set_input_delay -clock clk_static -max 1.0 [get_pins u_iso_in_reg/D]
set_input_delay -clock clk_static -min 0.2 [get_pins u_iso_in_reg/D]

# 输出隔离寄存器
set_output_delay -clock clk_static -max 2.0 [get_pins u_iso_out_reg/Q]
set_output_delay -clock clk_static -min 0.5 [get_pins u_iso_out_reg/Q]

警告:隔离逻辑的时序约束,必须跟动态区域的约束保持一致。如果动态区域的时钟变了,隔离逻辑的约束也要跟着变。否则,时序分析结果会不准确。

6.5 知识体系图

下面这张图,展示了重构时序分析的核心逻辑。我画这张图的时候,参考了多个项目的实际经验,希望能帮你理清思路。

重构时序分析知识体系 重构时序分析 时序约束 动态区域收敛 静态区域隔离 静态区域约束 动态区域约束 跨区域约束 优化策略 时序验证 隔离原理 实现方法 时钟定义 IO延迟 资源利用率 独立验证 寄存器隔离 锁存器隔离 分而治之:静态区域稳定,动态区域灵活

6.6 避坑指南

最后,分享几个我踩过的坑,希望能帮你少走弯路:

  • 坑1:我曾经在动态区域的边界上忘了加隔离逻辑,结果静态区域的时序被动态区域的变化搞得一塌糊涂。后来花了整整一周才排查出来。所以,隔离逻辑一定要加,而且要加在静态区域中。
  • 坑2:跨区域约束的延迟值,我一开始算得太紧,结果动态区域稍微有点变化,时序就崩了。后来我学会了留余量,一般加10%~20%的余量,稳得很。
  • 坑3:动态区域的资源利用率,我一开始放到了85%,结果布局布线怎么都跑不通。后来降到70%以下,问题就解决了。所以,动态区域的资源利用率一定要控制好。

总结一下:重构时序分析,说白了就是让静态区域和动态区域各玩各的,互不干扰。静态区域要稳定,动态区域要灵活。约束要分开写,隔离要加到位,验证要分两步走。做到这几点,重构时序分析就没那么难了。


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