1. 时序路径分析:先把“是什么”和“为什么”讲透
做芯片的人,无论是前端写RTL的,还是后端做布局布线的,或者是做验证、做DFT的,迟早都要面对“时序”这两个字。投片回来的芯片能不能跑起来、能跑多快、会不会在某些电压温度条件下突然罢工,很多时候都取决于时序是否收敛。我见过不少工程师,代码写得行云流水,一到时序约束、时序报告就头皮发麻,满屏的slack、setup、hold、skew看得一头雾水。这篇内容就是想把这些东西掰开揉碎,用干活儿的人能听懂的大白话,把芯片时序路径分析这件事的骨架搭起来,打好底子之后再去啃后面的实操案例。
所谓“时序路径分析”,通俗一点说,就是芯片内部的每一个触发器(Flip-Flop,也就是时序逻辑的存储单元)从一个时钟沿到下一个时钟沿之间,数据信号能不能在规定时间内稳稳当当地到达。如果数据到得太慢,超出时钟周期,那下一个时钟沿采样时数据可能还没稳定,这就是建立时间违例(setup violation)。如果数据变得太快,在时钟沿采样完之后紧接着又变掉了,导致本该保持住的数据被冲掉,那就是保持时间违例(hold violation)。这两类违例,就是芯片时序分析里最核心的两个检查。
我说这些,是为了先给一个全貌,因为后面所有讨论都围绕这个展开。这篇文章是“上篇”,会先讲清楚时序路径的构成、时序分析的基本原理、各种路径类型,以及我们在做时序约束时最常接触的几类东西。至于具体的怎么读时序报告、怎么修违例、怎么在项目里一步步收敛时序,放在“下篇”再展开。
从项目实际角度看,时序路径分析贯穿芯片开发的几乎每一个环节。前端设计完了要做综合,综合工具会做一次初步的时序预估,看看你的RTL结构是否有明显的时序瓶颈;后端布局布线之后要做signoff检查,这个时候的时序分析结果直接影响是否可以投片(tapeout);哪怕芯片已经流片回来,做bring-up调试的时候,如果发现某些频率点跑不过,也常常要从时序角度去反推原因。可以说,时序分析是整个芯片设计流程里最不能糊弄的一环。刚入行的工程师,可能觉得就是跑跑工具、看看报告而已,但真正深入之后会发现,时序分析背后涉及的时钟网络、单元库特性、PVT(工艺、电压、温度)影响、片上变异(OCV/AOCV)等等,每一项都能单独写一本书。
2. 时序路径的核心构成:起点、终点、组合逻辑
时序路径,英文叫Timing Path,简单理解就是一条数据信号从起点到终点所经过的物理和逻辑通路。STA(静态时序分析)工具在做路径分析的时候,会把整条路径分成三段来看:起点、组合逻辑网络、终点。搞清楚这三段,后面的所有概念都好理解得多。
2.1 起点和终点的类型
起点,也就是信号的发起端,主要有两类。一类是时序单元的时钟引脚,典型的就是触发器的CK引脚,在这个时钟沿到来之后,触发器会把D端的输入数据锁存到Q端输出,数据就从这个Q端出发了。另一类是输入端口(Input Port),也就是芯片顶层的输入引脚,信号从芯片外部打进来,经过input port后开始向内部传播。
终点也一样,两类。第一类是时序单元的数据引脚,典型的就是触发器的D端。数据到达D端之后,等待下一个时钟沿来采样式,采样的结果决定了这个触发器下一个状态的输出。第二类是输出端口(Output Port),数据经过组合逻辑传播之后,从芯片的输出引脚导出外部。
这里有个非常常见的地下概念叫“时序起点”和“时序终点”有严格的差异。在STA里,一个触发器的时钟引脚(CK)是时序路径的起点,而它的数据引脚(D)是时序路径的终点,起点和终点落在同一个器件上但是不同引脚,目的就是检查这个触发器自身能不能正确采到数据。而一个触发器的Q端并不是任何时序路径的终点,因为数据在Q端只是“通过”,它的归宿要么是下一级触发器的D端,要么是输出端口。
这么一来,一条从触发器到触发器(FF1到FF2)的典型路径,就包含了三个部分:FF1的CK引脚(起点)到Q端的内部延迟(clock-to-q,简称clk-to-q)、中间组合逻辑的传播延迟(含布线延迟)、以及到达FF2的D端后相对时钟沿的建立或保持时间检查。
2.2 组合逻辑在路径里扮演的角色
组合逻辑,就是由与门、或门、非门、选择器、加法器等构成的,没有存储功能的逻辑网络。数据经过这些逻辑单元时,会产生一级一级的延迟。这种延迟的来源有两层:第一层是单元本身的传播延迟(cell delay),也就是信号进入一个门、经过内部电路处理、再从输出端出来所花的时间;第二层是互连延迟(net delay),也就是信号从上一个门的输出引脚,通过金属导线,走到下一个门的输入引脚所花的时间。
在工艺节点比较老的时候,比如180nm、130nm,cell delay在总延迟里占大头,互连延迟相对次要。但是到了28nm往下,特别是16nm、7nm这些先进工艺节点,金属导线的电阻电容效应急剧上升,net delay的比重越来越高,甚至可能超过cell delay。这也是为什么后端工程师整天盯着floorplan和布局,因为线长的优劣直接决定了net delay的大小,net delay大了时序就很难看。
组合逻辑级数(logic level),就是一条时序路径上串联的组合逻辑单元数量。如果一条路径从起点到终点,中间经过了30级逻辑门,那它的组合逻辑延迟大概率会很大;如果能优化到15级甚至10级以内,时序余量就会从容很多。这也是架构设计阶段做流水线切割的一个基本原则——把长组合逻辑链打散,插入触发器做流水,等于用面积换时序余量。
2.3 数据路径与时钟路径的区分
时序分析里还要区分“数据路径”和“时钟路径”。数据路径是信号从起点数据端到终点数据端的传播路径,这个比较容易理解。时钟路径是时钟信号从时钟源头(PLL或者其他时钟源)出发,经过时钟树网络(clock tree),最终到达各个触发器的CK引脚的一条路径。
为什么要特别区分时钟路径?因为触发器采数据,不是拿“理想时钟”在做比较,而是拿“到达这个触发器CK引脚的实际时钟沿”在比较。如果时钟到达FF1和FF2的时间不一样,就会产生时钟偏斜(clock skew),这个skew会直接影响时序检查的结果。简单说,如果FF2的时钟到达得比FF1晚(positive skew),那FF2的采样沿整体往后移了,FF1发出来的数据反而有了更多时间到达,对建立时间是有利的,但对保持时间是不利的。这种此消彼长的关系,就是为什么时序分析必须同时做setup和hold两种检查的根本原因。
等做到后端阶段,时钟树综合(CTS)和时钟树优化,本质上就是在调整这条时钟路径上各处的buffer数量和位置,让skew值尽可能小,把时序余量吃回来的空间找出来。前端设计阶段往往不做太细的时钟树分析,但是设计RTL时要心里有数,时钟树的偏差最终是要在时序预算里预留一部分余量的。
3. 时序分析的基本原理:建立时间、保持时间、启动沿与捕获沿
时序分析要理解透了,核心就是两个时间检查:建立时间检查和保持时间检查。这两个检查背后,又牵出启动沿(launch edge)和捕获沿(capture edge)这两个概念。
3.1 启动沿、捕获沿、时钟周期
一条触发器到触发器的路径上,数据是在启动沿发射出来的,也就是起点触发器FF1的时钟引脚收到一个时钟沿,在这个沿的驱动下,FF1把D端数据锁存到Q端,数据沿着组合逻辑向前跑。而终点触发器FF2,会在捕获沿采样数据,也就是在下一个时钟沿到来时,把D端的数据锁存进去。
一般情况下,同一个时钟域里,启动沿是当前时钟周期,捕获沿是下一个时钟周期,两个沿之间隔了一个时钟周期(clock period)。这个就是setup检查的基本时间范围。hold检查不一样,它的比较对象是捕获沿和前一个启动沿,或者说捕获沿和启动沿之间的数据保持关系,它要确认的是前一个数据已经被采样完了,后一个数据不会过早地冲进来把还没采完的数据冲掉。
为了把这两个概念形象化,我给一个坐标轴式的理解方式:沿着时间轴,第一个时钟沿是启动沿,第二个时钟沿是捕获沿。数据从启动沿之后开始发生变化,在组合逻辑里逐渐传播,最终在捕获沿之前必须稳定下来,提前的时间量就是建立时间余量(setup slack);数据稳定之后不能立刻变化,要在捕获沿之后还保持住一段时间,这个保持的时间量就是保持时间余量(hold slack)。setup要求的是“你来得别太晚”,hold要求的是“你变完了别马上又变”。
3.2 建立时间公式与关键因素
从时序报告里经常能看到类似这样的约束关系:
data required time = capture edge + clock network delay at FF2 - setup time of FF2 data arrival time = launch edge + clock network delay at FF1 + clk-to-q delay + combinational delay setup slack = data required time - data arrival time这个公式看着简单,但每个参数都有讲究。clock network delay指的是时钟信号从时钟源到触发器CK引脚的传播时间,核心就是时钟树的延迟。在理想时钟模型下,假设时钟同时到达所有触发器,那这两项就可以抵消掉,但在真实世界里,FF1的clock network delay和FF2的clock network delay大概率不相等,它们的差值就是clock skew。
从公式可以直观看出来,如果FF2的CK晚到,data required time变大,setup slack变好。这一点我在前面提到过。反过来,如果你为了让setup通过而人为把FF2的时钟往后移,hold就会变差,所以setup和hold是天生的矛盾体。实际工程里,clock skew通常都是控制在极小的范围内,不会用大幅skew去换setup slack,因为太冒险了。
这里插一个重要细节:setup检查里的setup time,是触发器本身的库特性参数。标准单元库里,每个触发器的lib描述里都定义了setup time和hold time,这两个值本身还依赖输入转换时间(input slew)和输出负载电容。你选用的单元库不同、同一个单元在PVT不同条件下,setup/hold值都不一样。所以不要试图记忆某个固定的setup time值,要理解它是单元库在不同条件下提取出来的时序弧参数。
3.3 保持时间公式与快路径风险
hold时间的检查公式反过来看:
data arrival time at FF2 D pin(从捕获沿看,是下一份数据) hold required time = capture edge + clock network delay at FF2 + hold time of FF2 hold slack = data arrival time for hold - hold required timehold违例的本质,是数据变化得太快,快到把还在保持期内的老数据冲掉了。所以hold检查关注的是“最短路径”,也就是组合逻辑延迟最小的那条路径。如果起点触发器的clk-to-q很小、中间组合逻辑只有一两级、线又短,那这个数据可能在捕获沿之后很短的时间内就到达FF2的D端了,一旦这个到达时间比FF2要求的hold time还短,就保持不住,数据就坏了。
这就是为什么后端做hold修复时,往往在短路径上插buffer来人为增加延迟——因为短路径才是hold违例的重灾区。相反,setup检查关注的是“最长路径”,要在最大延迟条件下仍然满足建立要求。一个关注上限,一个关注下限,覆盖面完全不一样。
从物理意义上来讲,hold检查本质上做的就是“hold time is actually a minimum constraint on the data stability window after the clock edge.” 这个数据稳定窗口,不容许被过早到达的下一个数据破坏。
3.4 PVT对时序参数的影响
时序参数不是固定不变的。芯片在不同工艺角(Process Corner)、不同电压(Voltage)、不同温度(Temperature)下,单元延迟和连线延迟都会偏离典型值。
- 快工艺角(Fast Corner,典型FF):阈值电压低、迁移率高,单元延迟很小,路径跑得快。这时候setup通常比较好过,但hold容易出问题。
- 慢工艺角(Slow Corner,典型SS):单元延迟很大,路径跑得慢。setup容易出问题,hold反而好。
- 高电压下,单元速度更快,延迟更小;低电压下,延迟增大。
- 温度对延迟的影响在先进工艺下呈现逆趋势,低温反而可能让延迟变大,这个在项目里要特别留意。
所以STA工具在做收敛检查的时候,会用多种条件跑多轮:setup分析用最慢条件(Slow corner + 低电压 + 高温),hold分析用最快条件(Fast corner + 高电压 + 低温)。这也是为什么后端signoff要跑多个corner,不是只跑一个看了一遍就能完事的。
4. 时序路径的四大类型:从简到繁逐个说
STA工具在分析时序时,会按起点和终点的不同组合,把时序路径归成四类。这四类几乎覆盖了芯片内部所有需要检查的信号通路。
4.1 触发器到触发器(Reg-to-Reg)
这是最经典、也最常见的一类。起点是FF1的CK引脚,终点是FF2的D引脚。中间经过组合逻辑和互连线。
这条路径的分析意义在于:它对时钟周期做了全面检查,直接决定了芯片能够跑到的最高工作频率(Fmax)。如果reg-to-reg路径的setup slack为负,说明组合逻辑延迟过长,要么优化逻辑,要么插流水线,要么降频。
在综合阶段做floorplan前,工程师通常先看关键路径的级数和延迟分布,判断是否存在“一条路径打了太多级”的不合理结构。比如一条32位加法器如果不用进位旁路结构,进位链一级一级传下去会非常深,时序就极难收敛。
4.2 输入端口到触发器(Input-to-Reg)
这类路径的起点是芯片的输入端口(input port),终点是触发器D引脚。输入信号从外部进来之后,经过了一些组合逻辑,然后被内部触发器采样。
做STA时,工具并不知道外部信号什么时候到达输入端口,所以需要设计者给输入端口设一个约束,告诉它输入信号相对时钟沿的到达时间(input delay)。这个input delay是一个外部时序预算,它的含义是:在时钟沿之后多少纳秒,外部信号稳定到达输入端。
这个预算设置多少,直接影响STA检查的松紧。设得太紧,相当于要求内部组合逻辑延迟很小,否则时序报告里会报一堆假violation;设得太松,又等于默认外部信号到得非常晚,可能掩盖真实延迟问题。实际项目里,input delay通常根据片间接口协议、上一级芯片的output delay、板级走线延迟来推算。你要是只做单芯片内部的时序分析,可能觉得input/output delay约束很麻烦,但做系统级项目或者做接口IP的时候,这个约束对不对直接影响整个链路能不能跑起来。
4.3 触发器到输出端口(Reg-to-Output)
起点是FF的CK引脚,终点是芯片的输出端口。输出信号从触发器发出后,经过组合逻辑驱动到输出引脚,传到芯片外部。
和input delay一样,output delay也需要设计者在约束文件里定义。它表示:外部电路在时钟沿之后多长时间需要采到这个输出数据。如果输出数据到得太晚,外部采样就会失败。
这类路径的优化重点是输出端口附近的驱动能力。如果输出buffer太小,带不动较大的PCB负载电容,信号在输出引脚上的转换时间(slew)会很大,直接拖慢路径延迟,甚至导致输出波形畸变。
4.4 输入端口到输出端口(Input-to-Output)
起点是输入端口,终点是输出端口,中间是纯组合逻辑通路,没有触发器。这种纯组合路径在芯片内部比较少见,但在某些特殊设计里会存在,比如一些不带寄存器的直通功能模块、某些模拟数字混合信号的旁路通路。
因为中间没有寄存器隔离,这类路径的形状就是输入延迟 + 组合逻辑延迟 + 输出所需时间。它不直接受时钟频率约束,但受外部接口时序协议约束。有些SoC芯片里,某些测试模式或者调试模式会启用这种纯组合通路,用于特定功能的旁路。
在STA报告里,如果这类路径违例,通常的修法不是插buffer,而是考虑在输入或输出端口处增加寄存器做同步或打拍,把纯组合路径打断成寄存器到寄存器路径。
4.5 异步路径与会说话的“伪路径”
除了这四大类,STA里还有一类特殊的路径需要特殊处理,就是异步路径(false path)。比如跨时钟域(CDA)之间的某些路径,数据在不同时钟域之间传递,并不是严格按照某个单一时钟沿对齐的,STA工具强行检查反而会报出不真实的违例,因此需要用约束告诉工具这些路径不需要检查。
同理,还有一些路径虽然存在于网表里,但逻辑上永远不会被激活,例如某些配置模式下才会打开的路径。这些被标记为false path或者case analysis,能显著减轻工具的检查压力,也能让报告更聚焦。不过这里要提醒一句,false path约束要慎用,特别是跨时钟域路径,如果确实存在真实的亚稳态风险,还是需要同步器(synchronizer)来保障,而不是简单set_false_path了事。工具不检查,不代表风险不存在。
5. 时钟约束的四个基石:Creating Clocks, Uncertainty, Latency, Transition
做时序路径分析,光有网表和库还不够,还必须有正确的时钟约束。时钟约束是整个STA里的一等公民,因为所有路径的起点和终点都和时钟挂钩。
5.1 时钟定义(create_clock)
在SDC约束文件里,第一步通常是创建时钟,比如:
create_clock -name clk -period 10 -waveform {0 5} [get_ports clk]这条命令的意思很直白:定义一个名为clk的时钟,周期10纳秒,占空比50%,时钟端口是顶层的clk引脚。设置period为10,意味着后面所有setup检查都会以10纳秒为基准——如果某条数据路径从启动沿到捕获沿的数据到达时间接近甚至超过10纳秒,就一定会报违例。
这里要注意一点:create_clock只是告诉工具时钟存在以及它的周期和相位定义,但是真正的时钟信号到达各个触发器CK引脚的延迟,需要通过时钟树和时钟建模来计算。综合阶段还没有时钟树,工具会用理想时钟模型,也就是默认时钟网络零延迟,这个时候的时序报告更多用于评估逻辑结构合理性;后端时钟树做出来之后,带真实时钟树的时序分析才有signoff意义。
除了单一时钟,实际芯片里经常有多个时钟域。不同IP模块可能跑在不同的时钟频率下,比如总线时钟400MHz、CPU核时钟1.5GHz、外设时钟100MHz。每个时钟域内部做路径检查,跨时钟域的路径要么通过同步器打拍,要么单独约束。多时钟域之间的约束关系如果没理清楚,时序报告里可能出现海量假违例,看着吓人其实没什么实际影响。
5.2 时钟不确定性(clock uncertainty)
时钟不确定性,核心是给时序分析“泼一盆冷水”,提前预留出时钟沿可能发生抖动的余量。它包含两大部分:时钟源本身的抖动(jitter)和时钟树到达不同触发器之间的偏差余量(skew margin)。
实际项目里,时钟树是真实存在的,skew值会在CTS之后变得准确。但在综合阶段,时钟树还没建,工具默认理想时钟(零skew),所以我们必须人为设置一个较大的clock uncertainty来模拟skew的影响,避免综合结果太乐观。等到后端CTS结束,真实skew已知,uncertainty会被更新成一个较小的值。
set_clock_uncertainty -setup 0.2 [get_clocks clk] set_clock_uncertainty -hold 0.1 [get_clocks clk]如果把uncertainty设得太大,等于给设计加了很多无谓的时序余量,可能会导致不必要的面积和功耗浪费;设太小,又可能遗漏真实的时序风险。这个数值的设置,不同团队有不同经验值,常见在50ps到500ps区间,取决于工艺节点和设计场景。
5.3 时钟延迟(clock latency)与时钟转换时间(clock transition)
clock latency,就是时钟信号从时钟源到触发器CK引脚的传播时间。在综合阶段,这个值也是估算的,可以通过set_clock_latency来约束。在后端阶段,时钟树综合完成后,每个触发器的clock latency是工具根据真实插入的buffer链计算出来的。
clock transition,是时钟信号沿的转换时间,也就是从低电平跳到高电平需要的时间。如果时钟沿太斜(slew太大),触发器内部晶体管的导通时间会变长,直接影响时序弧参数,甚至可能让触发器误触发。时钟树上插入的buffer数量和尺寸,本质上就是在控制时钟slew在合理范围内。
在时序路径分析里,时钟沿的slew会进一步影响触发器的内部延迟,这个影响在先进工艺节点会被精细建模。很多时序工具在计算path delay时,会把输入slew作为查询表参数,通过Cell Library里的NLDM(Nonlinear Delay Model)或者CCS(Composite Current Source)模型获取精确延迟值。
6. 真实项目里做时序路径分析的心得:别被报告吓到
我对时序路径分析的理解,很大一部分是踩坑踩出来的,这里分享几个实实在在的体会,希望后来者少走弯路。
第一,拿到时序报告先看总的违例数量、关键路径所在的时钟域和模块归属,不要一头扎进去读每一条路径。芯片项目时序报告动辄几万条violations,如果逐条分析,光看完都要大半天。正确做法是先排序、按模块聚合,找规律。常见的情况是,大量违例集中在某几个IP模块里,而这些模块里往往就几条关键路径拖了后腿。把那几条路径优化掉,整个violations数量可能直接下降一个数量级。
第二,setup和hold要分开看,修复手段几乎是背道而驰的。修setup的核心是缩短组合逻辑路径延迟,手段包括逻辑重组、插入流水线、更换驱动能力更大的单元、优化布局拉近单元间距等;修hold的核心是延长短路径延迟,手段主要就是插buffer、插delay cell。如果混为一谈,修了一处另一处崩了,越修越乱。
第三,看路径报告时,要时刻区分cell delay和net delay。到了后端阶段,net delay偏高往往是布局布线质量的问题,比如两个逻辑相关的单元被floorplan隔得太远,线绕了一大圈。这种情况光靠优化逻辑是修不好的,需要回到布局层面调整单元位置。很多工程师修时序只盯着逻辑级数和单元尺寸,忽略了线长的影响,结果反复优化就是收不拢。
第四,PVT corner之间的时序行为差异巨大。慢工艺角setup差,不代表快工艺角也有问题;反过来,快工艺角hold差,也不代表慢工艺角会出问题。所以修violation的时候要明确自己在修哪个corner,改动会不会让其他corner变差。比如为了修慢corner的setup去换一个大驱动单元,可能会让快corner的hold变得更差,因为这些单元本身的延迟也变小了,短路径变得更短。
第五,对于跨时钟域的路径,一定要想清楚再用set_false_path。如果这个跨时钟域路径确实没做同步处理,真实硬件上就有亚稳态风险,光让STA工具不检查是掩耳盗铃。正确做法是确保设计里使用了合理的同步器,比如两级触发器同步,或者更稳妥的异步FIFO。在确认硬件结构无误的前提下,再通过约束告诉工具哪些路径无需时序检查。否则后面芯片回来了,数据偶尔出错,真凶还得从时序路径分析里找。
我个人的体会是,时序路径分析这件事的入门门槛其实不高,公式就那么几个,路径类型也就四类。但真正做深了之后发现,它背后牵扯的东西非常广:从单元库的建模精度,到时钟网络的设计质量,到布局布线的合理性,再到RTL的流水线结构,哪一个环节出问题都会在时序报告里体现出来。这也是为什么优秀的时序收敛工程师往往是全流程都比较熟悉的人,因为他们能从报告里的蛛丝马迹反推出问题出在整个链路里的哪一环。
关于时序路径分析的基础部分,到这里就基本铺完了。接下来的内容,会重点讲时序报告的解读、真实违例案例的修复过程、OCV和AOCV的概念,以及那些在项目收尾阶段必看的检查项。这些都是时序路径分析里真正打磨手感的部分,做好准备了就往下篇走。