Vivado集成开发环境时序约束介绍

Vivado时序约束

本文主要介绍如何在Vivado设计套件中进行时序约束,原文出自Xilinx中文社区。

1Timing Constraints in Vivado -UCF to XDC

Vivado软件相比于ISE的一大转变就是约束文件,ISE软件支持的是UCF(User Constraints File),而Vivado软件转换到了XDC(Xilinx Design Constraints)。XDC主要基于SDC(Synopsys Design Constraints)标准,另外集成了Xilinx的一些约束标准,可以说这一转变是Xilinx向业界标准的靠拢。Altera从TimeQuest开始就一直使用SDC标准,这一改变,相信对于很多工程师来说是好事,两个平台之间的转换会更加容易些。首先看一下业界标准SDC的原文介绍:

Synopsys' widely-used design constraints format, known as SDC, describes the "design intent" and surrounding constraints for synthesis, clocking, timing, power, test and environmental and operating conditions. SDC has been in use and evolving for more than 20 years, making it the most popular and proven format for describing design constraints. Essentially all synthesized designs use SDC and numerous EDA companies have translators that can read and process SDC.

Xilinx原先的自成一派(UCF)其实其实也算做的不错,相信使用过UCF的工程师也有同感,并没有什么不便。像Apple那样软件和硬件都自成一派而且能与其它所有派别抗衡的,背后需要有多强大的团队支持,可能Xilinx可是考虑到这点,不想花费过多的精力去维护。(个人见解)

文归正题,如果有读者以前没有使用XDC/SDC的经验,这边讲解一下如何从UCF到XDC的转换。如图1所示为UCF与SDC的约束命令比较,可以发现常用的命令都能对应上。

下面简单举例说明:

Clock Period:

UCF :NET "clka" TNM_NET = "clka";

TIMESPEC "TS_clka" = PERIOD "clka" 13.330 ns HIGH 50.00%;

XDC :create_clock -name clka -period 13.330 -waveform {0 6.665} [get_ports clka]

Input Port:

UCF :OFFSET = IN 8 BEFORE clka;

XDC :set_input_delay -clock clka 2 [all_inputs]

注: clock period = 10 ns.

Output Port:

UCF :OFFSET = OUT 12 AFTER clkc;

XDC :set_output_delay -clock clkc 8 [all_outputs]

注:clock period = 20 ns.

除了以上约束命令的差别外,UCF和XDC间的主要差别如下:

1. XDC是顺序执行约束,每个约束指令有优先级

2. UCF一般约束nets对象,而XDC约束类型是pins, ports和cells对象

3. UCF约束默认不对异步时钟间路径进行时序分析,而XDC约束默认所有时钟是相关的,会分析所有路径,可以通过设置时钟组(set_clock_groups)取消时

钟间的相关性。

下面介绍一下在Vivado中添加XDC文件以及加入约束命令的方法:

首先在Project Manager中展开Constraints类,选择Add Sources即可添加或者新建XDC约束文件,如图2所示。

图2

选择新建的XDC文件,双击打开,选择左侧的Templates,其中有XDC约束命令的实例,所有的约束命令都可以在其中找到,非常方便,如图3,4所示。

XDC约束文件,这样设计和维护效率都能得到提高。

图6

2Timing Constraints in Vivado -- 2. Timing Basics 在深入讲解XDC约束前,先介绍一下基本的时序约束、分析的概念。

2.1Timing Path:

图1中包含了主要的时序分析路径:

1. 输入端口到FPGA内部时序单元的路径

2. FPGA内部时序单元间的路径

3. FPGA内部时序单元到输出端口的路径

4. 输入端口到输出端口的路径

图1

不管时序单元是在FPGA内部还是外部,除了第4条路径,它是从输入端口到输出端口,其间没有锁存,其它3条路径的时序分析都以2个时序单元间的路劲进行分析,如图2所示。

第一个时序单元上的时钟称为source clock(启动时钟),第二个时序单元上的时钟称为destination clock(锁存时钟),时序分析从source clock的上升沿开始,到之后的destination clock的上升沿结束,时序分析的过程就是检验数据在两个上升沿时间差内经过数据路径传输后是否满足要求,数据到达时需要满足后一级时序单元的setup/hold要求,其本质上是需要数据在到达后一级时序单元时不发生亚稳态,数据能够被稳定地采集到并且稳定地输出。

2.2Clock Setup Check:

检验Setup是否满足要求,这边引入setup slack概念,只要setup slack的值大于零即Setup检查满足要求,其计算公式如下:

setup slack = data required time –data arrival time

其中:

data required time=destination clock edge time + destination clock path delay

- clock uncertainty- setup time

data arrival time = source clock edge time + source clock path delay

+ clock to output time + data path delay

公式代入可得到:

setup slack = (destination clock edge time - source edge time)

