VIVADO时序约束之时序例外(set_multicycle_path)

一、前言

多周期路径约束允许用户根据设计时钟波形修改计时器确定的setup和hold关系。默认情况下,Vivado IDE时序分析执行单周期分析。这种分析可能过于限制,并且可能不适用于某些逻辑路径。最常见的例子是逻辑路径,它需要一个以上的时钟周期才能使数据在端点稳定。如果路径起点和终点的控制电路允许,Xilinx建议您使用多周期路径约束来放宽设置要求。根据您的意图,保留要求可能仍然保持原始关系。这有助于时序驱动算法将注意力集中在要求更严格且具有挑战性的其他路径上。它还可以帮助减少运行时间。

二、set_multicycle_path 语法

指示从路径的开始到结束传播数据所需的时钟周期数。

set_multicycle_path [-setup] [-hold] [-rise] [-fall] [-start] -[end] [-reset_path] 
					[-from <args>] [-rise_from <args>] [-fall_from <args>]
					[-to <args>] [-rise_to <args>] [-fall_to <args>]
					[-through <args>] [-rise_through <args>] [-fall_through <args>]
					[-quiet] [-verbose] <path_multiplier>
选项 含义
-setup 应用于setup路径的多周期检查,同时也会影响hold路径的检查,当未指定-setup或hold时,这也是set_multiplier_path命令的默认行为;
-hold 仅仅作用于hold路径的多周期检查,用于改变hold路径的时钟周期关系;
-rise/fall 指定该约束专门应用于路径端点上的上升沿/下降沿延迟;
-start 默认情况下,setup路径多周期约束是相对于目标时钟定义的。要修改相对于源时钟的setup要求,必须使用-start选项;
-end 默认情况下,hold路径多周期约束是相对于源时钟定义的。要修改相对于目的时钟的hold要求,必须使用-end选项;
-reset_path 在应用多周期路径乘数之前重置指定的路径;
-from 多周期约束作用路径的起点列表
-rise_from 多周期约束作用起点列表的上升沿路径;
–fall_from 多周期约束作用起点列表的下降沿沿路径;
-to 多周期约束作用路径的终点列表
-rise_to 多周期约束作用终点列表的上升沿路径
-fall_to 多周期约束作用终点列表的下降沿路径
-through pins、cell、nets列表,所有经过该列表的路径均受多周期约束作用;
-rise_through pins、cell、nets列表,所有经过该列表的上升沿路径均受多周期约束作用;
-fall_through pins、cell、nets列表,所有经过该列表的下降沿路径均受多周期约束作用;
-quiet 忽略命令错误
建立时间和保持时间周期数

当-setup和-hold均未设置时,或者只设置了-setup,path_multiplier同时作用于setup和hold检查
当-rise和-fall均未设置时,默认path_multiplier同时作用于上升沿和下降沿

三、同时钟域下的multicycle约束

VIVADO时序约束之时序例外(set_multicycle_path)_第1张图片
静态时序分析工具,对默认的建立时间和保持时间的相对关系如下所示:
VIVADO时序约束之时序例外(set_multicycle_path)_第2张图片
此时,建立时间和保持时间的计算关系如下:
建立时间: T D a t a p a t h ( m a x ) < T C L K ( t = p e r i o d ) − T s e t u p T _{Datapath(max)} < TCLK_{(t=period)} - T_{setup} TDatapath(max)<TCLK(t=period)Tsetup
保持时间: T D a t a p a t h ( m i n ) < T C L K ( t = 0 ) + T h o l d T _{Datapath(min)} < TCLK_{(t=0)} + T_{hold} TDatapath(min)<TCLK(t=0)+Thold
放松setup约束,保持hold约束
VIVADO时序约束之时序例外(set_multicycle_path)_第3张图片

set_multicycle_path 2 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]

下图为约束前后,时序分析的差异性:
VIVADO时序约束之时序例外(set_multicycle_path)_第4张图片
由于时钟使能,此路径不需要将数据保持在data0_reg中一个周期即可正常工作。在这种情况下,Xilinx建议将保持关系更改回原始状态,即在相同的启动边缘和捕获边缘之间。为此,您必须添加第二个仅修改保持检查的多周期路径约束:

set_Multicycle_Path 1-hold-end-from[get_pins data0_reg/C] -To[get_pins data1_reg/D]

-end选项与set_muulticycle-hold命令一起使用,因为捕获时钟的边缘必须向后移动
VIVADO时序约束之时序例外(set_multicycle_path)_第5张图片
一般情况下,同时钟域下,或者两个时钟波形完全相同时,当setup多周期系数设置为N时,可设置hold的多周期值系数为N-1
set_multicycle_path N -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path N-1 -hold -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]

四、同频不同相的两个时钟域下的multicycle约束

