跨时钟域学习记录(二)——XPM_CDC

  本文以Xilinx提供的xpm_cdc代码为例,整理处理跨时钟域数据传输的常见方法。

宏定义

  Xilinx定义了多个宏定义代替描述触发器行为的always块,列举如下

宏名称含义
XPM_XSRREG带同步复位/置位的同步寄存器
XPM_XSRREGEN带同步复位/置位和使能的寄存器
XPM_XARREG带异步复位/置位和使能的寄存器
// Define Xilinx Synchronous Register.  Only to be used by xpm_cdc_* modules.
`define XPM_XSRREG(clk, reset_p, q, d, rstval)   \always @(posedge clk) begin                    \if (reset_p == 1'b1)                         \q <= rstval;                               \else                                         \q <= d;                                    \end// Define Xilinx Synchronous Register with Enable.  Only to be used by xpm_cdc_* modules.
`define XPM_XSRREGEN(clk, reset_p, q, d, en, rstval)   \always @(posedge clk) begin                          \if (reset_p == 1'b1)                               \q <= rstval;                                     \else                                               \if (en == 1'b1)                                  \q <= d;                                        \end// Define Xilinx Asynchronous Register. Only to be used by xpm_cdc_* modules.
`define XPM_XARREG(clk, reset_p, q, d, rstval)   \always @(posedge clk or posedge reset_p)       \begin                                          \if (reset_p == 1'b1)                         \q <= rstval;                               \else                                         \q <= d;                                    \end

1. xpm_cdc_single

   cdc_single使用多个寄存器构成寄存器同步链的方式进行跨时钟域同步,这种方式适合于单比特数据的同步。使用该原语时需要注意:

  1. 为了保证不存在漏采脉冲信号,Xilinx规定用户逻辑需要保证每次源时钟脉冲(数据变化)至少为两个目的时钟周期。
可调参数功能
DEST_SYNC_FF可设置为大于2的值,用于设置目的时钟域的同步寄存器级数
SRC_INPUT_REG可设置为0或1,在不为0时,会在源时钟域添加一级XPM_XSRREG寄存器采样src_in

module xpm_cdc_single #(// Module parametersparameter integer DEST_SYNC_FF    = 4,parameter integer INIT_SYNC_FF    = 0,parameter integer SIM_ASSERT_CHK  = 0,parameter integer SRC_INPUT_REG   = 1,parameter integer VERSION         = 0
) (// Module portsinput  wire         src_clk,input  wire         src_in,input  wire         dest_clk,output wire         dest_out
);// Set Asynchronous Register property on synchronizers(* XPM_CDC = "SINGLE", ASYNC_REG = "TRUE" *) reg [DEST_SYNC_FF-1:0] syncstages_ff;reg  src_ff;wire src_inqual;wire async_path_bit;assign dest_out       = syncstages_ff[DEST_SYNC_FF-1];assign async_path_bit = src_inqual;// Virtual mux:  Register at input optional.generateif (SRC_INPUT_REG) begin : extra_inregassign src_inqual = src_ff;end : extra_inregelse begin : no_extra_inregassign src_inqual = src_in;end : no_extra_inregendgenerate// Instantiate Xilinx Synchronous Register`XPM_XSRREG(src_clk , 1'b0,  src_ff,        src_in,         1'b0)`XPM_XSRREG(dest_clk, 1'b0,  syncstages_ff, { syncstages_ff[DEST_SYNC_FF-2:0], async_path_bit} , {DEST_SYNC_FF{1'b0}})endmodule : xpm_cdc_single# 单比特伪路径set_false_path -to [get_cells syncstages_ff_reg[0][*]]

2. xpm_cdc_gray

   通过格雷码方式传输多位宽连续变化数据(相邻变化范围不超过1),比较适合用作计数器的同步(如异步FIFO中)。使用该原语时需要注意:

1.为了保证不存在漏采脉冲信号,Xilinx规定用户逻辑需要保证每次源时钟脉冲(数据变化)至少为两个目的时钟周期。
2. 为了保证数据的正确性,源时钟域发出的新数据需要是由旧数据加1或减1得到的。

可调参数功能
DEST_SYNC_FF可设置为大于2的值,用于设置目的时钟域的同步寄存器级数
REG_OUTPUT可设置为0或1,在不为0时,会在源时钟域添加一级XPM_XSRREG寄存器采样src_in_bin的格雷码结果
WIDTH待同步数据位宽
module xpm_cdc_gray #(// Module parametersparameter integer DEST_SYNC_FF          = 4,parameter integer INIT_SYNC_FF          = 0,parameter integer REG_OUTPUT            = 0,parameter integer SIM_ASSERT_CHK        = 0,parameter integer SIM_LOSSLESS_GRAY_CHK = 0,parameter integer VERSION               = 0,parameter integer WIDTH                 = 2
) (// Module portsinput  wire             src_clk,input  wire [WIDTH-1:0] src_in_bin,input  wire             dest_clk,output wire [WIDTH-1:0] dest_out_bin
);// Set Asynchronous Register property on synchronizers(* XPM_CDC = "GRAY", ASYNC_REG = "TRUE" *) reg [WIDTH-1:0] dest_graysync_ff [DEST_SYNC_FF-1:0];`ifdef XPM_CDC_BHVSIM_ONLYif (INIT_SYNC_FF == 1) beginalways @(glblGSR_xpmcdc)if (glblGSR_xpmcdc)force dest_graysync_ff = '{default:(0)};elserelease dest_graysync_ff;end`endifwire [WIDTH-1:0] gray_enc;reg  [WIDTH-1:0] binval;reg  [WIDTH-1:0] src_gray_ff;wire [WIDTH-1:0] synco_gray;wire [WIDTH-1:0] async_path;reg  [WIDTH-1:0] dest_out_bin_ff;always @(posedge dest_clk) begindest_graysync_ff[0] <= async_path; // @2for (int syncstage = 1; syncstage < DEST_SYNC_FF ;syncstage = syncstage + 1)dest_graysync_ff[syncstage] <= dest_graysync_ff [syncstage-1];endassign async_path = src_gray_ff; // @1assign synco_gray = dest_graysync_ff[DEST_SYNC_FF-1];assign gray_enc = src_in_bin ^ {1'b0, src_in_bin[WIDTH-1:1]};// Convert gray code back to binaryalways_comb beginbinval[WIDTH-1] = synco_gray[WIDTH-1];for (int j = WIDTH - 2; j >= 0; j = j - 1)binval[j] = binval[j+1] ^ synco_gray[j];endgenerateif(REG_OUTPUT) begin : reg_outassign dest_out_bin     = dest_out_bin_ff;end : reg_outelse begin : comb_outassign dest_out_bin     = binval;end : comb_outendgenerate// Instantiate Xilinx Synchronous Register`XPM_XSRREG(src_clk, 1'b0,  src_gray_ff, gray_enc, {WIDTH{1'b0}})`XPM_XSRREG(dest_clk, 1'b0,  dest_out_bin_ff, binval, {WIDTH{1'b0}})endmodule : xpm_cdc_gray# 保证格雷码各位传输的最大路径延迟小于一个源时钟周期set_max_delay -from [get_cells src_gray_ff_reg*] -to [get_cells dest_graysync_ff_reg[0]*] $src_clk_period -datapath_only# 保证格雷码各位传输的偏斜不超过一个时钟周期set_bus_skew  -from [get_cells src_gray_ff_reg*] -to [get_cells dest_graysync_ff_reg[0]*] [expr min ($src_clk_period, $dest_clk_period)]

