2、STA基础回顾:建立时间与保持时间、时序路径类型、时钟域概念

各位同学,咱们今天聊聊STA的基础。说实话,这部分内容看起来简单,但很多工程师栽跟头就栽在这里。我见过不少项目,前端RTL写得飞起,一到后端时序分析就抓瞎。说白了,就是基础没打牢。

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

先问大家一个问题:为什么寄存器要满足建立时间和保持时间?

你可以把寄存器想象成一个「拍照」的过程。时钟上升沿就是快门按下的那一刻。建立时间要求数据在快门按下之前必须稳定,保持时间要求快门按下之后数据还得稳定一会儿。为什么?因为寄存器内部的电路需要时间来完成「采样」这个动作。

建立时间(Setup Time):数据在时钟有效沿之前必须保持稳定的最短时间。

保持时间(Hold Time):数据在时钟有效沿之后必须保持稳定的最短时间。

我在项目中遇到过一件挺尴尬的事。有一次做一款AI加速芯片,前端工程师拍着胸脯说时序没问题。结果后端布局布线之后,发现一条关键路径的建立时间违例了0.3ns。查了半天,原来是组合逻辑太深,数据从寄存器A传到寄存器B,中间绕了十几个门。你想想看,数据在路上跑的时间太长,留给建立时间的余量自然就少了。

这里有个公式,大家一定要刻在脑子里:

建立时间检查:T_clk_period + T_clk_skew > T_clk2q + T_comb + T_setup
保持时间检查:T_clk2q + T_comb > T_hold + T_clk_skew

嗯,注意看,建立时间和保持时间的公式里,时钟偏斜(clock skew)的符号是相反的。建立时间检查时,时钟偏斜是「帮忙」的;保持时间检查时,时钟偏斜是「捣乱」的。这个细节,我建议你拿小本本记下来。

避坑指南:我曾经在一个28nm的项目里,因为忽略了时钟偏斜对保持时间的影响,导致芯片在低温下出现随机错误。后来花了整整两周才定位到问题。记住:保持时间违例比建立时间违例更难修,因为它和频率无关,只和工艺、温度有关。

2.2 时序路径类型——四种路径,四种脾气

STA里把时序路径分成四类。说白了,就是看信号的起点和终点分别是什么。我习惯用「源-目的」的方式来记:

路径类型 起点 终点 典型约束
reg2reg 寄存器时钟端 寄存器数据端 create_clock
reg2out 寄存器时钟端 输出端口 set_output_delay
in2reg 输入端口 寄存器数据端 set_input_delay
in2out 输入端口 输出端口 set_max_delay

reg2reg路径:这是最核心的路径。芯片里90%的时序问题都出在这。两个寄存器之间夹着一堆组合逻辑,数据从第一个寄存器出来,经过组合逻辑,再进入第二个寄存器。说白了,STA主要就是在算这条路径能不能跑得通。

reg2out路径:数据从芯片内部的寄存器,一路跑到输出引脚。这里要注意的是,输出端口外面还连着别的芯片,所以我们需要用set_output_delay来告诉工具:外面的芯片需要多少建立时间和保持时间。

in2reg路径:数据从芯片的输入引脚进来,经过一些组合逻辑,最终到达寄存器。同样,我们需要用set_input_delay告诉工具:数据从外面进来的时候,相对于时钟是什么时候到的。

in2out路径:这条路径比较特殊,它没有寄存器。数据从输入直接跑到输出。这种路径通常用set_max_delay来约束。我在项目中遇到过一种情况:一个纯组合的in2out路径,因为没加约束,工具直接把它忽略了,结果芯片测试时发现延迟超标。嗯,这个坑我踩过。

个人经验:我建议你在做STA之前,先把这四种路径在芯片上的物理位置画出来。reg2reg在芯片内部,reg2out在输出侧,in2reg在输入侧,in2out是直通路径。这样画一遍,你对芯片的数据流就有了全局感。