有时,必须在具有相同时钟周期但两个时钟之间存在相移的两个时钟域之间定义定时约束。在这些情况下,了解工具在默认情况下的setup和hold时序分析原理至关重要。如果不仔细调整,两个时钟之间的相移可能会导致两个时钟域之间的逻辑受到过度约束。
VIVADO时序约束之时序例外(set_multicycle_path)_第6张图片

正相位偏移

假设CLK1和CLK2是同频不同相的,且CLK2相位落后于CLK1 0.3 ns。
定时引擎通过查看两个波形上的所有边缘并选择导致更严格约束的发射和捕获时钟上的两个边缘来计算设置关系。由于时钟相移,定时引擎使用的设置和保持关系可能与预期的不同。下图为默认情况下的时序分析:
VIVADO时序约束之时序例外(set_multicycle_path)_第7张图片
必须调整设置和保持边缘以符合您的意图。这是通过添加一个setup系数为2的多周期约束来完成的:

set_multicycle_path 2 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]

这导致将setup要求的捕获边沿向前移动一个周期,hold会随着setup的更改而更改,不需要指定。如下图所示:
VIVADO时序约束之时序例外(set_multicycle_path)_第8张图片

负相位偏移

VIVADO时序约束之时序例外(set_multicycle_path)_第9张图片
对于负相移,通常不需要多周期约束来平衡相移的影响。如果相移太大,必须调整时钟启动或捕获边沿,以保证实际的setup和hold要求,以免发生异常。

五、慢时钟域到快时钟域下的multicycle设置

VIVADO时序约束之时序例外(set_multicycle_path)_第10张图片
如上图所示,CLK1是慢时钟,CLK2是快时钟,假定,CLK2的频率是CLK1频率的3倍,接收端寄存器有时钟使能信号,允许两时钟之间做多周期约束,默认情况下,时序分析会按照如下约束分析:
VIVADO时序约束之时序例外(set_multicycle_path)_第11张图片
1、当只对setup做3周期的约束时:

set_multicycle_path 3 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]

setup周期的约束会将CLK2的数据采集沿向前推进2个周期。由于没有设置hold值,所以hold的相对时钟关系会随着setup的设置向前推进2个周期,launch clock的有效边沿不受多周期约束的修改而变化。如下图所示:
VIVADO时序约束之时序例外(set_multicycle_path)_第12张图片
2、setup和hold同时约束
为了放松hold time的时序要求,捕获时钟需要相后移动两个时钟周期。可以使用-end 选项与set_multicycle_path -hold命令一起使用:

set_multicycle_path 3 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
set_multicycle_path 2 -hold -end -from [get_clocks CLK1] -to [get_clocks CLK2]

注意:如果-end选项没有指定到set_multicycle_path -hold命令中,launch clock的边沿会向前推2个时钟周期。不符合预期的hold要求。
VIVADO时序约束之时序例外(set_multicycle_path)_第13张图片
一般情况下,慢时钟域到快时钟域下的时序约束,当setup设置为N时,hold需要设置为N-1,并需要和-end选项一起使用
set_multicycle_path N -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
set_multicycle_path N-1 -hold -end -from [get_clocks CLK1] -to [get_clocks CLK2]

六、快时钟域到慢时钟域下的multicycle设置

VIVADO时序约束之时序例外(set_multicycle_path)_第14张图片
如上图所示,CLK1是快时钟,CLK2是慢时钟,假定,CLK1的频率是CLK2频率的3倍,默认情况下,时序分析工具会根据下图的情况进行时序分析:
VIVADO时序约束之时序例外(set_multicycle_path)_第15张图片
假定setup时间相对于源时钟(-start)的多周期系数为3,hold的多周期系数值为1:

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]

相对于源时钟(-start)定义setup乘数的结果是将用于setup检查的源时钟的边沿向后移动两(2)个周期(即3-1个周期)。但是,由于hold乘数是根据源时钟定义的(默认的-start选项带有-hold),因此用于hold时序分析的的启动时钟的边沿向前移动两(2)个周期。对于setup和hold的分析,捕获时钟边沿不会改变。请参见下图。
VIVADO时序约束之时序例外(set_multicycle_path)_第16张图片
一般情况下,快时钟域到慢时钟域的跨时钟域路径的时序分析,通常设置setup相对于源时钟的多周期系数值为N,hold值为N-1
set_multicycle_path N -setup -start -from [get_clocks CLK1] -to [get_clocks CLK2]
set_multicycle_path N-1 -hold -from [get_clocks CLK1] -to [get_clocks CLK2]

七、实操演示

RTL code

module cdc_test(
	 input	wire	clk_src
	,input	wire	clk_dest0
	,input	wire	clk_dest1
	,input	wire	signal_in
	,output	wire	signal_out0
	,output	wire	signal_out1
);
//==============================================================================================
//======								define signal									========
//==============================================================================================
(*keep="ture"*)reg	[1:0]		ff_src		;
(*keep="ture"*)reg	[1:0]		ff_dest0	;
(*keep="ture"*)reg	[1:0]		ff_dest1	;
//==============================================================================================
//======                               behave of RTL                                    ========
//==============================================================================================
always@(posedge clk_src)begin
	ff_src[0] <= signal_in;
	ff_src[1] <= ff_src[0];