3. xpm_cdc_handshake

  具有握手信号的跨时钟域传输,源时钟域通过src_send发起新的传输,通过src_rcv信号确认传输结束,目的时钟域通过dest_req得知出现新的传输,通过dest_ack信号确认传输。这种方式不需要使用存储资源进行同步,适合传输多位宽非连续的数据。使用该原语时需要注意:

  1. 对于源时钟域逻辑而言,在目的时钟域确认握手结束前不能发起新的传输,即每次src_send拉高都需要等到src_rcv拉低后一个周期再进行
  2. 对于源时钟域逻辑而言,在目的时钟域未确认握手时需要持续等待,即每次src_send拉低都需要等到src_rcv拉高后一个周期再进行
  3. 对于目的时钟域逻辑而言,在源时钟域未发起握手时不能发起新的确认,即每次dest_ack拉高都需要dest_req拉高后一个周期进行
  4. 对于目的时钟域逻辑而言,在源时钟域未确认握手时需要持续等待,即每次dest_ack拉低都需要等到dest_req拉低后一个周期再进行
可调参数功能
DEST_EXT_HSK可设置为0和1,当为1时启用dest_ack信号由用户逻辑在需要确认时确认握手,为0时由系统自行通过dest_req确认握手
DEST_SYNC_FF可设置为大于2的值,用于设置握手信号在目的时钟域的同步寄存器级数
SRC_SYNC_FF可设置为大于2的值,用于设置握手信号在源时钟域的同步寄存器级数
WIDTH待同步数据位宽
module xpm_cdc_handshake #(// Module parametersparameter integer DEST_EXT_HSK    = 1,parameter integer DEST_SYNC_FF    = 4,parameter integer INIT_SYNC_FF    = 0,parameter integer SIM_ASSERT_CHK  = 0,parameter integer SRC_SYNC_FF     = 4,parameter integer VERSION         = 0,parameter integer WIDTH           = 1
) (// Module portsinput  wire             src_clk,input  wire [WIDTH-1:0] src_in,input  wire             src_send,output wire             src_rcv,input  wire             dest_clk,output wire [WIDTH-1:0] dest_out,output wire             dest_req,input  wire             dest_ack
);// -------------------------------------------------------------------------------------------------------------------// Local parameter definitions// -------------------------------------------------------------------------------------------------------------------// Set Asynchronous Register property on synchronizers(* XPM_CDC = "HANDSHAKE" *) reg [WIDTH-1:0] dest_hsdata_ff;// -------------------------------------------------------------------------------------------------------------------// Simulation only variable and signal assignment// -------------------------------------------------------------------------------------------------------------------// We can do set max delay between source and dest.// For option with no input register, we have to create a smart constraint// for set max delay.reg  [WIDTH-1:0] src_hsdata_ff;wire             dest_req_nxt;reg              dest_req_ff;(* DIRECT_ENABLE = "yes" *) wire  dest_hsdata_en;wire             dest_req_ext_nxt;reg              dest_req_ext_ff;wire [WIDTH-1:0] src_hsdata_nxt;wire [WIDTH-1:0] dest_hsdata_nxt;wire [WIDTH-1:0] src_data_src;wire             dest_req_sync;wire             dest_ack_sync_in;reg              src_sendd_ff;wire             src_sendd_nxt;// -------------------------------------------------------------------------------------------------------------------// xpm_cdc_single instantiation// -------------------------------------------------------------------------------------------------------------------xpm_cdc_single #  (.DEST_SYNC_FF   (DEST_SYNC_FF  ),.INIT_SYNC_FF   (INIT_SYNC_FF  ),.SRC_INPUT_REG  (0             ),.VERSION        (VERSION       )) xpm_cdc_single_src2dest_inst (.src_clk        (src_clk       ),.dest_clk       (dest_clk      ),.src_in         (src_sendd_ff  ),.dest_out       (dest_req_sync ));//src_data is always registered onceassign src_data_src = src_hsdata_ff;assign src_hsdata_nxt  = (src_sendd_ff == 1'b0) ? src_in : src_hsdata_ff;assign dest_hsdata_nxt = src_data_src;assign dest_out        = dest_hsdata_ff;assign dest_req_nxt    = dest_req_sync;assign dest_hsdata_en  = ~dest_req_ff && dest_req_sync;assign src_sendd_nxt   = src_send;// -------------------------------------------------------------------------------------------------------------------// xpm_cdc_single instantiation// -------------------------------------------------------------------------------------------------------------------xpm_cdc_single #  (.DEST_SYNC_FF   (SRC_SYNC_FF   ),.INIT_SYNC_FF   (INIT_SYNC_FF  ),.SRC_INPUT_REG  (0             ),.VERSION        (VERSION       )) xpm_cdc_single_dest2src_inst (.src_clk        (dest_clk        ),.dest_clk       (src_clk         ),.src_in         (dest_ack_sync_in),.dest_out       (src_rcv         ));generateif(DEST_EXT_HSK) begin : ext_desthskassign dest_ack_sync_in = dest_ack;assign dest_req_ext_nxt = dest_req_sync ;end : ext_desthskelse begin : internal_desthskassign dest_ack_sync_in = dest_req_ff;assign dest_req_ext_nxt = dest_req_sync & ~dest_req_ff;end : internal_desthskendgenerateassign dest_req = dest_req_ext_ff;// Instantiate Xilinx Synchronous Register`XPM_XSRREG(src_clk,  1'b0,  src_sendd_ff,    src_sendd_nxt,    1'b0)`XPM_XSRREG(src_clk,  1'b0,  src_hsdata_ff,   src_hsdata_nxt,   {WIDTH{1'b0}})`XPM_XSRREGEN(dest_clk, 1'b0,  dest_hsdata_ff,  dest_hsdata_nxt, dest_hsdata_en ,{WIDTH{1'b0}})`XPM_XSRREG(dest_clk, 1'b0,  dest_req_ff,     dest_req_nxt,     1'b0)`XPM_XSRREG(dest_clk, 1'b0,  dest_req_ext_ff, dest_req_ext_nxt, 1'b0)endmodule : xpm_cdc_handshake# 在数据位宽小于100时控制最大延时、偏斜为多周期路径if {$xpm_cdc_hs_width <= 100} {set_max_delay -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr {$dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff}] -datapath_onlyset_bus_skew  -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr {$dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff}]} else {set_max_delay -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr min ($src_clk_period, $dest_clk_period)] -datapath_only}

