FPGA 学习笔记——按键消抖中的亚稳态

(1) 理解亚稳态的两个前提

为了理解亚稳态的内涵,首先应该明确三个参数
  • t S U t_{SU} tSU:表示的是在时钟上升沿到来前数据需要保持稳定的最小时长。
  • t H t_{H} tH: 表示的是在时钟上升沿到来后数据需要保持稳定的最小时长。
  • t C O   ( c l o c k − t o − o u t p u t ) t_{CO}~(clock-to-output) tCO (clocktooutput):表示的是在这么长时间的延迟之后寄存器输出的数据就可以被读取了(即此时的输出数据是稳定的)。
  除此之外还应该明确在数字电路中学到的一个内容,就是逻辑 0 和逻辑 1 并不是指两个单一的电压值,实际上是一个范围。例如对 5V 的TTL电平输入在 0~0.8V 之间被认定为低电平 0 ,输入在 2~5V 之间会被认定为高电平 1,而输入在未定义的区间内就会成为未定态,也就是说会在 0 与 1 之间震荡,至于最后结果是什么就要看上帝的心情了。

(2) 理解亚稳态的内涵

  • 当输入没有在 t S U t_{SU} tSU 之前和 t H t_H tH 之后保持稳定而是在这段时间内发生变化,上升沿处的数据可能就会处于未定态。未定态的数据,一方面会导致最终输出的数据无法确定是 0 还是 1,另一方面会引起震荡并导致输出在 t C O t_{CO} tCO 的时间内无法稳定下来(这方面的破坏力远大于前面那个方面,所以最主要是要防范这方面情况的出现)。
  • 如果直接将这个输出结果输出到后端系统进行一定的操作就有可能导致后端系统的崩溃。设想这样一种情况,假如输出控制一个可以完全实时交易的股票买卖系统,0 表示卖出, 1 表示买进,那在几十纳秒甚至到几毫秒的时间内疯狂买进卖出可不是什么好事。

(3) 解决简单亚稳态问题的方法

       ~~~~~~       解决简单亚态问题(时钟频率不是很高的情况,对输入输出实时性的要求也不是很高)并不困难。具体操作就是在从异步的输入到系统的真实输入间增加两个或更多的同步寄存器。但是为什么这样就可以解决亚稳态问题? 我一开始也不是很清楚,只是知道书上都这样做,后来经过思考并且参考了一些文章后这里给出我个人的理解。

要理解这个问题就要从概率入手,下面给出关于这个问题定性的理解:

  • 情况一:产生亚稳态,但是亚稳态在下一个时钟上升沿到来的 t S H t_{SH} tSH 时刻前就已经稳定了。这样下一个寄存器就会输出一个稳定的逻辑(就算这个逻辑不一定是对的,但是不会因为逻辑的飘忽不定而使后级崩溃了)。这种情况是简单亚稳态问题中发生概率最大的情况。为了方便说明,这里假定这种概率为 95%。

  • 情况二:产生亚稳态,并且亚稳态在下一个时钟上升沿到来的 t S H t_{SH} tSH 时刻前还没有稳定。这样亚稳态的影响就会从第一个寄存器传导到第二个寄存器。概率仅为 5%。然后对于第二个寄存器就又会有以上的两种情况。从概率的角度来说,第三级寄存器得到稳定结果的概率为 99.75% 。因此从概率的角度考虑基本可以认为得到的结果是稳定的了

  • 具体的代码入下所示:

    module asy_to_syn(clk,rst_n,signal_in,signal_out);
    input clk;
    input rst_n;
    input signal_in;
    output  signal_out;
    reg state_tmp0,state_tmp1,state_tmp2;
    
    always@(posedge clk or negedge rst_n)
        if(!rst_n) begin
            state_tmp0 <= 1'b0;
            state_tmp1 <= 1'b0;
            state_tmp2 <= 1'b0;
        end
        else begin
            state_tmp0 <= signal_in;
            state_tmp1 <= state_tmp0;
            state_tmp2 <= state_tmp1;
        end
    assign signal_out = state_tmp2;
    endmodule
    

参考的文章是某个博客园大佬写的文章 FPGA中亚稳态——让你无处可逃

猜你喜欢

转载自blog.csdn.net/weixin_44618906/article/details/113373311