本文转载自CSDN博主「孤独的单刀」的原创文章,原文链接:https://blog.csdn.net/wuzhikaidetb/article/details/128339654
1、4种基本的时序路径
下图是一张典型的 FPGA 与上游器件、下游器件通信的示意图:
![](https://i-blog.csdnimg.cn/blog_migrate/394ff838c1fa139bf7bddc2c07204ee1.png)
其可以划分为4条基本的数据路径,这4条路径也是需要进行时序约束的最基本路径。
(1)寄存器到寄存器
路径2,FPGA内部的寄存器到另一个寄存器, 即 reg2reg(寄存器到寄存器),需要对其进行约束以满足 FPGA 端寄存器的建立时间和保持时间要求。
路径2约束的是FPGA内部源寄存器(起点)和FPGA内部目的寄存器(终点)的数据路径, 其目的是要通过提供要求的方式来使得综合工具 vivado 满足所有 FPGA 内部寄存器的建立时间要求和保持时间要求。
(2)管脚到寄存器
路径1,上游器件通过 FPGA 管脚到 FPGA 的寄存器的时序路径,即 pin2reg(管脚到寄存器),需要对其进行约束以满足FPGA端寄存器的建立时间和保持时间要求。
路径1约束的是上游器件的源寄存器(起点)和FPGA内部的目的寄存器(终点)的数据路径, 其目的是要满足后端即 FPGA 内部寄存器的建立时间要求和保持时间要求。
路径1可以视为是路径2的一种,只不过路径2的源寄存器和目的寄存器都在 FPGA 内部,而路径1的源寄存器在上游器件中。
(3)寄存器到管脚
路径3,FPGA 管脚到下游器件的寄存器的时序路径,即 reg2pin(寄存器到管脚),需要对其进行约束以满足下游器件的寄存器的建立时间和保持时间要求。
路径3约束的是 FPGA 内部的源寄存器(起点)和下游器件的目的寄存器(终点)的数据路径, 其目的是要满足前端即FPGA内部寄存器的建立时间要求和保持时间要求。
路径3同样可以视为是路径2的一种,只不过路径2的源寄存器和目的寄存器都在 FPGA 内部,而路径3的目的寄存器在下游器件中。
(4)管脚到管脚
路径4,FPGA 管脚到 FPGA 管脚的时序路径(不通过任何寄存器),其本质上是纯组合逻辑电路,仅仅需要将其值约束在一个指定范围,不需要满足建立时间和保持时间要求。
路径4中不存在任何寄存器,通常都是纯组合逻辑或者走线延迟等,所以也就不需要满足寄存器的建立时间要求和保持时间要求。需要的仅仅是根据开发需求约束其延迟的最小值和最大值。
2、发射沿(Launch Edge)与锁存沿(Latch Edge)
路径1、2、3实际上都是对寄存器到寄存器之间的数据路径之间的约束,而路径4则是约束纯组合逻辑。
由于寄存器的采样往往都发生在时钟的边沿,所以目的寄存器采样的值实际上是上个时钟周期的源寄存器的值,也就是说在源寄存器与目的寄存器之间其采样时间相差一个时钟周期。
![](https://i-blog.csdnimg.cn/blog_migrate/abdfc6156d8b65352101e5490ef78299.png)
发射沿(Launch Edge) :是源寄存器采样的时间点,也是时序分析路径的起点
锁存沿(Latch Edge):是目的寄存器采样的时间点,也是时序分析路径的终点
3、数据到达时间(Data Arrival Time)
由于2个寄存器之间存在的组合逻辑和走线延迟等,使得在发射沿采样到的数据需要一定的时间才能到达后级的锁存沿,这个时间就被称为 数据到达时间(Data Arrival Time)。
![](https://i-blog.csdnimg.cn/blog_migrate/f5677757d4590a232826724a7936df19.png)
如上图,在计算数据到达时间时,存在3个时间参数:
Tclk1:时钟信号从起点到达源寄存器 REG1 的时钟端口的时钟网络延时,产生原因 一般是走线延迟
Tco: 源寄存器REG1内部的数据输出延迟 ,这个延迟时间是寄存器的固有属性,只和使用的FPGA芯片型号有关
Tdata:数据从源寄存器 REG1 输出 Q 端到下级目的寄存器 REG2 的数据输入 D 之间的延时, 一般是组合逻辑器件产生的固有延时和走线延时
根据上图可以算出数据到达时间:Data Arrival Time = launch edge + Tclk1 + Tco +Tdata
4、数据需求时间 — 建立时间(Data Required Time - Setup)
时序约束的本质就是要满足所有寄存器的建立时间要求和保持时间要求,所以在数据经过一定的延迟从源寄存器到达目的寄存器后,同样需要满足目的寄存器的建立时间要求(Tsu)。
![](https://i-blog.csdnimg.cn/blog_migrate/95619c86d625cf74a89e6fa5241e8fbb.png)
如上图,在计算数据需求时间 — 建立时间时,存在2个时间参数:
Tclk2:时钟信号从起点到达目的寄存器 REG2 的时钟端口的时钟网络延时,产生原因一般是走线延迟
Tsu :在时钟有效边沿到达之间,输入数据必须保持不变的时间,这意味着上级寄存器的输入至少要在这之前就保持稳定
根据上图可以算出: Data Required Time + Tsu = latch edge + Tclk2 ,即 Data Required Time = latch edge + Tclk2 - Tsu
数据需求时间 — 建立时间,实际上是一种对时钟沿到来之前数据保持稳定的最极端时间要求。比如为了满足目的寄存器的建立时间要求,计算得到上级寄存器的输出必须至少在3ns之前即保持稳定,这也就意味着上级数据能到达的最晚时间是3ns,那么1ns、2ns到达自然是可以的。
5、数据需求时间 — 保持时间(Data Required Time - Hold)
建立时间和保持时间是寄存器的2个固定需求属性,所以在数据经过一定的延迟从源寄存器到达目的寄存器后,同样需要满足目的寄存器的保持时间要求(Th)。
![](https://i-blog.csdnimg.cn/blog_migrate/a08ba0c6208354e0fdc4d93a95e49319.png)
如上图,在计算数据需求时间 — 保持时间时,存在2个时间参数:
Tclk2:时钟信号从起点到达目的寄存器REG2的时钟端口的时钟网络延时,产生原因一般是走线延迟
Th:在时钟有效边沿到达之后,输入数据必须保持不变的时间,这意味着上级寄存器的输入至少要在这之后才能发生变化
所以可以算出: Data Required Time = latch edge + Tclk2 + Th
6、建立时间裕量(Setup Slack)
数据需求时间 — 建立时间实际上是一种对数据到来之前保持稳定的最极端的时间要求,比如为了满足目的寄存器的建立时间要求,计算得到上级寄存器的输出必须至少在时间刻度3ns之前即保持不变,这也就意味着上级数据能到达的最晚时间是3ns,那么1ns、2ns到达自然是可以的。
如果数据在1ns即到达了目的寄存器,那么建立时间裕量就是3ns-1ns = 2ns,那么这个裕量有什么作用呢或者说代表着什么?前面我们知道到寄存器之间可能会存在一段组合逻辑和走线延迟,如果你的设计中某2个寄存器之间的建立时间裕量是2ns,则意味着你还有空间去折腾,比如寄存器彼此之间还可以增加一些组合逻辑器件或者更长的走线。
![](https://i-blog.csdnimg.cn/blog_migrate/10228e5ca84276584ca7dbb2141b8a31.png)
根据上图,可以算出:
Setup Slack = Data Required Time – Data Arrival Time
即 Setup Slack = ( latch edge + Tclk2 - Tsu ) – ( launch edge + Tclk1 + Tco +Tdata )
即 Setup Slack = ( latch edge - launch edge ) + ( Tclk2 - Tclk1 ) - ( Tsu + Tco +Tdata )
即 Setup Slack = Tperiod + Tskew - ( Tsu + Tco +Tdata )
如果 Setup Slack 为正,则说明数据在规定的时间内达到了目的寄存器;反之,则认为数据并没有在规定的时间达到目标,此时 REG2 锁存的数据很有可能是亚稳态状态。
7、保持时间裕量(Hold Slack)
数据需求时间 — 保持时间实际上是一种对时钟沿到来之后数据保持稳定的最极端的时间要求,比如为了满足目的寄存器的保持时间要求,计算得到上级寄存器的输出必须至少在时间刻度3ns之前都保持不变,这也就意味着上级数据能变化的最早时间是3ns,那么4ns、5ns到达自然是可以的。
如果数据在5ns处才在目的寄存器发生了变化,那么保持时间裕量就是5ns-3ns = 2ns。
![](https://i-blog.csdnimg.cn/blog_migrate/0669d878f08a60a12563752df14ce43c.png)
根据上图,可以算出:
Hold Slack = Data Arrival Time - Data Required Time,
即 Hold Slack = ( latch edge + Tclk1 + Tco +Tdata ) - ( latch edge + Tclk2 + Th )
即 Hold Slack = ( Tco +Tdata - Th ) - ( Tclk2 - Tclk1 ) + ( latch edge - latch edge )
即 Hold Slack = ( Tco +Tdata - Th ) - Tskew
如果 Hold Slack 为正,则认为数据在被锁存的时候有足够多的稳定时间,是有效的;反之则认为数据可能是亚稳态状态。
8、总结
搞明白了这些概念,那么静态时序分析其实也就很简单了。上文出现了很多的公式,看起来有点晦涩难懂,但是没关系,这些公式实际上仅仅是起到一个辅助理解时序分析的作用,并不需要去记忆,更也不需要熟练掌握这些公式来生搬硬套时序分析。因为现在的综合工具已经足够智能了,你只需要提出时序约束的要求,综合工具 vivado 自然会对这些路径一一进行计算,你所要做的仅仅是找到时序裕量为负的路径并想办法改善即可。
此外,通过对上面公式的分析,可以让我们更好的了解静态时序分析的本质。根据上文有(1)和(2)两式:
建立时间裕量:Setup Slack = Tperiod + Tskew - ( Tsu + Tco +Tdata ) ----(1)
保持时间裕量:Hold Slack = ( Tco +Tdata - Th ) - Tskew ----(2)
其中:
Tperiod 是时钟周期;
Tskew 是寄存器之间的时钟偏差,产生的原因是时钟到达不同的寄存器的时钟端口有延迟;
Tsu 与 Th 分别是寄存器的建立时间要求和保持时间要求,这是寄存器的固有属性,只和 FPGA 的型号相关;
Tco 是从寄存器的输入端口到输出端口所需要的延时时间,同样是寄存器的固有属性;
Tdata 是寄存器之间的组合逻辑和走线延迟等之和,这与具体设计有关,平时我们大多都是通过减少Tdata来使得时间裕量为正,以此实现设计的时序收敛。
Tskew 实际上是一个可以被忽略掉的较小值,所以把它去掉,再对 (1)和(2)两式做变形(Slack>0需被满足),然后有(3)和(4)两式
Tperiod > ( Tsu + Tco +Tdata ) ----(3)
( Tco +Tdata ) > Th ----(4)
式子(3)中的(Tsu + Tco +Tdata)代表数据从源寄存器到目的寄存器所消耗的时间,即(Tsu + Tco +Tdata)< Tperiod 表示 数据从源寄存器的采样时刻传到目的寄存器的采样时刻,不能超过一个时钟周期 。如果数据传输超过一个时钟周期,那么就会导致目的寄存器开始采样的时候,从源寄存器出发的数据还没有传过来。
对于(4)式可以两边同时加上Tsu ,得到(5)式:
( Tco +Tdata + Tsu ) > ( Th + Tsu ) ----(5)
式子(5)中的(Tsu + Tco +Tdata)代表数据从源寄存器到目的寄存器所消耗的时间,(Th + Tsu)是建立时间和保持时间之和,即寄存器的采样窗口时间。那么(Tsu + Tco +Tdata) > Th + Tsu表示 数据从源寄存器的采样时刻传到目的寄存器的采样时刻,至少要大于寄存器的采样窗口 。假如数据传输时间不大于采样窗口,则意味着数据的传输是特别快的,有可能目的寄存器开始采样时,源寄存器的采样仍没有结束,如果这个时候输入端数据有变化,那么不仅源寄存器处于亚稳态,目的寄存器也将处于亚稳态!
所以,数据传输延时既不能太大以至于超过一个时钟周期,也不能太小以至于小于触发器采样窗口的宽度,即:
Tperiod > ( Tsu + Tco +Tdata ) > ( Th + Tsu )
这就是静态时序分析的物理意义了。