4. xpm_cdc_pulse

   本原语用于脉冲信号的跨时钟域传输,使用该原语时需要注意:

  1. 复位期间不能传输脉冲信号,即src_rst或dest_rst有效期间src_pulse不能拉高
可调参数功能
DEST_SYNC_FF可设置为大于2的值,用于设置握手信号在目的时钟域的同步寄存器级数
REG_OUTPUT0或1,使用额外1级触发器同步目的时钟域输出脉冲
RST_USED0或1,1启用复位引脚
module xpm_cdc_pulse #(parameter integer DEST_SYNC_FF    = 4,parameter integer INIT_SYNC_FF    = 0,parameter integer REG_OUTPUT      = 0,parameter integer RST_USED        = 1,parameter integer SIM_ASSERT_CHK  = 0,parameter integer VERSION         = 0
) (input  wire       src_clk,input  wire       src_pulse,input  wire       dest_clk,input  wire       src_rst,input  wire       dest_rst,output wire       dest_pulse
);// If toggle flop is not initialized,then it can be un-known forever.// It is assumed that there is no loss of coverage either way.// For edge detect, we would want the logic to be more controlled.reg  src_level_ff = 1'b0;reg  src_in_ff;wire src_level_nxt;wire src_edge_det;wire src_sync_in;wire dest_sync_out;wire dest_event_nxt;reg  dest_event_ff;wire dest_sync_qual;wire src_rst_qual;wire dest_rst_qual;wire dest_pulse_int;reg  dest_pulse_ff;//Assignmentsassign src_edge_det   = src_pulse & ~src_in_ff; // 上升沿assign src_level_nxt  = src_level_ff ^ src_edge_det; // 有上升沿且src_level_ff为低电平 或 无上升沿且src_level_ff为高电平,将脉冲信号转换为电平信号assign src_sync_in    = src_level_ff;     // 同步电平信号源时钟域assign dest_event_nxt = dest_sync_qual;assign dest_pulse_int = dest_sync_qual ^ dest_event_ff; // 电平信号转脉冲信号assign dest_sync_qual = dest_sync_out & ~dest_rst_qual; generateif(RST_USED) begin : use_rstassign src_rst_qual = src_rst;assign dest_rst_qual = dest_rst;end : use_rstelse begin : no_rstassign src_rst_qual = 1'b0;assign dest_rst_qual = 1'b0;end : no_rstendgenerategenerateif(REG_OUTPUT) begin : reg_outassign dest_pulse     = dest_pulse_ff;end : reg_outelse begin : comb_outassign dest_pulse     = dest_pulse_int;end : comb_outendgeneratexpm_cdc_single # (.DEST_SYNC_FF   (DEST_SYNC_FF ),.INIT_SYNC_FF   (INIT_SYNC_FF ),.SRC_INPUT_REG  (0            ),.VERSION        (VERSION      )) xpm_cdc_single_inst (.src_clk       (src_clk       ),.dest_clk      (dest_clk      ),.src_in        (src_sync_in   ),.dest_out      (dest_sync_out ));// Instantiate Xilinx Synchronous Register`XPM_XSRREG(src_clk,  src_rst_qual,   src_in_ff,     src_pulse,      1'b0)`XPM_XSRREG(src_clk,  src_rst_qual,   src_level_ff,  src_level_nxt,  1'b0)`XPM_XSRREG(dest_clk, dest_rst_qual,  dest_event_ff, dest_event_nxt, 1'b0)`XPM_XSRREG(dest_clk, dest_rst_qual,  dest_pulse_ff, dest_pulse_int, 1'b0)endmodule : xpm_cdc_pulse