+ (destination clock path delay - source clock path delay)

- clock uncertainty - setup time - clock to output time - data path delay

= T destination_to_source + (T clk-D2–T clk-D1) –T clk_uncertainty–T setup–

uT co - T data_path_delay

在Setup检查中source clock一定超前于destination clock。

其中第一部分T destination_to_source,当source clock和destination clock为异步时钟时,如图3中实例,source clock的周期等于6ns,destination clock的周期等于4ns,首先假定2个时钟的相位差为0,图中在这种情况下有2个setup关系,setup1下T destination_to_source = 4ns,setup2下T destination_to_source = 2ns,在实际分析中应该选取最严格的情况,即选取setup2这种。

而当source clock和destination clock为同一个时钟时,T destination_to_source的值很显然就是时钟周期T clk_period,这也是时序分析最多的情况了,进一步推导setup slack = T clk_period+ (T clk-D2–T clk-D1) –T clk_uncertainty - T setup–T data_path_delay > 0,可以得到:

T clk_period > T clk_uncertainty + T setup + T data_path_delay - (T clk-D2–T clk-D1)

T clk_period、T clk_uncertainty可以通过时序约束确定其值,uT co, T setup是时序单元的

属性值,(T clk-D2–T clk-D1)在布局布线后其值也能确定,剩下T data_path_delay对T-

影响最大,一个设计Setup检查中的关键路径往往是T data_path_delay值最大clk_period

的一条路径,影响其值有很多原因,如逻辑级数过多,扇出导致布线延时过大…

2.3Clock Hold Check:

对应Hold检查,也有hold slack,其计算公式如下:

hold slack = data arrival time –data required time

其中

data required time = destination clock edge time + destination clock path

delay

+ clock uncertainty + hold time

data arrival time = source edge time + source clock path delay

+ clock to output time + data path delay

代入公式得到:

hold slack = (source clock edge time - destination edge time)

+(source clock path delay - destination clock path delay)

- clock uncertainty - hold time + clock to output time + data path

delay

=T source_to_destination + (T clk-D1–T clk-D2) –T clk_uncertainty–T hold + uT co +

T data_path_delay

与Setup检查不同,在Hold检查下destination clock超前于source clock。

在Setup检查中,T destination_to_source的值选取destination clock和source clock相差最小的情况下进行分析;而Hold检查中T source_to_destination的值选取所有Setup关系分别进行分析,每一种Setup关系对应有两种情况,然后选取所有情况中T-

值大的计算对应的T source_to_destination

destination_to_source

a. 取Setup关系的前一个destination clock沿,如图4中Hold1a和Hold2a

b. 取Setup关系的destination clock沿,如图4中Hold1b和Hold2b

根据图4中实例计算得到:

Hold1a:Tdestination_to_source= 0ns

Hold1b:Tdestination_to_source= -2ns

Hold2a:Tdestination_to_source= -2ns

Hold2b:Tdestination_to_source= -4ns

显然选取Hold1a,对应Tsource_to_destination值为0ns

当source clock和destination clock为同一个时钟时,可以计算得到:

T source_to_destination值为0ns,进一步推导

hold slack = T source_to_destination + (T clk-D1–T clk-D2) –T clk_uncertainty–T hold+ T data_path_delay > 0可以得到:

T data_path_delay >T clk_uncertainty + T hold + (T clk-D2–T clk-D1)

由上得出数据路径的延时也不能过短,与Setup检查是矛盾对立的存在;在FPGA设计或者数字前端开发时,工程师考虑最多的是Setup是否满足要求,而Hold检查的工作主要交给工具或者负责数字后端的工程师解决。

2.4Timing Report in Vivado:

下面通过简单的实例说明一下vivado中的时序分析,当FPGA设计经过综合实现后,通过Report Timing Summary打开时序报告,如图5、6所示。

图6

图中有红色部分表示设计中有时序不满足要求,此例中是Setup。选择Setup 中未满足要求的Path,打开Path Properties,如图7所示。

图7

Setup关键路径的时序报告如图8所示,报告由四部分组成:Summary, Source Clock Path, Data Path和Destination Clock Path,其中由Source Clock Path和Data

Path得出Arrival Time,由Destination Clock Path得出Required Time。

Hold检查的报告也类似,如图9所示。

图9

3Timing Constraints in Vivado -- 3. Define Clocks Vivado进行时序分析,对时钟的约束是必不可少的,设计中的时钟可分为一下几种:

①Primary Clocks 主时钟;

②Generated Clocks 衍生时钟;

③Virtual Clocks 虚拟时钟。

3.1Primary Clocks

主时钟一般是FPGA外部芯片如晶振提供的时钟,通过FPGA引脚输入。

Vivado进行时序分析时,以主时钟的源端点作为延时计算起始点(0ns点)。主时钟的约束命令如下:

