crazybird

【原创】边沿检测中需要注意的细节

0
阅读(3438)

    很多人看到这个标题的时候,都会想边沿检测不是很简单的吗?有什么需要注意的?它是很简单,只要对输入信号进行两级缓存,然后通过判断前后两级的逻辑来决定信号的上升沿或下降沿。但你们有没有想过当系统复位时应该给寄存器赋什么值?估计很多人都没有想过吧,管它三七二十一,一律赋0(或1)。那恭喜你,你已经掉进陷阱了。什么陷阱?误判的陷阱。举个例子,检测一个信号的上升沿,见如程序清单1所示:

程序清单1

/******************************************Copyright********************************************
**                                             CrazyBird
**                                 http://blog.chinaaet.com/crazybird
**
**----------------------------------------File Infomation--------------------------------------
** FileName     :       edge_detection.v
** Author       :       CrazyBird
** Data         :       2015-10-25
** Version      :       v1.0
** Description  :       the rising edge detection of signal
**                      
************************************************************************************************/
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module edge_detection 
(
    input           clk,
    input           rst_n,
    input           din,
    output          pos_flag
);
//------------------------------------
// Two levels of cache on the signal
reg                 din_r1;
reg                 din_r2;
always @(posedge clk or negedge rst_n)
begin
    if(rst_n == 1'b0)
    begin
        din_r1 <= 1'b0;
        din_r2 <= 1'b0;
    end
    else
    begin
        din_r1 <= din;
        din_r2 <= din_r1;
    end
end

//------------------------------------
//  rising edge detect
assign  pos_flag = din_r1 & ~din_r2;

endmodule
//*****************************************End File**********************************************

    这是一个超级简单的信号上升沿检测,相信很多人也是这样写。但你这样设计出来的东西是不稳定的。为什么?从理论上分析,当复位后,din_r1和din_r2d的值都为1'b0。如果输入信号din为1'b1,在时钟上升沿到来时,din的值会被锁进din_r1即din_r1=1'b1,而din_r1前一时刻的值被锁进din_r2即din_r2=1'b0。此时,并没有信号的上升沿到来,而pos_flag的值为1'b1,从而导致第一次上升沿是误判的。也可以从仿真波形中体现出来,如图1所示。

1.bmp

图1  导致第一次上升沿误判

    为了避免误判情况的出现,我们采取措施:对于信号上升沿检测,复位后寄存器应都赋值为1'b1。修改后的代码如程序清单2所示:

程序清单2

/******************************************Copyright********************************************
**                                             CrazyBird
**                                 http://blog.chinaaet.com/crazybird
**
**----------------------------------------File Infomation--------------------------------------
** FileName     :       edge_detection.v
** Author       :       CrazyBird
** Data         :       2015-10-25
** Version      :       v1.0
** Description  :       the rising edge detection of signal
**                      
************************************************************************************************/
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module edge_detection 
(
    input           clk,
    input           rst_n,
    input           din,
    output          pos_flag
);
//------------------------------------
// Two levels of cache on the signal
reg                 din_r1;
reg                 din_r2;
always @(posedge clk or negedge rst_n)
begin
    if(rst_n == 1'b0)
    begin
        din_r1 <= 1'b1;
        din_r2 <= 1'b1;
    end
    else
    begin
        din_r1 <= din;
        din_r2 <= din_r1;
    end
end
//------------------------------------
//  rising edge detect
assign  pos_flag = din_r1 & ~din_r2;
endmodule
//*****************************************End File**********************************************

    仿真结果如图2所示:

2.bmp

图2  上升沿正确检测

    同样,对于下降沿检测,复位时应将寄存器都赋值为1'b0,大家可自行验证。


    总结一下,上升沿检测,复位时寄存器应赋值为1'b1;下降沿检测,复位时寄存器应赋值为1'b0。*^_^*