5. xpm_cdc_array_single

  该原语对多位宽数据进行同步,用于实现多个xpm_cdc_single的功能。该原语需要注意:

  1. 输入数据宽度需要保证能在目的时钟域有效沿采样至少两次
可调参数功能
DEST_SYNC_FF可设置为大于2的值,用于设置握手信号在目的时钟域的同步寄存器级数
SRC_INPUT_REG0或1,使用额外1级触发器采样源时钟域的输入数据
WIDTH待同步数据位宽
module xpm_cdc_array_single # (parameter integer DEST_SYNC_FF    = 4,parameter integer INIT_SYNC_FF    = 0,parameter integer SIM_ASSERT_CHK  = 0,parameter integer SRC_INPUT_REG   = 1,parameter integer VERSION         = 0,parameter integer WIDTH           = 2
) (input  wire             src_clk,input  wire [WIDTH-1:0] src_in,input  wire             dest_clk,output wire [WIDTH-1:0] dest_out
);(* XPM_CDC = "ARRAY_SINGLE", ASYNC_REG = "TRUE" *) reg  [WIDTH-1:0] syncstages_ff [DEST_SYNC_FF-1:0];// -------------------------------------------------------------------------------------------------------------------// Simulation only variable and signal assignment// -------------------------------------------------------------------------------------------------------------------reg  [WIDTH-1:0] src_ff;wire [WIDTH-1:0] src_inqual;wire [WIDTH-1:0] async_path_bit;assign dest_out = syncstages_ff[DEST_SYNC_FF-1];always @(posedge dest_clk) beginsyncstages_ff[0] <= async_path_bit;for (int syncstage = 1; syncstage < DEST_SYNC_FF ;syncstage = syncstage + 1)syncstages_ff[syncstage] <= syncstages_ff [syncstage-1];endassign async_path_bit = src_inqual;// Virtual mux:  Register at input optional.generateif (SRC_INPUT_REG) begin : extra_inregassign src_inqual = src_ff;end : extra_inregelse begin : no_extra_inregassign src_inqual = src_in;end : no_extra_inregendgenerategenvar vara_i;generate// Instantiate Xilinx Synchronous Register `XPM_XSRREG(src_clk, 1'b0, src_ff, src_in, {WIDTH{1'b0}})endgenerateendmodule : xpm_cdc_array_single# 单比特伪路径set_false_path -to [get_cells syncstages_ff_reg[0][*]]

