边沿检测原理

Posted bobuddy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了边沿检测原理相关的知识,希望对你有一定的参考价值。

目录
一、边沿检测原理
1、边检测原理(同步)
2、边检测原理(异步)
二、同步Verilog实现
一、边沿检测原理
1、边检测原理(同步)

上升沿就是从0到1变化的过程,而同步边沿检测就是使用一个基准时钟,来检测另外一个信号的上升沿。这种检测方法适用于被检测信号的最大频率小于基准时钟的频率


如上图,当第一个时钟上升沿来到,检测到输入信号为低0,下一个上升沿来到检测到高1,则检测到上升沿。

下降沿同理

如上图,当第一个时钟上升沿来到,检测到输入信号为高1,下一个上升沿来到检测到低0,则检测到下降沿。

如果被检测信号的最大频率大于基准时钟的频率就会发生如下的问题,可能会检测不到

如上图,当第一个时钟上升沿来到,检测到输入信号为低0,下一个上升沿来到检测到还是低0,但是输入信号在两个时钟上升沿之间是有上升沿的。出现了检测不到的问题。

这时就需要异步边沿检测

2、边检测原理(异步)
异步边沿检测是利用D触发器来实现边沿检测。适用于任意频率(只要不超过D触发器的触发范围)。这种检测方法常用于被检测信号的最大频率大于基准时钟的频率。

相当于把输入信号当成时钟,核心Verilog代码如下:

input                    singal_in;

output            reg        Y_p;
output            reg        Y_n;

// 检测上升沿
always@(posedge singal_in)begin
    if(singal_in)
        Y_p <= 1;
end

/ 检测下降沿
always@(negedge singal_in)begin
    if(!singal_in)
        Y_n <= 1;
end


二、同步Verilog实现
`timescale 1ns / 1ps

module edge_detection(
    input                    clk,
    input                    rst_n,
    input                    signal_in,
    
    output                    Y_p,            // 检测到上升沿输出1,否则0
    output                    Y_n                // 检测到下降沿输出1,否则0

    );
    
    reg            [1:0]        Y_p_g;
    reg            [1:0]        Y_n_g;
    
    assign Y_p = (!Y_p_g[1]) & Y_p_g[0];
    assign Y_n = Y_n_g[1] & (!Y_n_g[0]);
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            Y_p_g <= 2'd0;
            Y_n_g <= 2'd0;
        end
        else begin
            Y_p_g[0] <= signal_in;
            Y_p_g[1] <= Y_p_g[0];
            Y_n_g[0] <= signal_in;
            Y_n_g[1] <= Y_n_g[0];
        end
    end

endmodule


testbench文件

`timescale 1ns / 1ps

module edge_detection_tb();
    
    reg                    clk;
    reg                    rst_n;
    reg                    signal_in;
    
    wire                Y_p;
    wire                Y_n;
    
    initial begin
        clk = 0;
        rst_n = 0;
        singal_in = 0;
        #30;
        rst_n = 1;
    end
    
    always #10 clk = ~ clk;
    
    initial begin
        #45 signal_in= 1;
        #37 signal_in= 0;
        #29 signal_in= 1;
        #37 signal_in= 0;
        #100 $stop;
    end
    
    edge_detection edge_detection(
        .clk                (clk),
        .rst_n                (rst_n),
        .signal_in            (signal_in),
        
        .Y_p                (Y_p),
        .Y_n                (Y_n)
    );
    
endmodule


在代码中,有这几行代码


我们取其中的Y_p_g和Y_p来说

触发电路如下


假设signal_in 的输入情况,假设先输入0,再输入1
第一个上升沿来到,signal_in赋值给Y_p_g[0] = 0,此时Y_p_g[1]为默认状态,不管;
第一个上升沿来到,signal_in赋值给Y_p_g[0] = 1,此时Y_p_g[0]的值赋值给Y_p_g[1] = 0;


此时Y_p = 1;下降沿原理一样。
 

以上是关于边沿检测原理的主要内容,如果未能解决你的问题,请参考以下文章

verilog 按键消抖 vs 边沿检测

STM32——输入捕获实验原理及配置步骤

边沿检测电路

FPGA基础入门篇 边沿检测电路

边沿检测电路设计verilog

边沿检测电路设计verilog