create_clock-name -period -waveform { } [get_ports ]

下面通过几个实例说明一下约束命令:

a.

create_clock-name clk_main -period 10 -waveform {0 5} [get_ports GCLK]

周期10ns,0ns上升沿,5ns下降沿。

b.

create_clock-name clk_main -period 10 -waveform {0 2.5} [get_ports GCLK] 周期10ns,0ns上升沿,2.5ns下降沿;与a例周期相同,但是占空比不同,a例中50%,b例中25%。

c.

create_clock-name clk_main -period 20 -waveform {0 10} [get_ports GCLK]

周期20ns,0ns上升沿,10ns下降沿;与a例占空比相同,都是50%,但是周期不同,a例中10ns,b例中20ns。

3.2Generated Clocks

衍生时钟是由设计内部产生,一般由时钟模块(MMCM or PLL)或者逻辑产生,并且对应有一个源时钟,源时钟可以是系统的主时钟或者另外一个衍生时钟。约束衍生时钟时,除了定义周期,占空比,还需要指明与源时钟的关系。通过create_generated_clock命令约束衍生时钟,命令如下:create_generated_clock -name -source -divide_by

图1

如图1中,主时钟GCLK通过PLL产生两个衍生时钟CLKOUT1和CLKOUT2,其中GCLK—100MHz,CLKOUT1—100MHz,CLKOUT2—10MHz,对于MMCMx, PLLx, BUFR primitives这几种时钟模块,Vivado会自动对主时钟和衍生时钟进行约束。

在Tcl Console中输入report_clocks可以得到时钟报告,以下是未对设计进行任何时钟约束的情况:

report_clocks

INFO: [Timing 38-35] Done setting XDC timing constraints.

INFO: [Timing 38-2] Deriving generated clocks

*************************************************************************** * Report : Clocks

* Design : top

* Part : Device=7z020, Package=clg484, Speed=-1

* Version : Vivado v2013.1 Build 248050 by xbuild on Wed Mar 27 17:27:24 MDT 2013

* Date : Tue Dec 17 12:17:09 2013

*************************************************************************** Attributes

P: Propagated

G: Generated

V: Virtual

I: Inverted

Clock Period Waveform Attributes Sources

clk_in1 10.00000 {0.00000 5.00000} P {GCLK}

clkfbout_clk_gen 10.00000 {0.00000 5.00000}

P,G {clk_gen_u/inst/plle2_adv_inst/CLKFBOUT}

clk_out1_clk_gen 20.00000 {0.00000 10.00000}

P,G {clk_gen_u/inst/plle2_adv_inst/CLKOUT0}

clk_out2_clk_gen 100.00001 {0.00000 50.00000}

P,G {clk_gen_u/inst/ plle2_adv_inst/CLKOUT1}

====================================================

Generated Clocks

==================================================== Generated Clock : clkfbout_clk_gen

Master Source : clk_gen_u/inst/plle2_adv_inst/CLKIN1 Master Clock : clk_in1

Multiply By : 1

Generated Sources : {clk_gen_u/inst/plle2_adv_inst/CLKFBOUT} Generated Clock : clk_out1_clk_gen

Master Source : clk_gen_u/inst/plle2_adv_inst/CLKIN1 Master Clock : clk_in1

Edges : {1 2 3}

Edge Shifts : {0.000 5.000 10.000}

Generated Sources : {clk_gen_u/inst/plle2_adv_inst/CLKOUT0} Generated Clock : clk_out2_clk_gen

Master Source : clk_gen_u/inst/plle2_adv_inst/CLKIN1 Master Clock : clk_in1

Edges : {1 2 3}

Edge Shifts : {0.000 45.000 90.000}

Generated Sources : {clk_gen_u/inst/plle2_adv_inst/CLKOUT1}

图2

如图2中,衍生时钟CLKOUT1通过逻辑产生一个2分频的衍生时钟CLK_DIV2,CLKOUT1的约束已自动生成,对CLK_DIV2约束指令如下:

create_generated_clock

-name CLK_DIV2 -source [get_pins clk_gen_u/clk_out1] -divide_by 2

[get_pins clk_25m_reg/Q]

生成的时钟报告如下:

====================================================

Generated Clocks

====================================================

Generated Clock : CLK_DIV2

Master Source : clk_gen_u/clk_out1

Master Clock : clk_out1_clk_gen

Divide By : 2

Generated Sources : {clk_25m_reg/Q}

Generated Clock : clkfbout_clk_gen

Master Source : clk_gen_u/inst/plle2_adv_inst/CLKIN1

Master Clock : clk_in1

Multiply By : 1

Generated Sources : {clk_gen_u/inst/plle2_adv_inst/CLKFBOUT}

Generated Clock : clk_out1_clk_gen

