一、前言

当单bit信号由快时钟域传递给慢时钟域时,快时钟域的异步信号最小可为快时钟信号的一个时钟周期脉冲,快时钟域的单时钟周期脉冲长度小于慢时钟域的时钟周期,很有可能该脉冲信号在慢时钟域的两个时钟上升沿之间,导致该脉冲没有被慢时钟域采集到,从而导致信号数据丢失。

因此与单bit信号从慢时钟域到快时钟域直接打两拍不同,单bit信号从快时钟域到慢时钟域还需要特殊的处理。

二、脉冲同步器

脉冲同步器的原理为将快时钟域的脉冲拓展为电平信号,使得该电平的宽度大于慢时钟域的时钟周期,从而可以使用两级同步器进行同步,然后在同步后的时钟域进行脉冲恢复,从而完成将信号(尤其是脉冲信号)从快时钟域传递到慢时钟域。

verilog设计-CDC:单bit脉冲快时钟域到慢时钟域-LMLPHP

脉冲同步器的电路结构如上图所示。

在快时钟域,待同步信号低电平,寄存器Q端输出保持不变,待同步信号高电平时,寄存器的输出取反。在慢时钟域,首先进行两级寄存器同步,接着通过双边沿检测电路将脉冲信号恢复出来。

该电路具有如下特点:

1.该电路只能传递脉冲信号(也还能传递一直是0的信号,只不过工程意义不大),对于输入信号一直是1,或是只有0到1阶跃信号,只有1到0的变化的信号均无法正确传输;

2.该电路将输入端的脉冲传输给慢时钟域,无论输入端的脉冲有多宽,都只能在慢时钟域恢复成一个时钟周期宽度的脉冲;

3.输入信号的脉冲之间间隔要大于1倍的慢时钟周期,否则连着的两个脉冲问题会在慢时钟域合并为一个脉宽为2个慢时钟周期的脉冲,导致丢失一个脉冲。

三、脉冲同步器代码

`timescale 1ns/1ns

module pulse_detect(
  input         clk_fast  , 
  input         clk_slow  ,   
  input         rst_n    ,
  input        data_in    ,

  output         dataout
);
    
    //第一部分,脉冲电平转换
    reg data_in_r;
    always@(posedge clk_fast or negedge rst_n)begin
        if(~rst_n) 
            data_in_r <= 1'b0;
        else if(data_in)
            data_in_r <= ~data_in_r;
        else
            data_in_r <= data_in_r;
    end
    
    //第二部分,两级同步
    reg data_in_rt0,data_in_rt1;
    always@(posedge clk_slow or negedge rst_n)begin
        if(~rst_n) begin
            data_in_rt0 <= 1'b0;
            data_in_rt1 <= 1'b0;
        end
        else begin
            data_in_rt0 <= data_in_r;
            data_in_rt1 <= data_in_rt0;
        end
    end
    
    //第三部分,电平转换脉冲(边沿检测)
    reg data_in_m;
     always@(posedge clk_slow or negedge rst_n)begin
        if(~rst_n)
            data_in_m <= 1'b0;
         else
             data_in_m <= data_in_rt1;
     end
    
    assign dataout = data_in_m ^ data_in_rt1;

endmodule
03-22 07:12