当前位置:首页 > FPGA > 正文内容

CDC 单脉冲信号处理

chanra1n3年前 (2022-04-22)FPGA3854

代码中的Sys_clk其实是没有用到的,项目文件:

cdc_single.zip

//------------------------------------------------------
// File Name        : cdc.v
// Author           : ChanRa1n
// Description      : a cdc test ex
// Called by        : TopModule
// Revision History : 2022-04-22
// Revision         : 1.0
// Email            : [email protected]
// Copyright(c) 2018-Now, MYFPGA.CN, All right reserved.
//------------------------------------------------------

module cdc (
    input   wire   [0:0]   Sys_clk,
    input   wire   [0:0]   Sys_rst_n,

    input   wire   [0:0]   Clk_50M_in,
    input   wire   [0:0]   Clk_10M_in,

    input   wire   [0:0]   Sig_50M_in,
    input   wire   [0:0]   Sig_10M_in,

    output  wire   [0:0]   Sig_out_fast2slow,
    output  wire   [0:0]   Sig_out_slow2fast,

    output  wire   [0:0]   Sig_out_fast2slow_dff2,
    output  wire   [0:0]   Sig_out_slow2fast_dff2
);
//-----------------------------------------------------------------------------
    reg   [0:0]   Sig_out_fast2slow_reg ;
    reg   [0:0]   Sig_out_slow2fast_reg ;  
    assign   Sig_out_fast2slow = Sig_out_fast2slow_reg ;
    assign   Sig_out_slow2fast = Sig_out_slow2fast_reg ;

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_reg <= 0 ;
        end
        else begin
            Sig_out_fast2slow_reg <= Sig_50M_in ;
        end
    end

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_reg <= 0 ;
        end
        else begin
            Sig_out_slow2fast_reg <= Sig_10M_in ;
        end
    end
//-----------------------------------------------------------------------------
    reg   [0:0]   Sig_out_fast2slow_lvl_reg  ;
    reg   [0:0]   Sig_out_fast2slow_adj_reg0 ;
    reg   [0:0]   Sig_out_fast2slow_adj_reg1 ;

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_lvl_reg <= 0 ;
        end
        else begin
            if(Sig_50M_in)
                Sig_out_fast2slow_lvl_reg <= ~Sig_out_fast2slow_lvl_reg ;
            else
                Sig_out_fast2slow_lvl_reg <= Sig_out_fast2slow_lvl_reg ;
        end
    end

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_adj_reg0 <= 0 ;
            Sig_out_fast2slow_adj_reg1 <= 0 ;
        end
        else begin
            Sig_out_fast2slow_adj_reg0 <= Sig_out_fast2slow_lvl_reg ;
            Sig_out_fast2slow_adj_reg1 <= Sig_out_fast2slow_adj_reg0;
        end
    end

    assign   Sig_out_fast2slow_dff2 = Sig_out_fast2slow_adj_reg0 != Sig_out_fast2slow_adj_reg1;
//-----------------------------------------------------------------------------
    reg   [0:0]   Sig_out_slow2fast_lvl_reg  ;
    reg   [0:0]   Sig_out_slow2fast_adj_reg0 ;
    reg   [0:0]   Sig_out_slow2fast_adj_reg1 ;

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_lvl_reg <= 0 ;
        end
        else begin
            if(Sig_50M_in)
                Sig_out_slow2fast_lvl_reg <= ~Sig_out_slow2fast_lvl_reg ;
            else
                Sig_out_slow2fast_lvl_reg <= Sig_out_slow2fast_lvl_reg ;
        end
    end

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_adj_reg0 <= 0 ;
            Sig_out_slow2fast_adj_reg1 <= 0 ;
        end
        else begin
            Sig_out_slow2fast_adj_reg0 <= Sig_out_slow2fast_lvl_reg ;
            Sig_out_slow2fast_adj_reg1 <= Sig_out_slow2fast_adj_reg0;
        end
    end

    assign   Sig_out_slow2fast_dff2 = Sig_out_slow2fast_adj_reg0 != Sig_out_slow2fast_adj_reg1 ;

//-----------------------------------------------------------------------------
endmodule


//------------------------------------------------------
// File Name        : cdc_tb.v
// Author           : ChanRa1n
// Description      : Testbench file for cdc_tb
// Called by        : Simulation
// Revision History : 2022-04-22
// Revision         : 1.0
// Email            : [email protected]
// Copyright(c) 2018-Now, MYFPGA.CN, All right reserved.
//------------------------------------------------------

`default_nettype wire
`timescale 1ns/1ns

