您现在的位置是:首页 >技术杂谈 >[FPGA/VerilogHDL/Xilinx]设计约束之时序约束(一)网站首页技术杂谈

[FPGA/VerilogHDL/Xilinx]设计约束之时序约束(一)

always@(posedge clk) 2024-06-26 14:23:55
简介[FPGA/VerilogHDL/Xilinx]设计约束之时序约束(一)

概述

在基于Xilinx-FPGA器件以及Vivado平台的设计中,合格的约束的定义过程分为四个主要步骤,如下图所示。这些步骤遵循时序约束先后顺序和从属关系规则,并采用符合逻辑的方式来向时序引擎提供信息以执行分析。为新设计创建时序约束或者完成现有约束时,Xilinx建议使用时序约束向导 (Timing Constraints Wizard) 来快速识别下图中的前 3 个步骤中缺失的约束,从而确保设计约束的安全性和可靠性,实现正确的时序收敛。

​Xilinx官方提供的时序约束4个步骤


定义时钟约束

必须首先定义时钟,方可供其它约束使用。时序约束创建流程的第一步是明确必须定义哪些时钟,以及这些时钟必须定义为“基准时钟 (primary clock)”还是“生成时钟 (generated clock)”。

创建基准时钟

基准时钟是指用于为设计定义时序参考的时钟,而时序引擎可利用基准时钟衍生出时序路径要求以及与其它时钟的相位关系。主时钟插入延迟的计算方式为从时钟源点(定义时钟的驱动管脚/端口)到时钟扇出到的时序单元的时钟管脚。因此,重要的是在对应于设计边界的对象上定义基准时钟,以便准确计算其延迟并间接计算其偏差。以下部分描述了典型的基准时钟根。

​输入端口的 create_clock

约束示例: create_clock -name SysClk -period 10 -waveform {0 5} [get_ports sysclk]

该示例中,波形的占空比定义为 50%。以上显示的 -waveform 实参用于展示其利用率,只有在定义占空比非 50% 的时钟时才需要使用。对于差分时钟输入缓冲器,只需在差分对的 P 侧对基准时钟进行定义即可。

需要注意的是:

  • 使用特定名称定义时钟(-name 选项)时,必须验证该时钟名称未被任何其它时钟约束或现有自动生成时钟占用。如果已在多个时钟约束中使用某个时钟名称,Vivado Design Suite 时序引擎会发出消息,以提醒第 1 个时钟定义被覆盖。如果同一时钟名称使用了两次,那么第 1 个时钟定义将会丢失,并且 2 个时钟定义之间输入的引用此名称的所有约束也都将丢失;

  • 对于面向 UltraScale ™ 器件的设计,Xilinx不建议在 GT 的输出上定义基准时钟,因为在定义相关开发板输入时钟时,将自动衍生 GT 时钟。

创建生成时钟

生成时钟 (generated clock) 是从称为主时钟 (master clock) 的另一个现有时钟衍生的。它通常用于描述逻辑块对主时钟执行的波形变换。由于生成时钟定义取决于主时钟特性,因此必须首先定义主时钟。为显式定义生成时钟,必须使用create_generated_clock 命令。

自动衍生时钟

大部分生成时钟都是由 Vivado 时序引擎自动衍生的,该引擎可识别时钟修改块 (CMB) 及其对主时钟执行的变换。在Xilinx7系列器件中,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 命令(不指定波形变换)强制输入自己选择的名称。该约束应刚好位于约束文件中定义主时钟的约束之后。

create_generated_clock -name clk_gt_250mhz -source [get_pins clk_managment_inst/clk_gen_gt/clk_in1] -multiply_by 1 -add -master_clock jesd204_1_refclk [get_pins clk_managment_inst/clk_gen_gt/clk_out1]

为避免歧义,约束必须连接到时钟的源管脚。

用户定义的生成时钟

定义所有基准时钟后,可使用“时钟网络 (Clock Networks)”或“检查时序 (Check Timing)”(no_clock) 报告来识别时钟树中不含时序时钟的部分,并定义相应的生成时钟。有时要理解逻辑椎对主时钟所执行的变换并不容易。在此情况下,必须采用最保守的约束。例如,源管脚是时序单元输出。主时钟至少除以 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 命令验证每个时钟的波形以及主时钟和生成时钟之间的关系:

​此外,还可验证所有内部时序路径都被至少 1 个时钟所覆盖。“检查时序 (Check Timing)”报告为此提供了两项检查:

  • • no_clock:报告已定义的时钟无法连接到的任何活动时钟管脚。

  • • unconstrained_internal_endpoint:如果某些时序单元具有与时钟相关的时序检查但尚未定义时钟,则报告此类时序单元的所有数据输入管脚。

如果两项检查都返回 0,说明时序分析覆盖范围广。

或者,还可运行 XDC 和“时序方法论 (Timing Methodology)”检查来验证在建议的网表对象上是否已定义所有时钟,同时避免造成任何约束冲突或不准确的时序分析情境。使用以下命令来运行这些检查:

report_methodology -checks [get_methodology_checks {TIMING-* XDC*}]

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。