目录
一、背景
二、set_multicycle_path
a)Targets界面
b)options界面
c)setup与hold关系
三、多周期约束场景
3.1 单时钟域的多周期约束
3.2 多周期路径与时钟相移
3.3 慢时钟到快时钟的多周期约束
3.4 快时钟到慢时钟的多周期约束
四、工程示例
五、参考
对于Vivado时序分析工具,默认情况下是进行单个周期内的时序分析,这种分析存在一定的局限性,对于一些特殊的逻辑路径不适用,例如,对于数据从起点到达终点的时间需要超过一个时钟周期以上的场景。如果设计中控制电路的路径从起点到终点大于一个周期是符合设计需要的,此时,就需要使用多周期路径约束来放宽setup时间。通俗理解,多周期约束即调整时序分析中源时钟边沿与目的时钟边沿的位置关系。
设置多周期路径使用命令set_multicycle_path,进入Edit Timing Constraints中的Set Multicycle Path窗口。对象设置栏含义如下图。
Specify path_multiplier:设置多周期约束的数目,必须为大于0的整数,默认为1时为setup/recovery分析,为0时即hold/removal分析
Start Points:多周期约束的起点
Through Points:多周期约束中经过的位置
End Points:多周期约束的终点
Hold和Setup的分析边沿存在关联关系,对于大部分场景,可用下面的公式获得hold周期的个数。
Hold移动周期数=setup路径的Multiplier-1-hold路径的Multiplier。默认的setup路径的Multiplier是和目的时钟相关联,使用-start参数修可以修改setup时序要求,类似地,holdup周期数和源时钟有关,使用参数-end可以修正。
命令格式示例:
set_multicycle_path -fall_from [get_pins ff1_reg/C] -rise_to [get_pins ff2_reg/C] 2
Setup/Hold:设置多周期约束路径进行时序分析类型为setup或hold
Rise/Fall:设置多周期约束是针对上升沿Rise还是下降沿Fall,默认上升沿Rise
Start/End:设置约束中Multiplier的周期数的参考时钟是源时钟(startpoint)还是目的时钟(endpoint)
Remove existing path exceptions before setting multicycle path: 对于设置多周期约束的路径上如果存在其他时序例外约束的,勾选后将会移除,不勾选则保留该约束
对于一条时序路径上setup和hold的关系如下图,对于源时钟的启动沿,setup考虑的是一个源时钟周期后的边沿与源时钟对应的目的时钟的边沿,即寻找启动沿之后最近的一个捕获沿,可见图中“setup关系”的两个边沿,hold考虑的是和源时钟启动沿对应的目的时钟边沿,即寻找与启动沿对齐或在启动沿前面最靠近的一个捕获沿,如“hold关系1”和“hold关系2”的2组边沿。
对于源时钟和目的时钟非同相同频率时,需要指定-start,-end来指定参考时钟,启动沿和捕获沿与参数-start和-end在setup/hold时序分析中的关系如下表
注:当源时钟和目的时钟相同或波形相同或不存在相位差时,使用start和end参数将没有明显的区别,因为此时选择源时钟或目的时钟作为参数时钟都是同一个时钟。
下面,将针对一些常见的多时钟周期约束场景进行约束设置的说明,同时使用图片对setup/hold multipliers值以及参数-start,-end对时序路径的影响进行解释。
时序分析工具STA分析时序默认的setup和hold关系如下图
setup检查
Td(max)
hold检查
Td(min)>Tclk(t=0)+Thold =》数据传输的最小时延要大于寄存器的holdup时间
在发起时钟和捕获时钟为同一个时钟,或两个时钟有相同的波形(并且不存在相移)时,时序路径属于单时钟域内的时序路径,在数据传输到目的时钟的寄存器需要多个时钟周期时,就需要设置多周期约束。
以捕获时钟每两个周期进行数据捕获为例(通过使能信号每2个周期生效一次),触发器data1_reg每2个clk周期进行一次数据采集
多周期约束命令
set_multicycle_path 2 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
约束中仅仅对setup设置了约束,但setup和hold的关系都会改变,设置多周期约束前setup边沿和hold边沿在源时钟和目的时钟的关系如下图。
设置多周期约束后,setup边沿和hold边沿在目的时钟中前移一个周期
但触发器data0_reg中数据的hold边沿实际并未改变,因此,需要hold的关系通过多周期约束回到初始的边沿对比。
set_multicycle_path 1 -hold -end -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
-end参数配合-hold时,表示捕获时钟的边沿往回移动。另外,如果源时钟和目的时钟为相同的时钟时,-end可以省略,两条多周期约束的效果如下图
当setup multiplier为4时,对应的约束为
set_multicycle_path 4 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path 3 -hold -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
对应的波形效果如下图
下面,继续以移动setup的多周期为例
样例1:setup=5
只对setup约束5个周期的周期时延,约束命令为:
set_multicycle_path 5 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
由于未指定hold的时延周期,将自动的根据setup 启动沿和捕获沿推断出。通常情况,setup的multiplier是针对捕获时钟,将捕获时钟前移,hold的mulitplier未指定,因此捕获时钟中检查hold的边沿比setup检查的边沿提前一个周期,波形图如下。
由于hold有4个周期的移动,在时序路径上必须插入大量的时延,增加不必要的面积和功耗,因此,也得放宽hold的要求,见样例2。
样例2:setup=5/hold=4
多周期约束命令为
set_multicycle_path 5 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path 4 -hold -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
对应的波形图为:
由于源时钟和目的时钟波形相同,相位调整后和下图波形效果相同
总结:在一个时钟域内或源时钟和目的时钟波形相同且无相移时,对setup multiplier设置了N个周期时,对hold multiplier设置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]
有时,时钟约束必须定义两个有相同周期的时钟域,但两个时钟存在相移,此时,理解默认的setup和holdup关系是至关重要的,不合适的约束会导致两个时钟间的逻辑过度约束。
假设clk1和clk2有相同的波形,但clk2相对clk1进行了+0.3ns的相移,此时将会导致过约束
在这种情况下,由于setup约束中包含了0.3ns的相移,将导致无法时序收敛,因为数据到达时间在目的时钟的hold边沿和setup边沿之间,必有一个违例。因此,必须对setup和holdup的边沿进行调整,解决方法为对捕获时钟的setup要求前移一个周期,holdup无需进行约束
set_multicycle_path 2 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
约束后的波形
当相移为负的时候,无需考虑相移的影响,因为相移的值增加了hold的时间裕量,setup的捕获沿相比启动沿推迟很多可保证数据提前T到达,除非相移值太大导致时钟的启动沿或捕获沿必须调整。
启动时钟CLK1是慢时钟,捕获时钟CLK2是快时钟
CLK2的频率是CLK1的3倍,在静态时序分析中,setup和holdup边沿关系如下图
示例:setup=3,对setup设置周期为3的约束
set_multicycle_path 3 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
由于只设定了setup的multiplier值,holdup默认为前移3-1个周期,波形如下
示例:setup=3/hold=2(-end)
在上一个例子中,放宽hold要求,捕获时钟中hold的边沿需要往回移动2个周期,多周期约束命令
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]
波形如下图
总结:对于数据从慢时钟域到快时钟域时,setup的multiplier为N时,hold的multiplier为N-1
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]
在下面的场景中,CLK1为快时钟域,CLK2为慢时钟域
假设CLK1的频率是CLK2的3倍,不设置多周期约束时的时序分析波形如下,时序分析工具是按照最严苛的条件选择启动沿和捕获沿,因此源时钟clk1的启动沿选择最靠近目的时钟clk2前期的上升边沿。
示例:setup=3(-start)/hold=2,对setup/hold设置多周期约束
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]
定义setup的multiplier值,添加-start参数,可以将启动时钟往回移动
对应的波形为:
总结:对于快时钟域到慢时钟域,定义了setup的multiplier为N时,hold的multiplier需定义为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]
以慢时钟域到快时钟的多周期约束为例,主时钟create_clk1周期为10ns,生成时钟gen_clk_2,gen_clk_3的周期分别为40ns,2.5ns
工程代码
module timing(clk1,clk2,clk3,ce,d1,d2,out );
input clk1,clk2,clk3,ce,d1,d2;
output out;
reg ff1,ff2,ff3;
wire comb;
always@(posedge clk1,negedge ce)
begin
if(!ce)
ff1<=0;
else begin
ff1<=d1;
end
end
always@(posedge clk2,negedge ce)
begin
if(!ce)
ff2<=0;
else begin
ff2<=d2;
end
end
assign comb=ff1*ff2;
always@(posedge clk3,negedge ce)
begin
if(!ce)
ff3<=0;
else begin
ff3<=comb;
end
end
assign out=ff3;
endmodule
逻辑连接
触发器ff1_reg和ff2_reg的输出经过ff3_i_1单元进入ff3_reg的输入端口
多周期约束设置
a)寄存器ff1_reg的clk1约束了主时钟,ff2_reg和ff3_reg的clk分别约束了生成时钟gen_clk_2,gen_clk_3
b) ff1_reg/c到ff3_reg/c进行setup/hold的多周期约束
create_clock -period 10.000 -name create_clk1 -waveform {0.000 5.000} [get_ports clk1] #设置主时钟,周期为10ns
create_generated_clock -name gen_clk_2 -source [get_pins ff1_reg/C] -divide_by 4 -add -master_clock create_clk1 [get_pins ff2_reg/C] #设置生成时钟gen_clk_2,周期为40ns
create_generated_clock -name gen_clk_3 -source [get_pins ff1_reg/C] -multiply_by 4 -add -master_clock create_clk1 [list [get_pins ff2_reg/C] [get_pins ff3_reg/C]] #设置生成时钟gen_clk_3,周期为2.5ns
set_multicycle_path -setup -from [get_pins ff1_reg/C] -to [list [get_pins ff3_reg/C] [get_pins ff3_reg/D]] 4 #设置ff1_reg到ff3_reg的setup多周期约束,周期数是4
set_multicycle_path -hold -end -from [get_pins ff1_reg/C] -to [list [get_pins ff3_reg/C] [get_pins ff3_reg/D]] 3 #设置ff1_reg到ff3_reg的setup多周期约束,周期数是3
时序报告
setup分析
hold分析
用户手册:ug903-vivado-using-constraints-en-us-2022.2.pdf
链接:https://pan.baidu.com/s/17AK_-J4wRXiFLtLTorlrwg?pwd=mylt
提取码:mylt