【数字IC/FPFA】时序约束--时钟约束-程序员宅基地

技术标签: 时序分析  数字IC设计  时序约束  

时钟周期约束,顾名思义,就是我们对时钟的周期进行约束,这个约束是我们用的最多的约束了,也是最重要的约束。
下面我们以vivado中的时钟约束为例,介绍时钟约束的相关内容。

Create_clock

在Vivado中我们通过使用create_clock来创建时钟周期约束。使用方法如下:

create_clock -name <name> -period <period> -waveform {
    <rise_time> <fall_time>} [get_ports <input_port>]

其中,参数name为创建的时钟的名称,period为时钟周期,waveform是时钟波形参数,第一个数为上升沿时间,第二个为下降沿发生的时间。
通过create_clock创建的时钟必须是主时钟primary clock,主时钟通常有两种情形:一种是时钟由外部时钟源提供,通过时钟引脚进入FPGA,该时钟引脚绑定的时钟为主时钟;另一种是高速收发器(GT)的时钟RXOUTCLK或TXOUTCLK
例1:
在这里插入图片描述
在上图中,板级时钟通过sysclk端口进入FPGA,通过一个输入缓冲器和一个时钟缓冲器后到达寄存器,我们可以使用如下命令进行主时钟的定义:

create_clock -period 10 [get_ports sysclk]  

例2:
在这里插入图片描述
在本例中,时钟源由高速收发器gt0提供,并通过rxclk端口进入FPGA,之后经过混合时钟管理单元MMCM生成其他时钟,以gt0发出的时钟为主时钟,其他生成时钟都有一个共同的时钟源,使用如下命令进行约束:

create_clock -name rxclk -period 3.33 [get_pins gt0/RXOUTCLK]

例3:
在这里插入图片描述
在例三中,我们采用差分时钟输入,这也是高速时钟的输入方式。上图中差分时钟驱动一个PLL,定义主时钟时必须只创建差分缓冲器的正极输入,如果同时创建了正极、负极输入,将会导致错误的CDC路径。我们使用如下命令进行约束:

create_clock -name sysclk -period 3.33 [get_ports SYS_CLK_clk_p]

create_generated_clock

创建衍生时钟,用法如下

create_generated_clock -name <generated_clock_name> 
                       -source <master_clock_source_pin_or_port> 
                       -multiply_by <mult_factor> 
                       -divide_by <div_factor> 
                       -master_clock <master_clk> 
                       <pin_or_port>

从时序约束的名字就能看出来,这个是约束我们在FPGA内部产生的衍生时钟, 所以参数中有个-source,就是指定这个时钟是从哪里来的,这个时钟叫做master clock,是指上级时钟,区别于primary clock。它可以是我们上面讲的primary clock,也可以是其他的衍生时钟。该命令并不是设定时钟的周期或波形的,而是描述时钟电路如何对上级时钟进行转换。这种转换可以是下面的几种:
1.简单的频率分频
2.简单的频率倍频
3.频率倍频与分频的组合,获得一个非整数的比例,通常由MMCM或PLL完成
4.相移或波形反相
5.占空比改变
6.上述所有关系的组合
衍生时钟又分两种情况:
1.Vivado自动推导的衍生时钟,往往由特殊单元(如MMCM、PLL)生成。
2.用户自定义的衍生时钟。
例1:
在这里插入图片描述
这是一个简单的二分频电路,我们可以采用如下两种方法对生成时钟进行约束:

#定义主时钟,周期10ns,50%占空比
create_clock -name clkin -period 10 [get_ports clkin]
#约束方法1,主时钟作为源点
create_generated_clock -name clkdiv2 -source [get_ports clkin] -divide_by 2 [get_pins REGA/Q] 
#约束方法2,REGA的时钟管脚作为源点
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -divide_by 2 [get_pins REGA/Q]

此外,我们还可以使用-edges选项进行约束,如下所示:

