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]
- 约束前
- 约束后
时序正常!!!