Master Source : clk_gen_u/inst/plle2_adv_inst/CLKIN1

Master Clock : clk_in1

Edges : {1 2 3}

Edge Shifts : {0.000 5.000 10.000}

Generated Sources : {clk_gen_u/inst/plle2_adv_inst/CLKOUT0}

Generated Clock : clk_out2_clk_gen

Master Source : clk_gen_u/inst/plle2_adv_inst/CLKIN1

Master Clock : clk_in1

Edges : {1 2 3}

Edge Shifts : {0.000 45.000 90.000}

Generated Sources : {clk_gen_u/inst/plle2_adv_inst/CLKOUT1}

3.3Virtual Clocks

虚拟时钟是在FPGA设计不存在的时钟,但是为什么要引入呢?先看一下图3中结构,FPGA与板上的其它芯片间有数据交互,属于FPGA内部时序单元到输出端口的路径。芯片上的时钟并不是由FPGA提供,Vivado在进行这部分时序分析时并不知道芯片的时钟,因此需要定义一个虚拟时钟,然后约束输出端口的output delay。

图3

约束虚拟时钟的命令也是create_clock,但是其不需要指定-source,如下指令:

create_clock -period 100.000 -name SCLK -waveform {0.000 50.000}

时钟报告如下,定义的虚拟时钟SCLK属性为Virtual,无source。

report_clocks

INFO: [Timing 38-35] Done setting XDC timing constraints.

INFO: [Timing 38-2] Deriving generated clocks

*****************************************************************

* Report : Clocks

* Design : top

* Part : Device=7z020, Package=clg484, Speed=-1

* Version : Vivado v2013.1 Build 248050 by xbuild on Wed Mar 27 17:27:24 MDT 2013 * Date : Tue Dec 17 14:08:19 2013

*************************************************************************** Attributes

P: Propagated

G: Generated

V: Virtual

I: Inverted

Clock Period Waveform Attributes Sources

clk_in1 10.00000 {0.00000 5.00000} P {GCLK}

CLK_DIV2 40.00000 {0.00000 20.00000} P,G {clk_25m_reg/Q}

SCLK 100.00000 {0.00000 50.00000} V {}

clkfbout_clk_gen 10.00000 {0.00000 5.00000} P,G {clk_gen_u/inst/

plle2_adv_inst/CLKFBOUT}

clk_out1_clk_gen 20.00000 {0.00000 10.00000} P,G {clk_gen_u/inst/

plle2_adv_inst/CLKOUT0}

clk_out2_clk_gen 100.00001 {0.00000 50.00000}

P,G {clk_gen_u/inst/plle2_adv_inst/CLKOUT1}

4Timing Constraints in Vivado -- 4. Clock Groups 在第一节介绍过XDC与UCF的不同之处:Vivado会分析所有XDC约束时钟间的时序路径。通过set_clock_groups约束不同的时钟组(clock group),Vivado 在时序分析时,当source clock和destination clock属于同一个时钟组时,才会分析此时序路径;而source clock和destination clock属于不同时钟组时,则会略过此时序路径的分析。下面讲解一下set_clock_groups约束:

4.1Asynchronous Clock Groups

为了判别划分时钟组,将不同的时钟划分成以下两类:

a. Synchronous Clocks

当两个时钟间的相位是固定的,则可以称这两个时钟为同步时钟(synchronous clock)。一般同源,如由同一个MMCM or PLL产生的两个时钟可以称为同步时钟。因此可以将主时钟和与之对应的衍生时钟约束成同一个时钟组。

b. Asynchronous Clocks

无法判定两个时钟间相位时,则可以称这两个时钟为异步时钟(asynchronous clocks)。两个来自不同晶振的时钟,一定是异步时钟。通常情况下设计中不同的主时钟肯定是异步时钟,因此可以将这两个主时钟及其衍生时钟约束成不同的时钟组。

对于异步时钟,由于其两个时钟间相位不固定,时序分析的结果定然不确切,因此这部分的分析可以通过设置时钟组约束忽略,但是这并不意味着这部分的设计能工作正常;对于异步时钟间的设计,必须做跨时钟域处理,避免亚稳态的产生。

异步时钟组约束命令如下:

set_clock_groups-asynchronous-group [get_clocks {clk_Aclk_B}]

-group [get_clocks {clk_C}]-group …

如图1中结构,串行AD1和串行AD2接口都带有随路时钟SCLK1和SCLK2,SCLK1和SCLK2属于异步时钟;ADC串并转换后的数据需要经过跨时钟域处理(CDC),转到GCLK主时钟域,GCLK与ADC的时钟也属于异步时钟,因此约束命令如下:

set_clock_groups-asynchronous -group [get_clocks {SCLK1}]

-group [get_clocks {SCLK2}] -group [get_clocks {GCLK}]

相关文档
最新文档