#该约束与上面等效
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -eedges {
    1 3 5} [get_pins REGA/Q]
 #1 3 5 分别为生成时钟一个周期的三个沿对应master clock的沿的位置
 #即生成时钟的第一个上升沿对应master clock的第一个沿,生成时钟的第二个沿对应master clock的第3个沿,生成时钟的第三个沿(下一个周期的上升沿)对应master clock的第5个沿

例2:
在这里插入图片描述
例1是通过分频、倍频得到衍生时钟的一个例子,本例则是通过改变占空比与相移得到一个衍生时钟。我们使用-edge_shift选项可以正向或反向设定每一个生成时钟波形的相移量。需要注意的是,-edge_shift选项不能与-devide_by、-multiply_by、-invert选项同时使用。在本例中,上级时钟为clkin,进入mmcm0单元,产生一个25%占空比、相移90°的时钟。
我们可以采用如下方法对生成时钟进行约束:使用上级时钟的1、2、3标号边沿(即0ns、5ns、10ns)定义生成时钟,为了得到预期波形,1和3标号边沿要分别移动2.5ns,得到2.5ns、5ns、12.5ns的波形:

#定义主时钟,周期10ns,50%占空比
create_clock -name clkin -period 10 [get_ports clkin]
#定义生成时钟,周期10ns,25%占空比,90°相移
create_generated_clock -name clkshift -source [get_pins mmcm0/CLKIN] -edges {
    1 2 3} 
-edge_shift {
    2.5 0 2.5} [get_pins mmcm0/CLKOUT]
#即生成时钟的第一个上升沿,和正向移动2.5ns后的跳变沿1对齐,生成时钟的第二个沿,和源时钟的第二个沿对齐,而生成时钟的第三个沿,和相移2.5ns后的跳变沿3对齐。

例3:
同时倍频与分频,这种情况通常用于定义MMCM或PLL的输出,一般使用这些IP核时会自动创建相应约束。假设MMCM将上级时钟倍频到4/3倍,这时需要我们同时使用-divede_by和-multiply_by选项来实现:

create_generated_clock -name clk43 -source [get_pins mmcm0/CLKIN] -multiply_by 4 
-divide_by 3 [get_pins mmcm0/CLKOUT]

例4:自动生成时钟 Automatically Derived Clocks
这种类型时钟算是生成时钟的一种特例,“自动”是指在已经定义了上级时钟的情况下,Vivado会自动为时钟管理单元CMBs(Clock Modifying Blocks)的输出管脚创建约束,官方称作Automatically Derived Clocks或Auto-generated Clock
如果约束中已经存在用户在某一网表对象上定义的时钟,则不会创建相同对象上的自动生成时钟。
下面给出一个具体例子,下图中上级时钟clkin驱动clkip/mmcm0单元的CLKIN输入,该单元是一个MMCME2资源的实例,则自动生成时钟的定义源点为clkip/mmcm0/CLKOUT,顶层与此源点连接的网络名为clkip/cpuClk,自动生成时钟的名字便是cpuClk。
在这里插入图片描述

set_clock_groups

