脉冲边沿检测的亚稳态处理
脉冲边沿检测的亚稳态处理
转载请注明出处:http://blog.****.net/kevin_hee/article/details/78021443
一、原理
脉冲边沿检测是一个异步系统设计中常常会使用到的方法。
假设有一个系统,时钟域A是50MHz的时钟域,它有一个待检测的变化信号test;
存在时钟域B,利用此时钟来检测时钟域A中test信号的上下沿。
现在需要分两种情况讨论:
1)假设时钟域A的变化信号test变化得非常快,最大快到和50MHz的时钟一样快(把test想象成时钟)。这个时候时钟域B的时钟频率,按照采样定理,必须大于等于两倍50MHz,即时钟域B的时钟频率大小必须大于等于100MHz。
2)第二种情况就是test变化得非常慢,比如视频显示信号中的DE信号,在像素频率下显得变化得非常慢。这个时候时钟域B去采样test的上下边沿,就不需要遵循采样定理。这个时候时钟域B的时钟频率的大小甚至可以小于50MHz(当然可能没人会这样设计),都能正确的采样到test的上下边沿。
二、采样过程中的亚稳态
无论test是变化得很快还是很慢,时钟域B的采样时钟在采样的时候,如果正巧碰到或接近test变化的边沿,就会遭遇亚稳态。
如上图所示,D(test)的变化边沿正巧处于CLK采样时钟的Tsh/Th时间内,导致建立或保持时间违例,出现亚稳态(图中Tmet称为决断时间)。
可以预见,test变化得越快,亚稳态出现的概率越大。
而亚稳态的结果就是,Q端输出的结果是随机的、非预期的、不受控制的。
三、亚稳态的影响
一般的系统设计都存在复位的信号(这里说的复位不一定指全局复位,也是指局部的模块、逻辑复位),可以让系统从亚稳态导致的错误中恢复过来。
所以可以分为两种情况讨论。
1)后续逻辑受采样结果的影响时间很短。在正确的逻辑设计中,因为亚稳态出现的概率一般来说是远远小于正常预期结果的概率的。所以在短时间内设计虽然采样遭遇了亚稳态,并且输出了错误的结果。但是系统能很快从错误中恢复,受错误结果的影响很小。这种情况采样亚稳态似乎是可以接受的。
2)第二种就是一个非常糟糕的情况,后续逻辑受采样结果的影响时间很长。这个时候,亚稳态导致的错误输出结果对后续逻辑的影响可能是致命的,系统需要很长时间才能从错误中恢复过来。
四、处理亚稳态
实际上异步系统中消灭亚稳态基本是不可能的(以我的设计经验来说的),亚稳态总会发生并导致错误的结果产生。只能是减少并消灭亚稳态产生的错误结果的影响。
之前的设计中,对于异步时钟域的脉冲边沿检测是采用的常用的方法。
首先用第一级寄存器做同步(这里示例打一拍,推荐打两拍),然后再用两级寄存器做边沿检测。
大致代码如下:
always@(posedge clk) begin sync<= test; reg_r<= sync; reg_n<= reg_r; end assign rise_t= reg_r&(!reg_n); //上升沿检测 |
其中test为输入的待检测信号,sync为第一级同步寄存器。reg_r和reg_n为两级寄存器检测test的上升沿。
这段代码中,亚稳态就出现在sync寄存器上。sync输出错误的结果,就将导致rise_t错误的拉高一个周期。
如何减少并消灭sync寄存器错误给后续逻辑带来的影响呢?可以采用下面示例代码的做法(参考特权的写法):
always@(posedge clk) begin sync<= test; reg_r1<= sync; reg_r2<= reg_r1; reg_r3<= reg_r2; reg_r4<= reg_r3; end assign rise_t= reg_r1®_r2&(!reg_r3)&(!reg_r4); |
同样是用sync先做一级同步寄存,然后使用了四级寄存器来寄存sync输出的结果。最后在判断上升沿的时候用四个寄存器做逻辑判断。
实际工程中表明这种简单的方法可以有效的减少亚稳态导致的错误结果给后续逻辑带来的影响(在实际工程中,代检测的信号变化率相对很慢。而设计需要对这个信号的下降沿进行采样计数,然而最初实际的结果为计数远远大于预期的值。因此判断旧的检测方法或许是因为亚稳态问题,将上升沿也判断成了下降沿,因此计数变大。在使用四级寄存器做逻辑判断后,计数达到了预期值,且计数并没有减少。当然,也有可能会减少的,因为下降沿也会遇到亚稳态)。