前面的博文聊到了触发器的建立时间和保持时间:http://www.cnblogs.com/IClearner/p/6443539.html 那么今天我们来聊聊与触发器有关的亚稳态已经多时钟系统中的时钟切换。与亚稳态有关的问题比如跨时钟域的问题很快就会补充。今天的主要内容如下所示:
·亚稳态的产生与传输
·亚稳态的恢复时间与平均无故障时间
·减小亚稳态的建议
·多时钟切换电路
1、亚稳态的产生与传输
我们知道,交叉耦合反相器、SR锁存器、D锁存器和D触发器等存储元件有两个稳定的状态,即0和1,也就是能存储0和1这两个状态。那么亚稳态是什么呢?从字面上看,亚稳态就是亚于稳态,既0又不是1的状态。在时钟有效沿到来的前后,触发器的数据端的数据不稳定导致违反触发器的建立时间或者保持时间,引起触发器的输出处于未知的状态,这种未知的状态称为亚稳态。
我们知道了亚稳态是产生是由于违反了触发器的建立时间或者保持时间,那么为什么会有亚稳态呢?我们从底层的CMOS器件开始:
CMOS反相器的电平传输特性曲线如下所示:
在上面的图里面。我们把Vout=Vin的点叫做反相器的阈值电压。CMOS反相器的特性是,在阈值电压附近输出迅速完成了电平的切换,而在其他区域输出电平几乎不变。
对于输入,假设0~1V的输入是低电平,1.5V到2.5V是高电平;也就是说,反相器的输入在正常情况下要么是高电平,要么是低电平,那么反相器靠什么来识别它是高还是低了,就是靠输入电平的电压了;当输入信号在0~1V的时候,反相器识别为低,输入在1.5V~2.5V时反相识别为高输入。至于反相器的输入在1~1.5V的时候,这是没有定义的,也就是在阈值电压附近,反相器可能将它认为是高电平也可能认为是低电平。
对于输出,假设输出2.25~2.5V是高电平,0~0.25V是低电平。那么我们就从输入由0增大到2.5v的情况看看输出是怎么样的。当输入在0~1V时,反相器识别输入为低电平,根据电平传输特性曲线,输出基本大于2.25V,反相器输出为高电平(可能大于2.25V)。当反相器的输入从1过渡到1.5V的时候,反相器对这段的电压没有定义,比如输入为1.25V的时候,曲线对应的输出大概为1.25V,这是反相器就会迅速进行电平切换:可能进行高电平切换,认为这个输入是低电平于是对应的输出高电平;也有可能进行低电平切换,认为这个输入是高电平,于是对应输出低电平。因此在这段电压内,输出是高是低都有可能。当输入大于1.5V时,反相器识别为高电平,于是反相输出低电平。
当输入数据不满足寄存器的建立时间或者保持时间的时候,寄存器就很可能捕捉到输入数据的电平在未定义的电平区间,输出处于亚稳态(并不是所有未满足建立时间或者保持时间都会产生亚稳态!)。我们就拿上一篇博客中所描述的D触发来说明一下,该触发器电路结构(链接:https://www.cnblogs.com/IClearner/p/6443539.html)如下图所:
当建立时间不满足的时候,也就是数据端D的数据来得太晚了,使得 输入电压 或者 主D锁存器内部的线路电压 处于阈值电压附近,就可能会使主D锁存器不能正确输出,之后的从锁存器也不能正确输出,即输出Q处于亚稳态:输出电压可能处于阈值电压附近,也可能处于高电平,也可能处于低电平,也可能是在高低电平之间震荡(因为反相器具有电平切换功能),总之我们无法预测输出具体是哪一种稳定的电平状态。
同理,当保持时间不满足的时候也是一样,也会使主锁存器内部的线路电压不足以使门器件/反相器进行翻转/工作,也会导致亚稳态。
亚稳态用一个经典的图表示如下所示:
山顶就是亚稳态,这是数字逻辑中存在的一种状态,在这个状态下,触发器/寄存器的输出可能为毛刺或者某一未定义的电压值(电压值在高低电平之间波动),反正基本不是正确的输入值。
亚稳态是器件的固有属性,不能消除,只能从概率上减少这一状态的发生。
2、亚稳态的恢复时间与平均无故障时间
亚稳态除了可以用上面的那个图表示外,还可以用下面的时序图表示:
红色段就是处于亚稳态的输出段。我们再来看看这幅图,本来经过一定的延时值tco之后就会输出正确的稳定的电平值;由于产生了亚稳态,亚稳态持续了tMET时长后,恢复到稳定的电平状态(稳定,但不一定是正确的!),这段持续的时间叫做亚稳态的恢复时间,一般情况下这段时间不会超过一个或者两个时钟周期(取决于触发器的性能)。如果亚稳态持续时间过长(超过一个或者两个时钟周期),就有可能被下一级的触发器捕获,导致下一级触发器也处于亚稳态,这就是亚稳态的传播现象,这是很严重的。
触发器处于亚稳态可能会使系统产生故障,故障发生率的倒数叫做平均故障时间(MTBF,mean time before failure),平均故障时间越长,系统越稳定。在这里,我们不讨论平均故障时间怎么来的,我们了解平均故障时间的公式是什么,然后与哪些因素有关就OK了:
也就是说,故障发生的几率为:
其中:
·C2是一个与器件有关的常数,器件的建立时间和保持时间越小,C2越小。(--->使用更快的触发器)
·C1也是一个与器件相关的常数。
·fclk1是前级的时钟,fclk2是后一级电路的时钟(这里涉及到时钟域了),反正就知道与时钟有关就可以了。(--->降低系统的工作频率)
·tslack是时序裕量,可以理解为触发器喘息的时间。(--->使用同步器)
由此可见,时钟越快,越容易发送故障。
3、减小亚稳态的建议
亚稳态是不可避免的,但是我们可以减少亚稳态的发生和传播,从上面的内容中可以,我们有以下减少亚稳态的建议
·使用同步器;同步器在跨时钟域中会进行讲解,使用同步器可以减少采样异步信号导致的亚稳态。
·在满足要求的情况下,降低时钟频率。从上面的式子中可以知道,降低时钟频率,可以降低故障的发生率。
·采用反应更快的触发器。上面的式子中的常数跟触发器有关,如果有更快的触发器,同样可以减少亚稳态的产生。
·减少使用或者避免使用那种信号翻转时间很长的输入信号,如果翻转时间长,那么进入器件未定义的电平的时间也很长,容易导致亚稳态的产生。
当然还有其他减少亚稳态产生的方法,这里只是列出了典型的、常见的集中方法而已。
4、多时钟切换电路
为了承上启下,这里聊一下多时钟切换电路,承接亚稳态的问题,也是为以后的跨时钟域做一些铺垫,反正就是两边沾呗...
在前面的一篇博文:数字设计中的时钟与约束,链接如下:http://www.cnblogs.com/IClearner/p/6440488.html 提到了多时钟切换的问题,如下所示:
时钟在切换的时候难免会产生毛刺,这里就来聊聊如何把这个时钟切换产生的毛刺减少(甚至消灭)的典型电路,而不是要求时钟切换的时候寄存器要处于复位的情况(当然寄存器复位也是双重保险的措施)。
首先,我们来看看毛刺产生的根源:在clk1的高电平的时候进行切换,如果此时clk2正好为高电平,这时候clk2和clk1的高电平可能占空比变大也可能使占空比变小,总的来说有可能产生毛刺。在clk1的高电平的时候进行切换,如果此时clk2正好为低电平,那么肯定产生毛刺,因此这不能这样切换。从Clk2切向clk1也是这么一个原理。于是我们就有下面的结论:
电平相反的时候切换时钟,肯定有毛刺;电平相同的时候,有可能产生毛刺。这里我们关注低电平上产生的毛刺,同为高电平的时候切换,有可能产生毛刺,影响了上升沿,因此我们就选择在两者都是低电平的时候进行切换。根据这个选择方案,切换过程就是:A 先是选择信号改变(即进行时钟切换),B 然后clk1(或clk2)为低时停掉clk1(或clk2)的选择 ,C 接着在clk2(或clk1)为低时打开clk2((或clk21)的选择端,D 最后进行正常工作,完成切换。
至于这么设计这个电路呢?一个思路是使用状态机,但是这似乎不太现实,要是使用状态机,还得再要一个更高频率时钟最为状态寄存器的驱动时钟。除了状态机之外,前辈们给我们设计了这样的一个电路,使用负边沿触发的寄存器,设计的电路如下所示:
如何构思这个电路,下面这个链接的博客讲得挺好的了:
http://electron64.blog.163.com/blog/static/106033970201205103533471/
我就来分析这个电路是怎么工作的吧,反正我们大多数是用而已:
分析如下图所示:
当然,这个是波形是没有输出延时和转换延时的。从波形图里面可以看出,这个时钟切换电路理论上是没有毛刺的。