VIVADO技巧_BUFGMUX时序优化

1.版本说明

日期作者版本说明
2025xxxx风释雪初始版本

2.概述

基于VIVADO时序约束,BUFGMUX多路时钟选择原语的设计


3.原语介绍

7系列FPGA/UltraSCale/UltraSCale+

   BUFGMUX_CTRL BUFGMUX_CTRL_inst (.O(O),   // 1-bit output: Clock output.I0(I0), // 1-bit input: Clock input (S=0).I1(I1), // 1-bit input: Clock input (S=1).S(S)    // 1-bit input: Clock select);BUFGMUX #(.CLK_SEL_TYPE("SYNC")  // ASYNC, SYNC) BUFGMUX_inst (.O(O),   // 1-bit output: Clock output.I0(I0), // 1-bit input: Clock input (S=0).I1(I1), // 1-bit input: Clock input (S=1).S(S)    // 1-bit input: Clock select);

4.使用场景

  • 简单举例
时钟使用两个固定频率晶振产生,经过IO口进入FPGA内部,通过BUFGMUX选择作为全局时钟驱动逻辑;

在这里插入图片描述

  • 复杂举例
时钟使用两个固定频率晶振产生,经过IO口进入FPGA内部,通过BUFGMUX选择MMCM源,
MMCM产生三路时钟, 74.25(74.1758)、148.5(148.3516)、297(296.703),
经过2个BUFGMUX实现3选1的功能,然后作为全局时钟驱动逻辑;

在这里插入图片描述


5.时序问题

当使用BUFGMUX的时候,VIVADO会分析两个输入时钟之间的关系,会导致大量的时序错误,
但是实际情况,两个输入时钟,并不会同时工作,不需要分析两个时钟之间的

6.时序设计

  • create_generated_clock + set_clock_groups
create_generated_clock -name CLKI0 \-divide_by 1 \-source [get_pins INST_BUFGMUX/I0] \-master_clock [get_clocks -of_objects [get_pins INST_BUFGMUX/I0]] \[get_pins INST_BUFGMUX/O] -addcreate_generated_clock -name CLKI1 \-divide_by 1 \-source [get_pins INST_BUFGMUX/I1] \-master_clock [get_clocks -of_objects [get_pins INST_BUFGMUX/I1]] \[get_pins INST_BUFGMUX/O] -addset_clock_groups -logically_exclusive \-group [get_clocks -include_generated_clocks {CLKI0}] \-group [get_clocks -include_generated_clocks {CLKI1}]
  • set_case_analysis
时序分析时,选择频率最高的一路时钟,进行分析,其余路不分析
set_case_analysis 1 [get_pins INST_BUFGMUX/S]

7.实战

  • 代码
genlock_clkwiz inst_genlock_clkwiz
(.clk_in1                                    ( VID_SYNCCLK_148M5_148M3516),.clk_out1                                   ( VID_SYNCCLK_297M_296M7032 ),.clk_out2                                   ( VID_SYNCCLK_74M25_74M1758 )
);BUFGMUX #(.CLK_SEL_TYPE("ASYNC")) BUFGMUX_GENLOCK_0
(.O                                          ( VID_SYNCCLK_148M5_148M3516),.I0                                         ( LMH1983_CLK3_148M3516     ),.I1                                         ( LMH1983_CLK2_148M5        ),.S                                          ( select_freq_en[0]         )
);BUFGMUX #(.CLK_SEL_TYPE("ASYNC")) BUFGMUX_GENLOCK_1
(.O                                          ( VID_SYNCCLK_OUT1          ),.I0                                         ( VID_SYNCCLK_74M25_74M1758 ),.I1                                         ( VID_SYNCCLK_148M5_148M3516),.S                                          ( select_freq_en[1]         )
);BUFGMUX #(.CLK_SEL_TYPE("ASYNC")) BUFGMUX_GENLOCK_2
(.O                                          ( SDI_SYNCCLK               ),.I0                                         ( VID_SYNCCLK_OUT1          ),.I1                                         ( VID_SYNCCLK_297M_296M7032 ),.S                                          ( select_freq_en[2]         )
);
  • 约束
set_case_analysis 1 [get_pins inst_core/inst_genlock/BUFGMUX_GENLOCK_0/S]
set_case_analysis 1 [get_pins inst_core/inst_genlock/BUFGMUX_GENLOCK_1/S]
set_case_analysis 1 [get_pins inst_core/inst_genlock/BUFGMUX_GENLOCK_2/S]
  • 约束前

在这里插入图片描述

  • 约束后
    时序正常!!!