默认情况下,Vivado会检测设计中所有时钟之间的路径时序,添加如下两种约束可以控制该功能:
set_clock_groups:建立时钟组,Vivado不会对不同时钟组的时钟之间进行时序分析
set_false_path:将两个时钟之间的路径设置为false path后,不会对该路径进行任何时序分析;
根据时钟间的关系,可以做如下分类:
1.同步时钟:即两个时钟间有可预知的相对相位,通常它们的时钟树源自网表中的同一个根,且有一个公共周期
2.异步时钟:两个时钟间有无法预知的相对相位。比如两个独立的晶振信号通过两个输入端口进入FPGA中,生成两个时钟。由于两个主时钟没有明确的相位关系,两个生成时钟间便是异步的;
3.不可扩展时钟:Xilinx官方称作Unexpandable Clocks,是指时序引擎在1000个周期内无法判断两个时钟是否有公共周期。这种情况通常发生在两个时钟周期比是一个特殊的分数,比如一个主时钟通过MMCM生成一个周期为5.125ns的时钟clk1和一个周期为6.666ns的时钟clk2,尽管它们在时钟树的根上有一个确定的相位关系,但是在1000个周期内时钟上升沿无法再次对齐。
例1:异步时钟组
同步时钟可以安全地进行时序分析,异步时钟和不可扩展时钟虽然通过时序分析也会得到一个裕量值,但这个值不可作为可靠结果。因此从这个角度出发,不可扩展时钟也可以视作一种特殊的异步时钟,因此就需要通过设置时钟组来忽略异步时钟的时序路径上的时序分析 。
如下图所示,一个主时钟clk0通过MMCM生成两个时钟usrclk和itfclk;另一个主时钟clk1通过另一个MMCM生成两个时钟clkrx和clktx,则我们用如下命令创建异步时钟组:

set_clock_groups -name async_clk0_clk1 
                 -asynchronous 
                 -group {
    clk0 usrclk itfclk} 
                 -group {
    clk1 gtclkrx gtclktx}
#如果生成的时钟名称事先不知道,也可以用如下写法
set_clock_groups -name async_clk0_clk1 -asynchronous -group [get_clocks -include_generated_clocks clk0] -group [get_clocks -include_generated_clocks clk1]

例2:互斥时钟组 Exclusive Clock Groups
下面再介绍另一种会用到时钟组的情况:某些设计会有几个操作模式,不同操作模式使用不同的时钟,这些时钟通常由专用的时钟选择器进行选择,如BUFGMUX和BUFGCTRL。
这些单元都是组合逻辑单元,Vivado会将所有输入传递到输出。在Vivado IDE中,这几个时钟可以同时存在时钟树上,方便同时报告所有操作模式,但是在硬件中这是不可能的,它们之间是互斥的,这些时钟便称作互斥时钟
举个例子,一个MMCM实例生成的两个时钟clk0和clk1,与一BUFGMUX实例clkmux相连,clkmux的输出驱动设计时钟树。默认情况下,虽然clk0和clk1共享同一时钟树,但不能同时存在,然而Vivado还是会分析clk0和clk1之间的路径,这个问题要通过设置互斥时钟组来解决,达到禁止分析这两个时钟间路径的目的。约束方法如下:

set_clock_groups -name exclusive_clk0_clk1 
                 -physically_exclusive 
                 -group clk0 -group clk1

在ASIC工艺中通常使用-physically_exclusive和-logically_exclusive代表不同的信号完整性分析模式,但对于Xilinx FPGA而言,二者是等价的,都可以使用。

时钟延迟、抖动与不确定性

上述约束可以说都是对时钟的理想特征进行约束,为了更精确地进行时序分析,设计者还必须设定一些与运行环境相关的可预测变量和随机变量,这部分也称作时钟的不确定性特征

时钟延迟latency

经过板子和FPGA器件内部的传输,时钟边沿到达目的地后会有一个确定的延迟,这个延迟可以分为两个部分看待:
网络延迟:也称作插入延迟,指在FPGA内部传输带来的延迟;Vivado会自动分析计算该延迟,布线过程前只是一个粗略的估计,布线后便可以得到一个精确的值;对于生成时钟,包含其本身的网络延迟和上级时钟的网络延迟两部分。
源端延迟:通常指FPGA器件外,时钟进入源点前的传输延迟,这部分延迟与PCB设计相关,需要用set_clock_latency命令进行约束。
下面给出一个约束源端时钟延迟的例子:

# Minimum source latency value for clock sysClk (for both Slow and Fast corners)
set_clock_latency -source -early 0.2 [get_clocks sysClk]
# Maximum source latency value for clock sysClk (for both Slow and Fast corners)
set_clock_latency -source -late 0.5 [get_clocks sysClk]

