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

CDC 单脉冲信号处理

chanra1n3年前 (2022-04-22)FPGA3934

代码中的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            : chenyu@myfpga.cn
// 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            : chenyu@myfpga.cn
// 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            : chenyu@myfpga.cn
// 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://myfpga.cn/index.php/post/244.html

分享给朋友:

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

Intel FPGA初级考试模拟试题 四套含答案

Intel FPGA初级考试模拟试题 四套含答案

*1.下列对异步信号进行同步的描述错误的是(使用锁存器)。采用保持寄存器加握手信号的方法特殊的具体应用电路结构,根据应用的不同而不同使用锁存器异步 FIFO *2.FPGA 的可编程是主要基于什么结构(查找表(LUT))。查找表(LUT)ROM 可编程PAL 可编程与或阵列可编程解析:FP...

ALGO C4MB V11引脚参照表(持续更新)

ALGO C4MB V11引脚参照表(持续更新)

功能:常用引脚CLKPIN_E1LED0PIN_G15LED1PIN_F16LED2PIN_F15LED3PIN_D16KEY1PIN_E15KEY2PIN_E16KEY3PIN_M15KEY4PIN_M16RXDPIN_M2TXDPIN_G1功能:VGA引脚VGA_BLUE[0]PIN_C15VG...

基础实验十三,DS18B20温度传感器

基础实验十三,DS18B20温度传感器

//==========================================================================// Author     : ChanRa1n// Description: Training for Intel FPGA/...

Xilinx FIFO和ILA学习

Xilinx FIFO和ILA学习

`timescale 1ns / 1ps//-------------------------------------------------------//Filename       ﹕ FIFO_TOP.v//Author      ...