在 Vivado 中,xpm_cdc_single 是 Xilinx 参数化宏(XPM) 中的单比特时钟域交叉(CDC)模块。
一、概述
xpm_cdc_single 用于将单个信号从一个时钟域安全地传递到另一个时钟域。
二、基本语法
// Verilog 实例化 xpm_cdc_single #( .DEST_SYNC_FF(2), // 范围:2-10 .INIT_SYNC_FF(0), // 0-1 .SIM_ASSERT_CHK(0), // 0-1 .SRC_INPUT_REG(1) // 0-1 ) xpm_cdc_single_inst ( .src_clk(src_clk), // 源时钟 .src_in(src_in), // 源输入 .dest_clk(dest_clk), // 目标时钟 .dest_out(dest_out) // 目标输出 );
三、参数详解
关键参数
-
DEST_SYNC_FF(默认=2): 目标时钟域的同步寄存器级数 -
SRC_INPUT_REG(默认=1): 是否在源时钟域添加输入寄存器 -
INIT_SYNC_FF(默认=0): 同步寄存器的初始值 -
SIM_ASSERT_CHK(默认=0): 仿真断言检查
四、使用示例
示例 1:基本单比特 CDC
module cdc_example ( input wire clk_a, // 时钟域 A input wire clk_b, // 时钟域 B input wire signal_a, // 时钟域 A 的信号 output wire signal_b // 同步到时钟域 B 的信号 ); xpm_cdc_single #( .DEST_SYNC_FF(2), // 2级同步 .SRC_INPUT_REG(1) // 源寄存器使能 ) cdc_signal ( .src_clk(clk_a), .src_in(signal_a), .dest_clk(clk_b), .dest_out(signal_b) ); endmodule
示例 2:复位信号同步
module reset_sync ( input wire clk, input wire async_rst, output wire sync_rst ); xpm_cdc_single #( .DEST_SYNC_FF(2), .INIT_SYNC_FF(0) // 初始值为 0 ) rst_cdc ( .src_clk(1'b0), // 复位是异步的,不需要源时钟 .src_in(async_rst), .dest_clk(clk), .dest_out(sync_rst) ); endmodule
五、应用场景
1. 控制信号跨时钟域
// 使能信号从低速时钟域到高速时钟域 xpm_cdc_single #(.DEST_SYNC_FF(3)) cdc_enable ( .src_clk(slow_clk), .src_in(enable_slow), .dest_clk(fast_clk), .dest_out(enable_fast) );
2. 状态标志传递
// 完成标志从处理时钟域到控制时钟域 xpm_cdc_single cdc_done ( .src_clk(proc_clk), .src_in(process_done), .dest_clk(ctrl_clk), .dest_out(done_status) );
3. 按钮去抖和同步
module button_sync ( input wire clk, input wire btn_async, output wire btn_sync ); xpm_cdc_single #( .DEST_SYNC_FF(2) ) btn_cdc ( .src_clk(1'b0), // 按钮是异步输入 .src_in(btn_async), .dest_clk(clk), .dest_out(btn_sync) ); endmodule
六、VHDL 实例化
-- VHDL 组件声明
COMPONENT xpm_cdc_single
GENERIC (
DEST_SYNC_FF : integer := 2;
INIT_SYNC_FF : integer := 0;
SIM_ASSERT_CHK : integer := 0;
SRC_INPUT_REG : integer := 1
);
PORT (
src_clk : IN std_logic;
src_in : IN std_logic;
dest_clk : IN std_logic;
dest_out : OUT std_logic
);
END COMPONENT;
-- 实例化
xpm_cdc_single_inst : xpm_cdc_single
GENERIC MAP (
DEST_SYNC_FF => 2,
SRC_INPUT_REG => 1
)
PORT MAP (
src_clk => clk_a,
src_in => signal_a,
dest_clk => clk_b,
dest_out => signal_b
);
七、时序特性
1. 同步器延迟
-
2 级同步器: 2 个目标时钟周期延迟
-
3 级同步器: 3 个目标时钟周期延迟
-
N 级同步器: N 个目标时钟周期延迟
2. 参数选择指南
// 对于一般应用 .DEST_SYNC_FF(2) // MTBF 足够用于大多数设计 // 对于高可靠性应用 .DEST_SYNC_FF(3) // 提高 MTBF // 对于异步输入(如复位、中断) .DEST_SYNC_FF(2), .SRC_INPUT_REG(0) // 对于寄存器输出 .DEST_SYNC_FF(2), .SRC_INPUT_REG(1)
八、在 Vivado 中的使用
1. 包含 XPM 库
// 在 Verilog 文件顶部 `timescale 1ps / 1ps (* XPM_CDC = "SINGLE" *) // 可选属性
2. 在 IP Integrator 中使用
-
在 Block Design 中添加 Utility Vector Logic
-
配置为 CDC 电路
-
或直接使用 HDL 实例化
3. 约束考虑
# 在 XDC 文件中,同步器通常不需要特殊约束 # Vivado 会自动识别 CDC 路径
九、优势
-
可靠性: Xilinx 优化的同步电路
-
可移植性: 在所有 Xilinx 器件上一致工作
-
可维护性: 参数化配置
-
工具支持: Vivado 能够识别和正确处理
十、注意事项
1. ⚠️ 重要限制
-
仅适用于单比特信号
-
不适用于多比特总线(使用
xpm_cdc_array_single或xpm_cdc_gray) -
源信号必须保持稳定至少一个目标时钟周期
2. 正确用法
// 正确:电平信号 xpm_cdc_single cdc_level ( .src_clk(clk_a), .src_in(enable_flag), // 电平信号,稳定多个周期 .dest_clk(clk_b), .dest_out(enable_sync) ); // 错误:脉冲信号(除非已知频率关系) xpm_cdc_single cdc_pulse ( // 可能丢失脉冲! .src_clk(clk_a), .src_in(pulse_signal), // 单周期脉冲 .dest_clk(clk_b), .dest_out(pulse_sync) // 可能无法捕获 );
xpm_cdc_single 是处理单比特时钟域交叉的最简单、最可靠的方法,在 Vivado 设计中推荐使用。
2535

被折叠的 条评论
为什么被折叠?