时钟抖动jitter

对于ASIC器件来说,时钟抖动通常代表了时钟不确定性特征,但对于Xilinx FPGA而言,抖动属性被当作可预测变量看待。抖动有的需要单独设置,有的在时序分析过程中自动计算,抖动分为两种:
输入抖动:指实际时钟边沿与理想时钟边沿到达时刻之间的差值,使用set_input_jitter命令为每个主时钟单独设置输入抖动,但是不能直接为生成时钟设置输入抖动,这部分由工具自动计算,如果(1)生成时钟由一个组合或时序单元创建,生成时钟的抖动与上级时钟相同;(2)生成时钟由 MMCM或PLL驱动,生成时钟的抖动为一个自动计算的值。
系统抖动:指电源噪声、板级噪声或其它原因引起的整体的抖动,对于整个设计,使用set_system_jitter命令设置一个值即可,会应用到所有时钟。
下面给出一个约束输入抖动的例子:

#主时钟传输过程中有±100ps的抖动
set_input_jitter [get_clocks -of_objects [get_clocks sysclk]] 0.1

不过,时钟抖动对整个时钟不确定性计算的影响不是太大。计算时钟不确定性时对每条路径都是独立的,且主要依赖于时钟拓扑结构、路径上的时钟对、时钟树上是否存在MMCM/PLL单元等其它因素。

附加的时钟不确定性 Additional Clock Uncertainty

使用set_clock_uncertainty命令可以根据需要为特定的时钟关系定义附加的时钟不确定性,这样在时序分析时,可以为设计中的某些部分增加额外裕量。
前面文章说过XDC约束带有顺序性,后面的约束会重写前面的约束。但在这里,时钟间的不确定性总是优先于单个时钟的不确定性,不管约束顺序如何,看下面的例子:

set_clock_uncertainty 2.0 -from [get_clocks clk1] -to [get_clocks clk2] 
set_clock_uncertainty 1.0 [get_clocks clk1]

这里首先约束从clk1到clk2有一个2ns的时钟不确定性,接着又约束clk1有1ns的时钟不确定性,但是后面这条约束不会改动从clk1到clk2之间的关系,同时,要注意clk1到clk2有时钟间的不确定性,clk2到clk1也有时钟间的不确定性,所以要约束完整。

创建虚拟时钟

虚拟时钟通常用于设定对输入和输出的延迟约束,这个约束其实是属于IO约束中的延迟约束,之所以放到这里来讲,是因为虚拟时钟的创建,用到了本文的一些理论。顾名思义,虚拟时钟,就是没有与之绑定的物理管脚。
虚拟时钟主要用于以下三个场景:
外部IO的参考时钟并不是设计中的时钟
FPGA I/O路径参考时钟来源于内部衍生时钟,但与主时钟的频率关系并不是整数倍
针对I/O指定不同的jitter和latency
  简而言之,之所以要创建虚拟时钟,对于输入来说,是因为输入到FPGA数据的捕获时钟是FPGA内部产生的,与主时钟频率不同;或者PCB上有Clock Buffer导致时钟延迟不同。对于输出来说,下游器件只接收到FPGA发送过去的数据,并没有随路时钟,用自己内部的时钟去捕获数据。
  如下图所示,在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参数,因此被称为虚拟时钟。
再举个输出的例子,我们常用的UART和SPI,当FPGA通过串口向下游器件发送数据时,仅仅发过去了uart_tx这个数据,下游器件通过自己内部的时钟去捕获uart_tx上的数据,这就需要通过虚拟时钟来约束;而当FPGA通过SPI向下游器件发送数据时,会发送sclk/sda/csn三个信号,其中sclk就是sda的随路时钟,下游器件通过sclk去捕获sda的数据,而不是用自己内部的时钟,这是就不需要虚拟时钟,直接使用set_output_delay即可。
需要注意的是,虚拟时钟必须在约束I/O延迟之前被定义。

