原创 异步复位时亚稳态危害的例子

2011-8-8 01:47 1570 0 3 分类: FPGA/CPLD

下面是一个异步复位危害的例子,这是我自己想了好久才想出来的,不对的地方请高手指出。

代码很简单,就是一个计时器,设置了一个8位的定时计时器counter(也可以是更多的位),复位的时候counter0,复位释放时counterCLK作用下开始自加1

ssssalways @(posedge clk or negedge rst_n)

 

   if(!rst_n) counter<= 8'b0;

   else begin

       counter<=counter+1'b1;

       rst_sync<=counter;

   end

如果正常复位的话,counter[7:0]8个触发器都会在复位释放后从0开始计数,但如果异步复位导致寄存器处于亚稳态,触发器的输出端Q7:Q0就处于一个不确定的状态,可能有的是0,有的是1,就像下图一样,这样子当下一个CLK到来的时候,counter[7:0]就不是从0开始自加1,而是有可能从0-255的任意一个数开始加1

20110808014731001.jpg

显而易见,如果后级模块需要靠这个counter精确定时序,肯定会产生错误。

如果只有一个触发器,其输出端Q做下一级模块的启动标志位,复位时Q=0,在复位释放时处于亚稳态,本应该输出还为0,但如果错误的输出1,导致下一级模块启动,再接着会导致后级出现更多的问题。 

? 复位亚稳态的解决

复位亚稳态的问题看来都是因为触发器输出端处于不确定状态导致的,而解决思路就是使其复位释放时输出处于确定状态,其实就是使用异步复位同步释放的办法。

从网上的设计来看主要有两种电路:

? 电路1

input         CLK,RSTn;

output        rstn_r2;

 

reg           rstn_r1,rstn_r2;

 

always@(posedge CLK or negedge RSTn)

    if(!RSTn) rstn_r1<=1'b0;

    else rstn_r1<=1'b1;

 

always@(posedge CLK or negedge RSTn)

    if(!RSTn) rstn_r2<=1'b0;

    else rstn_r2<=rstn_r1;

其综合出来的RTL视图为:

20110808014732002.jpg

上图使用rstn_r2作为后级的复位输出,为什么它能实现正常复位呢,我开始时百思不得其解,因为我犯了两个错误:

1错误地认为对于单级的异步复位,即使在RST释放时处于当前时钟的上升沿而导致触发器输出亚稳态,比如触发器要输出1但是因为亚稳态输出0,但是到下一个CLK不就输出1了吗?

——这种分析没有考虑周全,如果一个边沿检测寄存器 (触发器)作为下一个的标志位,要求在复位时为0,复位释放后如果边沿检测输入没有下降沿则要求输出为0,只有在有下降沿输入时其触发器输出才为1,而如果触发器因为亚稳态在复位释放时就输出为1,则会错误置边沿检测标志位为1,导致后级认为发生了边沿下降。

2错误地把理想状态和实际状态混到一起了,我认为rstn_r2复位释放上升到1的期间正好在CLK上升沿,那么这个给后一级的复位也会处于亚稳态。

——其实不是这样的,rstn_r2复位释放上升1的期间正好在CLK上升沿是理想状态下的时序,理想状态下这样完全可以正常让后级复位,因为就算是单级的异步复位在理想状态时,如果CLKRSTn上升沿完全重合也可以正常复位(这是从RTL仿真看出来的),让我们来看看实际状态的时序图。

20110808014732003.gif

异步复位信号RSTn在任意时间释放,

假设正好在CL1的上升沿释放,则触发器rstn_r1处于亚稳态,在CLK=1时错误输出为0

直到CLK2来到后正确检测到RSTn=1才使rstn_r1正确输出1rstn_r1要比CLK延迟Tco1,此时rstn_r2因为非阻塞赋值还是为0

CLK3到来时正确检测到rstn_r11,所以rstn_r2正确输出为1rstn_r2要比CLK延迟Tco2,如果理想状态下rstn_r2CLK是同时上升的,但是在实际状态下触发器输出总比CLK延迟Tco时间,所以这个rstn_r2作为下一级的复位端不会和当前CLK同时上升,因此不会出现亚稳态,下一级的复位释放要到CLK4来到才能释放。

这样就保证了复位释放时触发器处于稳定状态。

? 电路2:先把RSTn和时钟同步一下

input         d,CLK,RSTn;

output        q;

reg           q,rstn;

 

always@(posedge CLK)

    if(!RSTn) rstn<=1'b0;

    else rstn<=1'b1;

   

always@(posedge CLK or negedge rstn)

    if(!rstn) q<=1'b0;

    else q<=d;

其综合出来的RTL视图如下:

20110808014732004.jpg

上图首先用触发器把RSTn同步一下,采用触发器输出端rstn作为下一级的复位端, 时序图如下;

20110808014735005.gif

CLK0时,复位还没结束,RSTn,rstn,q都还处于复位状态;

CLK1时,RSTn复位释放,对于触发器rstn其输入是处于亚稳态,按照错误触发就是rstn输出为0

CLK2RSTn已经稳定,rstn经过Tco1延时后输出正常为1,当然这时候的CLK2已经在上升沿之后不能检测rstn,而rstn作为触发器q的复位端在CLK3到来之前就已经保持稳定,即处于CLK3TsuTh之外;

所以CLK3来到时触发器q能正确复位。

? 总结

    从上面的两个例子可以看出只要使用同步器把RSTn同步,就可以使RSTn在释放时输出的rstn端落在CLKTsuTh之外,保证CLK采样时处于稳定状态。

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1851850 2016-5-20 16:59

看了你的 终于懂了。

用户541503 2011-10-19 14:29

上面的分析貌似遗漏了一点: rst_r1没有出现亚稳态,而rstn_r2出现亚稳态

用户1634340 2011-8-27 13:27

学习下

用户238107 2009-12-2 13:15

顶一下
相关推荐阅读
用户1064897 2011-08-08 01:51
Always过程块语法
★   Always过程块语法: always过程块是由always过程语句和语句块组成的,语法格式如下: always @ (敏感事件1 or 敏感事件2 or 敏感事件3…….) 语句块   ...
用户1064897 2011-08-07 23:35
亚稳态2——异步复位时亚稳态产生的影响
——摘自异步复位设计中的亚稳态问题及其解决方案 Trecovery ( recovery time) 指的是原本有效的异步复位信号释放(对低电平有效的复位来说就是上跳沿) 与紧跟其后的第一个时钟有效...
用户1064897 2011-08-07 23:28
初步理解亚稳态1——多看E文才是正道
    这是转发特权同学的翻译《 Understanding Metastability in FPGAs 》,加入了一些自己的理解 所有数字器件(例如FPGA)的信号传输都会有一定的时序要求,...
用户1064897 2011-07-24 22:58
FIFO的使用注意
一个最简单的FIFO如下图: 左图包括数据输入data[7:0],输出q[7:0],写请求wrreq,读请求rdreq,时钟clock,FIFO满标志位full,有的还有FIFO空标志位empty...
用户1064897 2011-07-24 22:55
Altera器件型号指南
1.    其型号编号方式EP1C代表Cyclone器件,EP2C代表Cyclone II,EP3C代表Cyclone III,EP4C代表Cyclone IV,EP5C代表Cyclone V 2....
我要评论
3
0
关闭 站长推荐上一条 /3 下一条