XPM_CDC_ARRAY_SINGLE
免责声明:本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下,作者不对因使用本文内容而导致的任何直接或间接损失承担责任,包括但不限于数据丢失、业务中断或其他经济损失。
读者在使用本文信息时,应自行验证其准确性和适用性,并对其使用结果负责。本文内容不构成专业技术咨询或建议,具体的技术实现和应用应根据实际情况和需要进行详细分析和验证。
本文所涉及的任何商标、版权或其他知识产权均属于其各自的所有者。若本文中引用了第三方的资料或信息,引用仅为学术交流目的,不构成对第三方内容的认可或保证。
若有任何疑问或需进一步信息,请联系本文作者或相关专业人士。
前言
本期介绍第一个Xilinx FPGA跨时钟域原语XPM_CDC_ARRAY_SINGLE
一、Introduction
-
功能概述: 这个宏用于将单比特信号从源时钟域传输到目标时钟域。它解决了跨时钟域传递数据时的同步问题。
-
正确操作的条件: 为了确保同步正确,目标时钟域需要对输入信号进行至少两次采样。这通常是通过使用多个寄存器级(通常称为“同步器”)来实现的,目的是降低由跨时钟域传输带来的亚稳态问题。
-
同步器寄存器级数的配置: 你可以定义同步器中使用的寄存器级数(也就是采样几次),以此控制同步的稳健性。更多的寄存器级数可以增加同步的可靠性,但会增加延迟。
-
可选的输入寄存器: 宏提供了一个可选的输入寄存器,可以在源时钟域内对输入信号进行预采样(在将信号传递到同步器之前)。这可以进一步确保输入信号的稳定性,减少输入信号在跨时钟边界时的毛刺或不确定性。
-
仿真功能: 宏还包含一个仿真特性,用于在仿真环境中检测和报告任何潜在的错误使用。开启此功能后,仿真时若发现该宏被错误配置或使用,将会生成警告或消息提示你进行检查和修正。
注:源数组中的每个比特在传输过程中是独立的,且彼此之间没有依赖关系。如果比特之间存在某种关系(例如多位信号代表某个多比特数据),则不应该使用这个同步宏,而应使用其他特定的同步方法(如 XPM_CDC_HANDSHAKE 或 XPM_CDC_GRAY)。
二、使用方法
xpm_cdc_array_single #( .DEST_SYNC_FF(2), // 同步器寄存器级数的配置 range: 2-10 .INIT_SYNC_FF(0), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values .SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages .SRC_INPUT_REG(1), // 可选的输入寄存器; 0=do not register input, 1=register input .WIDTH(2) // 单bit阵列位宽: 1-1024 ) xpm_cdc_array_single_inst ( .dest_out(data_o), //同步后的目的端数据 .dest_clk( clk2 ), //目的时钟.src_clk ( clk1 ), //源时钟.src_in (data_i) //源数据 );
当SRC_INPUT_REG = 1时:多一组寄存器src_ff_reg
当SRC_INPUT_REG = 0时:
三、仿真
module xpm_test(
input clk1 ,
input clk2 ,
input [1:0] data_i ,
output [1:0] data_o );xpm_cdc_array_single #( .DEST_SYNC_FF(2), // 同步器寄存器级数的配置 range: 2-10 .INIT_SYNC_FF(0), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values .SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages .SRC_INPUT_REG(0), // 可选的输入寄存器; 0=do not register input, 1=register input .WIDTH(2) // 单bit阵列位宽: 1-1024 ) xpm_cdc_array_single_inst ( .dest_out(data_o), //同步后的目的端数据 .dest_clk( clk2 ), //目的时钟.src_clk ( clk1 ), //源时钟.src_in (data_i) //源数据 );endmodule
module TB();reg clk1 ;
reg clk2 ;
reg [1:0] data_i_1 ;
reg [1:0] data_i_2 ;
wire [1:0] data_o ; initial begin
clk1 = 1;
clk2 = 1;
#200
data_i_1 = 2'b10;
#400
data_i_1 = 2'b11;
endalways #5 clk1 = ~clk1;
always #10 clk2 = ~clk2; always@(posedge clk1) data_i_2 <= data_i_1 ;xpm_test t1(
. clk1 ( clk1 ) ,
. clk2 ( clk2 ) ,
. data_i ( data_i_2 ) ,
. data_o ( data_o )); endmodule
结果:
总结
本章就到这儿,再见。