最大最小延迟约束

顾名思义,就是设置路径的max/min delay,主要应用场景有两个:

输入管脚的信号经过组合逻辑后直接输出到管脚

异步电路之间的最大最小延迟
在这里插入图片描述
设置方式为:

set_max_delay <delay> [-datapath_only] [-from <node_list>][-to <node_list>][-through <node_list>]
set_min_delay <delay> [-from <node_list>] [-to <node_list>][-through <node_list>]

max/min delay的约束平时用的相对少一些,因为在跨异步时钟域时,我们往往会设置asynchronous或者false_path对于异步时钟,我们一般都会通过设计来保证时序能够收敛,而不是通过时序约束来保证

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40268672/article/details/124065733

智能推荐

论文笔记--DeepFly3D,一种基于深度学习的方法,用于拴住的成年果蝇的3D肢体和附属物追踪_动物行为3d模拟算法-程序员宅基地

文章浏览阅读3k次。没有外部校准模式的校准  从多个图像中估计3D姿势需要校准相机,以达到与目标尺寸相称的精度水平–在测量像果蝇这样小的动物的腿部运动时,这是一个困难的挑战。因此,DeepFly3D没有使用典型的外部校准网格,而是使用苍蝇本身作为校准目标。它检测苍蝇身体上的任意点,并依靠捆绑调整(Chavdarova等人,2018)来同时为这些点分配三维位置,并估计每个摄像头的位置和方向。为了提高鲁棒性,它执行了适用于系留苍蝇的肢体长度和运动范围的几何约束。_动物行为3d模拟算法

未能加载文件或程序集“ExcelHelper”或它的某一个依赖项。试图加载格式不正确的程序。_未能加载文件或程序集“excelreport”或它的某一个依赖项。试图加载格式不正确的-程序员宅基地

文章浏览阅读823次。未能加载文件或程序集“ExcelHelper”或它的某一个依赖项。试图加载格式不正确的程序。说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“ExcelHelper”或它的某一个依赖项。试图加载格式不正确的_未能加载文件或程序集“excelreport”或它的某一个依赖项。试图加载格式不正确的

python中try...except...else...finally_try: 语句1 语句x #该语句会产生异常 语句2 except: 语句3 else: 语句4 f-程序员宅基地

文章浏览阅读267次。python中的try、except、else、finally用法_try: 语句1 语句x #该语句会产生异常 语句2 except: 语句3 else: 语句4 finally:

rosbag文件如何解析出来_ros解析bag-程序员宅基地

文章浏览阅读2.5k次。1、cd xxx/xxxx //进入bag所在路径2、rosbag info xxx.bag //查看rosbag的信息如下图所示:解析数据获得带时间戳的点云数据1、rosrun pcl_ros bag_to_pcd <*.bag> <output_directory>获得带时间戳的图像数据法1如下代码能一次性没有遗漏的解析出全部带有时间戳的图片#coding:utf-8import roslib; import rosbagimport _ros解析bag

linux 查看gz打包文件里的日志_根据时间查询.gz中的日志-程序员宅基地

文章浏览阅读2.8w次,点赞10次,收藏7次。有很多时候我们想要查看日志文件,发现服务器已经被重启了,然后原来的日志就被打包存起来了,这个时候生成的gz日志文件我们就没有办法直接去查看了。 所以这个时候我们就需要zcat+日志名.gz来查看,还可以用 | grep 来进行筛选自己想要的日志信息。..._根据时间查询.gz中的日志

Snort规则入门学习_snort和mtx规则区别-程序员宅基地

