创建生成时钟
生成时钟源自另一个现有时钟 (主时钟)。通常用来描述由逻辑块在主时钟上执行的波形变换。由于生成时钟的定义
取决于主时钟特性,因此必须首先定义主时钟。要明确定义生成时钟,必须使用
create_generated_clock
命令。
自动衍生时钟
大部分生成时钟都由
Vivado Design Suite
时序引擎自动衍生获得,该引擎可识别
Clock Modifying Block (CMB)
及其对
主时钟所执行的变换。
赛灵思
7
系列器件中,
CMB
为:
• MMCM*/PLL*
• BUFR
• PHASER*
赛灵思
UltraScale
器件系列中,
CMB
为:
• MMCM*/PLL*
• BUFG_GT/BUFGCE_DIV
• GT*_COMMON/GT*_CHANNEL/IBUFDS_GTE3
• BITSLICE_CONTROL/RX*_BITSLICE
• ISERDESE3
对于时钟树上的任何其它组合单元而言,时序时钟可通过它们进行传输,且无需在输出端重新定义,除非波形已被相
应单元转换。通常应该尽可能多地依靠自动衍生机制,因为就定义可对应于实际硬件行为的生成时钟来说,这是最安
全的方法。
如果
Vivado Design Suite
时序引擎所选择的自动衍生时钟名称并不合适,您可以使用
create_generated_clock
命
令强行定义自己的名称,此时无需指定波形转换。该约束应刚好位于约束文件中定义主时钟的约束之后。例如,由
MMCM
实例生成的时钟的默认名称是
net0
,您可以添加如下约束强制将其设定为自己的名称 (此例中是
fftClk
):
create_generated_clock -name fftClk [get_pins mmcm_i/CLKOUT0]
为避免歧义,约束必须连接到时钟的源引脚。
用户定义的生成时钟
一旦所有主时钟都完成定义,您就可以利用
(
no_clock
)
报告来识别不含时序时钟的时钟树部分,并相应地定义生成
时钟。
有时候很难理解逻辑椎
(cone)
对主时钟执行的变换。这种情况下必须采用最保守的约束。例如,源引脚是时序单元输
出。主时钟至少除以
2
,因此正确的约束应当为:
create_generated_clock -name clkDiv2 -divide_by 2 \
-source [get_pins fd/C] [get_pins fd/Q]
最后,如果设计包含锁存器,那么锁存器门控引脚也需要连接时序时钟,如果约束缺失,
Check Timing (
no_clock
)
将会报告相应的锁存器问题。您可以按照上面的实例来定义这些时钟。
主时钟与生成时钟间的路径
与主时钟不同,生成时钟必须在主时钟的传递扇出中进行定义,这样时序引擎就能精确计算它们的插入延迟。若不遵
守这个原则会导致错误的时序分析,而且很有可能导致无效的时序裕量。例如,在下图中
gen_clk_reg/Q
作为下一
个寄存器
(
q_reg
)
的时钟,而且还位于主时钟
c1
的扇出椎中。因此,
gen_clk_reg/Q
上应具有
create_generated_clock
,而不是
create_clock
。

