在 Verilog 中,xpm_cdc_array_single 是 Xilinx 参数化宏(XPM) 中的数组单次传输时钟域交叉(CDC)模块,用于多比特数据的单次安全传输。
一、概述
xpm_cdc_array_single 将多比特数组数据从源时钟域一次性传递到目标时钟域,使用同步器确保数据完整性。
二、基本语法
// Verilog 实例化 xpm_cdc_array_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 .WIDTH(8) // 范围:1-1024 ) xpm_cdc_array_single_inst ( .src_clk(src_clk), // 源时钟 .src_in(src_in), // 源数据输入 .dest_clk(dest_clk), // 目标时钟 .dest_out(dest_out) // 目标数据输出 );
三、参数详解
1. 关键参数
-
WIDTH(必须): 数据宽度(1-1024 位) -
DEST_SYNC_FF(默认=2): 目标时钟域同步寄存器级数 -
SRC_INPUT_REG(默认=1): 源输入寄存器使能 -
INIT_SYNC_FF(默认=0): 同步寄存器初始值
四、使用示例
示例 1:基本数组数据传输
module array_cdc_example ( input wire clk_a, input wire clk_b, input wire [31:0] data_a, output wire [31:0] data_b ); xpm_cdc_array_single #( .WIDTH(32), // 32位数据 .DEST_SYNC_FF(2), // 2级同步 .SRC_INPUT_REG(1) // 源输入寄存器 ) array_cdc ( .src_clk(clk_a), .src_in(data_a), .dest_clk(clk_b), .dest_out(data_b) ); endmodule
示例 2:配置寄存器同步
module config_sync ( input wire cfg_clk, input wire sys_clk, input wire [63:0] config_reg, output wire [63:0] sys_config ); xpm_cdc_array_single #( .WIDTH(64), .DEST_SYNC_FF(3), // 3级同步提高可靠性 .INIT_SYNC_FF(0) ) config_cdc ( .src_clk(cfg_clk), .src_in(config_reg), .dest_clk(sys_clk), .dest_out(sys_config) ); endmodule
五、工作原理
xpm_cdc_array_single 内部结构:
-
源寄存器(可选):在源时钟域寄存输入数据
-
同步器链:多级同步器将数据传递到目标时钟域
-
目标寄存器:在目标时钟域输出稳定数据
六、应用场景
1. 静态配置寄存器
module static_config_sync ( input wire init_clk, input wire oper_clk, input wire [23:0] init_params, // 初始化参数 output wire [23:0] oper_params // 操作参数 ); xpm_cdc_array_single #( .WIDTH(24), .DEST_SYNC_FF(2) ) param_sync ( .src_clk(init_clk), .src_in(init_params), .dest_clk(oper_clk), .dest_out(oper_params) ); endmodule
2. 状态监控信号
module status_monitor_sync ( input wire mon_clk, input wire ctrl_clk, input wire [15:0] status_bus, // 状态总线 output wire [15:0] ctrl_status // 控制端状态 ); xpm_cdc_array_single #( .WIDTH(16), .SRC_INPUT_REG(0) // 状态信号可能已寄存 ) status_sync ( .src_clk(mon_clk), .src_in(status_bus), .dest_clk(ctrl_clk), .dest_out(ctrl_status) ); endmodule
3. 低频更新数据
module slow_data_sync ( input wire slow_clk, // 低速时钟(如配置时钟) input wire fast_clk, // 高速时钟(如系统时钟) input wire [47:0] slow_data, // 低频更新数据 output wire [47:0] fast_data // 同步到高速时钟域 ); xpm_cdc_array_single #( .WIDTH(48), .DEST_SYNC_FF(2) ) slow_data_cdc ( .src_clk(slow_clk), .src_in(slow_data), .dest_clk(fast_clk), .dest_out(fast_data) ); endmodule
4. 多比特控制信号
module control_signal_sync ( input wire ctrl_clk, input wire datapath_clk, input wire [7:0] ctrl_bits, // 控制位 output wire [7:0] sync_ctrl_bits // 同步的控制位 ); xpm_cdc_array_single #( .WIDTH(8), .DEST_SYNC_FF(2), .SRC_INPUT_REG(1) // 寄存控制信号 ) ctrl_sync ( .src_clk(ctrl_clk), .src_in(ctrl_bits), .dest_clk(datapath_clk), .dest_out(sync_ctrl_bits) ); endmodule
七、完整参数列表
xpm_cdc_array_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=启用) .WIDTH(8) // 数据宽度(1-1024) )
八、时序特性
1. 传输延迟
数据变化 → [SRC_INPUT_REG个src_clk] → 同步开始 → [DEST_SYNC_FF个dest_clk] → 稳定输出
2. 典型延迟
-
最小延迟:
DEST_SYNC_FF个目标时钟周期 -
最大延迟:
SRC_INPUT_REG + DEST_SYNC_FF个时钟周期
九、在 Vivado 中的使用
1. 自动识别
Vivado 能够自动识别 XPM CDC 模块并应用适当的时序约束。
2. 约束建议
# 设置异步时钟组
set_clock_groups -asynchronous \
-group [get_clocks src_clk] \
-group [get_clocks dest_clk]
# 对于宽总线,可能需要设置最大偏斜
set_max_delay -from [get_pins {xpm_cdc_array_single_inst/src_in[*]}] \
-to [get_pins {xpm_cdc_array_single_inst/dest_out[*]}] \
-datapath_only 2.0
十、优势
-
简单性:无需握手协议,接口简单
-
低延迟:相比握手协议延迟更低
-
资源效率:不需要额外的控制逻辑
-
适用性广:适用于各种多比特数据场景
十一、注意事项
1. 适用场景
// 正确:静态或低频变化数据
reg [31:0] config_value;
always @(posedge cfg_clk) begin
if (update_config)
config_value <= new_config; // 不频繁更新
end
xpm_cdc_array_single #(.WIDTH(32)) good_use (
.src_clk(cfg_clk),
.src_in(config_value), // 稳定多个周期
.dest_clk(sys_clk),
.dest_out(sys_config)
);
2. 不适用场景
// 错误:高频变化数据 reg [31:0] counter; always @(posedge src_clk) counter <= counter + 1; // 每个周期都变化 xpm_cdc_array_single #(.WIDTH(32)) bad_use ( .src_clk(src_clk), .src_in(counter), // 连续变化 .dest_clk(dest_clk), .dest_out(sync_counter) // 可能得到错误值 );
3. 数据稳定性要求
// 数据必须稳定至少 (DEST_SYNC_FF + 1) 个源时钟周期 // 例如:DEST_SYNC_FF=2 时,数据需要稳定至少 3 个 src_clk 周期
4. 复位考虑
// 模块本身没有复位端口
// 需要在外部处理复位逻辑
reg [WIDTH-1:0] src_data;
always @(posedge src_clk) begin
if (src_rst)
src_data <= {WIDTH{1'b0}};
else
src_data <= next_data;
end
xpm_cdc_array_single #(.WIDTH(WIDTH)) cdc_inst (
.src_clk(src_clk),
.src_in(src_data),
.dest_clk(dest_clk),
.dest_out(dest_data)
);
十二、参数选择指南
// 对于一般应用 xpm_cdc_array_single #( .WIDTH(16), .DEST_SYNC_FF(2), // 平衡MTBF和延迟 .SRC_INPUT_REG(1) // 推荐启用 ) // 对于高可靠性应用 xpm_cdc_array_single #( .WIDTH(32), .DEST_SYNC_FF(3), // 提高MTBF .SRC_INPUT_REG(1) ) // 对于已寄存的输入 xpm_cdc_array_single #( .WIDTH(8), .SRC_INPUT_REG(0) // 输入已寄存 )
十三、相关 XPM CDC 模块
-
xpm_cdc_single: 单比特电平信号 CDC -
xpm_cdc_handshake: 带握手的多比特数据 CDC -
xpm_cdc_gray: 计数器格雷码 CDC -
xpm_cdc_array_single: 多比特数组单次传输 CDC
xpm_cdc_array_single 是处理静态或低频变化的多比特数据跨时钟域的最简单方法,特别适用于配置寄存器、状态信号和控制位等场景。
2535

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



