3.1 主时钟约束
FPGA中的主时钟主要来源有两种:一是外部时钟源通过引脚引入,二是高速收发器内部产生。主时钟必须与一个网表对象相连,该对象代表了所有时钟边沿的开始点,并且在时钟树中向下传递。也可以说,主时钟的源点定义了0时刻,vivado以此来计算时钟延迟和不确定性。
主时钟只能通过create_clock命令定义,且必须放在约束的开始,这是因为其它时序约束几乎都要参考主时钟,主时钟约束的语法如下:
| create_clock -name <clock_name> -period <clock_period> -waveform {<rise_time> <fall_time>} [get_ports <input_port>] | ·name:定义时钟名
·period:定义时钟周期,为时钟频率的倒数
·waveform:定义一个时钟周期内,时钟的上升沿时刻和下降沿时刻
·get_ports:顶层文件中接口信号名
若时钟从外部晶振通过clk引脚引入,定义其周期为10ns,占空比50%,相移为0,则主时钟约束如下:
| create_clock -name sysclk -period 10 -waveform {0 5} [get_ports I_clk] | 定义一个板级时钟devclk,定义其周期为10ns,占空比50%,相移为180°,则主时钟约束如下:
| create_clock -name devclk -period 10 -waveform {5 10} [get_ports I_clk] | 如果输入的时钟为差分时钟,则只需约束差分时钟的P端即可。
| create_clock -name sysclk -period 3.33 [get_ports I_clk_p] | 如下图所示,差分时钟驱动一个PLL,差分时钟输入通过IBUFDS转为单端进入CLKIN1。如果同时创建了P端和N端输入,将会导致错误的CDC路径。
高速收发器内部产生的时钟,如下图所示,输出到MMCM用于用户时钟和GT通道中PCS逻辑的内部时钟。对于7系列FPGA,通常将高速收发器输出的时钟作为主时钟,约束如下:
create_clock -name tx_clk -period 6.4 [get_pins GT/TXOUTCLK]
3.2 生成时钟约束
生成时钟也叫衍生时钟,是由主时钟经过CMB(PLL、MMCM、BUFR)或逻辑生成的倍频或分频时钟信号。
create_generated_clock -name <generated_clock_name> \
-source <master_clock_source_pin_or_port>
-multiply_by <mult_factor> \
-divide_by <div_factor> \
<pin_or_port> | ·name:定义生成时钟名
·source:源时钟名
·multiply_by:相对于源时钟的倍频系数
·divide_by:相对于源时钟的分频系数
对于MMCM或PLL输出出来的时钟,工具会自动推导约束,可以不写入时序约束。如果用户认为工具自动生成的约束不正确,或想改变生成的时钟名,可以自己手动添加约束,手动添加的约束会覆盖自动生成的约束。对于通过逻辑分频或倍频的时钟,工具难以识别,需要我们手动添加约束。
100MHz差分时钟通过MMCM生成125m的生成时钟约束如下:
create_clock -name I_sysclk_p -period 10 waveform {0 5} [get_ports I_sysclk_p]
create_generated_clock -name a_tx_clk \
-source [get_ports I_sysclk_p] \
-divide_by 4 \
-multiply_by 5 \
[get_pins clk_wiz_0_inst/inst/mmcme4_adv_inst/CLKOUT0] | 在时序报告中的Clock Summary界面中,如下图所示,可以看到生成时钟在源时钟的下一级,MMCM输出的其它时钟已经被工具自动约束,生成的125MHz时钟被我们添加的约束覆盖。
通过组合逻辑,将时钟I_clk二分频产生O_clkdiv的rtl代码如下:
always@(posedge I_clk) begin
O_clk_div <= ~O_clk_div;
end | 通过如下语句进行约束:
create_clock -period 10.000 -name sys_clk -waveform {0.000 5.000} [get_ports I_clk]
create_generated_clock -name clk_div -source [get_ports I_clk] -divide_by 2 [get_ports O_clk_div] | 最后生成的时序报告如下图所示:
3.3 虚拟时钟约束
虚拟时钟不是物理上存在的时钟,是为了进行时序分析而人为定义的一个时钟。实际信号采集的时候必须还是用物理时钟去采样。
3.3.1 虚拟时钟和物理时钟的比较
假设需要定义一个周期为20ns的虚拟时钟虚拟时钟的定义如下:
| create_clock -name vclk -period 20 waveform {0 10} | 可以看到虚拟时钟不需要约束引脚。
以下两种约束的结果一样,说明使用虚拟时钟约束可以达到和物理时钟一样的效果既vsclk=sysclk
不使用虚拟时钟的约束:
create_clock -name sysclk -period 20 waveform {0 10} [get_ports I_sysclk]
set_input_delay -clock sysclk 4 [get_ports I_data_a] | 使用虚拟时钟的约束:
create_clock -name sysclk -period 20 waveform {0 10} [get_ports I_sysclk]
create_clock -name vclk -period 20 waveform {0 10}
set_input_delay -clock vclk 4 [get_ports I_data_a] | 时序分析报告如下图所示,可以看出结果一样。
不使用虚拟时钟约束的set up路径报告:
使用虚拟时钟约束的set up路径报告:
3.3.2 虚拟时钟的应用场景
输入dina和dinb信号没有同步时钟,到FPGA,我们需要控制dina和dinb在FPGA内部的布线延迟,并且dinb又经过了PLL采样的,使用虚拟时钟还可以简化约束,如下图所示。
假设sysclk 50MHZ采样dina,PLL倍频后125MHZ采样dinb,由于PLL输出时钟和sysclk时钟不是整数倍关系,导致是时序约束分析困难,此时使用虚拟时钟可以轻松解决这个问题。
create_clock -period 20.000 -name sysclk -waveform {0.000 10.000} [get_ports I_sysclk]
create_clock -period 8.000 -name vclk -waveform {0.000 4.000}
set_input_delay -clock sysclk 4 [get_ports {I_data_a}]
set_input_delay -clock vclk 4 [get_ports {I_data_b}] | 在一些以FPGA的设计验证系统中,我们需要对dev寄存器的在不同的延迟情况下进行验证性设计,模型如下图所示。
该系统为1个系统同步路径,时钟到达dev寄存器的路径比到达Fpga的路径延迟1ns,假设dev到fpga的数据路径最大延迟是4ns最小数据路径延迟是2ns
create_clock -period 20.000 -name sysclk -waveform {0.000 10.000} [get_ports I_sysclk]
create_clock -period 20.000 -name vclk -waveform {0.000 10.000}
set_clock_latency -source 1 [get_clocks vclk]
set_input_delay -clock vclk -max 4 [get_ports {I_data_a}]
set_input_delay -clock vclk -min 2 [get_ports {I_data_a}] | 该时序约束也可以等效这样
create_clock -name sysclk -period 10 waveform {0 5} [get_ports I_sysclk]
create_clock -name vclk -period20 waveform {1 10}
set_input_delay -clock virclk -min 2 [get_ports I_data]
set_input_delay -clock virclk -max 4 [get_ports I_data] | 对于输出系统,利用虚拟时钟的特点,我们也可以简化约束,如下图所示。
该输出模型中,没有同步时钟输出,但是对于douta和doutb在FPGA从寄存器到引脚的输出延迟路径有要求。因此我们可以定义2个虚拟时钟来约束douta和doutb
假设sysclk 50MHZ采样dina,PLL倍频后125MHZ采样dinb
create_clock -period 20.000 -name sysclk -waveform {0.000 10.000} [get_ports I_sysclk]
create_clock -period 20.000 -name vclk_a_o -waveform {0.000 10.000}
create_clock -period 8.000 -name vclk_b_o -waveform {0.000 4.000}
set_outout_delay -clock vclk_a_o -max 4 [get_ports {O_data_a}]
set_outout_delay -clock vclk_a_o -min 2 [get_ports {O_data_a}]
set_output_delay -clock vclk_b_o -max -1 [get_ports {O_data_b}]
set_output_delay -clock vclk_b_o -min -2[get_ports {O_data_b}] |
3.4 时钟特性约束
由于时钟源本身抖动、外部噪声和传输延迟造成时钟具有一些不确定因素,时钟进行约束时还需要考虑延迟、漂移、抖动、失真等影响,这些属性称为时钟的不确定特性。
3.4.1 用户时钟不确定度
数字电路中,时钟信号到达触发器的精确时间存在的不确定性(clock uncertainty)。这种不确定性主要来源于两个方面:时钟偏差(Clock Skew)和时钟抖动(Clock Jitter),关于时钟偏差(Clock Skew)和时钟抖动(Clock Jitter)可以阅读一章节相关内容。
如果需要在某个时钟的时序路径上或2个时钟之间的时序路径上添加额外裕度,使其抗噪声能力更强,必须使用set_clock_uncertainty命令为不同的角点、延迟或特定的时钟关系定义额外的时钟不确定性。这也是对部分设计进行过度优化而不必修改实际时钟的最安全途径。
如果要让设计时钟sys_clk的时钟域下的所有路径上的裕度收紧,幅度为500ps,约束命令如下:
| set_clock_uncertainty -from sys_clk -to sys_clk 0.5 | 3.4.2 时钟延时
时钟延迟指时钟信号在各节点之间传播需要的时间,可以分为源延时和网络延时。时钟延时约束语法如下:
| set_clock_latency [-rise] [-fall] [-max/-min] [-source/network] [pins/ports/cells] | ·[-rise] [-fall]指定约束是针对时钟上升沿还是下降沿
·[-max/-min]指定约束的是最大值还是最小值,min和max不可以同时指定,不使用该因子默认同时对max和min约束。min用于建立时间检查,max用于保持时间检查。
·[-source]指定源延时,通常表示为时钟源点之前的延迟,在设备外部。[-network]指定网络延时,为布局布线后精确计算的延时。
如下图所示,以该路径为例进行分析。
指定主时钟的源延时的最大值为1ns,最小值为0.5ns,约束命令如下:
set_clock_latency -max 1 -source [get_ports I_clk_p]
set_clock_latency -min 0.5 -source [get_ports I_clk_p] | 时序分析工具在对建立时间裕量分析时,源时钟路径的延迟去最大值,目的时钟路径的延迟取最小值。
指定电路图中reg0时钟端C的网络延时的最大值为3ns,最小值为2ns,约束命令如下:
set_clock_latency -max 3 -network [get_pins data_reg0_reg[0]/C]
set_clock_latency -min 2 -network [get_pins data_reg0_reg[0]/C] | 工具约束了设计时钟从引脚到达C端口路径的延时,如下图所示。
建立时间检查中,该路径的延迟取最大值。
|