备战秋招[二]-亚稳态与同步器

欢迎关注个人公众号摸鱼范式

------------------------------------------

版权声明:

本文作者: 烓围玮未

首发于知乎专栏:芯片设计进阶之路

转发无需授权,请保留这段声明。

------------------------------------------

亚稳态

随着芯片设计越来约复杂,功耗问题越来越成为首要问题,单纯的单时钟芯片已经是一种奢望,大部分芯片都会由多个甚至几十上百个异步时钟驱动。只要有多个时钟,就会碰到跨时钟域(Clock Domain Crossing, CDC)信号处理的问题,那么首先要考虑的就是亚稳态。

什么是亚稳态

亚稳态是指在设计的正常运行过程中,信号在一定时间内不能达到稳定的0或者1的现象。在多时钟设计中,亚稳态是不可避免的,我们可以减少亚稳态发生和传播,消除亚稳态的有害影响。下面是一个亚稳态的例子:

上图显示了当在一个时钟域(aclk)中生成的信号adat被送到了另一个时钟域(bclk)中采样,由于采样时间太靠近第二个时钟的上升沿时,发生的同步失败。同步失败是由于输出bdat1变为亚稳态,而在bdat1再次被采样时没有收敛到合法的稳定状态。

为什么会产生亚稳态

存储元件如交叉耦合反相器、SR锁存器、D锁存器和D触发器等都有两个稳定的状态,即0和1,也就是能存储0和1这两个状态。亚稳态就是既不是0又不是1的状态,或者说可能0也可能是1,不能确切知道它的状态。为什么会出现亚稳态呢?这是因为我们在分析元器件时,是把元器件抽象为理想器件以简化分析,但实际的元器件并不是理想的。比如对于一个理想的CMOS反相器的电平传输特性如下所示:

理想CMOS反相器的电平传输特性

可以看到,在0<VIN<V+/2时,VOUT=V+; 在V+/2<VIN<V+时,VOUT=0;

这里理想化的是这个变化过程,刚好在V+/2这个点就能瞬时完成“突变”,界限十分分明。但是实际上不可能是这样的,变化是有一个过程的,这种理想的器件现实世界是生产不出来的。实际的CMOS反相器电平传输特性如下:

实际CMOS反相器的电平传输特性

可以看到:

在0<VIN<VIL时,VOH<VOUT < Vmax;

在VIH<VIN<V+时,Vmin<VOUT <VOL;

在VIL<VIN<VIH时,VOUT=VIN; (VOL<VOUT<VOH)

如果后一级的判断电路把低于VOL的电压判断为0,把高于VOH的电压判断为1,那么在输入为VIL~VIH这个范围的电压产生的VOUT后一级的电路就不能判断当前是0还是1,有可能是0,也有可能是1,不能准确预测它的输出。

补充一下,数字化电路都是二值化的,只有0和1,理想情况下,如果输入电压高于Vth那么就是1,如果低于VH就是0,Vth叫做判断阈值。但是实际情况往往不是这样的,没有一个点来作为分界线,实际的电路做不出来。实际上是高于VH才算1, 低于VL才算0, VH>VL,也就是说高阈值VH和低阈值VL之间是有一段距离的。

结合上面的分析,我们很容易就知道,数字信号跳变,0->1 或者 1->0,对应的是电压的变化,实际情况下,这个变化需要时间的。如果输入信号刚好在寄存器不能判断的区间(VL~VH),那么,输出就不能判断是0还是1,也就是亚稳态。

也就是说当输入数据不满足寄存器的建立时间或者保持时间的时候,寄存器就很可能捕捉到输入数据的电平在未定义的电平区间,输出处于亚稳态。

这里的建立时间和保持时间,就可以粗略的看作电压变化到VL或者VH所需要的时间。

不是每个违反寄存器建立保持时间的信号翻转都会导致亚稳态。一个寄存器进入亚稳态和从亚稳态进入稳态的时间依赖于制造商的制造工艺和使用环境。大部分情况下,寄存器会很快的进入一个定义的稳态中。

亚稳态的危害

由于亚稳态的输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值,因此亚稳态除了导致逻辑误判之外,输出0~1之间的中间电压值还会使下一级产生亚稳态(即导致亚稳态的传播)。 逻辑误判有可能通过电路的特殊设计减轻危害(如异步FIFO中Gray码计数器的作用),而亚稳态的传播则扩大了故障面,难以处理。

电平信号的逻辑误判一般只会对电路造成几个时钟的延时,后面还会稳定在需要的电平,不会造成逻辑错误。

亚稳态信号的稳定时间通常比一个时钟周期要短得多,一般情况下不会超过一个或者两个周期, 这取决于触发器的性能。如果亚稳态超过一个或者两个周期,那么就会被下一个触发器采样到,这样就会造成亚稳态的传播。如下图所示

上图中,bdat1的亚稳态在下一个时钟沿还没有稳定,就造成了亚稳态的传播。这里可以选择更快的触发器,减少亚稳态收敛的时间。

亚稳态的量化公式

由于我们不能完全消除亚稳态问题,因此必须做好解决问题的准备。为此,设计人员采用平均故障间隔时间 (MTBF:mean-time-between-failure) 这个指标来估算从问题出现并导致故障的两个事件间的平均时间。MTBF 值越高,就说明设计的稳定性越高。如果发生了“故障”,只是说明没有解决亚稳态问题,而并不是系统本身真的出现了故障。我们可用以下方程式计算出寄存器的 MTBF:

公式中,C1 和 C2 代表寄存器技术相关常数,tMET 代表亚稳态的稳定时间。

C2是器件相关的常数,器件的建立时间和保持时间越小,C2越小,MTBF就越大。所以可以通过选择更快的触发器,来减少亚稳态发生的概率。

不考虑器件本身的影响,对同一个触发器,MTBF可以简化为:

可以看到,数据变化频率越小,采样时钟越低,MTBF越大。

公式的推导这里就不详细论述了。

减少亚稳态的方法

亚稳态是不可避免的,这是器件的固有属性,并没有理想器件。但是我们可以减少亚稳态的发生和传播,避免亚稳态带来的消极影响。只要遵循一定的规则,即使如CPU/GPU这些超级规模的芯片,都能做到Zero-bug。

减少亚稳态的方法有以下几种:

  1. 使用同步器:也就是我们常用的2级或者多级FF打拍的方法;同步器后面会专门论述;
  2. 降低频率:如果能满足功能要求,那么降低频率能够减少亚稳态的产生;
  3. 避免变化过快或者过于频繁的信号进行跨时钟采样;
  4. 采用更快的触发器:更快的触发器,也可以减少亚稳态的产生。

从上面几条可以看到,在RTL设计中比较常用的是使用同步器。

同步器

当信号跨时钟域时候,最容易忽视的一个问题是,这个信号需要每个时钟都被采样,不能漏掉每一个值吗?这是新手最容易忽视的一个问题。

信号跨时钟边界,一般有两种场景:

  1. 信号跨时钟边界,可以漏掉某些值;
  2. 信号跨时钟边界,不能漏掉任何值。

大部分都是第一种场景,忽略这个问题的大部分也是默认是第一种场景。比如一个enable信号,跨时钟后,在另外一个时钟域中,是第5个cycle生效还是第6个cycle生效,其实我们并不关心。几个cycle的延时,在大部分跨时钟域的设计中,并没有影响。

当然还是有第二种场景的存在,比如一个连续计数的counter值,需要跨时钟域,那么在另外一个时钟中就不能漏掉值,否则功能就不正常了。这种情况需要考虑的是,为什么需要把这种信号跨时钟,能否在目标时钟域来进行计数。如果一定要使用这种信号,那么就需要进行握手的设计,来保证目标时钟域不漏掉任何值。

两级触发同步器

最简单和最常用的同步器就是两级FF同步器,如下图所示:

如图所示,bclk的第一级FF输出发生亚稳态,亚稳态维持了一个周期,并在下一个时钟上升沿稳定,被识别为高,这样第二级的FF就能正确的将adat采样到了bq2_dat。但是另外两种种可能:

  1. 如果亚稳态维持的时间不止一个周期,在下一个时钟上升沿没有稳定,那么第二级的FF就也会进入亚稳态。那么这种情况的概率是多少呢?就是我们上面描述的1/MTBF。

  2. 第一级的亚稳态在下一个时钟上升沿稳定,但是被识别为0,那么第二级的FF输出bq2_dat就是0,说明信号跨时钟采样失败。但是这种情况不会造成亚稳态的传播,也就是不会影响后面的设计。针对这种情况,我们一般会改变设计,不会让快时钟域的单cycle脉冲,跨时钟到慢的时钟内采样。

那么第一种情况发生的概率或者说MTBF是多少呢?有文献给出的数据:对于一个采样频率为200Mhz的系统,不做同步MTBF是2.5us,一级DFF同步的MTBF大概是23年,两级DFF同步的大约MTBF大概是640年;虽然不同设计不同工艺的MTBF有些区别,但是对大部分设计来说,两级FF同步器足够了。

三级或多级同步器

在高速,超高速设计种,两级的MTBF可能还不够;或者针对重点信号,为了保险会采样三级或多级同步器。注意,2级FF和3级FF的MTBF计算公式如下:

可以看到,3级FF的MTBF是2级FF的MTBF的=7倍。

一般情况下,2级FF的同步器都是足够的。但是要注意的是MTBF不可能是无穷大,也就是说亚稳态发生的概率(1/MTBF)不可能是0,所以即使用一万级的FF来做同步,还是可能会发生亚稳态。但是,工程设计不可能因噎废食,只要能保证使用中发生的概率足够小就可以了。

同步器的输入:源时钟寄存

采用同步器还有另外一个要求:通常,需要跨时钟的信号,需要在源时钟域先经过一级FF进行寄存输出。也就是说,跨时钟信号必须是寄存器的输出,中间不能有组合逻辑。还是刚才的电路,如果输入不是寄存器的输出,而是组合逻辑的输出那么情况会是怎样的呢?如下图所示:

可以看到,adat是组合逻辑的输出,变化的频率更快了,根据MTBF公式:

数据变化太快,会减小MTBF,增加亚稳态发生的概率。如果adat是FF的输出,那么根据FF的特性,输出在一个时钟周期内是不会改变的,数据的变化频率不会超过时钟频率,这样就能降低跨时钟信号变化的频率,减小亚稳态发生的概率,如下图所示:

所以,在使用同步器同步信号时,要求输入信号必须是源时钟域的寄存输出

这一点是很容易犯错和很多老手容易忘记的,只有理解了其中的原理,才能明白为什么要这么做,才会在使用的时候不会犯错。

原文地址:https://www.cnblogs.com/icparadigm/p/12794422.html