module cdc_tb ();
    reg Sys_clk;
    reg Sys_rst_n;

    reg    [0:0]   Clk_50M_in;
    reg    [0:0]   Clk_10M_in;
    reg    [0:0]   Sig_50M_in;
    reg    [0:0]   Sig_10M_in;
    wire   [0:0]   Sig_out_fast2slow;
    wire   [0:0]   Sig_out_slow2fast;
    wire   [0:0]   Sig_out_fast2slow_dff2;
    wire   [0:0]   Sig_out_slow2fast_dff2;

    localparam CLK_PERIOD = 10;

    always #(CLK_PERIOD/2) Sys_clk=~Sys_clk;
    always #(100) Clk_10M_in=~Clk_10M_in;
    always #(20) Clk_50M_in=~Clk_50M_in;

    initial begin
        #1 Sys_rst_n<=1'b0;Sys_clk<=1'b0;Clk_10M_in<=0;
        #1 Clk_50M_in<=0;
        #(CLK_PERIOD*3) Sys_rst_n<=1;
        #(CLK_PERIOD*3000);
        $stop;
    end
   
    initial begin
        forever begin
        @(posedge Clk_10M_in);
        Sig_10M_in <= {$random} % 2;
        end
    end

    initial begin
        forever begin
        @(posedge Clk_50M_in);
        Sig_50M_in <= {$random} % 2;
        end
    end

    cdc cdc (
    .Sys_clk(Sys_clk),
    .Sys_rst_n(Sys_rst_n),
    .Clk_50M_in(Clk_50M_in),
    .Clk_10M_in(Clk_10M_in),
    .Sig_50M_in(Sig_50M_in),
    .Sig_10M_in(Sig_10M_in),
    .Sig_out_fast2slow(Sig_out_fast2slow),
    .Sig_out_slow2fast(Sig_out_slow2fast),
    .Sig_out_fast2slow_dff2(Sig_out_fast2slow_dff2),
    .Sig_out_slow2fast_dff2(Sig_out_slow2fast_dff2)
    );

endmodule

image.png

image.png

image.png


当然,光是对高速信号展宽还是不够,我们依旧没有消除亚稳态,所以这里需要再进行打两拍。也就是这样:

//------------------------------------------------------
// File Name        : cdc.v
// Author           : ChanRa1n
// Description      : a cdc test ex
// Called by        : TopModule
// Revision History : 2022-04-22
// Revision         : 1.0
// Email            : [email protected]
// Copyright(c) 2018-Now, MYFPGA.CN, All right reserved.
//------------------------------------------------------

module cdc (
    input   wire   [0:0]   Sys_clk,
    input   wire   [0:0]   Sys_rst_n,

    input   wire   [0:0]   Clk_50M_in,
    input   wire   [0:0]   Clk_10M_in,

    input   wire   [0:0]   Sig_50M_in,
    input   wire   [0:0]   Sig_10M_in,

    output  wire   [0:0]   Sig_out_fast2slow,
    output  wire   [0:0]   Sig_out_slow2fast,

    output  wire   [0:0]   Sig_out_fast2slow_dff2,
    output  wire   [0:0]   Sig_out_slow2fast_dff2
);
//-----------------------------------------------------------------------------
    reg   [0:0]   Sig_out_fast2slow_reg ;
    reg   [0:0]   Sig_out_slow2fast_reg ;  
    assign   Sig_out_fast2slow = Sig_out_fast2slow_reg ;
    assign   Sig_out_slow2fast = Sig_out_slow2fast_reg ;

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_reg <= 0 ;
        end
        else begin
            Sig_out_fast2slow_reg <= Sig_50M_in ;
        end
    end

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_reg <= 0 ;
        end
        else begin
            Sig_out_slow2fast_reg <= Sig_10M_in ;
        end
    end