6. xpm_cdc_sync_rst

  该原语用于同步复位信号的跨时钟域同步,类似xpm_cdc_single的功能。该原语需要注意:

  1. 输入复位信号宽度需要保证能在目的时钟域有效沿采样至少两次
可调参数功能
DEST_SYNC_FF可设置为大于2的值,用于设置握手信号在目的时钟域的同步寄存器级数
INIT用于设置同步寄存器默认值
module xpm_cdc_sync_rst # (parameter integer DEST_SYNC_FF    = 4,parameter integer INIT            = 1,parameter integer INIT_SYNC_FF    = 0,parameter integer SIM_ASSERT_CHK  = 0,parameter integer VERSION         = 0) (input  wire       src_rst,input  wire       dest_clk,output wire       dest_rst
);// Define local parameter for settingslocalparam DEF_VAL        = (INIT == 1) ? 1'b1 : 1'b0;// Set asynchronous register property on synchronizers and initialize register with INIT value(* XPM_CDC = "SYNC_RST", ASYNC_REG = "TRUE" *) reg [DEST_SYNC_FF-1:0] syncstages_ff = {DEST_SYNC_FF{DEF_VAL}};// -------------------------------------------------------------------------------------------------------------------// Simulation only variable and signal assignment// -------------------------------------------------------------------------------------------------------------------wire async_path_bit;assign dest_rst = syncstages_ff[DEST_SYNC_FF-1];assign async_path_bit = src_rst;// Instantiate Xilinx Synchronous Register`XPM_XSRREG(dest_clk, 1'b0,  syncstages_ff, { syncstages_ff[DEST_SYNC_FF-2:0], async_path_bit}, {DEST_SYNC_FF{1'b0}})endmodule : xpm_cdc_sync_rst# 单比特伪路径
set_false_path -to [get_cells syncstages_ff_reg[0]]

7. xpm_cdc_async_rst

  该原语用于异步复位信号的跨时钟域同步,类似xpm_cdc_sync_rst的功能。

可调参数功能
DEST_SYNC_FF可设置为大于2的值,用于设置握手信号在目的时钟域的同步寄存器级数
RST_ACTIVE_HIGH0或1,分别代表低电平有效异步复位、高电平有效异步复位
module xpm_cdc_async_rst # (parameter integer DEST_SYNC_FF    = 4,parameter integer INIT_SYNC_FF    = 0,parameter integer RST_ACTIVE_HIGH = 0,parameter integer VERSION         = 0) (input  wire       src_arst,input  wire       dest_clk,output wire       dest_arst
);// -------------------------------------------------------------------------------------------------------------------// Local parameter definitions// -------------------------------------------------------------------------------------------------------------------// Define local parameter for settingslocalparam DEF_VAL        = (RST_ACTIVE_HIGH == 1) ? 1'b0 : 1'b1;localparam INV_DEF_VAL    = (RST_ACTIVE_HIGH == 0) ? 1'b0 : 1'b1;// Set asynchronous register property on synchronizers and initialize register with default value(* XPM_CDC = "ASYNC_RST", ASYNC_REG = "TRUE" *) reg [DEST_SYNC_FF-1:0] arststages_ff = {DEST_SYNC_FF{DEF_VAL}};// -------------------------------------------------------------------------------------------------------------------// Simulation only variable and signal assignment// -------------------------------------------------------------------------------------------------------------------wire                    async_path_bit;wire                    reset_pol;wire                    reset_polo;assign reset_polo = arststages_ff[DEST_SYNC_FF-1];assign async_path_bit = (RST_ACTIVE_HIGH == 1) ? 1'b0 : 1'b1;assign reset_pol = src_arst ^ ~RST_ACTIVE_HIGH;assign dest_arst = reset_polo;// Instantiate Xilinx Asynchronous Clear Register`XPM_XARREG(dest_clk, reset_pol,  arststages_ff, { arststages_ff[DEST_SYNC_FF-2:0], async_path_bit}, {DEST_SYNC_FF{INV_DEF_VAL}})endmodule : xpm_cdc_async_rst# 单比特伪路径
set_false_path -through [get_ports -no_traverse src_arst]