2.3 时钟域概念——不同节奏的舞者

时钟域,说白了就是被同一个时钟驱动的所有寄存器的集合。但现实世界没这么简单。一个芯片里往往有多个时钟域,它们之间还可能互相通信。

我举个例子。你做一个手机芯片,CPU跑2GHz,GPU跑1.5GHz,DDR跑800MHz。这三个时钟域各自独立,但CPU和DDR之间要传数据。这时候问题就来了:CPU域的数据,怎么安全地送到DDR域?

这里有几个关键概念:

  • 同步时钟域:两个时钟同源,频率成整数倍关系。比如一个200MHz,一个100MHz,都是同一个PLL分出来的。
  • 异步时钟域:两个时钟不同源,或者频率不成整数倍关系。比如一个来自PLL1,一个来自PLL2。
  • 跨时钟域(CDC):数据从一个时钟域传到另一个时钟域。这是芯片设计里最容易出bug的地方之一。

核心原则:跨时钟域传输必须做同步处理。常用的方法有:双级触发器同步、异步FIFO、握手协议。千万别直接把一个时钟域的信号直接接到另一个时钟域的寄存器上,那叫「亚稳态炸弹」。

我记得有一次做一颗通信芯片,前端工程师在代码里直接跨时钟域赋值。STA工具报了一堆违例,他还不信邪,说「仿真跑得好好的啊」。我告诉他:仿真只能验证功能,STA才能验证时序。后来他加了双级触发器,问题就解决了。你想想看,仿真时亚稳态的概率很低,但芯片量产几百万颗,总有一颗会撞上。

关于时钟域,STA里还有一个重要概念叫「时钟域交叉分析」。工具会检查所有跨时钟域的路径,如果发现没有做同步处理,就会报CDC违例。我建议你在项目早期就做CDC检查,别等到后端才去修,那时候改RTL的成本太高了。

特别注意:即使两个时钟是同步的,如果它们的相位关系不确定,STA也会把它们当作异步来处理。我曾经在一个项目里,两个时钟明明同源,但因为PLL的相位对齐没做好,导致工具报了一堆假违例。后来加了set_clock_groups -asynchronous才解决。

2.4 知识体系总览

下面这张图,是我自己总结的STA基础框架。你可以把它当作一张「地图」,每次做STA时对照着看,思路会清晰很多。

STA基础回顾知识体系 建立时间与保持时间 • 建立时间定义 • 保持时间定义 • 时序检查公式 • 时钟偏斜影响 • 违例修复方法 建立时间:加流水线 保持时间:加缓冲器 时序路径类型 • reg2reg(核心路径) • reg2out(输出路径) • in2reg(输入路径) • in2out(组合路径) 约束方式: create_clock set_input/output_delay set_max_delay 时钟域概念 • 同步时钟域 • 异步时钟域 • 跨时钟域(CDC) 同步方法: 双级触发器 异步FIFO 握手协议 ⚠ 亚稳态风险 三者共同构成STA分析的基础框架

这张图把STA基础分成了三大块。左边是建立时间和保持时间,这是STA的「物理基础」;中间是四种时序路径,这是STA的「分析对象」;右边是时钟域概念,这是STA的「环境约束」。三者缺一不可。

我个人习惯在做每个项目之前,先花半天时间把这三块内容过一遍。别觉得浪费时间,磨刀不误砍柴工。你想想看,如果连建立时间和保持时间都搞不清楚,后面修违例的时候只会越修越乱。

好了,这一章的内容就到这里。记住:STA不是玄学,它是可以量化的科学。把基础打牢,后面修违例的时候你才能游刃有余。

课后小练习:打开你的STA工具,找一个已有的设计,分别找出reg2reg、reg2out、in2reg、in2out这四种路径各一条,看看它们的时序报告长什么样。相信我,亲手做一遍比看十遍书都管用。

可可精品资料库