Reference:1,xilinx FPGA权威设计指南;2, ASIC集成电路设计;3,综合与时序分析的设计约束实用指南
(1) 发送沿(Launch Edge):指发送数据的源时钟的活动边沿。
(2) 捕获边沿(Capture Edge):指捕获数据的目的时钟的活动边沿。
(3) 源时钟(Source Clock):指发送数据的时钟。
(4) 目的时钟(Destination clock):指捕获数据的时钟。
(5) 建立要求(Setup Requirement):指定义了最苛刻建立约束的发送沿和捕获沿之间的关系。
(6) 建立关系(Setup Relationship):指由时序分析工具验证的建立检查。
(7) 保持要求(Hold Requirement):指定义了最苛刻保持约束的发送沿和捕获沿之间的关系。
(8) 保持关系(Hold Relationship):指由时序分析工具验证的保持检查。
图 1
如图1所示,需要约束的时序路径有四种:
(1)从输入端口到内部时序单元的路径(set_input_delay)。
(2)从时序单元到时序单元的内部路径(create_clock)。
(3)从内部时序单元到输出端口的路径(set_output_delay)。
(4)从输入端口到输出端口的路径。(创建虚拟时钟来约束)
当建立时间/保持时间的Slack值为正数时,表示时序满足要求。
(1).建立时间检查(公共时钟周期)
图 2
图2所示为对图1中的时序单元之间的路径进行建立时间检查(Setup Check)的计算过程,在计算过程中:
Tdata_arrival表示数据到达时间,Tlaunch表示数据发送时钟沿的时间,Tclk1表示数据发送时序单元距离源时钟(Source Clock)的路径延迟时间,Tco表示数据发送寄存器内的数据传输延迟时间,Tdata表示数据在发送数据寄存器和接受数据寄存器间的组合逻辑电路的延迟时间。
Tclk_arrival表示时钟达到时间,Tcapture表示数据接受时钟沿的时间,Tclk2表示数据接受时序单元距离源时钟(Source Clock)的路径延迟时间,Tsetup表示器件的建立时间。
对于建立时间检查,本质是要两时序单元(触发器)间的组合逻辑传输延迟要足够小,即在数据接受时钟沿前的Tsetup时间内数据保持稳定不变。要求数据比时钟先到达,即Tclk_arrival的值要大于等于Tdata_arrival的值(Slack(Setup) = Tclk_arrival - Tdata_arrival >= 0)。
这里需要注意的是,在建立时间检查的过程中,数据接受时钟沿的时间比数据发送时钟沿的时间晚(相同同步时钟是晚了一个时钟周期,即Tcapture - Tlauch = T) ,Tclk2 - Tclk1 = Tskew。根据这两个条件便可以计算出约束在时序单元之间的时钟周期最小值(或者说在给定的运行时钟频率或时钟周期下,两个时序单元之间的组合逻辑最大延迟值。)
(2)保持时间检查
图 3
图3所示为对图1中的时序单元之间的路径进行保持时间检查(Hold Check)的计算过程,在计算过程中:
Tdata_arrival表示数据到达时间,Tlaunch表示数据发送时钟沿的时间,Tclk1表示数据发送时序单元距离源时钟(Source Clock)的路径延迟时间,Tco表示数据发送寄存器内的数据传输延迟时间,Tdata表示数据在发送数据寄存器和接受数据寄存器间的组合逻辑电路的延迟时间。
Tclk_arrival表示时钟达到时间,Tcapture表示数据接受时钟沿的时间,Tclk2表示数据接受时序单元距离源时钟(Source Clock)的路径延迟时间,Thold表示器件的保持时间。
对于保持时间检查,本质是要两时序单元(触发器)间的组合逻辑传输延迟要足够大,即在数据接受时钟沿到来后的Thold时间内数据保持稳定不变。要求数据比下一个接受时钟沿先到达,即Tclk_arrival的值要小于等于Tdata_arrival的值(Slack(Hold) =Tdata_arrival - Tclk_arrival>= 0) ,这里的计算方式也是Designer Compiler等各种时序分析工具的计算方式,本质是为了建立时间和保持时间的Report出的Slack都是正值的时候,表示无时序违例。
这里需要注意的是,在保持时间检查的过程中,数据接受时钟沿的时间和上一个数据发送时钟沿的时间相同(Tdata_arrival中的Tlaunch为上一个数据发送时钟沿,Tclk_arrival中的Tcapture为当前数据接受时钟沿,此时Tcapture = Tlauch) ,Tclk2 - Tclk1 = Tskew。根据这两个条件便可以计算出约束在时序单元之间的组合逻辑电路传输最小延迟值。
总结:结合建立时间检查和保持时间检查,我们可以知道:
(1) 建立时间检查用于确定两个时序单元之间的组合逻辑电路传输的最大延迟值,即信号不能传的太慢了;保持时间检查用于确定两个时序单元之间的组合逻辑电路传输的最小延迟值,即信号不能传的太快了。
(2) 因为两个时序单元(触发器)的具体位置是不确定的,所以Tskew的值可能为正值也可能为负值,为正值的时候,有助于增大Tdata,有利于建立时间检查的修复; 为负值的时候,有助于减小Tdata,有利于保持时间检查的修复。
(3)恢复和去除检查
恢复和去除时序检查类似于建立和保持检查,但是他们应用于异步引脚,如置位和复位。
对于一个包含有异步复位的寄存器来说:
(1)恢复时间是指把异步复位信号切换到不活动状态后下一个活动时钟沿之前的最小时间,这个时间用于安全地锁存一个新的数据。
(2)去除时间是指在一个活动时钟沿后异步复位信号可以安全切换到不活动状态前的最小时间。
时序约束的基本元素由时钟定义,时钟组,I/O延迟约束,时序例外组成。
1. 基本时钟
一个基本时钟是指PCB上的时钟,它通过下面方式输入设计。
(1)一个输入端口。
(2)一个吉比特收发器输出引脚,如一个恢复的时钟。
通过create_clock命令定义一个基本时钟。在网表对象中,必须添加一个基本时钟,通过这个时钟将衍生出设计所用的时钟树。换句话说,当计算时钟延迟和不确定性时,基本时钟源为vivado定义了时序的零点。
如下约束是对图6.8中的sysclk的约束
create_clock -period 10 [get_ports sysclk]
图6.9中给出了一个GT基本时钟的例子,收发器gt0用于从PCB的一个高速链路中恢复时钟rxclk,该时钟的属性描述为周期为3.33ns,占空比为50%,该时钟连接mmcm0。该模块生成一些补偿后的时钟,用于设计。该时钟约束表示为:
create_clock -name rxclk -period 3.33 [get_ports gt0/RXOUTCLK]
虚拟时钟是指没有物理连接设计中任何网表元器件的时钟。通过create_clock定义虚拟时钟,并没有指明一个源对象。
在下面的条件中,通过虚拟时钟说明输入和输出延迟约束。
(1)外部设备I/O参考时钟不是设计中的一个时钟。
(2)FPGA I/O路径和内部生成时钟相关,但是不能正确地对该生成时钟进行定时。
(3)设计者只想为与I/O延迟约束相关的时钟指明不同的抖动和延迟,但是不修改内部的时钟特性。
如下约束为创建一个周期为10ns,占空比为50%的虚拟时钟,注意虚拟时钟没有port/pin,但是一定要有个名字来区分。
create_clock -name clk_virt -period 10
生成时钟由设计内特殊的称为时钟修改模块(MMCM)的单元或者一些用户逻辑生成。生成时钟总是和一个基本时钟或者其他生成时钟相关。通过他们的主时钟,可以直接得到生成时钟的属性。在生成时钟中不指定它们的周期和波形,而是设计者描述正在修改的电路如何对主时钟进行交换。
1)用户定义的时钟
(1)通过命令create_generated_clock定义用户所需要的时钟。
(2)将其连接到一个网表对象,最好是时钟树根引脚。
如下约束是对图6.10中的源时钟和生成时钟的约束,对于生成时钟有直接中clkin作为源时钟,或者REGA的时钟输入作为源时钟两种约束方式。
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.
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -divide_by 2 [get_pins REGA/Q]
此外,可以不使用”-divided_by”选项,而使用”-edge”选项代替它,根据主时钟的边沿直接描述生成时钟的波形。它的参数是主时钟边沿的索引,以列表形式给出。该列表用于定义生成时钟边沿的位置,它起始于时钟的上升沿。如下约束所示:
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -edges {1 3 5} [get_pins REGA/Q]
通过使用”-edge_shift”选项,可以对生成时钟波形的每个边沿移动正值或者负值。当需要相移时,才使用这个选项。
对于图6.11所示生成时钟的约束如下所示:
create_clock -name clkin -period 10 [get_ports clkin]
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]
同时使用”-divide_by”和”-multiply_by”,假设输入主时钟乘以4/3的约束如下:
create_generated_clock -name clk43 -source [get_pins mmcm0/CLKIN] -multiply_by 4\
-divide_by 3 [get_pins mmcm0/CLKOUT]
2) 自动得到的时钟
自动得到的时钟也称为自动生成的时钟。vivado集成开发环境在时钟修改模块(CMB)的输出引脚自动创建这些约束。CMB是MMCM,PLL或者BUFR原语,包含MIG IP内的PHASER_x。
如果在相同的网表对象上定义了用户(基本的或者生成的)时钟,则不会创建自动生成的时钟。自动生成的时钟的名字取决于定义点直接相连的网络名字。
默认的,Vivado集成开发环境总是计算设计中所有时钟之间的路径,除非设计者通过时钟组指定或者存在假的路径约束。”set_clock_groups”命令禁止在所标识的时钟组之间,以及在一个时钟组内的时钟进行时序分析。
1. 时钟范围:同步时钟,异步时钟和不可扩展时钟
1)同步时钟
当可以预测两个时钟的相对相位时,则称这两个时钟同步(相位固定)。
2)异步时钟
当不可能确定两个时钟的相对相位时,两个时钟就是异步的(相位变化)。
3)不可扩展时钟--经常把它们当作异步时钟
当时序引擎在1000个周期后也不能确定它们的公共周期时,两个时钟就是不可扩展的。在这种情况下,在时序分析中,使用贯穿于这1000个周期内的最坏建立关系。
例如:时钟clk0的周期为5.125ns,时钟clk1的周期为6.66ns。在1000个周期内,它们的上升沿没有对齐。时序引擎在两个时钟之间的时序路径上使用一个0.01ns建立路径要求。即使这两个时钟在它们的时钟树根上有一个已知的相位关系,但是它们的波形不允许它们之间实现安全的时序分析。
2. 异步时钟组
如下为对异步时钟组进行的约束,这样工具在两个时钟组间的时钟不进行时序分析:
set_clock_groups -name async_clk0_clk1 -asynchronous -group {clk0 usrclk itfclk} \
-group {clk1 gtclkrx gtclktx}
3.互斥时钟组
一些设计有几种操作模式,这些操作模式要求不同的时钟。通过一个时钟多路复用器,如BUFGMUXH,BUFGCTRL或者LUT,选择不同的时钟。由于这些单元是可组合的单元,在同一时刻可以存在几种时序时钟,这样便于一次报告所有的操作模式,但是在硬件上是不可能的。
这些时钟称为互斥时钟,通过使用”set_clock_groups”选项约束它们。
(1)-logically_exclusive (2) -physically_exclusive
set_clock_groups -name exclusive_clk0_clk1 -physically_exclusive -group clk0 -group clk1
4. 时钟延迟,抖动和不确定性
1)时钟延迟
当时钟在板上和FPGA元器件内传播时,经历某个延迟后到达目的地。源延迟,即在时钟点前的延迟,通常在元器件外。网络延迟,由网络延迟引入的延迟。
set_clock_latency -source -early 0.2 [get_clocks sysClk] (最小)
set_clock_latency -source -late 0.5 [get_clocks sysClk] (最大)
2)时钟抖动和不确定性
对ASIC元器件来说,时钟不确定性经常用于表示时钟抖动。然而,对于Xilinx FPGA,抖动属性是可预测的,可以通过时序分析引擎自动计算它们。
(1)输入抖动
输入抖动是连续时钟沿之间的不同,它们是相对正常的或者理想的时钟到达时间的。使用”set_input_jitter”命令为每个基本时钟指定输入抖动。设计者不能在生成时钟上直接指定输入抖动,但是vivado集成开发环境可以自动计算从主时钟继承过来的生成时钟抖动。
(2)系统抖动
系统抖动是整体的抖动。- 供电噪声,PCB噪声,系统任何额外的抖动。在XDC中,使用”set_system_jitter”命令为整个设计只设置一个值。
(3)额外的时钟不确定性
使用”set_clock_uncertainty”命令定义额外的时钟不确定性,用于不同的拐点,延迟或者特殊时钟关系。
在设计中,为了准确建模外部的时序现场,设计者必须为输入端口和输出端口提供时序信息。由于Xilinx Vivado集成开发环境只识别FPGA元器件边界内的时序,因此设计者需要使用下面的命令为边界外指定延迟值。
1. 输入延迟 ---- set_input_delay
命令”set_input_delay”用于标识输入端口上的输入路径延迟,它是相对设计接口上的一个时钟边沿而言的。
(1)通过板子,从一个外部芯片到FPGA元器件输入封装引脚的数据。
(2)相对的参考板时钟。
输入延迟值可以是正值或者负值,这取决于FPGA元器件接口时钟和数据的相对相位。
1)最小和最大输入延迟命令选项 ---- -min/-max
create_clock -name sysClk -period 10 [get_ports CLK0]
set_input_delay -clock sysClk -max 4 [get_ports DIN]
set_input_delay -clock sysClk -min 1 [get_ports DIN]
如果没有使用该选项,则输入延迟值用于最小和最大。
create_clock -name sysClk -period 10 [get_ports CLK0]
set_input_delay -clock sysClk 2 [get_ports DIN]
2)时钟下降输入延迟命令选项 ---- -clock_fall
“-clock_fall” 选项标识输入延迟约束,应用于由相对时钟下降沿发出的时序路径。如果没有该选项,Vivado集成开发环境假设相对时钟只有上升沿。
3)添加延迟输入延迟命令选项 ---- -add_delay
(1)存在一个最大(最小)输入延迟约束。
(2)设计者想在相同端口上添加第二个最大(最小) 输入延迟。
这个选项通常用于约束相对多个时钟沿的一个输入端口。
Note:输入延迟选项只能用于输入或者双向端口,不包括时钟端口(将自动忽略该端口)。设计者不可以将输入延迟约束应用到一个内部引脚。
2.输出延迟 ---- set_output_delay
命令”set_output_delay”用于标识输出端口上相对时钟沿的输出路径延迟。当考虑实际的PCB时,这个延迟标识下面之间的相位不同。
(1)通过PCB,从FPGA元器件输出封装引脚到一个外部芯片的数据。
(2)相对的参考板时钟。
1)最小和最大输出延迟命令选项 ---- -min/-max
create_clock -name sysClk -period 10 [get_ports CLK0]
set_output_delay -clock sysClk 6 [get_ports DOUT]
定义虚拟时钟:
create_clock -name clk_port_virt -period 10
set_output_delay -clock clk_port_virt 6 [get_ports DOUT]
2) 时钟下降输出延迟命令选项 ----- -clock_fall
create_clock -name clk_ddr -period 6 [get_ports DDR_CLK_IN]
set_output_delay -clock clk_ddr -max 2.1 [get_ports DDR_OUT]
set_output_delay -clock clk_ddr -max 1.9 [get_ports DDR_OUT] -clock_fall -add_delay
set_output_delay -clock clk_ddr -min 0.9 [get_ports DDR_OUT]
set_output_delay -clock clk_ddr -min 1.1 [get_ports DDR_OUT] -clock_fall -add_delay
3) 添加延迟输出延迟命令选项
如果出现下面情况,必须使用”-add_delay”。
(1)存在一个最大输出延迟约束。
(2)设计者想在相同端口上标识第二个最大输出延迟约束。
这对于最小输出延迟约束也是一样的,该选项通常用于约束相对于多个时钟沿的一个输出端口。
当逻辑行为以默认的方式不能正确定时逻辑行为时,需要时序例外(Timing Exception)。当设计者不想以不同的方式处理时序时,就必须使用时序例外命令。
1)set_multicycle_path
指明将数据从路径开始传播到路径结束时所需要的时钟周期数。
2)set_false_path
指明在设计中不进行分析的路径。
3)set_max_delay/set_min_delay
设置最小和最大路径延迟值。这将使用户指定的最大和最小延迟值覆盖默认的建立和保持约束。
4)set_case_analysis
使用逻辑常数或者在端口/引脚上的逻辑跳变执行时序分析,以限制通过设计的信号传播。
1. 多周期路径
(1)默认的,所定义的建立路径乘子是相对目的时钟的,通过使用”-start”选项修改相对源时钟的建立要求。
(2)类似的,所定义的保持路径乘子是相对源时钟的,通过使用”-end”选项修改相对目的时钟的保持要求。
1)单时钟域上的多周期
set_multicycle_path 2 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path 1 -hold -end -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
Note:在使用”set_multicycle_path -hold”命令时,需要”-end”选项,这是由于必须要将捕获沿向后(移动到原来的位置)移动。
set_multicycle_path 2 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path 1 -hold -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
2)多周期路径和时钟相位移动
set_multicycle_path 2 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
3)从慢时钟到快时钟的多周期
set_multicycle_path 3 -setup -from [get_clocks CLK] -to [get_clocks CLK2]
4)从快时钟到慢时钟的多周期
set_multicycle_path 3 -setup -start -from [get_clocks CLK1] -to [get_clocks CLK2]
set_multicycle_path 2 -hold -from [get_clocks CLK1] -to [get_clocks CLK2]
2. 伪路径
1) 去除从reset端口到所有寄存器的时序路径。
set_false_path -from [get_ports reset] -to [all_registers]
2) 禁止两个异步时钟域之间的时序路径
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
3) 禁止两个时钟域任何方向的所有路径
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
Note:当两个或者多个时钟域是异步的,并且禁止任何方向上这些时钟域之间的路径时,推荐使用”set_clock_groups”命令: set_clock_group -group CLK -group CLKB
set_false_path -through [get_pins MUX1/a0] -through [get_pins MUX2/a1]
3. 最大/最小延迟 ---- set_max_delay/set_min_delay
(1) 使用最大延迟约束覆盖一个路径上的默认建立(恢复)要求。
(2) 使用最小延迟约束覆盖默认保持(去除)要求。
1) 在一个路径上设置最大延迟和最小延迟约束的结果
在路径上设置最大延迟约束时,如果没有使用”-datapath_only”选项,则不会修改路径上的最小要求。路径上的保持(去除)检查保持其默认状态。如果使用”-datapaht_only”选项,将导致保持要求成为这些路径上的假路径。在路径上设计最小延迟约束时,不修改默认的建立(恢复)检查。
2) 约束输入和输出逻辑
“set_max_delay”和”set_min_delay”命令不用于约束输入和输出逻辑。用于约束基于输入端口和输出端口之间纯粹的组合逻辑路径。
3) 约束异步信号
“set_max_delay”命令可以用于约束异步信号: (1) 没有一个时钟关系; (2) 要求最大的延迟
4. Case分析 ---- set_case_analysis
create_clock -name clk_1 -period 10.0 [get_pins clock_sel/I0]
create_clock -name clk_2 -period 15.0 [get_pins clock_sel/I1]
set_case_analysis 1 [get_pins clock_sel/S]