8. xpm_cdc_low_latency_handshake

  该原语功能类似与xpm_cdc_handshake,不同之处在于实现了一个深度为1的FIFO,并采用AXIS valid-ready握手的方式实现跨时钟域低延时传输。

可调参数功能
DEST_EXT_HSK可设置为0和1,当为1时启用dest_ack信号由用户逻辑在需要确认时确认握手,为0时由系统自行通过dest_req确认握手
DEST_SYNC_FF可设置为大于2的值,用于设置握手信号在目的时钟域的同步寄存器级数
SRC_SYNC_FF可设置为大于2的值,用于设置握手信号在源时钟域的同步寄存器级数
WIDTH待同步数据位宽
module xpm_cdc_low_latency_handshake #(// Module parametersparameter integer DEST_EXT_HSK    = 1,parameter integer DEST_SYNC_FF    = 4,parameter integer INIT_SYNC_FF    = 0,parameter integer SIM_ASSERT_CHK  = 0,parameter integer SRC_SYNC_FF     = 4,parameter integer VERSION         = 0,parameter integer WIDTH           = 1
) (// Module portsinput  wire             src_clk,input  wire [WIDTH-1:0] src_in,input  wire             src_valid,output wire             src_ready,input  wire             dest_clk,output wire [WIDTH-1:0] dest_out,output wire             dest_valid,input  wire             dest_ready
);// -------------------------------------------------------------------------------------------------------------------// Local parameter definitions// -------------------------------------------------------------------------------------------------------------------// Set Asynchronous Register property on synchronizers(* XPM_CDC = "LOW_LATENCY_HANDSHAKE" *) reg [WIDTH-1:0] dest_hsdata_ff;// -------------------------------------------------------------------------------------------------------------------// Simulation only variable and signal assignment// -------------------------------------------------------------------------------------------------------------------reg  [WIDTH-1:0] src_hsdata_ff;wire             src_valid_nxt;wire              src_count_nxt;reg              src_count_ff = 1'b0;wire        src_count_sync_ff;(* DIRECT_ENABLE = "yes" *) wire  dest_hsdata_ff_en;reg        dest_valid_ext_ff;wire        dest_valid_nxt;wire              dest_ready_in;wire       dest_ready_nxt;wire             dest_count_nxt;wire        dest_count_eq;reg              dest_count_ff = 1'b0;wire             dest_count_sync_ff;wire              src_count_eq;wire              src_ready_nxt;reg        src_ready_ext_ff;assign src_valid_nxt = src_valid && src_ready;assign src_count_nxt = (src_valid_nxt == 1'b1) ? (src_count_ff+1'b1) : src_count_ff;assign dest_ready_nxt = dest_valid_ext_ff && dest_ready_in  ;assign dest_count_nxt = (dest_ready_nxt == 1'b1) ? (dest_count_ff+1'b1) : dest_count_ff;assign dest_count_eq  = (src_count_sync_ff == dest_count_ff) ? 1'b1 : 1'b0;assign dest_hsdata_ff_en = !dest_count_eq && !dest_valid_ext_ff;assign dest_valid_nxt = !dest_count_eq && !dest_ready_nxt;assign dest_valid     = dest_valid_ext_ff;assign src_count_eq   = (src_count_ff == dest_count_sync_ff) ? 1'b1 : 1'b0;assign src_ready_nxt  = src_count_eq && !src_valid_nxt;assign src_ready      = src_ready_ext_ff;assign dest_out = dest_hsdata_ff;generateif(DEST_EXT_HSK) begin : ext_desthskassign dest_ready_in = dest_ready;end : ext_desthskelse begin : internal_desthskassign dest_ready_in = 1'b1;end : internal_desthskendgenerate//Instantiate Xilinx Synchronous Register`XPM_XSRREGEN(src_clk, 1'b0,  src_hsdata_ff,  src_in, src_valid_nxt ,{WIDTH{1'b0}})`XPM_XSRREGEN(dest_clk, 1'b0,  dest_hsdata_ff,  src_hsdata_ff, dest_hsdata_ff_en,{WIDTH{1'b0}})`XPM_XSRREG(src_clk, 1'b0,  src_count_ff, src_count_nxt, 1'b0)`XPM_XSRREG(dest_clk, 1'b0,  dest_count_ff, dest_count_nxt, 1'b0)`XPM_XSRREG(dest_clk, 1'b0,  dest_valid_ext_ff, dest_valid_nxt, 1'b0)`XPM_XSRREG(src_clk, 1'b0,  src_ready_ext_ff, src_ready_nxt, 1'b0)// -------------------------------------------------------------------------------------------------------------------// xpm_cdc_single instantiation// -------------------------------------------------------------------------------------------------------------------xpm_cdc_single #  (.DEST_SYNC_FF   (DEST_SYNC_FF  ),.INIT_SYNC_FF   (INIT_SYNC_FF  ),.SRC_INPUT_REG  (0             ),.SIM_ASSERT_CHK (SIM_ASSERT_CHK),.VERSION        (VERSION       )) xpm_cdc_single_src2dest_inst (.src_clk        (src_clk       ),.dest_clk       (dest_clk      ),.src_in         (src_count_ff  ),.dest_out       (src_count_sync_ff ));// -------------------------------------------------------------------------------------------------------------------// xpm_cdc_single instantiation// -------------------------------------------------------------------------------------------------------------------xpm_cdc_single #  (.DEST_SYNC_FF   (SRC_SYNC_FF   ),.INIT_SYNC_FF   (INIT_SYNC_FF  ),.SRC_INPUT_REG  (0             ),.SIM_ASSERT_CHK (SIM_ASSERT_CHK),.VERSION        (VERSION       )) xpm_cdc_single_dest2src_inst (.src_clk        (dest_clk      ),.dest_clk       (src_clk       ),.src_in         (dest_count_ff ),.dest_out       (dest_count_sync_ff ));endmodule : xpm_cdc_low_latency_handshake# 在数据位宽小于100时控制最大延时、偏斜为多周期路径if {$xpm_cdc_hs_width <= 100} {set_max_delay -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr {$dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff}] -datapath_onlyset_bus_skew  -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr {$dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff}]} else {set_max_delay -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr min ($src_clk_period, $dest_clk_period)] -datapath_only}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/770861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【物联网】Qinghub Kafka 数据采集

