在之前的时序分析中,通常是假定时钟是稳定理想的,即设置主时钟周期后按照周期精确的进行边沿跳动。在实际中,时钟是非理想存在较多不确定的影响,存在时延和波形的变化,要准确分析时序也需将其考虑进来,下面将对其进行介绍。
Vivado的时序约束中,考虑时钟不稳定影响的约束包括set_clock_latency,
set_clock_uncertainty,set_input_jitter,set_system_jitter,这些约束可分为两类:clock latency和clock uncertainty
信号从外部传输到FPGA内部后,时钟到达内部的目的地存在确定的时延,该时延包括源点的延时(source latency)和网络延时(network latency,也称为插入时延)。source latency表示时钟信号从波形的起点传输到芯片源点引脚的时延,时钟网络时延表示时钟信号从芯片源点引脚到芯片寄存器时钟引脚的时延。
网络延时在预布线阶段会分析工具自动的估算,在完成布线后可以精确的计算。在许多非赛灵思的时序分析工具中,要求设置set_propagated_clock约束来计算时钟树上的传输延时。vivado不需要该命令,会默认自动考虑所有时钟的传输时延,对于生成时钟的时延,包含主时钟的插入时延和自身的网络时延。
赛灵思器件使用set_clock_latency约束主要是约束器件外部的时钟时延,约束命令设置界面如图
Relative clocks:设置与指定对象objects相关联的时钟时延,为可选项。
Latency type:选择时延类型,可以是Source或Network,未进行设置时,默认为Network
Latency value:设置时延值应用的分析类型,min为hold,max为setup,不勾选时,对setup/hold分析都有效。
Source latency variation bound:在latency type选Source才能设置该项,设置时钟延时是早于early还是晚于late时钟边沿到达,early表示应用于hold分析,late应用于setup分析,不设置时对setup/hold分析都有效
Operating condition:设置延时
Clock rise latency/Clock fall latency:设置时延是针对上升沿触发,下降沿触发,还是对两者都触发的场景
Object:时钟时延约束的对象,可以是clocks,cell pins,I/O port
clock uncertainty包含clock jitter,input jitter,system jitter
对于ASIC器件来说,时钟抖动clock jitter通常表示时钟不确定的特征,但对于FPGA来说,时钟抖动是可预知的,时序分析工具会自动计算时钟抖动。
输入抖动input jitter是指与理想的连续时钟到达时间相比,连续的时钟边沿到达时间存在变化,输入抖动是一个绝对值,代表了每一个时钟沿的变动。使用set_input_jitter约束可以设置每一个主时钟的输入抖动,但不能直接对生成时钟设置时钟抖动,时序分析工具会自动的根据主时钟的输入抖动计算生成时钟的时钟抖动。
a)对于来自于MMCM或PLL的生成时钟,将用一个独立的抖动值来替代时钟抖动
b)对于来自组合逻辑的生成时钟,生成时钟的时钟抖动和主时钟相同
set_input_jitter设置方式简单,对象只能为clock。
系统抖动system jitter是由于电源供电噪声,板级噪声,或其他系统的抖动一起引起的抖动,使用约束命令set_system_jitter设置的抖动是针对整个设计,所有的时钟。
以经过主时钟的时钟输入端口clkin设置
ps的时钟抖动为例
set_input_jitter [get_clocks -of_objects [get_ports clkin]] 0.1
使用set_clock_uncertainty可以对不同的场景,延时或者是需要的时钟关系设置时钟不确定性,对于设置中的部分添加时序裕量是一种很方便的方式。
Clock uncertainty type:有两种设置不确定性方式,simple uncertainty和interclock uncertainty。simple uncertainty是针对同步时钟,objects可以是Cell pins,clocks,I/O port,interclock uncertainty针对异步时钟,需设置-from和-to参数
跨时钟间的不确定性总是优于简单的时钟不确定性,不受约束顺序的影响。以下面约束为例,尽管第二条简单的不确定约束放在后面,从clk1到clk2的时序路径不确定性依旧为2ns
- set_clock_uncertainty 2.0 -from [get_clocks clk1] -to [get_clocks clk2]
- set_clock_uncertainty 1.0 [get_clocks clk1]
当在跨时钟域的两个时钟间设置了不确定约束时,需确保约束了两个时钟域间所有的跨时钟域路径,如clk1到clk2,clk2到clk1。
工程代码
- module timing(d1,d2,clk1,clk2,ce,ff2);
- input d1,d2,clk1,clk2,ce;
- output ff2;
- reg ff1,ff2;
- wire comb;
- always@(posedge clk1,negedge ce)
- begin
- if(!ce)
- begin
- ff1<=0;
- end
- else begin
- ff1<=d1;
- end
- end
- assign comb=ff1&d2;
- always@(posedge clk2,negedge ce)
- begin
- if(!ce)
- ff2<=0;
- else begin
- ff2<=comb;
- end
- end
- endmodule
a)无时钟不确定约束时,路径中clock uncertainty也存在,时序分析工具会自动计算Total system jitter,此处为0.071,按照公式(Tsj^2+Tij^2+DJ)/2+PE的值为0.035。
b) 设置set_clock_latency约束
- create_clock -period 10.000 -name clk1 -waveform {0.000 5.000} [get_ports clk1]
- create_clock -period 7.000 -name clk2 -waveform {0.000 3.500} [get_ports clk2]
- set_clock_latency -source 0.800 [get_clocks clk1] //设置latency为0.8ns
时序分析报告,setup分析中source clock path路径的clock source latency为0.8
c) 设置set_clock_uncertainty值为2.660,因为设计中clk1和clk2为异步时钟域,Clock uncertainty type选择interclock uncertainty。
- create_clock -period 10.000 -name clk1 -waveform {0.000 5.000} [get_ports clk1]
- create_clock -period 7.000 -name clk2 -waveform {0.000 3.500} [get_ports clk2]
- set_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] 2.660
查看时序路径中setup或hold路径的Clock uncertainty为2.695ns,该值的计算可以看右侧中的计算公式(Tsj^2+Tij^2+DJ)/2+PE+UU。UU为用户约束的不确定值,即为2.66ns,和约束值一致。
同理,查看路径的clock path skew,通过clock path skew equation可以知道计算方式,DCD-SCD-CPR
d) 设置set_input_jitter为1.66ns
- create_clock -period 10.000 -name clk1 -waveform {0.000 5.000} [get_ports clk1]
- create_clock -period 7.000 -name clk2 -waveform {0.000 3.500} [get_ports clk2]
- set_input_jitter [get_clocks clk1] 1.660
查看setup路径中clock uncertainty值为0.831ns,查看计算使用值中total input jitter为1.66ns,和约束值一致
用户手册:ug903-vivado-using-constraints-en-us-2022.2.pdf
链接:https://pan.baidu.com/s/17AK_-J4wRXiFLtLTorlrwg?pwd=mylt
提取码:mylt