在 Verilog 中,xpm_cdc_pulse 是 Xilinx 参数化宏(XPM) 中的脉冲时钟域交叉(CDC)模块,专门用于单周期脉冲信号的跨时钟域传输。
一、概述
xpm_cdc_pulse 将源时钟域的单周期脉冲安全地传递到目标时钟域,确保每个源脉冲在目标时钟域产生一个对应的单周期脉冲。
二、基本语法
// Verilog 实例化 xpm_cdc_pulse #( .DEST_SYNC_FF(2), // 范围:2-10 .INIT_SYNC_FF(0), // 0-1 .REG_OUTPUT(0), // 0-1 .RST_USED(0), // 0-1 .SIM_ASSERT_CHK(0) // 0-1 ) xpm_cdc_pulse_inst ( .src_clk(src_clk), // 源时钟 .src_rst(src_rst), // 源复位(可选) .src_pulse(src_pulse), // 源脉冲输入 .dest_clk(dest_clk), // 目标时钟 .dest_rst(dest_rst), // 目标复位(可选) .dest_pulse(dest_pulse) // 目标脉冲输出 );
三、参数详解
关键参数:
-
DEST_SYNC_FF(默认=2): 目标时钟域的同步寄存器级数 -
REG_OUTPUT(默认=0): 是否在目标时钟域添加输出寄存器 -
RST_USED(默认=0): 是否使用复位信号 -
INIT_SYNC_FF(默认=0): 同步寄存器的初始值
四、使用示例
示例 1:基本脉冲同步
module pulse_cdc_example ( input wire clk_a, // 时钟域 A input wire clk_b, // 时钟域 B input wire pulse_a, // 时钟域 A 的脉冲 output wire pulse_b // 同步到时钟域 B 的脉冲 ); xpm_cdc_pulse #( .DEST_SYNC_FF(2), // 2级同步 .RST_USED(0) // 不使用复位 ) pulse_cdc_inst ( .src_clk(clk_a), .src_rst(1'b0), // 未使用复位时接地 .src_pulse(pulse_a), .dest_clk(clk_b), .dest_rst(1'b0), .dest_pulse(pulse_b) ); endmodule
示例 2:带复位的脉冲同步
module pulse_cdc_with_rst ( input wire src_clk, input wire dest_clk, input wire src_rst, input wire dest_rst, input wire trigger_pulse, output wire synced_pulse ); xpm_cdc_pulse #( .DEST_SYNC_FF(3), // 3级同步提高可靠性 .RST_USED(1), // 使用复位信号 .REG_OUTPUT(1) // 输出寄存器 ) pulse_cdc_rst ( .src_clk(src_clk), .src_rst(src_rst), .src_pulse(trigger_pulse), .dest_clk(dest_clk), .dest_rst(dest_rst), .dest_pulse(synced_pulse) ); endmodule
五、工作原理
xpm_cdc_pulse 内部工作机制:
-
检测源脉冲:在源时钟域检测输入脉冲
-
电平转换:将脉冲转换为电平信号
-
同步传递:使用同步器将电平信号传递到目标时钟域
-
边沿检测:在目标时钟域检测电平变化的边沿,重新生成脉冲
六、应用场景
1. 启动信号同步
module start_signal_sync ( input wire config_clk, input wire proc_clk, input wire start_config, output wire start_processing ); xpm_cdc_pulse start_pulse_cdc ( .src_clk(config_clk), .src_rst(1'b0), .src_pulse(start_config), .dest_clk(proc_clk), .dest_rst(1'b0), .dest_pulse(start_processing) ); endmodule
2. 中断请求传递
module interrupt_sync ( input wire peri_clk, // 外设时钟 input wire cpu_clk, // CPU 时钟 input wire irq_request, // 中断请求脉冲 output wire irq_synced // 同步的中断信号 ); xpm_cdc_pulse #( .DEST_SYNC_FF(2), .REG_OUTPUT(1) // 确保干净的输出 ) irq_cdc ( .src_clk(peri_clk), .src_rst(1'b0), .src_pulse(irq_request), .dest_clk(cpu_clk), .dest_rst(1'b0), .dest_pulse(irq_synced) ); endmodule
3. 多时钟域触发
module multi_domain_trigger ( input wire slow_clk, // 低速时钟(如配置时钟) input wire fast_clk, // 高速时钟(如处理时钟) input wire slow_trigger, // 低速触发 output wire fast_trigger // 高速触发 ); xpm_cdc_pulse #( .DEST_SYNC_FF(3) // 更安全的同步 ) trigger_cdc ( .src_clk(slow_clk), .src_rst(1'b0), .src_pulse(slow_trigger), .dest_clk(fast_clk), .dest_rst(1'b0), .dest_pulse(fast_trigger) ); endmodule
4. 测试和调试信号
module debug_pulse_sync ( input wire test_clk, input wire sys_clk, input wire debug_trigger, output wire sys_debug_pulse ); xpm_cdc_pulse debug_cdc ( .src_clk(test_clk), .src_rst(1'b0), .src_pulse(debug_trigger), .dest_clk(sys_clk), .dest_rst(1'b0), .dest_pulse(sys_debug_pulse) ); endmodule
七、完整参数配置
xpm_cdc_pulse #( .DEST_SYNC_FF(2), // 目标同步寄存器级数 .INIT_SYNC_FF(0), // 同步寄存器初始值(0或1) .REG_OUTPUT(0), // 输出寄存器(0=禁用,1=启用) .RST_USED(0), // 复位使用(0=无复位,1=有复位) .SIM_ASSERT_CHK(0) // 仿真断言检查 )
八、时序特性
1. 脉冲行为
-
源脉冲:必须在源时钟域是单周期脉冲
-
目标脉冲:在目标时钟域产生单周期脉冲
-
最小间隔:源脉冲之间必须有足够间隔,避免丢失
2. 延迟特性
// 典型延迟 源脉冲 → [1个src_clk] → 同步开始 → [DEST_SYNC_FF个dest_clk] → 目标脉冲
九、复位行为
1. 当 RST_USED = 1 时
xpm_cdc_pulse #(.RST_USED(1)) cdc_with_rst ( .src_clk(clk_a), .src_rst(reset_a), // 源复位,异步或同步 .src_pulse(pulse_in), .dest_clk(clk_b), .dest_rst(reset_b), // 目标复位,异步或同步 .dest_pulse(pulse_out) );
十、在 Vivado 中的使用
1. 自动识别
Vivado 能够自动识别 XPM CDC 模块并应用适当的时序约束。
2. 约束建议
# 设置异步时钟组
set_clock_groups -asynchronous \
-group [get_clocks clk_a] \
-group [get_clocks clk_b]
# 如果需要,可以设置最大延迟约束
set_max_delay -from [get_cells src_pulse_reg] \
-to [get_cells xpm_cdc_pulse_inst/*sync*] \
-datapath_only 1.0
十一、优势
-
可靠性:专门为脉冲信号优化
-
完整性:确保每个源脉冲都产生目标脉冲
-
简单性:无需手动实现复杂的 CDC 逻辑
-
可配置性:参数化满足不同需求
十二、注意事项
1. 正确用法
// 正确:单周期脉冲,足够间隔 reg pulse_gen; always @(posedge src_clk) begin if (condition) pulse_gen <= 1'b1; else pulse_gen <= 1'b0; end xpm_cdc_pulse good_cdc ( .src_clk(src_clk), .src_pulse(pulse_gen), // 单周期脉冲 .dest_clk(dest_clk), .dest_pulse(pulse_out) );
2. 错误用法
// 错误1:多周期脉冲 wire multi_cycle_pulse = some_condition; // 可能多周期 // 错误2:连续脉冲(可能丢失) always @(posedge src_clk) begin pulse_gen <= ~pulse_gen; // 连续快速脉冲 end // 错误3:异步输入 wire async_pulse = external_signal; // 需要先同步到源时钟域
3. 脉冲间隔要求
// 最小间隔 = DEST_SYNC_FF + 2 个源时钟周期 // 例如:DEST_SYNC_FF=2 时,最小间隔为4个源时钟周期
十三、相关 XPM CDC 模块
-
xpm_cdc_single: 单比特电平信号 CDC -
xpm_cdc_handshake: 带握手的多比特数据 CDC -
xpm_cdc_gray: 计数器格雷码 CDC
xpm_cdc_pulse 是处理单周期脉冲信号跨时钟域的理想选择,特别适用于触发信号、中断请求和命令传递等场景。
XPM脉冲跨时钟域同步
4355

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



