虚拟时钟我的理解就是源同步模型中,目的寄存器在FPGA内部,源寄存器在外部,同时,需要对数据端口做input delay,ouput delay的约束,那么fpga无法知道源时钟的信息,需要使用虚拟时钟,告诉FPGA源时钟的信息,input delay,ouput delay的约束并不产生什么影响,也只是告诉FPGA外部数据延时的情况(是有一个范围),在进行布线和时序计算的时候,需要把误差给考虑到。
使用虚拟时钟约束的场景主要涉及到FPGA设计中与外部器件同步或源同步接口的时序分析问题。以下是几个具体的例子来说明使用虚拟时钟约束的场景:
- 外部IO的参考时钟并不是设计中的时钟
在FPGA设计中,有时外部IO的参考时钟并不直接连接到FPGA的内部时钟网络上,或者其路径与内部主时钟路径不一致(例如,多了一个BUFFER)。此时,时序分析工具无法直接利用内部主时钟来准确评估外部IO路径的时序性能。因此,需要创建一个虚拟时钟来模拟外部IO的参考时钟,以便进行时序约束。
例如,假设外部有一个10MHz的时钟信号作为FPGA某个IO接口的参考时钟,但该时钟信号并未直接连接到FPGA的内部时钟输入引脚,而是经过了一个BUFFER后才到达FPGA的IO引脚。此时,可以在约束文件中创建一个周期为10ns的虚拟时钟,并使用该虚拟时钟来约束相关IO路径的输入和输出延时。
- FPGA I/O路径参考时钟来源于内部衍生时钟,但与主时钟的频率关系不是整数倍
在某些情况下,FPGA的I/O路径可能使用内部生成的衍生时钟作为参考时钟,但这些衍生时钟与内部主时钟的频率关系可能不是整数倍。此时,直接使用主时钟来约束I/O路径的时序可能会导致分析结果不准确。因此,需要创建一个虚拟时钟来模拟这种非整数倍关系的衍生时钟。
例如,假设FPGA内部有一个主时钟clk,频率为10MHz。同时,FPGA内部还通过MMCM(混合模式时钟管理器)生成了一个60MHz的衍生时钟clk_derived,用于某个IO路径的数据采样。由于60MHz与10MHz不是整数倍关系,因此不能直接使用clk来约束该IO路径的时序。此时,可以创建一个周期为16.67ns(60MHz的周期)的虚拟时钟,并使用该虚拟时钟来约束相关IO路径的输入和输出延时。
- 在不修改时钟特性的情况下针对I/O指定不同的jitter和latency
在某些特定应用中,可能需要在不修改内部时钟特性的情况下,为FPGA的输入输出路径指定不同的jitter(抖动)和latency(延迟)。这通常用于优化系统性能或满足特定的时序要求。此时,可以使用虚拟时钟来单独设置这些参数。
例如,假设FPGA的某个IO路径需要具有较低的jitter和较高的latency以满足外部器件的同步要求。同时,内部主时钟clk的jitter和latency已经固定,无法修改。此时,可以创建一个与clk同频的虚拟时钟virtual_clk,并在约束文件中为virtual_clk设置较低的jitter和较高的latency值。然后,使用virtual_clk来约束相关IO路径的输入和输出延时。
如下图所示,在FPGA的A和B端口分别有两个输入,其中捕获A端口的时钟是主时钟,而捕获B端口的时钟是MMCM输出的衍生时钟,而且该衍生时钟与主时钟的频率不是整数倍关系。
这种情况下时序约束如下:
create_clock -name sysclk -period 10 [get_ports clkin]
create_clock -name virclk -period 6.4
set_input_delay 2 -clock sysclk [get_ports A]
set_input_delay 2 -clock virclk [get_ports B]
可以看到,创建虚拟时钟用的也是create_clock约束,但后面并没有加get_ports参数,因此被称为虚拟时钟。
set_input_delay其实就是告诉了编译器,分析的哪个数据端口路径,数据端口路径延迟范围是什么,所在的时钟域是什么。
再举个输出的例子,我们常用的UART和SPI,当FPGA通过串口向下游器件发送数据时,仅仅发过去了uart_tx这个数据,下游器件通过自己内部的时钟去捕获uart_tx上的数据,这就需要通过虚拟时钟来约束;而当FPGA通过SPI向下游器件发送数据时,会发送sclk/sda/csn三个信号,其中sclk就是sda的随路时钟,下游器件通过sclk去捕获sda的数据,而不是用自己内部的时钟,这是就不需要虚拟时钟,直接使用set_output_delay即可。
注意,虚拟时钟必须在约束I/O延迟之前被定义。
总结
虚拟时钟约束在FPGA设计中非常有用,特别是在处理与外部器件同步或源同步接口的时序问题时。通过创建虚拟时钟来模拟外部或内部衍生时钟的时序特性,可以更准确地进行时序分析和约束,从而确保设计的稳定性和性能。
最大最小延迟约束
顾名思义,就是设置路径的max/min delay,主要应用场景有两个:
输入管脚的信号经过组合逻辑后直接输出到管脚
异步电路之间的最大最小延迟(跨时钟域)
设置方式为:
set_max_delay [-datapath_only] [-from <node_list>][-to <node_list>][-through <node_list>]
set_min_delay [-from <node_list>] [-to <node_list>][-through <node_list>]
max/min delay的约束平时用的相对少一些,因为在跨异步时钟域时,我们往往会设置asynchronous或者false_path。对于异步时钟,我们一般都会通过设计来保证时序能够收敛,而不是通过时序约束来保证。