//-----------------------------------------------------------------------------
    reg   [0:0]   Sig_out_fast2slow_lvl_reg  ;
    reg   [0:0]   Sig_out_fast2slow_adj_reg0 ;
    reg   [0:0]   Sig_out_fast2slow_adj_reg1 ;
    reg   [0:0]   Sig_out_fast2slow_adj_reg2 ;
    reg   [0:0]   Sig_out_fast2slow_adj_reg3 ;

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_lvl_reg <= 0 ;
        end
        else begin
            if(Sig_50M_in)
                Sig_out_fast2slow_lvl_reg <= ~Sig_out_fast2slow_lvl_reg ;
            else
                Sig_out_fast2slow_lvl_reg <= Sig_out_fast2slow_lvl_reg ;
        end
    end

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_adj_reg0 <= 0 ;
            Sig_out_fast2slow_adj_reg1 <= 0 ;
        end
        else begin
            Sig_out_fast2slow_adj_reg0 <= Sig_out_fast2slow_lvl_reg ;
            Sig_out_fast2slow_adj_reg1 <= Sig_out_fast2slow_adj_reg0;
        end
    end

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_fast2slow_adj_reg2 <= 0 ;
            Sig_out_fast2slow_adj_reg3 <= 0 ;
        end
        else begin
            Sig_out_fast2slow_adj_reg2 <= Sig_out_fast2slow_adj_reg0 != Sig_out_fast2slow_adj_reg1 ;
            Sig_out_fast2slow_adj_reg3 <= Sig_out_fast2slow_adj_reg2;
        end
    end

    assign   Sig_out_fast2slow_dff2 = Sig_out_fast2slow_adj_reg3;
//-----------------------------------------------------------------------------
    reg   [0:0]   Sig_out_slow2fast_lvl_reg  ;
    reg   [0:0]   Sig_out_slow2fast_adj_reg0 ;
    reg   [0:0]   Sig_out_slow2fast_adj_reg1 ;
    reg   [0:0]   Sig_out_slow2fast_adj_reg2 ;
    reg   [0:0]   Sig_out_slow2fast_adj_reg3 ;

    always@(posedge Clk_10M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_lvl_reg <= 0 ;
        end
        else begin
            if(Sig_50M_in)
                Sig_out_slow2fast_lvl_reg <= ~Sig_out_slow2fast_lvl_reg ;
            else
                Sig_out_slow2fast_lvl_reg <= Sig_out_slow2fast_lvl_reg ;
        end
    end

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_adj_reg0 <= 0 ;
            Sig_out_slow2fast_adj_reg1 <= 0 ;
           
        end
        else begin
            Sig_out_slow2fast_adj_reg0 <= Sig_out_slow2fast_lvl_reg ;
            Sig_out_slow2fast_adj_reg1 <= Sig_out_slow2fast_adj_reg0;
        end
    end

    always@(posedge Clk_50M_in or negedge Sys_rst_n)begin
        if(~Sys_rst_n)begin
            Sig_out_slow2fast_adj_reg2 <= 0 ;
            Sig_out_slow2fast_adj_reg3 <= 0 ;
        end
        else begin
            Sig_out_slow2fast_adj_reg2 <= Sig_out_slow2fast_adj_reg0 != Sig_out_slow2fast_adj_reg1 ;
            Sig_out_slow2fast_adj_reg3 <= Sig_out_slow2fast_adj_reg2;
        end
    end

    assign   Sig_out_slow2fast_dff2 = Sig_out_slow2fast_adj_reg3 ;

//-----------------------------------------------------------------------------
endmodule

image.png


扫描二维码推送至手机访问。

版权声明:本文由我的FPGA发布,如需转载请注明出处。

本文链接:https://world.myfpga.cn/index.php/post/244.html

分享给朋友:

“CDC 单脉冲信号处理” 的相关文章

3-8译码器

3-8译码器

译码:译码是编码的逆过程,在编码时,每一种二进制的代码,都赋予了特殊的含义,即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码,实现译码操作的电路称为译码器。译码器:一类多输入多输出的组合逻辑电路器件,其可以分为:变量译码和显示译码两类3-8译码器 模块框图:输出信号定义为...

半加器

半加器

半加器:两个输入数据位相加,输出一个结果位和进位,没有进位输入的加法器电路。即两个一位二进制数的加法运算电路。半加器 模块框图:sum:结果位count:进位半加器 真值表:半加器 波形图:代码部分:选择器代码:在Src文件夹中新建 half_adder.v文件module half_adder...

全加器(层次化设计)

全加器(层次化设计)

该篇博客根据上一篇半加器的设计,再结合层次化的设计思想来实现一个全加器!层次化设计理论部分:数字电路中根据模块层次的不同有两种基本的结构设计方法:自底向上的设计方法 和 自顶向下的设计方法自底向上(Bottom-Up)        自底向上的设计是一种传统的设计方法,对设计进行逐次划分的过程是从存...

FPGA时序分析和时序约束

FPGA时序分析和时序约束

时序分析:时序分析的目的就是通过分析FPGA设计中各个寄存器之间的数据和时钟传输路径,来分析数据延迟和时钟延迟之间的关系。一个设计OK的系统,必然能够保证整个系统中所有的寄存器都能够正确的寄存数据。数据和时钟传输路径是由EDA软件,通过针对特定器件布局布线得到的。时序约束:两个作用告知 EDA 软件...