Xilinx 参数化宏(XPM)xpm_cdc_array_single

       在 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. 源寄存器(可选):在源时钟域寄存输入数据

  2. 同步器链:多级同步器将数据传递到目标时钟域

  3. 目标寄存器:在目标时钟域输出稳定数据

六、应用场景

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. 简单性:无需握手协议,接口简单

  2. 低延迟:相比握手协议延迟更低

  3. 资源效率:不需要额外的控制逻辑

  4. 适用性广:适用于各种多比特数据场景

十一、注意事项

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 是处理静态或低频变化的多比特数据跨时钟域的最简单方法,特别适用于配置寄存器、状态信号和控制位等场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值