时序路径分类:四大路径类型详解

做时序分析这么多年,我见过不少新手一上来就盯着工具报的时序违例看,结果越看越懵。其实啊,你得先搞清楚一件事:时序分析到底在分析什么路径?

说白了,FPGA里的时序路径就四种。你把这四种路径搞明白了,STA就入门了一半。我在项目中遇到过好几次,新人拿着时序报告来找我,说「这里怎么违例了」,我一看,连路径类型都没分清楚——这就像医生看病连症状都搞错了,能开对药吗?

核心要点:所有时序约束,本质上都是在约束这四种路径的延迟。一个不漏,才能保证芯片正常工作。

1. 寄存器到寄存器路径(Reg-to-Reg)

这是最常见的一种路径,也是我们做时序约束时最关心的。

什么叫寄存器到寄存器?就是一个触发器的输出,经过组合逻辑,跑到另一个触发器的输入。你想想看,整个FPGA里大部分逻辑都在干这件事。

// 典型的Reg-to-Reg路径
always @(posedge clk) begin
    reg_a <= data_in;           // 第一个寄存器
    reg_b <= reg_a + 1;         // 组合逻辑 + 第二个寄存器
end

这里有个关键点:两个寄存器必须在同一个时钟域,或者至少是同步时钟域。我刚开始做设计时,有一次把两个不同PLL出来的时钟连到这两个寄存器上,结果时序怎么都过不了。后来才发现,跨时钟域的路径不能这么约束。

我的经验:做Reg-to-Reg约束时,我习惯先看数据路径的延迟,再看时钟偏斜。如果数据路径太长,就在中间插一级流水线。这招在高速设计中特别管用。

2. 输入到寄存器路径(Input-to-Reg)

这条路径从芯片的输入引脚开始,经过输入缓冲、布线,最后到达第一个触发器的数据端。

为什么要单独分析这条路径?因为输入信号是外部来的,你没法控制它。你只能约束它——告诉工具:这个输入信号相对于时钟,什么时候来,什么时候走。

// 输入到寄存器的典型约束
set_input_delay -clock clk -max 2.5 [get_ports data_in]
set_input_delay -clock clk -min 1.0 [get_ports data_in]

嗯,这里要注意:输入延迟的参考点是芯片的时钟引脚。我曾经见过有人把输入延迟设成负值,结果工具报了一堆违例。其实负延迟在某些场景下是合理的,比如DDR接口,但新手最好先别碰。

避坑指南:我曾经在一个项目中,把输入延迟设得太保守,结果内部时序裕量全被吃掉了。后来我学乖了:先看芯片手册,再根据PCB走线长度估算,最后留10%的余量。这样既不过分悲观,也不过分乐观。

3. 寄存器到输出路径(Reg-to-Output)

这条路径从最后一个触发器开始,经过输出缓冲,到达芯片的输出引脚。

它的时序分析和输入路径正好相反。输入路径关心的是「数据什么时候准备好」,输出路径关心的是「数据什么时候能出去」。

// 寄存器到输出的典型约束
set_output_delay -clock clk -max 3.0 [get_ports data_out]
set_output_delay -clock clk -min 1.5 [get_ports data_out]

我个人习惯在做输出约束时,先问自己一个问题:下游芯片需要多快的建立时间和保持时间?这个答案直接决定了输出延迟的取值。

关键区别:输入路径的约束影响的是内部寄存器的建立时间检查,输出路径的约束影响的是外部芯片的建立时间检查。方向不同,但原理相通。

4. 输入到输出路径(Input-to-Output)

这条路径最特殊——它直接从输入引脚跑到输出引脚,中间不经过任何寄存器。

说白了,这就是纯组合逻辑路径。在FPGA里,这种路径很少见,因为大部分设计都会在中间插寄存器。但有些场景下确实存在,比如异步复位、一些简单的组合逻辑。

// 输入到输出的组合路径
assign data_out = data_in & enable;  // 纯组合逻辑

你想想看,这种路径怎么约束?没有时钟,所以不能用建立时间和保持时间来约束。实际上,我们用的是最大延迟和最小延迟约束。

我的建议:除非万不得已,别用纯组合路径。我在一个项目中用过一次,结果因为温度变化,路径延迟漂了20%,差点导致系统失效。从那以后,我只要看到Input-to-Output路径,就会建议设计师加一级寄存器。

四种路径的对比

路径类型 起点 终点 约束方式 常见场景
Reg-to-Reg 寄存器时钟端 寄存器数据端 时钟周期约束 大部分逻辑电路
Input-to-Reg 输入引脚 寄存器数据端 输入延迟约束 外部数据输入
Reg-to-Output 寄存器时钟端 输出引脚 输出延迟约束 数据输出到外部
Input-to-Output 输入引脚 输出引脚 最大/最小延迟 纯组合逻辑

四种路径的关系图

下面这张图是我画的,把四种路径的关系理清楚了。你看一眼就能明白:所有路径都围绕着寄存器展开

FPGA时序路径分类 输入引脚 寄存器1 (起点) 寄存器2 (终点) 输出引脚 路径2 Input-to-Reg 路径1 Reg-to-Reg 路径3 Reg-to-Output 路径4 Input-to-Output 组合逻辑区域 (所有路径都可能经过) 时钟域 所有路径都基于同一个时钟参考 Reg-to-Reg Input-to-Reg Reg-to-Output Input-to-Output

从这张图你能看到:路径1和路径2、3都经过寄存器,只有路径4是纯组合的。这也是为什么大部分时序约束都围绕着寄存器展开——寄存器是时序分析的锚点。

实际项目中怎么用?

我一般拿到一个新设计,会先做三件事:

  1. 识别所有路径类型——打开RTL代码,把四种路径标出来
  2. 优先处理Reg-to-Reg——这是最核心的路径,先保证它能跑在目标频率上
  3. 再处理I/O路径——根据芯片手册和PCB信息,设置输入输出延迟

注意:千万别漏掉任何一条路径。我见过一个案例,设计师把所有Reg-to-Reg路径都约束好了,但忘了约束一个异步复位信号的Input-to-Reg路径,结果芯片在高温下频繁复位失败。这种问题最难排查,因为时序报告不会主动告诉你「你漏了一条路径」。

好了,四种路径就讲到这里。记住这个分类,后面的时序约束和STA分析都离不开它。

专注资料整理