Vivado时序约束
本文主要介绍如何在Vivado设计套件中进行时序约束,原文出自Xilinx中文社区。
- Timing 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的约束命令比较,可以发现常用的命令都能对应上。
图1
下面简单举例说明:
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所示。
图3
图4
XDC约束文件可以在编译综合和实现过程中使用时,在综合和实现设置中都能选择需要的约束,如图5。通过创建约束文件集,如图6,设计者可以使能不同的约束集合测试FPGA设计的性能;在约束文件集中可以包含多个XDC约束文件,在FPGA设计比较复杂时,可以分模块或者IP核约束,相应的则有多个XDC约束文件,这样设计和维护效率都能得到提高。
XDC约束文件可以在编译综合和实现过程中使用时,在综合和实现设置中都能选择需要的约束,如图5。通过创建约束文件集,如图6,设计者可以使能不同的约束集合测试FPGA设计的性能;在约束文件集中可以包含多个XDC约束文件,在FPGA设计比较复杂时,可以分模块或者IP核约束,相应的则有多个XDC约束文件,这样设计和维护效率都能得到提高。
图6
- Timing Constraints in Vivado -- 2. Timing Basics
在深入讲解XDC约束前,先介绍一下基本的时序约束、分析的概念。
-
- Timing 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
-
- Clock 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
= Tdestination_to_source + (Tclk-D2 – Tclk-D1) – Tclk_uncertainty – Tsetup – uTco - Tdata_path_delay
在Setup检查中source clock一定超前于destination clock。
其中第一部分Tdestination_to_source,当source clock和destination clock为异步时钟时,如图3中实例,source clock的周期等于6ns,destination clock的周期等于4ns,首先假定2个时钟的相位差为0,图中在这种情况下有2个setup关系,setup1下Tdestination_to_source = 4ns,setup2下Tdestination_to_source = 2ns,在实际分析中应该选取最严格的情况,即选取setup2这种。
图3
而当source clock和destination clock为同一个时钟时,Tdestination_to_source的值很显然就是时钟周期Tclk_period,这也是时序分析最多的情况了,进一步推导setup slack = Tclk_period+ (Tclk-D2– Tclk-D1) – Tclk_uncertainty - Tsetup – Tdata_path_delay > 0,可以得到:
Tclk_period > Tclk_uncertainty + Tsetup + Tdata_path_delay - (Tclk-D2 – Tclk-D1)
Tclk_period、Tclk_uncertainty可以通过时序约束确定其值,uTco, Tsetup是时序单元的属性值,(Tclk-D2 – Tclk-D1)在布局布线后其值也能确定,剩下Tdata_path_delay对Tclk_period影响最大,一个设计Setup检查中的关键路径往往是Tdata_path_delay值最大的一条路径,影响其值有很多原因,如逻辑级数过多,扇出导致布线延时过大…
-
- Clock 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
=Tsource_to_destination + (Tclk-D1 – Tclk-D2) – Tclk_uncertainty – Thold + uTco + Tdata_path_delay
与Setup检查不同,在Hold检查下destination clock超前于source clock。在Setup检查中,Tdestination_to_source的值选取destination clock和source clock相差最小的情况下进行分析;而Hold检查中Tsource_to_destination的值选取所有Setup关系分别进行分析,每一种Setup关系对应有两种情况,然后选取所有情况中Tdestination_to_source值大的计算对应的Tsource_to_destination
a. 取Setup关系的前一个destination clock沿,如图4中Hold1a和Hold2a
b. 取Setup关系的destination clock沿,如图4中Hold1b和Hold2b
图4
根据图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为同一个时钟时,可以计算得到:
Tsource_to_destination值为0ns,进一步推导
hold slack = Tsource_to_destination + (Tclk-D1 – Tclk-D2) – Tclk_uncertainty – Thold+ Tdata_path_delay > 0可以得到:
Tdata_path_delay >Tclk_uncertainty + Thold + (Tclk-D2 – Tclk-D1)
由上得出数据路径的延时也不能过短,与Setup检查是矛盾对立的存在;在FPGA设计或者数字前端开发时,工程师考虑最多的是Setup是否满足要求,而Hold检查的工作主要交给工具或者负责数字后端的工程师解决。
-
- Timing Report in Vivado:
下面通过简单的实例说明一下vivado中的时序分析,当FPGA设计经过综合实现后,通过Report Timing Summary打开时序报告,如图5、6所示。
图5
图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。
图8
Hold检查的报告也类似,如图9所示。
图9
- Timing Constraints in Vivado -- 3. Define Clocks
Vivado进行时序分析,对时钟的约束是必不可少的,设计中的时钟可分为一下几种:
- Primary Clocks 主时钟;
- Generated Clocks 衍生时钟;
-
Virtual Clocks 虚拟时钟。
- Primary Clocks
主时钟一般是FPGA外部芯片如晶振提供的时钟,通过FPGA引脚输入。Vivado进行时序分析时,以主时钟的源端点作为延时计算起始点(0ns点)。主时钟的约束命令如下:
create_clock-name <clock_name> -period <period> -waveform {<rise_time> <fall_time>} [get_ports <input_port>]
下面通过几个实例说明一下约束命令:
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。
-
- Generated Clocks
衍生时钟是由设计内部产生,一般由时钟模块(MMCM or PLL)或者逻辑产生,并且对应有一个源时钟,源时钟可以是系统的主时钟或者另外一个衍生时钟。约束衍生时钟时,除了定义周期,占空比,还需要指明与源时钟的关系。通过create_generated_clock命令约束衍生时钟,命令如下:
create_generated_clock -name<generated clock name> -source <master clock source pin or port> -divide_by <div_factor> <pin_or_port>
a.
图 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}
b.
图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}
-
- Virtual 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}
- Timing 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约束:
-
- Asynchronous 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}]
-
- Exclusive Clock Groups
在有些设计中,可能需要不同的工作模式,对应需要不同的时钟输入,通过时钟选择模块选择需要的时钟,如BUFGMUX,BUFGCTRL or A LUT。但是这些输入的不同时钟间是互斥的,即一个模式只允许一个时钟输入,不同时钟间是没有时序关系,因此只需单独对每个时钟做时序分析即可,添加互斥时钟组可使Vivado进行时序分析时忽略互斥时钟组间的时序路径,约束命令如下:
set_clock_groups -logically_exclusive -group{clk_A} -group {clk_B}
或
set_clock_groups –physically_exclusive -group{clk_A} -group {clk_B}
如图2中结构,可将CLKMUX1,CLKMUX2约束成互斥时钟组,约束命令如下:
set_clock_groups - physically_exclusive -group [get_clocks {CLKMUX1}]
-group [get_clocks {CLKMUX2}]
图2
- Timing Constraints in Vivado -- 5. Constraining Input Delay
Timing Constraints in Vivado系列博文已有了一定的进展,经过上两节的介绍,约束设计中的时钟后,Vivado已能完成基本的时序分析。
在第二节“Timing Basics”中提到时序路径分为以下四种:
1) FPGA内部时序单元间的路径
2) 输入端口到FPGA内部时序单元的路径
3) FPGA内部时序单元到输出端口的路径
4) 输入端口到输出端口的路径
其中1. FPGA内部时序单元间的路径中,时序分析所需要的时间参数:Tclk-D1, Tclk-Q, Tdata_path_delay, Tclk_D2, Tsetup, Thold已能确定,只要属于FPGA内部的时间参数,Vivado则会根据相应设计计算得到,因此4. 输入端口到输出端口的路径的时间参数也能确定。
其它两条路径都相应缺少FPGA外部的几个时间参数,这些参数都需要通过时序约束告知Vivado,然后Vivado才能精确地进行这些路径的时序分析。这一节先介绍2. 输入端口到FPGA内部时序单元的路径这条路径的约束。
在输入端口到FPGA内部时序单元的路径中,Input Delay这段路径是在FPGA外部,因此需要约束设置其时间参数,通过set_input_delay约束命令约束,具体如下:
set_input_delay –clock{clk} –max/-min input_delay_value [get_ports {DIN}]
另外根据source clock和destination clock,输入接口可分为以下两种情况:
-
- System Synchronous Input
分析输入端口到FPGA内部时序单元的路径时,当source clock和destination clock来自同一个系统时钟时,称为系统同步输入(system synchronous input)。
如图1所示为系统同步输入,source clock是CLKA,destination clock是CLKB,其中CLKB通过输入端口引入FPGA内部(约束成主时钟),而CLKA引到了FPGA外部的板上芯片,并没有引入到FPGA内部,CLKB是采集输入端口的时钟,因此首先约束CLKB为主时钟,约束如下:
create_clock -name CLKB -period 10 -waveform {0 5} [get_ports {CLKB}]
图1
其中Tclkd_ext表示外部时钟源到外部芯片的延时;Tclkd_int表示外部时钟源到FPGA输入端口的延时;Tco表示外部芯片tCO时间;Tbd表示外部芯片输出端口到FPGA芯片的板上延时。
对应max_input_delay和min_input_delay,以上几个时间参数都有max和min值,约束如下:
set_input_delay -clockCLKB-max [Tclkd_ext_max + Tco_max + Tbd_max – Tclkd_int_min] [get_portsDIN]
set_input_delay -clockCLKB-min [Tclkd_ext_min + Tco_min + Tbd_min – Tclkd_int_max] [get_portsDIN]
-
- Source Synchronous Input
分析输入端口到FPGA内部时序单元的路径时,当destination clock来自外部芯片,即与数据输入同源,称为源同步输入(source synchronous input)。
结构如图2所示,从板上芯片输入到FPGA除了有数据,还有一个随路时钟,是由板上芯片产生的。
图2
-
- Input Delay Value:
约束Input Delay分max值和min值,参考图2中时间参数,其中Tcd表示外部芯片时钟输出到FPGA输入端口的延时;Tco表示外部芯片tCO时间;Tbd表示外部芯片输出端口到FPGA芯片的板上延时。Input delay的计算式如下:
max_input_delay = Tbd_max + Tco_max - Tcd_min
min_input_delay = Tbd_min + Tco_min - Tcd_max
-
- Clock & Data:
源同步输入的约束相比于系统同步输入的复杂些,其根据时钟与数据的关系,可分为边缘对齐(Edge Aligned Clock&Data)和中心对齐(Center Aligned Clock&Data)两种:
1) Center Aligned
中心对齐是指时钟和数据到达后级时序单元时,时钟沿在数据中心,如图3所示。
在这种情况下可以直接使用时钟采集数据。
图3
约束如下:
create_clock -name CLKB -period clk_period [get_ports {CLKB}]
set_input_delay -clock[get_clocks CLKB] -max max_input_delay [get_ports indata]
set_input_delay -clock[get_clocks CLKB] -min min_input_delay [get_ports indata] -add_delay
2) Edge Aligned
边缘对齐是指时钟和数据到达后级时序单元时,时钟沿与数据变化沿重合,如图4所示。
图4
这种情况下显然不满足后级时序单元的Setup要求,因此时钟需要经过一定的移相才能去采集数据,通常采用MMCM模块实现移相,如图5所示。
图5
时钟约束如下:
create_clock -name CLKB -period clk_period [get_ports {CLKB}]
create_generated_clock -name CLKB_90 -source [get_clocks CLKB] –phase 90 [get_pins{MMCM|co[0]}]
set_input_delay -clock[get_clocks CLKB_90] -max max_input_delay [get_ports indata]
set_input_delay -clock[get_clocks CLKB_90] -min min_input_delay [get_ports indata] -add_delay
2.3 SDR & DDR:
源同步接口常用于高速数据传输,如DDR存储器、HyperTransport总线和SPI-4.2标准接口等。其中DDR指双倍速率数据采集(Double Data Rate),在时钟的上升沿和下降沿都传输数据实现双倍速率。
1) SDR(Single Data Rate)
单倍速率数据采集只在时钟的上升沿或者下降沿采集数据,如图6所示。
图6
Input约束只需针对时钟的上升沿或者下降沿进行,如:
set_input_delay -clock[get_clocks CLKB] -max max_input_delay [get_ports indata]
set_input_delay -clock[get_clocks CLKB] -min min_input_delay [get_ports indata] -add_delay
2) DDR(Double Data Rate)
双倍速率数据采集在时钟的上升沿和下降沿都采集数据,如图7所示。
图7
针对时钟的上升沿和下降沿都需要进行Input约束,如:
set_input_delay -clock[get_clocks CLKB] -max max_input_delay [get_ports indata]
set_input_delay -clock[get_clocks CLKB] -min min_input_delay [get_ports indata] -add_delay
set_input_delay -clock[get_clocks CLKB] -max max_input_delay [get_ports indata] -clock_fall -add_delay
set_input_delay -clock[get_clocks CLKB] -min min_input_delay [get_ports indata] -clock_fall -add_delay
-
- Timing Check in Vivado
以上讲解了如何进行Input delay的约束,可能大家还不明白为什么需要约束input delay?那下面就讲解一下input delay 在时序分析中的作用:
在Vivado中时序分析分为setup check和hold check,其中引入了setup slack和hold slack来界定时序是否收敛。在《2. Timing Basics》中介绍过FPGA内部register_to_register路径setup slack和hold slack的计算方法,本文则介绍一下输入端口到FPGA内部时序单元的路径slack的计算方法,公式如下:
Setup check:
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
+ max input delay
+ pin to register delay
为了确认公式的正确性,打开Vivado软件,新建了一个约束了input delay的工程,如下几图所示为中其中一条路径的setup check报告。
约束的时钟周期为40ns,max input delay为15ns
data arrival time= 15.322ns
data required time = 40.199ns
时序报告中slack计算方式与公式完全一致,因此可以得到setup slack = data required time – data arrival time= 40.199ns – 15.322ns = 24.846ns。
Hold check:
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
+ pin to register delay
+ min input delay
如下几图为Vivado软件分析得到的hold check时序报告:
约束的min input delay = 8ns
data arrival time= 6.474ns
data required time= 1.045ns
时序报告中slack计算方式与公式完全一致,因此可以得到hold slack = data arrival time – data required time= 6.474ns – 1.045ns = 5.429ns。