关灯
请选择 进入手机版 | 继续访问电脑版
米联客uisrc 首页 博文 笔记 查看内容
1

米联客(MSXBO)基于VIVADO FPGA时序笔记之时钟(二)

摘要: 1.1概述数字设计中,“时钟”表示在寄存器间可靠地传输数据所需的参考时间。Vivado的时序引擎通过时钟特征来计算时序路径需求,通过计算裕量(Slack)的方法报告设计时序空余。时钟必须有合适的定义,包含如下特性: ...

1.1概述

数字设计中,“时钟”表示在寄存器间可靠地传输数据所需的参考时间。Vivado的时序引擎通过时钟特征来计算时序路径需求,通过计算裕量(Slack)的方法报告设计时序空余。时钟必须有合适的定义,包含如下特性:

1)、定义时钟树的驱动管脚或端口,通常称作根或源点。

2)、通过周期和波形属性来描述时钟边沿。

3)、周期(period)以ns为单位进行设定,与波形重复率相关。

4)、波形(waveform)以列表的形式给出,表中包含上升沿和下降沿在周期中的绝对时间,以ns为单位。

 

如下图给出了两个时钟

Clk0: period=10, waveform={0 5}

Clk1: period=8, waveform = {2 8}

上述给出的只是时钟的理想特征,实际上当时钟通过外部的晶振或者芯片时钟,通过FPGA的管脚进入FPGA内部逻辑,时钟会产生延迟、飘逸、抖动、失真等现象,所以在硬件设计和软件设计上都必须考虑时钟的影响。

1)、应该增加时钟的稳定性,减少抖动和失真,在一些工业场合还要考虑温度导致的时钟偏移;

2)、高频的时钟应该走专用的FPGA时钟管脚

3)、异步时钟传输数据需要正确采取跨时钟域的解决办法

4)、使用VIVADO软件进行正确的时序约束设计

 

1.2主时钟Primary Clock

主时钟通常由两个来源:

1)、板级时钟通过输入端口进入设计;

2)、GT收发器的输出管脚(如恢复时钟)。主时钟必须与一个网表对象相连,该对象代表了所有时钟边沿的开始点,并且在时钟树中向下传递。也可以说,主时钟的源点定义了0时刻,Vivado靠此来计算时钟延迟和不确定性。

 

主时钟只能通过create_clock命令来定义,且必须放在约束的开始,这是因为其它时序约束几乎都要参考主时钟。下面给出两个主时钟的例子。第一个例子如下图所示,采用单端时钟输入:

如上图,板级时钟通过sysclk端口进入FPGA,通过一个输入缓冲器和一个时钟缓冲器后到达寄存器。下面是一些常用的时钟约束定义方法:

 

1)、定义一个周围为10ns,占空比50%,无相移的时钟

create_clock –name sysclk -period 10 [get_ports sysclk]  #10ns周期,,

2)、定义一个板级时钟devclk,周期10ns,占空比25%相移90°。

create_clock -name devclk -period 10 -wavefor {2.5 5} [get_ports sysclk]

3)、GTP/GTX恢复时钟

高速通信GTP/GTX的时钟是来自于恢复时钟,对于初学者来说可能还不清楚什么是恢复时钟,在做光通信部分的例子就知道了。光通信1条数据通道,可以从1条数据通道中恢复出来传输的时钟,然后用这个时钟同步用户数据就不会出错了。在GT0的引脚上定义rxclk时,gt0 / RXOUTCLK就是由MMCM驱动的所有生成的时钟的时钟源点,

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

4)、采用差分时钟输入只要约束P端就可以

create_clock -name sysclk -period 3.33 [get_ports SYS_CLK_clk_p]

上图中差分时钟驱动一个PLL,差分时钟输入通过IBUFDS转为单端进入CLKIN1。如果同时创建了P和N端输入,将会导致错误的CDC路径。

1.3虚拟时钟Virtual Clock

虚拟时钟通常用于设定输入和输出的延迟约束。之所以称为“虚拟”,是因为这种时钟在物理上没有与设计中的任何网表对象相连。定义时使用create_clock命令,但无需指定源对象。使用虚拟时钟在设置IO delay约束的时候可以简化我们的代码量,增加可读性,这个在我们最后分析udp通信RGMII时序约束中会用到。

下列情况需要用到虚拟时钟:

1)、所有设计时钟都不是外部器件I/O的参考时钟。

2)、FPGA的I/O路径与一个内部生成的时钟相关,但是该时钟不能合适地通过对板级时钟计时来生成(如两个周期的比不是整数)。

3)、希望为与I/O延迟约束相关的时钟设定不同的抖动和延迟,但是不希望修改内部时钟的特征。

比如时钟clk_virt的周期为10ns,且不与任何网表对象相连,可以这样定义:

create_clock -name clk_virt –period 10

没有指定objects参数。注意,虚拟时钟必须在使用之前便定义好。

        