基础信息 组件名称 &#xff1a; kafka-connector 组件版本&#xff1a; 1.0.0 组件类型&#xff1a; 系统默认 状 态&#xff1a; 正式发布 组件描述&#xff1a;通用kafka连接网关&#xff0c;消费来自kafka的数据&#xff0c;并转发给下一个节点做相关的数据解析。 配置文…

网络七层模型之物理层:理解网络通信的架构(一)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Visual Studio 常用快捷键大全

前言 对于开发者而言&#xff0c;熟悉快捷键的使用&#xff0c;能够起到事半功倍的作用&#xff0c;提高工作效率。以下是我整理的一份Visual Studio常用快捷键清单&#xff0c;希望能够帮助到你。 常用快捷方式 快捷键功能Ctrl K C注释选定内容Ctrl K U取消注释选定内容…

Vue 3.0 中一些主要的生命周期钩子

Vue 3.0 的生命周期钩子与 Vue 2.x 有所不同&#xff0c;但基本的概念和用途是相似的。这些钩子函数允许你在组件的不同阶段执行特定的逻辑。以下是 Vue 3.0 中一些主要的生命周期钩子&#xff1a; setup()&#xff1a;这是 Vue 3 引入的一个新钩子&#xff0c;它在组件创建之前…

如何忽略Chrome最小字号的限制

通过控制台调整字体大小时&#xff0c;可以发现即便设置了小于12px的字号&#xff0c;也并不会变小&#xff0c;这是因为Chrome默认最小字号为12px。 在Chrome设置中的外观选项卡中可以发现&#xff0c;默认字体是16px。将最小字号改为0&#xff0c;就能随意设置小于12px的字号…

spring boot商城、商城源码 欢迎交流

一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、拥有分布式锁&#xff0c;为生产环境多实例完全准备&#xff0c;数据库为b2b2c设计&#xff0c;拥有完整sku和下单流程的商城 联系: V-Tavendor

文件编辑命令—vim

1.vim vim 是vi的升级版本.vi 文件名(vi方向键用不了) vim 的官方网站 (welcome home : vim online) 自己也说 vim 是一个程序开发工具而不是文字处理软件。 2.安装vim sudo apt install vim 如果出错了:apt update:刷新软件源; 出现"无法获得锁 之类的"sudo rm 文件…

Java 如何针对不同类型判断一个对象是否为空

在Java中&#xff0c;要判断一个对象是否为空&#xff0c;通常需要考虑不同类型的对象。下面是针对不同情况的一些常用方法&#xff1a; 判断引用类型对象是否为null&#xff1a; 对于引用类型的对象&#xff0c;可以使用简单的判空操作来检查是否为null。 Object obj null…

