简介
本章节针对大部分情况下的信号做时序约束分析
正所谓无设计不仿真,其实也可以说无设计不约束,正因为设计工程有约束的存在才可以保证设计的代码稳定性和可靠性高。
本文就vivado给出的原语约束进行总结。
打开Vivado,找到约束文件,如下图所示:
图中总共有时钟约束,输入信号约束,输出信号约束,以及设置一些时序路径例外的约束(exceptions),下面就每个约束做详细介绍。
clocks约束
clock constraint on input port
这是最常用的时钟约束,代码如下:
create_clock -name <clock_name> -period <period> [get_ports <clock port>]
<period>代表的是周期值,以ns为单位;
默认情况下占空比是50%,如果有特殊要求可以执行以下约束:
create_clock -period <period> -waveform {<rise_time> <fall_time>} [get_ports <input_port>]
-waveform {<rise_time> <fall_time>}有明确标注时钟高电平和低电平时间。
create_generated_clock
create_generated_clock是一个用于定义派生时钟信号的命令,生成时钟使用create_generated_clock命令定义,该命令不是设定周期或波形,而是描述时钟电路如何对上级时钟进行转换。
它可以根据主时钟信号的周期和相位来生成新的时钟信号。具体用法包括指定新时钟的名称、主时钟、分频和倍频系数、占空比等参数。
vivado约束原语如下:
分频
create_generated_clock -name <generated_clock_name> \
-source <master_clock source_pin_or_port> \
-divide_by <div_factor> \
<pin_or_port>
倍频
create_generated_clock -name <generated_clock_name> \
-source <master_clock source_pin_or_port> \
-multiply_by <mult_factor> \
<pin_or_port>
参数说明:
- -name:指定新时钟的名称。
- -source:指定主时钟信号的来源。
- -divide_by:指定分频系数,用于降低时钟频率。
- -multiply_by:指定倍频系数,用于增加时钟频率。
- -duty_cycle_low 和 -duty_cycle_high:指定新时钟的低占空比和高占空比,默认50%。
设计中生成时钟通常来源于设计内部的时钟管理单元,如MMCM,PLL等,生成时钟是与主时钟相关,其来源来自主时钟或其他生成时钟。因此,需先定义主时钟,再定义生成时钟。优点是主时钟变化时会同步进行变化。
下图中,主时钟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]
作者认为可使用PLL做分频,无需我们通过逻辑实现,同样在另一篇文章里有介绍到PLL生成的时钟无需再做约束,原话如下:
生成时钟包括上面PLL等衍生时钟、自己分频的时钟。注意这里VIVADO对PLL的衍生时钟已经默认自己加了约束,当然我们也可以重新添加约束,约束是我们后添加的为准。
input delay constraints
系统同步
输入信号分系统同步和源同步,系统同步定义如下:
系统同步是指发送端和接收端都由同一个系统时钟驱动,数据和时钟信号由同一个时钟源产生。在这种同步方式下,数据和时钟信号的传输依赖于共同的时钟源,因此系统的时钟频率受到限制,且对时钟的稳定性和准确性要求较高。例如传感器里的SPI/IIC协议一般采用系统同步采样,这就导致传输速度无法很快。
系统同步时序约束如下:
# input __________ __________
# clock __| |__________| |__
# |
# |------> (tco_min+trce_dly_min)
# |------------> (tco_max+trce_dly_max)
# __________ ________________
# data __________XXXXXX_____ Data _____XXXXXXX
#
set input_clock <clock_name>; # Name of input clock
set tco_max 0.000; # Maximum clock to out delay (external device)
set tco_min 0.000; # Minimum clock to out delay (external device)
set trce_dly_max 0.000; # Maximum board trace delay
set trce_dly_min 0.000; # Minimum board trace delay
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $tco_max + $trce_dly_max] [get_ports $input_ports];
set_input_delay -clock $input_clock -min [expr $tco_min + $trce_dly_min] [get_ports $input_ports];
# input __ __________ __
# clock |__________| |__________|
# |
# |------> (tco_min+trce_dly_min)
# |------------> (tco_max+trce_dly_max)
# __________ ________________
# data __________XXXXXX_____ Data _____XXXXXXX
#
set input_clock <clock_name>; # Name of input clock
set tco_max 0.000; # Maximum clock to out delay (external device)
set tco_min 0.000; # Minimum clock to out delay (external device)
set trce_dly_max 0.000; # Maximum board trace delay
set trce_dly_min 0.000; # Minimum board trace delay
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $tco_max + $trce_dly_max] [get_ports $input_ports] -clock_fall;
set_input_delay -clock $input_clock -min [expr $tco_min + $trce_dly_min] [get_ports $input_ports] -clock_fall;
# input _______________________________ ________
# clock _| |________________________________|
# | |
# |-> (trco_min+trce_dly_min) |-> (tfco_min+trce_dly_min)
# |-----> (trco_max+trce_dly_max) |-----> (tfco_max+trce_dly_max)
# ____ ____________________________ ____________________________ ___
# data ____XXXX__________Rise_Data_________XXXX__________Fall_Data_________XXXX___
#
set input_clock <clock_name>; # Name of input clock
set trco_max 0.000; # Maximum clock to output delay from rising edge (external device)
set trco_min 0.000; # Minimum clock to output delay from rising edge (external device)
set tfco_max 0.000; # Maximum clock to output delay from falling edge (external device)
set tfco_min 0.000; # Minimum clock to output delay from falling edge (external device)
set trce_dly_max 0.000; # Maximum board trace delay
set trce_dly_min 0.000; # Minimum board trace delay
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $trco_max + $trce_dly_max] [get_ports $input_ports];
set_input_delay -clock $input_clock -min [expr $trco_min + $trce_dly_min] [get_ports $input_ports];
set_input_delay -clock $input_clock -max [expr $tfco_max + $trce_dly_max] [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min [expr $tfco_min + $trce_dly_min] [get_ports $input_ports] -clock_fall -add_delay;
源同步
源同步则是由发送端在发送数据的同时发送一个选通信号(也称为源同步时钟信号)。接收端使用这个选通信号作为接收时钟,控制信号的接收。源同步时序系统中,数据和源同步时钟信号是同步传输的,理论上不受传输延迟的影响,极大地提高了数据传输的速度。例如源同步高速ADC采集芯片,数据和时钟均从ADC输出,在高速下保证信号和时钟对齐。一般百兆以上的通信采用源同步。
源同步中间对齐
中心对齐分三种类型,分别是单沿上升沿对齐,单沿下降沿对齐,双沿上下沿中间对齐,时序约束如下:
# input ____ __________
# clock |_________| |_____
# |
# dv_bre | dv_are
# <------>|<------>
# __ ________|________ __
# data __XXXX____Rise_Data____XXXX__
#
set input_clock <clock_name>; # Name of input clock
set input_clock_period <period_value>; # Period of input clock
set dv_bre 0.000; # Data valid before the rising clock edge
set dv_are 0.000; # Data valid after the rising clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $input_clock_period - $dv_bre] [get_ports $input_ports];
set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports];
# input _________ ____
# clock ____| |_________|
# |
# dv_bfe | dv_afe
# <------>|<------>
# __ ________|________ __
# data __XXXX____Fall_Data____XXXX__
#
set input_clock <clock_name>; # Name of input clock
set input_clock_period <period_value>; # Period of input clock
set dv_bfe 0.000; # Data valid before the falling clock edge
set dv_afe 0.000; # Data valid after the falling clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $input_clock_period - $dv_bfe] [get_ports $input_ports] -clock_fall;
set_input_delay -clock $input_clock -min $dv_afe [get_ports $input_ports] -clock_fall;
# input ____________________
# clock _____________| |_____________
# | |
# dv_bre | dv_are dv_bfe | dv_afe
# <------>|<------> <------>|<------>
# _ ________|________ ________|________ _
# data _XXXX____Rise_Data____XXXX____Fall_Data____XXXX_
#
set input_clock <clock_name>; # Name of input clock
set input_clock_period <period_value>; # Period of input clock (full-period)
set dv_bre 0.000; # Data valid before the rising clock edge
set dv_are 0.000; # Data valid after the rising clock edge
set dv_bfe 0.000; # Data valid before the falling clock edge
set dv_afe 0.000; # Data valid after the falling clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 - $dv_bfe] [get_ports $input_ports];
set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports];
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 - $dv_bre] [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min $dv_afe [get_ports $input_ports] -clock_fall -add_delay;
源同步边沿对齐
边沿对齐的情况下分两种情况,上升沿模式下VIVADO原话如下:
1、Edge-Aligned Rising Edge Source Synchronous Inputs(Using an MMCM/PLL)
2、Edge-Aligned Rising Edge Source Synchronous Inputs(Using a direct FF connection)
通过查阅资料说明如下:
Edge-Aligned (clock with MMCM): 在这种配置中,时钟信号通过混合模式时钟管理器(MMCME2)进行处理。MMCME2是一个混合信号块,设计用于支持频率合成、时钟网络偏移校正和抖动减少。时钟输出可以根据相同的VCO频率分别具有单独的分频、相移和占空比。此外,MMCME2支持动态相移和小数分频。这种配置通常用于处理源同步数据,其中数据速率和时钟频率不同,需要通过MMCME2生成适当的时钟信号来捕获数据。例如,当数据以160Mbps的速度到达,但时钟仅为40MHz时,可以通过MMCME从40MHz时钟输入生成160MHz时钟,然后使用此生成的160MHz时钟以单数据速率方案捕获160Mbps数据。这种情况下,数据的边沿与生成的时钟的上升沿对齐,因此需要配置MMCME2,使160MHz时钟相移180度,使上升沿位于数据传输的中心1。
Edge-Aligned (clock directly to ff): 在这种配置中,时钟信号直接连接到FPGA内部的触发器(ff),而不需要经过MMCME2的处理。这种配置适用于系统同步输入的情况,即当source clock和destination clock来自同一个系统时钟时。在这种情况下,首先约束source clock为主时钟,然后进行相应的时序约束分析。例如,当分析输入端口到FPGA内部时序单元的路径时,如果source clock和destination clock来自同一个系统时钟,称为系统同步输入。在这种情况下,首先约束destination clock为主时钟,然后进行相应的时序约束分析23。
综上所述,Edge-Aligned (clock with MMCM) 主要用于处理源同步数据,其中数据速率和时钟频率不同,需要通过MMCME2生成适当的时钟信号。而 Edge-Aligned (clock directly to ff) 则适用于系统同步输入的情况,其中时钟信号直接连接到FPGA内部的触发器,不需要经过额外的时钟管理器处理。
Edge-Aligned (clock with MMCM)
约束如下:
# Edge-Aligned Rising Edge Source Synchronous Inputs
# (Using an MMCM/PLL)
input __________ ________________
# clock |________________| |__________
# |
# skew_bre|skew_are
# <------>|<------>
# _________________ | _________________
# data XX____Rise_Data____XXXXXXXXXXXXXXXXX_________________XX
#
set input_clock <clock_name>; # Name of input clock
set skew_bre 0.000; # Data invalid before the rising clock edge
set skew_are 0.000; # Data invalid after the rising clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max $skew_are [get_ports $input_ports];
set_input_delay -clock $input_clock -min -$skew_bre [get_ports $input_ports];
# Edge-Aligned Falling Edge Source Synchronous Inputs
# (Using an MMCM/PLL)
# input ________________ __________
# clock __________| |________________|
# |
# skew_bfe|skew_afe
# <------>|<------>
# _________________ | _________________
# data XX____Fall_Data____XXXXXXXXXXXXXXXXX_________________XX
#
set input_clock <clock_name>; # Name of input clock
set skew_bfe 0.000; # Data invalid before the falling clock edge
set skew_afe 0.000; # Data invalid after the falling clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max $skew_afe [get_ports $input_ports] -clock_fall;
set_input_delay -clock $input_clock -min -$skew_bfe [get_ports $input_ports] -clock_fall;
# Edge-Aligned Double Data Rate Source Synchronous Inputs
# (Using an MMCM/PLL)
# input ___________________________
# clock _____________________| |__________
# | |
# skew_bre|skew_are skew_bfe|skew_afe
# <------>|<------> <------>|<------>
# ___________ | ___________ __
# data XX_Rise_Data_XXXXXXXXXXXXXXXXX_Fall_Data_XXXXXXXXXXXXXXXXX__
#
set input_clock <clock_name>; # Name of input clock
set skew_bre 0.000; # Data invalid before the rising clock edge
set skew_are 0.000; # Data invalid after the rising clock edge
set skew_bfe 0.000; # Data invalid before the falling clock edge
set skew_afe 0.000; # Data invalid after the falling clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max $skew_are [get_ports $input_ports];
set_input_delay -clock $input_clock -min -$skew_bre [get_ports $input_ports];
set_input_delay -clock $input_clock -max $skew_afe [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min -$skew_bfe [get_ports $input_ports] -clock_fall -add_delay;
以上约束一般使用在视频采集/多通道ADC采集中,一个时钟里面有多组数据。
Edge-Aligned (clock directly to ff)
时序约束如下:
# Edge-Aligned Rising Edge Source Synchronous Inputs
# (Using a direct FF connection)
# input __________ ________________
# clock |________________| |__________
# |
# skew_bre|skew_are
# <------>|<------>
# ________________ | ________________
# data XXX________________XXXXXXXXXXXXXXXXX____Rise_Data___XXX
#
set input_clock <clock_name>; # Name of input clock
set input_clock_period <period_value>; # Period of input clock
set skew_bre 0.000; # Data invalid before the rising clock edge
set skew_are 0.000; # Data invalid after the rising clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $input_clock_period + $skew_are] [get_ports $input_ports];
set_input_delay -clock $input_clock -min [expr $input_clock_period - $skew_bre] [get_ports $input_ports];
# Edge-Aligned Falling Edge Source Synchronous Inputs
# (Using a direct FF connection)
# input ________________ __________
# clock __________| |________________|
# |
# skew_bfe|skew_afe
# <------>|<------>
# ________________ | ________________
# data XXX________________XXXXXXXXXXXXXXXXX____Fall_Data___XXX
#
set input_clock <clock_name>; # Name of input clock
set input_clock_period <period_value>; # Period of input clock
set skew_bfe 0.000; # Data invalid before the falling clock edge
set skew_afe 0.000; # Data invalid after the falling clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $input_clock_period + $skew_afe] [get_ports $input_ports] -clock_fall;
set_input_delay -clock $input_clock -min [expr $input_clock_period - $skew_bfe] [get_ports $input_ports] -clock_fall;
# Edge-Aligned Double Data Rate Source Synchronous Inputs
# (Using a direct FF connection)
# input _________________________________
# clock _________| |___________________________
# | |
# skew_bre|skew_are skew_bfe|skew_afe
# <------>|<------> <------>|<------>
# _ | _________________ | _________________
# data _XXXXXXXXXXXXXXXXX____Rise_Data____XXXXXXXXXXXXXXXXX____Fall_Data____XX
#
set input_clock <clock_name>; # Name of input clock
set input_clock_period <period_value>; # Period of input clock (full-period)
set skew_bre 0.000; # Data invalid before the rising clock edge
set skew_are 0.000; # Data invalid after the rising clock edge
set skew_bfe 0.000; # Data invalid before the falling clock edge
set skew_afe 0.000; # Data invalid after the falling clock edge
set input_ports <input_ports>; # List of input ports
# Input Delay Constraint
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 + $skew_afe] [get_ports $input_ports];
set_input_delay -clock $input_clock -min [expr $input_clock_period/2 - $skew_bfe] [get_ports $input_ports];
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 + $skew_are] [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min [expr $input_clock_period/2 - $skew_bre] [get_ports $input_ports] -clock_fall -add_delay;
上面第三种情况刚好可以使用在千兆以太网时序里。
output delay constraints
系统同步
系统约束分上升沿触发、下降沿触发、双沿触发,约束公式如下:
# Rising Edge System Synchronous Outputs
# dest __________ __________
# clk ____| |__________|
# |
# (trce_dly_max+tsu) <---------|
# (trce_dly_min-thd) <-|
# __ __
# data XXXXXXXXXXXXXXXX__DATA__XXXXXXXXXXXXX
#
set destination_clock <clock_name>; # Name of destination clock
set tsu 0.000; # Destination device setup time requirement
set thd 0.000; # Destination device hold time requirement
set trce_dly_max 0.000; # Maximum board trace delay
set trce_dly_min 0.000; # Minimum board trace delay
set output_ports <output_ports>; # List of output ports
# Output Delay Constraint
set_output_delay -clock $destination_clock -max [expr $trce_dly_max + $tsu] [get_ports $output_ports];
set_output_delay -clock $destination_clock -min [expr $trce_dly_min - $thd] [get_ports $output_ports];
# Falling Edge System Synchronous Outputs
# dest ____ __________
# clk |__________| |__________
# |
# (trce_dly_max+tsu) <---------|
# (trce_dly_min-thd) <-|
# __ __
# data XXXXXXXXXXXXXXXX__DATA__XXXXXXXXXXXXX
#
set destination_clock <clock_name>; # Name of destination clock
set tsu 0.000; # Destination device setup time requirement
set thd 0.000; # Destination device hold time requirement
set trce_dly_max 0.000; # Maximum board trace delay
set trce_dly_min 0.000; # Minimum baord trace delay
set output_ports <output_ports>; # List of output ports
# Output Delay Constraint
set_output_delay -clock $destination_clock -max [expr $trce_dly_max + $tsu] [get_ports $output_ports] -clock_fall;
set_output_delay -clock $destination_clock -min [expr $trce_dly_min - $thd] [get_ports $output_ports] -clock_fall;
# Double Data Rate System Synchronous Outputs
# dest ________________________________ __________
# clk ____| |________________________________|
# | |
# (trce_dly_max+tsu_f) <---------| (trce_dly_max+tsu_r) <---------|
# (trce_dly_min-thd_f) <-| (trce_dly_min-thd_r) <-|
# __ __ __ __
# data XXXXXXXXXXXXXXXXXXXXXXXXXXX__DATA__XXXXXXXXXXXXXXXXXXXXXXXXX__DATA__XXXXXXXXXXXXX
#
set destination_clock <clock_name>; # Name of destination clock
set tsu_r 0.000; # Destination device setup time requirement for rising edge
set thd_r 0.000; # Destination device hold time requirement for rising edge
set tsu_f 0.000; # Destination device setup time requirement for falling edge
set thd_f 0.000; # Destination device hold time requirement for falling edge
set trce_dly_max 0.000; # Maximum board trace delay
set trce_dly_min 0.000; # Minimum baord trace delay
set output_ports <output_ports>; # List of output ports
# Output Delay Constraint
set_output_delay -clock $destination_clock -max [expr $trce_dly_max + $tsu_r] [get_ports $output_ports] ;
set_output_delay -clock $destination_clock -min [expr $trce_dly_min - $thd_r] [get_ports $output_ports] ;
set_output_delay -clock $destination_clock -max [expr $trce_dly_max + $tsu_f] [get_ports $output_ports] -clock_fall -add_delay;
set_output_delay -clock $destination_clock -min [expr $trce_dly_min - $thd_f] [get_ports $output_ports] -clock_fall -add_delay;
这里我们可以看到系统同步,不论输入还是输出只有边沿对齐,并没有中心对齐,FPGA作为从端只能做边沿触发。
源同步
边沿对齐时序如下:
# Rising Edge Source Synchronous Outputs
# forwarded _____________
# clock ___________| |_________
# |
# bre_skew|are_skew
# <------>|<------>
# ______ | ____________
# data ______XXXXXXXXXXXXXXXXX____________XXXXX
#
# Example of creating generated clock at clock output port
# create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>]
# gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk".
set fwclk <clock_name>; # forwarded clock name (generated using create_generated_clock at output clock port)
set fwclk_period <period_value>; # forwarded clock period
set bre_skew 0.000; # skew requirement before rising edge
set are_skew 0.000; # skew requirement after rising edge
set output_ports <output_ports>; # list of output ports
# Output Delay Constraints
set_output_delay -clock $fwclk -max [expr $fwclk_period - $are_skew] [get_ports $output_ports];
set_output_delay -clock $fwclk -min $bre_skew [get_ports $output_ports];
# Falling Edge Source Synchronous Outputs
# forwarded ____________ _________
# clock |_____________|
# |
# bfe_skew|afe_skew
# <------>|<------>
# ______ | ____________
# data ______XXXXXXXXXXXXXXXXX____________XXXX
#
# Example of creating generated clock at clock output port
# create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>]
# gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk".
set fwclk <clock_name>; # forwarded clock name (generated using create_generated_clock at output clock port)
set fwclk_period <period_value>; # forwarded clock period
set bfe_skew 0.000; # skew requirement before falling edge
set afe_skew 0.000; # skew requirement after falling edge
set output_ports <output_ports>; # list of output ports
# Output Delay Constraints
set_output_delay -clock $fwclk -max [expr $fwclk_period - $afe_skew] [get_ports $output_ports] -clock_fall;
set_output_delay -clock $fwclk -min $bfe_skew [get_ports $output_ports] -clock_fall;
# Double Data Rate Source Synchronous Outputs
# forwarded __________________________
# clock ____________| |______________
# | |
# bre_skew|are_skew bfe_skew|afe_skew
# <------>|<------> <------>|<------>
# ______ | __________ | ______
# data ______XXXXXXXXXXXXXXXXX__________XXXXXXXXXXXXXXXXX______
#
# Example of creating generated clock at clock output port
# create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>]
# gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk".
set fwclk <clock_name>; # forwarded clock name (generated using create_generated_clock at output clock port)
set fwclk_period <period_value>; # forwarded clock period (full-period)
set bre_skew 0.000; # skew requirement before rising edge
set are_skew 0.000; # skew requirement after rising edge
set bfe_skew 0.000; # skew requirement before falling edge
set afe_skew 0.000; # skew requirement after falling edge
set output_ports <output_ports>; # list of output ports
# Output Delay Constraints
set_output_delay -clock $fwclk -max [expr $fwclk_period/2 - $afe_skew] [get_ports $output_ports];
set_output_delay -clock $fwclk -min $bre_skew [get_ports $output_ports];
set_output_delay -clock $fwclk -max [expr $fwclk_period/2 - $are_skew] [get_ports $output_ports] -clock_fall -add_delay;
set_output_delay -clock $fwclk -min $bfe_skew [get_ports $output_ports] -clock_fall -add_delay;
中心对齐约束如下:
# Rising Edge Source Synchronous Outputs
# forwarded ____ ___________________
# clock |____________________| |____________
# |
# tsu | thd
# <---------->|<--------->
# ____________|___________
# data @ destination XXXXXXXXX________________________XXXXX
#
# Example of creating generated clock at clock output port
# create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>]
# gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk".
set fwclk <clock-name>; # forwarded clock name (generated using create_generated_clock at output clock port)
set tsu 0.000; # destination device setup time requirement
set thd 0.000; # destination device hold time requirement
set trce_dly_max 0.000; # maximum board trace delay
set trce_dly_min 0.000; # minimum board trace delay
set output_ports <output_ports>; # list of output ports
# Output Delay Constraints
set_output_delay -clock $fwclk -max [expr $trce_dly_max + $tsu] [get_ports $output_ports];
set_output_delay -clock $fwclk -min [expr $trce_dly_min - $thd] [get_ports $output_ports];
# Falling Edge Source Synchronous Outputs
#
# forwarded _________________ _______
# clock ____| |__________________|
# |
# tsu | thd
# <---------->|<--------->
# ____________|___________
# data @ destination XXXXXXXXX________________________XXXXX
#
# Example of creating generated clock at clock output port
# create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>]
# gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk".
set fwclk <clock-name>; # forwarded clock name (generated using create_generated_clock at output clock port)
set tsu 0.000; # destination device setup time requirement
set thd 0.000; # destination device hold time requirement
set trce_dly_max 0.000; # maximum board trace delay
set trce_dly_min 0.000; # minimum board trace delay
set output_ports <output_ports>; # list of output ports
# Output Delay Constraints
set_output_delay -clock $fwclk -max [expr $trce_dly_max + $tsu] [get_ports $output_ports] -clock_fall;
set_output_delay -clock $fwclk -min [expr $trce_dly_min - $thd] [get_ports $output_ports] -clock_fall;
# Double Data Rate Source Synchronous Outputs
# forwarded _________________________________
# clock __________| |______________
# | |
# tsu_r | thd_r tsu_f | thd_f
# <------>|<-------> <------>|<----->
# ________|_________ ________|_______
# data @ destination XXX__________________XXXXXXXXXXXXXXXX________________XXXXX
#
# Example of creating generated clock at clock output port
# create_generated_clock -name <gen_clock_name> -multiply_by 1 -source [get_pins <source_pin>] [get_ports <output_clock_port>]
# gen_clock_name is the name of forwarded clock here. It should be used below for defining "fwclk".
set fwclk <clock-name>; # forwarded clock name (generated using create_generated_clock at output clock port)
set tsu_r 0.000; # destination device setup time requirement for rising edge
set thd_r 0.000; # destination device hold time requirement for rising edge
set tsu_f 0.000; # destination device setup time requirement for falling edge
set thd_f 0.000; # destination device hold time requirement for falling edge
set trce_dly_max 0.000; # maximum board trace delay
set trce_dly_min 0.000; # minimum board trace delay
set output_ports <output_ports>; # list of output ports
# Output Delay Constraints
set_output_delay -clock $fwclk -max [expr $trce_dly_max + $tsu_r] [get_ports $output_ports];
set_output_delay -clock $fwclk -min [expr $trce_dly_min - $thd_r] [get_ports $output_ports];
set_output_delay -clock $fwclk -max [expr $trce_dly_max + $tsu_f] [get_ports $output_ports] -clock_fall -add_delay;
set_output_delay -clock $fwclk -min [expr $trce_dly_min - $thd_f] [get_ports $output_ports] -clock_fall -add_delay;
以上是理论知识,后面会陆续添加各种不同的案例做详细介绍。
系统同步实际用例
源同步实际用例
例如双沿采样信号如下:
套用源同步双边沿公式如下:
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 + $skew_afe] [get_ports $input_ports];
set_input_delay -clock $input_clock -min [expr $input_clock_period/2 - $skew_bfe] [get_ports $input_ports];
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 + $skew_are] [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min [expr $input_clock_period/2 - $skew_bre] [get_ports $input_ports] -clock_fall -add_delay;
假如我们同步时钟是54Mhz,按照IMX222的时序参数rise max= 18.518/2 + 2ns; rise min = 18.518/2 -2ns;同理下降沿也是,最终约束如下:
create_clock -period 18.518 -name rx_clk -waveform {0.000 9.259} [get_ports rx_clk]
set_input_delay -clock [get_clocks rx_clk] -rise -max 11.259 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -rise -min 7.259 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -clock_fall -fall -max -add_delay 11.259 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -clock_fall -fall -min -add_delay 71.259 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
再以千兆以太网做example:
理论上接收的时序如下:
实际接收的信号会有偏移,变成了类似中间沿对齐的模式,如下图所示:
时序介绍如下:
调用公式如下:
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 - $dv_bfe] [get_ports $input_ports];
set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports];
set_input_delay -clock $input_clock -max [expr $input_clock_period/2 - $dv_bre] [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min $dv_afe [get_ports $input_ports] -clock_fall -add_delay;
其中系统时钟是125MHz,转换成时间是8ns,带入公式$input_clock_period/2=4ns;
$dv_bre、$dv_are 、¥dv_bfe均可以认为是2ns;
标签:set,clock,get,约束,delay,Vivado,input,时序,ports From: https://blog.csdn.net/weixin_51418325/article/details/141899864