目录
- 一、概述
- 二、时序分析基本概念
- 时钟抖动
- 时钟偏差
- 时钟不确定性Clock Uncertainty
- 同步电路和异步电路
- 建立时间和保持时间
- 发起沿和采样沿
- 关键路径
- 三、时序分析的基本公式
- 时序分析的基本路径
- 数据到达时间和时钟到达时间
- 建立时间的裕量(Setup slack)
- 保持时间的裕量(Hold slack)
- 多周期路径检查
- 四、FPGA器件时序模型
- PVT
- 基本单元
- Path
- 五、FPGA时序约束的方法
- 时钟约束
- 时钟约束+时序例外约束
- 系统时钟约束+时序例外约束+I/O 约束
- 六、Vivado时序分析
- 分析工具
- 常用时序约束命令
- 七、时序优化
- 插入寄存器
- 寄存器平衡
- 并行处理(操作符平衡)
- 消除代码优先级
- 逻辑复制
- 关键路径重组
参考: 正点原子FPGA静态时序分析与时序约束
一、概述
时序分析:我们提出一些特定的时序要求(或者说是添加特定的时序约束),使用特定的时序模型,针对特定的电路进行分析。分析的最终结果是要求系统时序满足我们提出的要求。
静态时序分析(STA):采用穷尽的分析方法,依据电路网表的拓扑结构,计算并检查每个触发器的建立时间和保持时间是否满足时序要求。
优点:
- 不需要输入向量就可以穷尽所有路径;
- 运行速度快,占用内存小;
缺点:
- 只能对同步电路进行分析,不能对异步电路进行时序分析;
动态时序分析(DTA):验证器件在实际延时情况下的逻辑功能,就是通常说的时序仿真。
优点:
- 结果精确;
- 适用更多的设计类型;
缺点:
- 分析速度较慢,可能会遗漏一些关键路径,难以保证足够的覆盖率;
二、时序分析基本概念
时钟抖动
时钟抖动:相对于理想时钟沿,实际时钟存在不随时间积累的、时而超前、时而滞后的偏移。
时钟偏差
时钟偏差:同一个时钟域内的时钟信号到达数字电路各个部分(一般是指寄存器)所用时间的差异。
时钟延时Tskew=Tc2d-Tc2s。
正偏差:当信号传输的目标寄存器在接收寄存器之前捕获正确的时钟信号,电路发生正偏差(也就是时钟布线方向与数据流水方向一致);
负偏差:当信号传输的目标寄存器在接收寄存器之后捕获正确的时钟信号,电路发生负偏差(也就是时钟布线方向与数据流水方向相反);
时钟不确定性Clock Uncertainty
时钟不确定性=时钟偏差+时钟抖动
Clock Uncertainty的约束是为了让时序分析更贴近真实的电路设计。一般来说,频率较高的时钟,我们可以设置相对较小的 Clock Uncertainty;而频率较低的或者经过分频的时钟,我们可以把 Clock Uncertainty 加大一些。
同步电路和异步电路
同步电路:寄存器全部使用一个时钟的设计
寄存器 B 只可能采样到寄存器 A 的 Q 端数据跳变后的状态, 寄存器 B 是不可能采样到 Q 的信号跳变沿。
异步电路:寄存器使用多个时钟的设计
寄存器 B 可能采样到寄存器 A 输出的任意状态,包括 Q 的信号跳变沿。
建立时间和保持时间
建立时间(Tsu):时钟上升沿之前数据必须稳定的最短时间。
保持时间(Th):时钟上升沿之后数据必须稳定的最短时间。
寄存器的采样需要同时满足建立时间和保持时间,这两个值是寄存器成功采样的前提。如果不满足建立时间或保持时间,数据无法进入寄存器,寄存器的数据采样会失败。
发起沿和采样沿
发起沿:发送数据的时钟边沿,通常选择上升沿。
采样沿:采样到该数据的时钟边沿, 通常也是上升沿。
rega 的数据送到 regb 的 D 端,必须要在一个时钟周期内到达,否则就会出现、regb 采样失败的问题,因为 regb 采样时不看 rega 数据是否已到达, regb 采样的时候是只要有 Capture edge 边沿就进行采样。
关键路径
关键路径通常指同步逻辑电路中,组合逻辑时延最大的路径,关键路径是对时序性能起决定性影响的路径。
三、时序分析的基本公式
时序分析的基本路径
管脚输入和寄存器之间的路径(pin2reg):从 device A 的时钟到 FPGA 的第一级寄存器的输入端口,这个部分包括 3 个延迟,分别是 Tco( 时钟到寄存器输出延时),Input Delay( PCB 板子的输入走线延迟)和Internal Delay( FPGA 内部的输入走线延迟) 。
寄存器和寄存器之间的路径(reg2reg):两个同步元件之间的路径(rega 到 regb) ,这个部分包括 2 个延迟,分别是 Tco( 时钟到寄存器输出延时)和 Data Path Delay( FPGA 内部的组合逻辑和数据走线延迟) 。
寄存器和管脚输出之间的路径(reg2pin):最后一级寄存器到 device B 数据端口的路径(黄色) ,这个部分包括 3 个延迟,分别是 Tco( 时钟到寄存器输出延时), Internal Delay( FPGA 内部的输入走线延迟)和Output Delay( PCB 板子的输出走线延迟) 。
管脚输入和管脚输出之间的路径(pin 2pin):端口到端口的路径( dinb 到 doutb ) ,这个部分包括 1 个延迟,即 Data Path Delay( FPGA 内部的组合逻辑和数据走线延迟) 。
数据到达时间和时钟到达时间
数据到达时间:数据在发送沿发送之后,经过多长时间会到达接收寄存器的数据端口,即到达 regb的 D 端口的时刻。
通常选择 launch edge 作为零时刻基准点,数据经过 Tco 时间,到达 Q 端口,从 Q 端口要经过组合逻辑,以及布线的线延时才能到达接收短的 D 端口。
数据到达时间 Data Arrival Time = 启动沿时间 + Tclka + Tco + Tdata
时钟到达时间 Clock Arrival Time = 采样沿时间(launch edge 加上一个时钟周期)+ Tclkb
建立时间的裕量(Setup slack)
建立裕量为正值说明两个寄存器有合格的建立关系,建立裕量为负值说明两个寄存器建立关系不满足,会导致采样出错。
数据到达时间=启动沿时间 + Tclk1 + Tco + Tdata= 0ns + 3.2ns + 0.2ns + 0.6ns= 4ns
数据锁存时间=锁存沿时间+ Tclk2 - Tsu= 10ns + 2ns -1.4ns=10.6ns
建立裕量=数据锁存时间 - 数据到达时间=10.6ns-4ns=6.6ns
保持时间的裕量(Hold slack)
保持裕量为正值说明两个寄存器有合格的保持关系,保持裕量为负值说明两个寄存器保持关系不满足,也会导致采样出错。
保持关系是指寄存器1在还没有更新输出之前,寄存器2用最快速的速度读取从寄存器1发送过来的数据。
数据保持时间 = 启动沿+ Tclk1 + Tco+ Tdata + 数据周期时间=0ns + 3.2ns + 0.2ns + 0.6ns + 10ns = 14ns
数据锁存时间 = 锁存沿+ Tclk2 + Th=10ns + 2ns + 1.4ns = 13.4ns
保持裕量=数据保持时间- 数据锁存时间=14ns-13.4ns=0.6ns
多周期路径检查
一些数据不需要在下一个时钟周期就稳定下来,可能在数据发送后几个时钟周期之后才起作用;一些数据经过的路径太复杂,延时太大,不可能在下一个时钟周期稳定下来,必须要在数据发送后数个时钟周期之后才能被采用。多周期路径是为了解决信号传播太慢的问题,慢到一个周期都不够,所以要把Setup Time的检查往后推几个周期——扩大Setup Time检查的时间窗口。
不设置多周期路径约束的后果有两种:一是按照单周期路径检查的结果,虚报时序违规;二是导致布局布线工具按照单周期路径的方式执行,虽然满足了时序规范,但是过分优化了本应该多个周期完成的操作,造成过约束。过约束会侵占本应该让位于其他逻辑的布局布线资源,有可能造成其他关键路径的时序违规或时序余量变小。
在多周期路径的建立时间( Setup Time)检查中, 时序分析软件会按照用户指定的周期数延长Data Required Time,放松对相应数据路径的时序约束,从而得到正确的时序余量计算结果。
四、FPGA器件时序模型
PVT
PVT 是指芯片工艺( Process)、电压( Voltage)和温度( Temperature) 。 不同的 PVT 参数,芯片的时序模型都是有差异的。
工艺角(Process corner)一般有三种模型:Typical corner、Fast corner、Slow corner
时序分析工具通过 Worst corner 来保证建立时间的时序,通过 Best corner 来保证保持时间的时序。由于一般情况下设计以建立时间违例为主,所以时序分析工具默认使用slow corner。
时序分析工具会依据仿真需求,使用不同的 PVT 组合,用于 STA 分析。
一般时序分析会涉及到如下三种情况:
- 最好的条件(BCF)— 速度最快:fast process,lowest temperature,high voltage
- 最坏的条件(WCS)— 速度最慢:slow process,high temperature,lowest voltage
- 典型的条件(TYP)— 速度介于最快和最慢之间:typical process,nominal temperature,nominal voltage
基本单元
FPGA 开发工具需要读入布局布线后的网表才能进行时序分析。
网表的构成:
- cell:FPGA网表中最普遍的单元(如寄存器、查找表、IO单元、硬件乘法器等逻辑资源);
- pin:cell的输入输出端口,不包括器件的输入输出引脚;
- net:同一个cell中从输入 pin 到输出 pin 经过的逻辑。网表中连接两个相邻 Cell 的连线不被看作 Net,而被看作同一个点,等价于 Cell 的 pin 。但这个连线等价于 FPGA 器件中的一段布线逻辑,会引入一定的延迟;
- port:顶层逻辑的输入输出端口,对应已经分配的器件引脚;
Path
时序分析一般关注的是时序违例,这些时序违例的路径一般都是由各种 path组成的。
Path的分类:
- Clock paths:从 Clock Port 或内部生成的 clock pin 到寄存器 Cell 的时钟输入Pin。
- Data paths:从输入 Port 到寄存器 Cell 的数据输入 pin ,或从寄存器 Cell 的数据输出 pin 到另一个寄存器 Cell 的数据输入 pin 。
- Asynchronous paths:从输入 Port 到寄存器 Cell 的异步输入 pin ,或从寄存器Cell 的数据输出 pin 到另一个寄存器 Cell 的异步输入 pin 。
五、FPGA时序约束的方法
时钟约束
时钟约束是最基本的一个约束,FPGA工具不知道我们要跑多高的频率,所以必须要告诉工具要跑的时钟频率,时钟约束就是经常看到的Fmax,这是针对最差劲路径的。
时钟约束+时序例外约束
有时候一个设计中存在多个时钟,光有时钟约束是不够的,还需要加一些例外约束,
时序例外约束包括 FalsePath 、 MulticyclePath、 MaxDelay、 MinDelay。
系统时钟约束+时序例外约束+I/O 约束
IO 约束包括引脚分配、位置、空闲引脚驱动方式、外部走线延时(InputDelay 、 OutputDelay)、上下拉电阻、驱动电流强度等。
六、Vivado时序分析
分析工具
Constraints Wizard:创建新设计的时序的向导
Edit Timing Constraints:编辑时序约束
report timing summary:报告时序汇总
no_clock:没有时序约束的时钟
constant_clock:时钟引脚被误接到常数时钟上面。
no_input_dela:一个输入延迟约束都没有的 non-clock 输入端口数量。
no_output_delay:一个输出延迟约束都没有的 non-clock 输出端口数量。
一般只关注 TNS,分数是 0,说明时序是满足的,分数是负的,说明时序是不满足的,负分越大,说明时序越差,时序负分过大会导致功能可能出问题。
WNS:最差负时序裕量
TNS:总的负时序裕量
WHS:最差保持时序裕量
THS:总的保持时序裕量
WPWS:最差脉冲宽度裕量
TPWS:总的脉冲宽度裕量
report clock networks:报告时钟网络,时钟网络反映了时钟从时钟引脚进入FPGA后在FPGA内部的传播路径。报告时钟网络提供设计中的时钟树图,每个时钟树显示从源到端点的时钟网络。
report clock interaction:报告跨时钟域路径分析,分析从一个时钟域跨到另一个时钟域的时序路径。
report methodology:检查当前设计是否符合设计方法论。
report DRC:检查设计规则,DRC会使用一套设计检查项来检查当前设计是否违反这套规则。
report noise:估计同步转换噪声(SSN)。可以估计I/O Bank中管脚在同时转换输出状态时对其它输出端口造成的干扰。这是一个常见的问题,许多总线有大量的位宽,当总线数据有多位同时变化时,很容易在其它I/O上产生噪声。
report utilization:查看各模块资源占用情况。
report power:评估设计的功耗。
schematic:显示布局布线后网表的连接,和SYSTHESIS中schematic不同的是布局布线会根据一些策略进行网表的调整。
常用时序约束命令
1.创建时钟约束:create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
该约束含义是创建一个时钟周期 20ns 的时钟,时钟名字为 sys_clk。
如果是差分时钟,只需要约束差分时钟的 P 端,N 端不用约束。
2.设置时钟不确定性:set_clock_uncertainty -from clk0 -to clk0 0.500
该约束含义是设计时钟 clk0 全部时钟间路径的裕量需严格设置在 500ps
3.设置管脚输入延迟:set_input_delay -clock clk0 5 [get_ports din]
该约束含义是 din 端口与 clk0 关联,输入延迟约束为 5ns。
4.设置管脚输出延迟:set_output_delay -min -0.5 -clock CLK [get_ports DOUT]
该约束含义表示设计内部直到 DOUT 管脚的延迟必须至少超过 0.5ns,才能满足保持时间
的需要。
5.设置false path路径:set_false_path -from [get_cells REG0] -to [get_cells REG1a]
该约束含义表示 REG1a 到 REG0 之间的路径不需要时序检查。
6.约束指定输入到输出端口之间组合逻辑的最大/最小延时:set_max/min_delay –from [get_ports in1] –to [get_ports out*] 1.0
7.当无需限制最大延迟时,可使用时钟组。
set_clock_groups -asynchronous -group clkA -group clkB
当两个主时钟以及它们各自的生成时钟构成两个异步域,且两域之间所有路径都被正确同步时,可立即对多个时钟同时应用时钟组约束。
set_clock_groups -asynchronous \
-group [get_clocks -include_generated_clock clkA] \
-group [get_clocks -include_generated_clock clkB]
七、时序优化
参考文档:
解决FPGA时序问题的八大忠告
时序优化的几种方法
FPGA设计性能优化
时序分析之关键路径
插入寄存器
组合路径延时过长,就会成为影响设计的关键路径,这时可以考虑在路径上插入额外的寄存器,这种方法也称为插入流水线,多用于高度流水的设计中。这种插入额外的寄存器增加了时钟周期的延迟,但并不会违反整个设计的要求,从而不会影响设计的整体功能实现,即插入额外的寄存器在保持吞吐量不变的情况下改善了设计的时序性能,但也会带来面积的增加。
原设计:
always @ (posedge clk or negedge rst_n) beginif (rst_n)beginin1_temp <= 1'd0;in2_temp <= 1'd0;in3_temp <= 1'd0;in4_temp <= 1'd0;out <= 1'd0;end else beginin1_temp <= in1;in2_temp <= in2;in3_temp <= in3;in4_temp <= in4;out <= (in1_temp*in2_temp)*(in3_temp*in4_temp);end
end
优化后:
always @ (posedge clk or negedge rst_n) beginif (rst_n)beginin1_temp <= 1'd0;in2_temp <= 1'd0;in3_temp <= 1'd0;in4_temp <= 1'd0;in1_reg <= 1'd0;in2_reg <= 1'd0;out <= 1'd0;end else beginin1_temp <= in1;in2_temp <= in2;in3_temp <= in3;in4_temp <= in4;in1_reg <= in1_temp * in2_temp;in2_reg <= in1_temp * in2_temp;out <= in1_reg * in2_reg;end
end
寄存器平衡
在不增加寄存器个数的前提下,通过改变寄存器的位置来优化关键路径,以最小化两个寄存器之间的最大延时。这个技巧通常用于关键路径和其相邻路径之间的逻辑高度不平衡的情况。其实寄存器平衡就是通过移动关键路径和其他相邻路径上的组合逻辑来提升设计的时序性能。
原设计:
always @(posedge clk) beginrA <= A;rB <= B;rC <= C;Sum <= rA+rB+rC;end
优化后:
always @(posedge clk) beginrABSum <= A + B;rC <= CSum <= rABSum + rC;end
并行处理(操作符平衡)
并行处理本质上是通过重组组合逻辑来减少关键路径上的延迟。
消除代码优先级
若设计中不需要有优先级,可以优化掉优先级电路,这样路径延迟得以缩短,若设计需要有优先级则不能采用该方法。常用方法是用各项平级的if语句或case语句替换if-else语句。
原设计:
always @ (posedge clk) beginif (in1 == 4'b0001)out <= 4'b0001;else if(in1 == 4'b0010)out <= 4'b0010;else if(in1 == 4'b0100)out <= 4'b0100;else if(in1 == 4'b1000)out <= 4'b1000;elseout <= 4'b1001;
end
优化后:
always @ (posedge clk) begincase(in1)4'b0001:out <= 4'b0001;4'b0010:out <= 4'b0010;4'b0100:out <= 4'b0100;4'b1000:out <= 4'b1000;default:out <= 4'b1001;endcase
end
逻辑复制
如果某个信号需要驱动很多后级单元,此时该信号扇出非常大,会造成该信号到各个目的逻辑节点的路径变得过长,从而成为设计中的关键路径。此时可以复制生成这个信号的逻辑,用多路同频同相的信号驱动后续电路,使平均到每路的扇出变低。
高扇出会增加布局布线的难度、减缓布线速度,这样其扇出的节点也就无法被布局为彼此靠近,所以就导致了布线长度过大。高扇出信号多为同步信号,即寄存器信号,所以进行逻辑复制时是对寄存器进行复制。
关键路径重组
关键路径重组技术多用于关键路径由多个路径组合而成的场合,而且这些被组合的路径之间又可以重组相互之间的先后顺序,从而使得寄存器之间的关键路径被拉近。可以通过减少关键路径上的组合逻辑单元数来减小该路径上的延时,从而达到优化的目的。
原设计:
always @ ( * ) beginif (critical && sel)out_reg = in1;elseout_reg = in2;
endalways @ (posedge clk) beginout <= out_reg;end
优化后:
always @ ( * ) beginif (sel)out_temp = in1;elseout_temp = in2;
endalways @ ( * ) beginif (critical)out_reg = out_temp;elseout_reg = in2;
endalways @ (posedge clk) beginout <= out_reg;
end