文章浏览阅读6.9k次,点赞5次,收藏32次。Snort规则学习入门引言从一条简单的snort规则开始alert tcp any any -> 192.168.1.0/24 111(content:"|00 01 86 a5|";msg:"mountd access";)snort 每条规则都可以分成逻辑上的两个部分:规则头(header)和规则选项(General Option)从开头到括号前属于规则头部分,括号内的部分属于规则选项。规则选项中冒号前面的词叫做选项关键词(option keywords)。如果许多选项组合在一起_snort和mtx规则区别

随便推点

【PCIe总线】-- PCI、PCIE基础知识_pci1x2x-程序员宅基地

文章浏览阅读2.7k次。整理的一部分PCI、PCIe基础知识PCI基础知识: 1.PCI总线的组成:HOST桥、PCI桥、PCI设备、 2.PCI桥的作用可以隔离PCI设备,不影响各条总线的带宽 3.总线x1上的通讯和总线x2上的通讯无关,同一条总线上的设备可以自由通讯; 4.如果PCI桥出现问题,那么PCI桥下的设备之间可以自由通讯但是无法将数据发送到外面 5.PCI的..._pci1x2x

LVM逻辑卷与快照_卷和快照-程序员宅基地

文章浏览阅读2.4k次。简介LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制,它由Heinz Mauelshagen在Linux 2.4内核上实现,Linux用户安装Linux操作系统时遇到的一个常见的难以决定的问题就是如何正确地评估各分区大小,以分配合适的硬盘空间。普通的磁盘分区管理方式在逻辑分区划分好之后就无法改变其大小,当一个逻辑分区存..._卷和快照

HTTP状态码(HTTP Status Code)-程序员宅基地

文章浏览阅读1.9k次。HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。HTTP: Status 1xx (临时响应)->表示临时响应并需要请求者继续执行操作的状态代码。详细代码及说明:HTTP: Status 1

(建议收藏)计算机网络:TCP-首部格式,序号确认和连接管理习题解析与拓展_当 tcp 接收端要确认一个有效载荷大小 是100b和序列号为800 的数据段时,应该-程序员宅基地

文章浏览阅读3k次,点赞3次,收藏46次。TCP(1)-首部格式,序号确认和连接管理一.单选题(共12题,69.6分)1 关于TCP,以下哪一项描述是错误的A、提供面向字节流传输服务B、因为面向字节流,所示实现过程简单C、提供面向连接传输服务D、实现进程间通信正确答案: B首先要明确一点,TCP确实是面向字节流的,物理层是比特流。意思就是说,在网络里,不管是UDP还是TCP,都是面向字节流的,因为他们都以字节传输。但是TCP要比UDP更加复杂,这里不能说它所示实现过程简单,和UDP比复杂多了。TCP是面向连接的,服务给应用层_当 tcp 接收端要确认一个有效载荷大小 是100b和序列号为800 的数据段时,应该

python是高级语言还是低级语言_作为一名程序员必需知道的术语:高级/低级语言?解释/编译语言?...-程序员宅基地

文章浏览阅读1.3w次。作为一名合格的程序员,你必须知道一些计算机软件编程方面的术语。这次给大家解释一下下面两对常见的术语:高级语言/低级语言、解释语言/编译语言。什么是高级语言/低级语言?1、高级语言我们现在大多数人使用的语言,如C、C++、Python、Java、Matlab、LabVIEW等等,都属于高级语言,相对于低级语言,它更接近于我们平时正常的人思维,其最大的特点是编写容易,代码可读性好。实现同样的功能,使用..._python属于高级语言吗

Button和ImageButton_下列说法错误的是a button和imagebutton都可以实现按钮功能b button没有src-程序员宅基地

文章浏览阅读1.5k次。Button----按钮ImageButton----图片按钮 共有特征:都可以作为一个按钮产生点击事件不同点1、 Button有text的属性,ImageButton没有2、 ImageButton有src属性,Button没有onClick事件Button和ImageButton都有一个onClick事件通过他们自身的.setOnClickListener(_下列说法错误的是a button和imagebutton都可以实现按钮功能b button没有src属

推荐文章

热门文章

相关标签