后端常问面经之并发

volatile 关键字 volatile关键字是如何保证内存可见性的&#xff1f;底层是怎么实现的&#xff1f; "观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现&#xff0c;加入volatile关键字时&#xff0c;会多出一个lock前缀指令”lock前缀指令实际上相…

2015年认证杯SPSSPRO杯数学建模D题(第二阶段)城市公共自行车全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 D题 城市公共自行车 原题再现&#xff1a; 城市交通问题直接影响市民的生活和工作。在地形平坦的城市&#xff0c;公共自行车出行系统是一种很好的辅助手段。一般来说&#xff0c;公共自行车出行系统由数据中心、驻车站点、驻车桩、自行车&…

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.1-3.5

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第三周&#xff1a;浅层神经网络(Shallow neural networks)3.1 神经网络概述&#xff08;Neural Network Overview&#xff09;3.2 神经网络的表示&#xff08;Neural Network Representation…

2024年碑林区软科学研究项目申报类型方向、时间流程要求

一、征集类型及研究方向 项目类型:重点支持综合运用自然科学、社会科学和工程技术多门类、多学科知识,为科技和经济社会发展的重大决策提供支撑。 项目支持以“五大发展理念”为指导,围绕科技、经济、民生等社会发展问题,开展对策研究,包含但不限于:加快培育新质生产力、秦创…

【Java八股面试系列】中间件-Redis

目录 Redis 什么是Redis Redis解决了什么问题 Redis的实现原理 数据结构 String 常用命令 应用场景 List(列表) 常用命令 应用场景 Hash(哈希) 常用命令 应用场景 set(集合) 常见命令​编辑 应用场景 Sorted Set(有序集合) 常见命令​编辑 应用场景 数据持…

idea中gradle编译下运营main方法报CreateProcess error=206

问题描述 CreateProcess error206 文件名或扩展名太长 问题分析 解决方案 build.gradle文件里添加 buildscript {repositories {maven {url "https://plugins.gradle.org/m2/"}}dependencies {classpath "gradle.plugin.ua.eshepelyuk:ManifestClasspath:1.…

kali MSF网络安全框架

MSF&#xff0c;全称The Metasploit Framework&#xff0c;简称MSF&#xff0c;是一个强大的网络安全框架&#xff0c;主要用于进行渗透测试和漏洞利用。它提供了丰富的模块和工具&#xff0c;帮助安全研究人员和渗透测试人员发现、利用和修复系统中的安全漏洞。 操作: 不夸张…

web渗透测试漏洞流程:红队资产信息收集之单个目标信息收集

端口爆破工具用法 Hydra 参数详解: -R 根据上一次进度继续破解 -S 使用SSL协议连接 -s 指定端口 -l 指定用户名 -L 指定用户名字典(文件) -p 指定密码破解 -P 指定密码字典(文件) -e 空密码探测和指定用户密码探测(ns) -M <FILE>指定目标列表文件一行一条 -…

Pandas操作MultiIndex合并行列的Excel,写入读取以及写入多余行及Index列处理,插入行,修改某个单元格的值

Pandas操作MultiIndex合并行列的excel&#xff0c;写入读取以及写入多余行及Index列处理 1. 效果图及问题2. 源码参考 今天是谁写Pandas的 复合索引MultiIndex&#xff0c;写的糊糊涂涂&#xff0c;晕晕乎乎。 是我呀… 记录下&#xff0c;现在终于灵台清明了。 明天在记录下直…

【Python百日进阶-Web开发-Peewee】Day287 - Peewee 的扩展(六)字段等

文章目录 13.10 字段class CompressedFieldclass PickleField 13.11 混合属性 Hybrid Attributes13.11.1 混合 APIclass hybrid_methodclass hybrid_property 13.12 键/值存储 Key/Value Storeclass KeyValue 13.10 字段 这些字段可以在playhouse.fields模块中找到。 class C…

Ubuntu22.04安装WordPress教程

Ubuntu22.04安装LEMP堆栈(Nginx MariaDB PHP)教程 Ubuntu22.04安装WordPress教程&#xff08;利用nginx环境和MariaDB数据库&#xff0c;安装使用WordPress&#xff09; 本教程将展示如何在 Ubuntu22.04 上安装 LEMP 堆栈。 一个软件堆栈是捆绑在一起的一组软件工具。 LEMP …

华为全套企业管理资料合集(21专题)

华为全套企业管理资料合集-知识星球下载 1.绩效考核 华为内训绝密资料:绩效管理与绩效考核.ppt 华为绩效管理与绩效考核制度.docx 华为公司实用性各种绩效图表汇总.doc 华为公司考勤管理制度.doc 华为IPD模式中跨部门团队成员的考核激励制度.doc 2.企业管理 华为公司人力资源…