end
always@(posedge clk_dest0)begin
	ff_dest0[0] <= ff_src[1];
	ff_dest0[1] <= ff_dest0[0];
end
always@(posedge clk_dest1)begin
	ff_dest1[0] <= ff_src[1];
	ff_dest1[1] <= ff_dest1[0];
end

assign signal_out0 = ff_dest0[1];
assign signal_out1 = ff_dest1[1];

a、同频时钟

constrains

# period 10ns,duty 50%,no phase shift
create_clock -name clock_src [get_ports clk_src] -period 10.000 
# period 10ns,duty 50%,phase shift 90 degress
create_clock -name clock_dest0 [get_ports clk_dest0] -period 10.000 -waveform {2.5 7.5}
# period 10ns,duty 50%,phase shift 180 degress
create_clock -name clock_dest1 [get_ports clk_dest1] -period 10.000 -waveform {5 10}

set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest0] -setup 1
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest0] -hold 0
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest1] -setup 2
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest1] -hold 1

时序分析结果:

clock_src 到 clock_dest0,setup
在这里插入图片描述
clock_src 到 clock_dest0,hold在这里插入图片描述
clock_src 到 clock_dest1,setup
在这里插入图片描述
clock_src 到 clock_dest1,hold
在这里插入图片描述
clock_src 到 clock_dest0的setup和hold的组合实践结果:

setup multiplier hold multiplier setup requirement hold requirement
0 -1 -7.500 -7.500
0 0 -7.500 -17.500
1 -1 2.500 2.500
1 0 2.500 -7.500
1 1 2.500 -17.500
2 -1 12.500 12.500
2 0 12.500 2.500
2 1 12.500 -7.500
2 2 12.500 -17.500

总结:setup requirement只与setup multiplier有关,hold requirement受setup multiplier和hold multiplier共同作用,计算关系如下:

T s e t u p _ r e q u i r e m e n t = ( N s e t u p _ m u l t i − 2 ) ∗ T p e r i o d _ c l k _ d e s t + T p e r i o d _ c l k _ s r c T _{setup\_requirement}=(N_{setup\_multi} - 2) * T_{period\_clk\_dest} + T_{period\_clk\_src} Tsetup_requirement=(Nsetup_multi2)Tperiod_clk_dest+Tperiod_clk_src
T h o l d _ r e q u i r e m e n t = ( N s e t u p _ m u l t i − 1 ) ∗ T p e r i o d _ c l k _ d e s t + N h o l d _ m u l t i ∗ T p e r i o d _ c l k _ s r c T _{hold\_requirement}=(N_{setup\_multi} - 1) * T_{period\_clk\_dest} + N_{hold\_multi} * T_{period\_clk\_src} Thold_requirement=(Nsetup_multi1)Tperiod_clk_dest+Nhold_multiTperiod_clk_src

b、慢时钟域到快时钟域

constrains

# period 50ns,duty 50%,no phase shift
create_clock -name clock_src [get_ports clk_src] -period 50.000 
# period 10ns,duty 50%,no phase shift
create_clock -name clock_dest0 [get_ports clk_dest0] -period 10.000
# period 10ns,duty 50%,no phase shift
create_clock -name clock_dest1 [get_ports clk_dest1] -period 10.000

set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest0] -setup 5
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest0] -hold 4
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest1] -setup 5
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest1] -hold 4 -end

时序分析结果:

clock_src 到 clock_dest0,setup
在这里插入图片描述
clock_src 到 clock_dest0,hold
在这里插入图片描述
clock_src 到 clock_dest1,setup
在这里插入图片描述
clock_src 到 clock_dest1,hold
在这里插入图片描述

c、快时钟域到慢时钟域

constrains

# period 10ns,duty 50%,no phase shift
create_clock -name clock_src [get_ports clk_src] -period 10.000 
# period 50ns,duty 50%,no phase shift
create_clock -name clock_dest0 [get_ports clk_dest0] -period 50.000
# period 50ns,duty 50%,no phase shift
create_clock -name clock_dest1 [get_ports clk_dest1] -period 50.000

set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest0] -setup 5
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest0] -hold 4
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest1] -setup 5 -start
set_multicycle_path -from [get_clocks clk_src] -to [get_clocks clock_dest1] -hold 4

时序分析结果:

clock_src 到 clock_dest0,setup
在这里插入图片描述
clock_src 到 clock_dest0,hold
在这里插入图片描述
clock_src 到 clock_dest1,setup
在这里插入图片描述
clock_src 到 clock_dest1,hold
在这里插入图片描述

你可能感兴趣的:(vivado,fpga开发)