时序分析的基本步骤:
一个合理的时序约束可以分为以下步骤:
时序约束整体的思路如下:
- 先是约束时钟,让软件先解决内部时序问题;(在这一步骤中可以适当加入时序例外,以便时序通过)
- 然后再加入IO的延迟约束;
- 最后针对没有过的时序,添加时序例外。
1、 IO口的建立时间与保持时间
1.1 输入延迟
外部器件发送数据到FPGA系统模型如下图所示。对FPGA的IO口进行输入最大最小延时约束是为了让FPGA设计工具能够尽可能的优化从输入端口到第一级寄存器之间的路径延迟,使其能够保证系统时钟可靠的采到从外部芯片到FPGA的信号。
输入延时即为从外部器件发出数据到FPGA输入端口的延时时间。其中包括时钟源到FPGA延时和到外部器件延时之差、经过外部器件的数据发送Tco,再加上PCB板上的走线延时。如下图所示,为外部器件和FPGA接口时序。
最大输入延时(input delay max)为当从数据发送时钟沿(lanuch edge)经过最大外部器件时钟偏斜(Tclk1),最大的器件数据输出延时(Tco),再加上最大的PCB走线延时(Tpcb),减去最小的FPGA时钟偏移(FTsu)的情况下还能保证时序满足的延时。这样才能保证FPGA的建立时间,准确采集到本次数据值,即为setup slack必须为正,计算公式如下式所示:
Setup slack =(Tclk + Tclk2(min))–(Tclk1(max) +Tco(max) +Tpcb(max) +FTsu)≥0 (1)
最小输入延时(input delay min)为当从数据发送时钟沿(lanuch edge)经过最小外部器件时钟偏斜(Tclk1),最小器件数据输出延时(Tco),再加上最小PCB走线延时(Tpcb),此时的时间总延时值一定要大于FPGA的最大时钟延时和建立时间之和,这样才能不破坏FPGA上一次数据的保持时间,即为hold slack必须为正,计算公式如下式所示:
Hold slack = (Tclk1(min) + Tco(min) + Tpcb(min))–(FTh + Tclk2(max))≥ 0 (2)
我们很容易就可以从公式(1)和(2),推到出(3)
Tclk – Ftsu ≥Tclk1 - Tclk2 + Tco + Tpcb ≥ FTh (3)
在公式(3)中,我们发现Tclk 、Ftsu以及FTh,对于工具来说是已知的,而Tclk1 - Tclk2 + Tco + Tpcb正是我们需要告知综合工具的延迟量。
从我们推到出的公式,我们可以得到
Input_delay_max = Tclk – Ftsu; Input_delay_min = FTh ;
1.2 输出延迟
FPGA输出数据给外部器件模型如下图所示。对FPGA的IO口进行输出最大最小延时约束是为了让FPGA设计工具能够尽可能的优化从第一级寄存器到输出端口之间的路径延迟,使其能够保证让外部器件能准确的采集到FPGA的输出数据。
输出延时即为从FPGA输出数据后到达外部器件的延时时间。其中包括时钟源到FPGA延时和到外部器件延时之差、PCB板上的走线延时以及外部器件的数据建立和保持时间。如所示,为FPGA和外部器件接口时序图。
最大输出延时(output delay max)为当从FPGA数据发出后经过最大的PCB延时、最小的FPGA和器件时钟偏斜,再加上外部器件的建立时间。约束最大输出延时,是为了约束IO口输出,从而使外部器件的数据建立时间,即为setup slack必须为正,计算公式如下式所示:
Setup slack =(Tclk + Tclk2(min))–(Tclk1(max) +FTco(max) +Tpcb(max) +Tsu)≥0 (4)
最小输出延时(output delay min)为当从FPGA数据发出后经过最小的PCB延时、最大的FPGA和器件时钟偏斜,再减去外部器件的建立时间。约束最小输出延时,是为了约束IO口输出,从而使IO口输出有个最小延时值,防止输出过快,破坏了外部器件上一个时钟的数据保持时间,导致hlod slack为负值,不能正确的锁存到数据,最小输出延时的推导计算公式如下式所示:
Hold slack = (Tclk1(min) + FTco(min) + Tpcb(min))–(Th + Tclk2(max))≥ 0 (5)
我们很容易就可以从公式(4)和(5),发现这两条公式与前面推导输入延迟如出一辙。只不过现在FPGA变成了输出器件,而Tsu、Th是下游器件的参数,综合工具并不知情,需要我们告诉他。除了FTco以外,其他参数都需要我们告诉工具。
由公式(4)我们可以推导出:
FTco(max) + Tpcb(max) –(Tclk2(min) – Tclk1(max)+Tsu ≤Tclk
那么output delay max = Tpcb(max) –(Tclk2(min) – Tclk1(max)+Tsu
同理我们由公式(5)可以推导出:
FTco(min) + Tpcb(min) – (Tclk2(max) – Tclk1(min))– Th ≥ 0
那么output delay min = Tpcb(min) – (Tclk2(max) – Tclk1(min))– Th
2 、 电路内部的建立时间与保持时间
建立时间公式:Tcycle + Tskew > Tco + Tgate + Tsu;
保持时间公式:Thold + Tskew < Tc0 + Tgate
通过以下几个例子来学习时序分析的方法。
例题一:
这个题目堪称经典中的经典,因为从这个题目是标准的建立时间和保持时间考题,并从中可以总结出系统最大时钟频率以及建立时间和保持时间需要满足的公式。
我们知道系统周期需要满足的条件是:
Tcycle + Tskew > Tco + Tgate + Tsu
代入上面的条件,得:Tcycle + T5 > T1 + T2 + T3 + T4 + Tsetup
上面的时钟路径是存在偏斜的,而且是正时钟偏斜,则对于保持时间的满足更加的困难,需要满足:
Thold + Tskew < Tc0 + Tgate
代入上面的条件,得: Thold + T5 < T1 + T2 + T3 + T4
例题二:
在上题的基础上,你也许会分析触发器的建立时间和保持时间应该满足的关系了,可是考题也许会变了法的考你,如下:
求系统的最高频率?
仔细看来,这是一个触发器到自身的反馈,可以看做两个触发器之间进行数据传输,其实也就是如此。
需要明白的是,由于时钟到达这个触发器的时间一致,所以不存在时钟偏斜。
给出系统周期满足的关系:
Tcycle > Tco + Tgate + Tsu - Tskew
所以时钟最大频率可以为100MHz。
例题三:
如果都是分析触发器的建立时间和保持时间就好了,可惜不是这样的,套路来了:
如下图,将框内的电路作为一个寄存器,那么其有效的建立时间和保持时间是多少?
求框内电路的有效建立时间和保持时间,给出了框内触发器的建立时间和保持时间以及其他一些逻辑的延迟,我们就以触发器的建立时间和保持时间为准来倒逼整个电路的建立时间和保持时间,一切还都是为了让触发器满足时序要求。
有效建立时间分析:
假设电路的有效Setup为Tsetup_valid:
对于D触发器而言,其本身的建立时间是2ns,也就是说数据必须在时钟有效沿到达之前2ns保持稳定,这样到达D端后就一定是稳定的数据了。
这个电路的数据来自于IN,时钟来自于CLK;
考虑时钟路径延迟影响:
时钟CLK要早于触发器的时钟1ns到达,因此对于D触发器建立时间的满足是有害的,电路有效建立时间
Tsetup_valid = Tsetup - 1ns = 1ns(因为数据需要提前1ns稳定下来)
考虑数据路径延迟影响:
Tsetup_valid = Tsetup - 1ns + 2ns = 3ns;(经过组合逻辑后的数据需要在时钟有效沿之前Tsetup时间稳定下来)
有效保持时间分析:
和建立时间分析套路一致,对于D触发器而言,数据需要在时钟有效沿到来之后保持Thold时间。
考虑时钟延迟的影响:
考虑到电路时钟对于触发器时钟早到1ns,所以电路有效保持时间Thold_valid = Thold + 1ns = 3ns;
考虑路径延迟影响:
数据需要经过一段组合逻辑之后才能保持稳定,因此电路的有效保持时间为:
Thold_valid = Thold + 1ns - 2ns = 1ns。
例题四:
下面这个题目和上面题目相差无几:
1. 求该电路的固有建立时间与保持时间?
求电路的固有建立时间和保持时间和上一题的有效建立时间和保持时间是一个意思的。因此:
固有建立时间为:Tsu_valid = Tsu - T_offset + Tpd + Tpd1= 2 - 1.2 + 1.2 + 0.9 = 2.9ns
固有保持时间为:Th_valid = Th + T_offset - Tpd - Tpd1= 1.5 + 1.2 - 1.2 - 0.9 = 0.6ns.
2. 该电路的最高工作频率?
先求系统的最小周期,考虑两个触发器之间的路径:
Tmin = Tco + Tpd + Tsu = 1.8 + 1.2 + 2 = 5ns,那么系统最高频率为200MHz。
例题五:
求下图电路中,flop2 的 setup time margin = ?ns
这个题目让求setup time margin,意思大概就是建立时间裕量,就是系统周期减去Tco,Tgate以及Tsu之后还可以有多少裕量,那,Tco,Tgate以及Tsu当然要用最大的来代入,因为要保证系统在最恶劣的情况下,能有多少裕量。
因此:Tmargin = Tclk + Tskew - (Tco + Tgate +Tsu)
Tmargin = 10ns + 0.6ns - 0.2ns - 0.65ns - 0.35ns - 0.45ns = 8.95ns
其中0.6ns - 0.2ns表示的是时钟偏斜量,可见是时钟正偏斜,有利于时钟裕量。
时钟违例的一些处理方法
下面介绍主要面对的两个时序问题的处理技巧。
1)setup time 建立时间问题
建立时间是工程设计中最常遇到的问题了。一般说来,导致建立时间违例主要有两个原因:逻辑级数太大或者扇出太大。
打开Report Timing Summary界面查看路径延迟信息。
【 逻辑级数太大 】
Levels指的是逻辑级数logic level,一个logic level的延迟对应的是一个LUT和一个Net的延迟,对于不同的器件,不同频率的设计能容纳的logic level是不同的。假设7系列的-2速度等级250MHz的设计,电路设计的大部分levels最好不要超过8,否则会造成时序收敛困难。
Logic level太大的处理方法就是重定时(Retiming)了,典型的重定时方法就是流水线,将过于冗长的组合逻辑增加寄存器进行打拍。
【 扇出太大 】
High Fanout指的是扇出,同样和器件、设计频率等有关,如下图所示:
降低扇出最好不要在综合设置中指定,过低的扇出限制会造成设计堵塞反而不利于时序收敛,最好的方法是根据设计中时序最差路径的扇出进行针对性的优化。
1. 如果是寄存器的输出扇出很大,可以使用max_fanout属性标记寄存器声明,也可以手动复制寄存器,具体可参考:
网络直接连接到触发器,对扇出超过25K的net插入BUFG:
set_property CLOCK_BUFFER_TYPE BUFG [get_nets netName]
当然,也可以在后期Implementation的物理优化设置中优化扇出。
2)hold time 保持时间问题
在实践中,我们发现保持时间的问题往往是异步处理的问题。
对于一个信号的跨时钟域问题,一般使用双寄存器法(对于慢采快的结绳法这里不讨论)。为了降低MTBF(Mean Time Between Failures,平均无障碍时间),这两个寄存器最好位于同一个slice中。可以使用tcl语言指定,如:
set_property ASYNC_REG TRUE [get_cells [list sync0_reg sync1_reg]]
也可以直接在代码中指定:
(* ASYNC_REG = "TRUE" *) (* keep = "true" *)reg sync0_reg, sysnc1_reg;
也可以参考代码模板使用XPM模板进行处理。
**注意
在发现同一个时钟域中,时序还不满足要求,那应该怎么处理呢?
(这时候只能在修改代码方向努力了,回到Chipplanner中,分析关键路径,看布线后的路径是否过长,导致影响时序。还是由于高扇出导致时序违例。针对不同的原因,修改代码。比如说,路径过长,
1. 通常检测是否代码中嵌套的if语句级数太多?(可以尝试case语句替代)。
2. 又或者if的判断中有表达式(if(a>b)之类的,看能否用电平替代,if(en)等。
3. 在使用 if 或 case 的时候,避免产生不必要的锁存器
4. 对于有些逻辑融合起来一个大的模块,看能否将大的逻辑块划分为若干个小逻辑块实现。
5. 针对高扇出问题,上述已提到相应的处理方式。
6. 布局优化
写到最后想说的是,调时序是一个比较难啃的活,有时候你增加了约束可能时序还会变的更差了,所以说一个良好的代码风格很重要。假如上述的方法都已经试过了,时序还是很难满足,可能器件已经快到达极限了,尤其是资源占用率比较高的时候。这时候只能降低时钟或者替换更高性能的器件啦。
Hello world! Keep coding!