create_generated_clock -name GC1 -source [get_pins gen_clk_reg/C] -divide_by 2
[get_pins gen_clk_reg/Q]
核实时钟定义与覆盖范围
一旦所有设计时钟都定义完毕并且应用于内存之后,您就可以核实每个时钟的波形,并使用
report_clocks
命令查
看主时钟与生成时钟之间的关系:
Clock Period Waveform Attributes Sources
sysClk 10.00000 {0.00000 5.00000} P {sysClk}
clkfbout 10.00000 {0.00000 5.00000} P,G {clkgen/mmcm_adv_inst/CLKFBOUT}
cpuClk 20.00000 {0.00000 10.00000} P,G {clkgen/mmcm_adv_inst/CLKOUT0}
…
====================================================
Generated Clocks
====================================================
Generated Clock : cpuClk
Master Source : clkgen/mmcm_adv_inst/CLKIN1
Master Clock : sysClk
Edges : {1 2 3}
Edge Shifts : {0.000 5.000 10.000}
Generated Sources : {clkgen/mmcm_adv_inst/CLKOUT0}
此外,您还可以核实所有内部时序路径是否至少被一个时钟覆盖。
check_timing
报告可以为此提供两项检查内容:
• no_clock
报告定义时钟没有达到的任何活动时钟引脚。
• unconstrained_internal_endpoint
若时序单元具有与时钟有关的时序检查且这个时钟尚未定义,则会报告此类时序单元的所有数据输入引脚。
如果两项检查都返回零,说明时序分析覆盖范围广。
您也能运行
XDC
和
Timing Methodology
检查来验证是否所有时钟定义在建议网表对象上,同时不会造成任何约束冲
突或不准确的时序分析情境。
如果您在使用
Vivado Design Suite2016.3
之前版本,请使用以下命令运行以下检查:
report_drc -checks [get_drc_checks {XDC* TIMING-*}]
如果您使用的是
Vivado Design Suite
版本
2016.3
或更高版本,请使用以下命令运行以下检查:
report_methodology -checks [get_methodology_checks {TIMING-* XDC*}]
如需了解更多信息,请参阅
第
4
章中的
“
运行报告方法
”
。
调整时钟特性
在定义时钟及其波形后,下一步是输入与噪声或不确定性建模有关的信息。
XDC
语言可将与抖动和相位误差有关的不
确定性从与偏差和延迟建模有关的不确定性中区分开来。
抖动
对于抖动,最好使用
Vivado Design Suite
的默认值。按下列方法修改默认计算:
•
如果随机抖动大于
0
的主时钟输入器件,请使用
set_input_jitter
命令以设定抖动值。
•
如果器件电源有噪声,想要调整全局抖动,应使用
set_system_jitter
。赛灵思不建议增加默认的系统抖动值。
对于生成时钟,抖动源自主时钟和时钟修改块的特性。用户不需要调整这些数字。
更多不确定性
当您需要在时钟的时序路径上或两个时钟之间添加额外裕量时,必须使用
set_clock_uncertainty
命令。这也是
对设计某个部分进行过约束且不改变实际时钟边缘和整体时钟关系的最佳、最安全的方法。用户定义的时钟不确定性
会增加
Vivado
工具计算的抖动,而且可针对建立和保持分析单独进行指定。
例如,设计时钟
clk0
全部时钟间路径的裕量需严格地设置在
500 ps
,以使设计的建立和保持抗噪声能力更强:
set_clock_uncertainty -from clk0 -to clk0 0.500
如果您在两个时钟之间指定更多不确定性,那么约束必须同时应用于两个方向 (假设数据向两个方向流动)。下面的
例子展示了如何仅针对建立而将
clk0
和
clk1
之间的不确定性增大
250 ps
:
set_clock_uncertainty -from clk0 -to clk1 0.250 -setup
set_clock_uncertainty -from clk1 -to clk0 0.250 -setup
时钟源位置的时钟时延
可使用带
-source
选项的
set_clock_latency
命令对时钟源位置的时钟时延进行建模。该方法在两种情况下有用:
•
指定器件外部与输入和输出延迟约束无关的时钟延迟传输。
•
对块在无关联
(OOC)
编译过程中使用的时钟的内部传输时延进行建模。在这样的编译流程中,未对完整时钟树进
行描述,因此无法自动计算块外部最小和最大运行条件之间的差异,必须进行手动建模。
此约束只能由高级用户使用,因为通常很难提供合法的时延数值。
MMCM
或
PLL
外部反馈回路延迟
当连接
MMCM
或
PLL
反馈回路用以补偿电路板延迟 (而非内部时钟插入延迟)时,必须使用
set_external_delay
命令指定最好和最差情况下
FPGA
器件外部延迟。未指定此延迟将使
MMCM
或
PLL
有关的
I/O
时序分析变得无关紧要,并可能导致时序收敛无法实现。此外,当使用外部补偿时,必须相应地调整输入和输出延
迟增益值,而不是仅仅考虑正常情况下电路板上的时钟走线延迟。