虚拟机时钟的应用

1)、用于IO延迟案例1

create_clock -name clk –period 10 [get_ports clkin]

create_clock –name vclk –period 5

set_input_delay 6 –clock clk [get_ports dina]

set_input_delay 6 –clock vclk [get_ports dinb]

以上时序关于虚拟时钟的约束作用和经过MMCM的输出时钟作用是一样的。

 

 

2、用于IO延迟案例2

create_clock -name clk –period 10 [get_ports clkin]

create_clock –name vclk –period 5

set_clock_latency –source 1[get_clocks vclk]

set_input_delay –clock vclk –max 4 [get_ports dina]

set_input_delay –clock vclk –min 2 [get_ports dina]

由于外部数据没有匹配的输入同步时钟,所以可以指定一个虚拟时钟设置dina的时序约束。

1.4生成时钟Generated Clock

生成时钟是指在设计内部由特殊单元(如MMCM、PLL)或用户逻辑驱动的时钟。生成时钟与一个上级时钟(注:官方称作master clock,为与primary clock作区分,这里称作上级时钟)相关,其属性也是直接由上级时钟派生而来。上级时钟可以是一个主时钟,也可以是另一个生成时钟。

生成时钟使用create_generated_clock命令定义,该命令不是设定周期或波形,而是描述时钟电路如何对上级时钟进行转换。这种转换可以是下面的关系:

1)、简单的频率分频

2)、简单的频率倍频

3)、频率倍频与分频的组合,获得一个非整数的比例,通常由MMCM或PLL完成

4)、相移或波形反相

5)、占空比改变

6)、上述所有关系的组合

注意:Vivado计算生成时钟的延迟时,会追踪生成时钟的源管脚与上级时钟的源管脚之间的所有组合和时序路径。某些情况下可能只希望考虑组合逻辑路径,在命令行后添加-combinational选项即可。

以下是一些生成时钟的案例

 

1)、简单的2分频

下图中,主时钟clkin通过端口进入FPGA,使用一个寄存器REGA对其2分频,得到的生成时钟clkdiv2驱动其它的寄存器管脚

可以采用如下两种方法对生成时钟进行约束:

#定义主时钟,周期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]

 

         2)使用2分频-edges命令

约束命令中使用**-source选项来设定上级时钟,但如上所示,该选项只能设定为一个端口或管脚类型的网表对象,不能直接设置为时钟类型对象。上面约束使用-divide_by选项设置分频系数,此外还可以使用-edges**选项,如下所示:

#该约束与上面等效

create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -eedges {1 3 5} [get_pins REGA/Q]

-edges的参数为一个列表,该列表通过主时钟的边沿来描述生成时钟的波形。列表中的值为主时钟边沿的序号(注意观察上图),由时钟上升沿开始,定义了生成时钟边沿的时间点。

 

3)、改变占空比与相移

如果仅需要改变时钟的相移,使用**-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 clkshifit -source [get_pins mmcm0/CLKIN] -edges {1 2 3} -edge_shift {2.5 0 2.5} [get_pins mmcm0/CLKOUT]

4)、同时倍频与分频

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

create_clock -name clkin -period 10 [get_ports clkin] #定义主时钟

#定义生成时钟,4/3倍频

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

5)、仅通过组合路径追踪上级时钟

我们想在多路复用器输出上创建一个生成的时钟,以反映从主时钟到多路复用器的组合路径的延迟。 这是通过使用-combinational命令行选项完成的:

create_generated_clock -name clkout -source [get_pins mmcm0/CLKIN] –combinational [get_pins MUX/O]

下图中,上级时钟同时传递到寄存器和多路选择器中,寄存器对时钟进行2分频。多路选择器从寄存器的2分频时钟和上级时钟中选择一个作为生成时钟输出。

显而易见,从上级时钟到生成时钟有两条路径,一条为时序路径,一条为组合路径。如果我们只希望考虑组合路径上的延迟时,定义生成时钟时就需要使用-combinational选项。

         5)、ODDR驱动的转发时钟

在此示例中,在由ODDR单元驱动的输出端口上创建了转发时钟。 转发的时钟参考驱动ODDR / CLKDIV引脚的主时钟,并具有与主时钟相同的周期(-divide_by 1):

create_generated_clock -name ck_vsf_clk_2 \

-source [get_pins ODDRE1_vsfclk2_inst/CLKDIV] -divide_by 1 [get_ports vsf_clk_2]

6)、自动生成时钟

这种类型时钟算是生成时钟的一种特例,“自动”是指在已经定义了上级时钟的情况下,Vivado会自动为时钟管理单元CMBs(Clock Modifying Blocks)的输出管脚创建约束。官方称作Automatically Derived Clocks或Auto-generated Clock。

 

7系列FPGA的CMB单元包括MMCM、PLL、BUFR、PHASER;UltraScale系列FPGA的CMB单元种类与数量更多,这里不陈列。如果约束中已经存在用户在某一网表对象上定义的时钟,则不会创建相同对象上的自动生成时钟。

 

下面给出一个具体例子。下图中上级时钟clkin驱动clkip/mmcm0单元的CLKIN输入,该单元是一个MMCME2资源的实例。则自动生成时钟的定义源点为clkip/mmcm0/CLKOUT,顶层与此源点连接的网络名为clkip/cpuClk,自动生成时钟的名字便是cpuClk。

如上所述,Vivado会自动创建自动生成时钟的名称(Name),如果两个名称发生冲突也会自动添加后缀,如usrclk、usrclk_1等等。Vivado也支持对已经创建好的自动生成时钟重新命名,但很少用到,这里不做介绍。

1.5 时钟组Clock Group

 

很多初学者应该也没有接触过时钟组这个概念。默认情况下,Vivado会测量设计中所有时钟之间的路径时序。添加如下两种约束可以控制该功能:

 

set_clock_groups:建立时钟组,Vivado不会对不同时钟组的时钟之间进行时序分析。

set_false_path:将两个时钟之间的路径设置为false path后,不会对该路径进行任何时序分析。

划分时钟组通常有两个依据:(1).原理图或时钟网络报告中的时钟树拓扑图,判断哪些时钟不应该放在一起做时序分析;(2).时钟交互报告查看两个时钟间存在的约束,判断它们是否有共享的主时钟(代表是否有已知的相位关系)或者是否有公共周期。

 

但要明白,我们设定时钟组的目的还是为了保证设计在硬件中能正常工作,因此我们必须确保这些忽略了时序分析的路径有合适的再同步电路或异步数据传输协议。根据时钟间的关系,可以做如下分类:

 

同步时钟:即两个时钟间有可预知的相对相位,通常它们的时钟树源自网表中的同一个根,且有一个公共周期。

异步时钟:两个时钟间有无法预知的相对相位。比如两个独立的晶振信号通过两个输入端口进入FPGA中,生成两个时钟。由于两个主时钟没有明确的相位关系,两个生成时钟间便是异步的。

不可扩展时钟:官方称作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 clkrx clktx}

#如果时钟名称事先不知道,可以用如下写法

set_clock_groups -name async_clk0_clk1 -asynchronous -group [get_clocks -include_generated_clocks clk0] -group [get_clocks -include_generated_clocks clk1]

 

2、互斥时钟组

下面再介绍另一种会用到时钟组的情况。某些设计会有几个操作模式,不同操作模式使用不同的时钟。这些时钟通常由专用的时钟选择器进行选择,如BUFGMUX和BUFGCTRL,最好不要用LUT作时钟选择器。

 

这些单元都是组合逻辑单元,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而言,二者是等价的,都可以使用。

 

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

 

1)、时钟延迟latency

经过板子上和FPGA器件内部的传输,时钟边沿到达目的地后会有一个确定的延迟。这个延迟可以分为两个部分看待:

网络延迟:

也称作插入延迟,指再FPGA内部传输带来的延迟。Vivado会自动分析计算该延迟,布线过程前只是一个粗略的估计,布线后便可以得到一个精确的值。对于生成时钟,包含其本身的网络延迟和上级时钟的网络延迟两部分。

源端延迟:

通常指FPGA器件外,时钟进入源点前的传输延迟,这部分延迟与PCB设计相关,需要用set_clock_latency命令进行约束。

VIVADO IDE 使用set_clock_latency 设置时钟在外部的延迟

# 最小延迟

set_clock_latency -source -early 0.2 [get_clocks sysClk]

# 最大延迟

set_clock_latency -source -late 0.5 [get_clocks sysClk]

2)抖动

#主时钟传输过程中有±100ps的抖动

set_input_jitter [get_clocks -of_objects [get_clocks sysclk]] 0.1

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

2)、附加的时钟不确定性

使用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之间的关系。

 

关于时序约束时钟部分的介绍就到这里,掌握了这些基本的概念和理论是我们后面实战的基础。

6

路过

雷人

握手

鲜花

鸡蛋

刚表态过的朋友 (6 人)

说点什么...

已有1条评论

最新评论...

I'mpossible2020-4-1 16:28引用

感谢分享

查看全部评论(1)

本文作者
2019-10-20 22:50
  • 5
    粉丝
  • 1393
    阅读
  • 1
    回复
相关分类
资讯幻灯片
热门评论
热门专题
排行榜

关注我们:微信公众号

官方微信

官方微信

客服热线:

0519-80699907

公司地址:常州溧阳市天目云谷3号楼北楼2楼

运营中心:常州溧阳市天目云谷3号楼北楼2楼

邮编:213300 Email:270682667#qq.com

Copyright   ©2019-2026  米联客uisrc内容版权归©UISRC.COM技术支持:UISRC.COM  备案号:苏ICP备19046771号