搞定亚稳态
什么是亚稳态
所有数字器件(如 FPGA)的信号传输都会有一定的时序要求 ,从而保证每个寄存器将捕获的输入信号正确输出。 为了确保可靠的操作 ,输入寄存器的信号必须在时钟沿的某段时间(寄存器的建立时间Tsu)之前保持稳定.并且持续到时钟沿之后的某段时间(寄存器的保持时间Tb)之后才能改变,而该寄存器的输入反映到输出则需要经过一定的延时(时钟到输出的时间Tco)。如果数据信号的变化违反了Tsu或者Th的要求,那么寄存器的输出就会处于亚稳态。此时,寄存器的输出会在高电平1和低电平0之间盘旋一段时间,这也意味着寄存器的输出达到一个稳定的高或者低电平的状态所需要的时间会大于Tsu。 在同步系统中 ,输入信号总是能够达到寄存器的时序要求,所以亚稳态不会发生。 亚稳态问题通常发生在一些跨时钟域信号的传输上。 由于数据信号可能在任何时间到达异步时钟域 的目的寄存器,所以设计者无法保证满足Tsu和Th的要求。 然而,并非所有违反寄存器的Tsu或Th要求的信号都会导致输出亚稳态。某个寄存器进入了亚稳态后重新回到稳定状态的时间取决于器件的制造工艺与工作环境。在大多数情况下,寄存器将会快速地返回稳定状态。 寄存器在时钟沿采样数据信号好比一个球从小山的一侧抛到另一侧。如图2.49所示,小山的两侧代表数据的稳定状态一旧的数据值或者新的数据值;山顶代表亚稳态。如果球被抛到山顶上,它可能会停在山顶上,但实际上它只要稍微有些动静就会滚落到山底。在一定时间内,球滚得越远,它达到稳定状态的时间也就越短。 如果数据信号的变化发生在时钟沿的某段时间之后(Th),就好像球跌落到了小山的“old dala value”一侧,输出信号仍然保持时钟变化前的值不变。如果数据信号的变化发生在时钟沿的某段时间(Tu)之前,并且持续到时钟沿之后的某段时间(Tb)都不再变化,那就好像球跌落到了小山的“new data value”一侧,输出数据达到稳定状态的时间为Tco。然而,当一个寄存器的轮入数据违反了Tsu,或者Th,就像球被抛到了山顶,如果球在山顶停留得越久,那么它到达山底的时间也就越长,这就相应地延长了从时钟变化到输出数据达到稳定状态的时间(Tco) 。 图2.50很好地阐释了亚稳态信号。在时钟变化的同时,寄存器的输入数据信号也处于从低电平到高电平的变化状态,这就违反了寄存器的Tsu要求。图中的输出信号从低电平变化到亚稳态,即盘旋于高低电平之间的一个状态。信号输出A最终达到输入信号的新状态值1, 信号输出B却返回了输入信号的旧状态值0。在这两种情况下,信号输出变化稳定在固定的1或者0状态的时间远超过了寄存器的固有Tco。 如果输出信号在下一个寄存器捕获数据前(下一个时钟锁存沿的Tsu时间前)处于一个稳定的有效状态,那么亚稳态信号不会对该系统造成影响。但是如果亚稳态信号在下一个寄存器捕获数据时仍然盘旋于高或者低电平之间,那将会对系统的后续电路产生影响。继续讨论球和小山的比喻,当球到达山底的时间(处于稳定的逻样值0或1)超过了扣除寄存器Tco以外的余量时间,那么问题就随之而来。
同步寄存器
当信号变化处于一个不相关的电路或者异步时钟域,它在被使用前就需要先被同步到新的时钟域中。新的时钟域中的第1个寄存器将扮演同步寄存器的角色。 为了尽可能减少异步信号传输中由于亚稳态引发的问题, 设计者通常在目的时钟域中使用一串连续的寄存器(同步寄存器链或者同步装置)将信号同步到新的时钟域中,这些寄存器有额外的时间用于信号在被使用前从亚稳态达到稳定值。 同步寄存器到寄存器路径的时序余量 ,也就是亚稳态信号达到稳定的最大时间,也被认为是亚稳态持续时间。 同步寄存器链或者同步装置;被定义为一串达到以下要求的连续寄存器 : 1.链中的寄存器都由相同的时钟或者相住相关的时钟触发; 2.链中的第l个寄存器由不相关时钟域或者是异步的时钟来触发; 3.每个寄存器的扇出值都为1,链中的最后1个寄存器可以例外。 同步寄存器链的长度就是达到以上要求的同步时钟域的寄存器数量, 图 2.51 是一个两级的同步寄存器链。 传输在不相关时钟域的信号.都有可能在相对于捕获寄存器时钟沿的任何时间点变化。因此,设计者无法预测信号变化的顺序或者说信号两次变化间经过了几个锁存时钟周期。 例如 , 一条异步总线的各个数据信号可能在不同的时钟沿变化, 结果接收到的数据值可能是错误的. 设计者必须考虑到电路的这些情况,而使用双时钟 FIFO(DCFIFO)传输信号或者使用握手信号进行控制。 FIFO使用同步装置处理来自不同时钟域的控制信号,数据的读/写使用两套独立的总线。 此外,如果异步信号作为两个时钟域的握手逻辑,这些控制信号就需要用于指示何时数据信号可以被接收时钟域锁存。 如此一来,就可以利用同步寄存器确保亚稳态不会影响控制信号的传输,从而保证数据在使用前有充足的时间等待亚稳态达到稳定。 还是回到主题中,在明确了这些基本的概念和基本的方法后,就要学以致用。 文章的后面 Altera提出了MTBF(Mean Time Between Failures)的概念,即所谓的平均无故障时间;而其 没有提出的一个关键问题在于如何最有效地进行握手信号req、ack的采样。 这个问题可以先从Altera提出的MTBF推导公式的各个参数入手分析。 在这个公式中,tMEF指寄存器从时钟上升沿触发后的时序余量时间,fCLK是接收时钟域的时钟频率,fDATA是数据的变化频率,而C1、 C2 则是与器件有关的参数,对于用户是一个固定值。由此看来 ,设计者只能通过改变tMET、 fLK、fDATA来提高MTBF值。 MTBF值越大,说明出现亚稳态的几率越小。 要增大MTBF值,可以延长tMET,也可以降低fCLK和fDATA这两个频率。 首先看看如何延长tMEF时间,如图2.52所示。 tMEF时间=采样时钟周期时间一输出信号正常时的 Tco时间一数据到达下一级寄存器输入端口的其他延时时间TDATA 一 下一级寄存器的Tsu时间。 从严格意义上来说,tMEF 时间还应该加上时钟网络延时时间(Tclk1-Tclk2)。总之,这个tMEF时间是指正常亚稳态情况下,寄存器输出信号从源寄存器到目的寄存器的建立时间余量。 由于决定tMEF取值的参数中Tco和Tsu都是由FPGA器件本身的工艺以及工作环境决定的,设置时钟网络延时参数也很大程度上由器件决定,所以 ,如果在时钟频率fclk和数据变化率fDATA固定的情况下, 要增大tMEF值,那么设计者要做的只能是减小TDATA值。而这个TDATA是指两个寄存器间的逻辑延时以及走线延时之和,要最大程度地减小它,估计也只能是不在两个寄存器间添加任何逻辑而已,正如实例中也只有简单的input=output。 再看 fclk,它是接收域的采样时钟,就是异步信号需要被同步到的那个时钟域,它的频率是越小越好。当然了 ,事物都有其两面性,这个频率小到影响系统正常工作可就不行了 。 设计者需要从各个方面考虑来决定这个频率,不会仅为了降低亚稳态发生的概率而无限制地降低系统的时钟频率。如此分析,发现这个fcLK基本也是一个比较固定的值,不是可以随便说降就降的。 降低 fclk其实也就是在增大 tMEF时间,因为它是 tMEF公式计算中的被减数,好像是一环扣一环地放入。另外,在不降低采样频率fclk的情况下,通过使用使能信号的方式得到一 个二分频时钟去采样信号也可以达到降频的目的,只不过这样会多耗费几个时钟周期用于同步,但是有时也能够明显改善性能。 如图2.53所示 ,前两级采样电路都做了二分频 ,然后第3级使用原来时钟进行采样。它的好处在于给第1级和第2级同步寄存器更多的tMEF时间,将亚稳态抑制在第2级寄存器输人之前,从而保证第3级寄存器的可靠采样。虽然它在1、2级寄存器的输入端增加了一些逻辑,可能会增大TDATA,但是相比于这个采样时钟的一半降额,它的变化是可以忽略不计的。 另一种方法是在不降低每级寄存器采样频率的情况下采用更多的同步寄存器,尽量去使用后级的寄存器,这也是一个笨办法。Altera的笔记里打了一个比喻,如果一个设计使用了9级的同步寄存器,那么MTBF是100年,而当使用了10级的同步寄存器, 那么MTBF是l 000 年。这个解决办法其实有点类似冗余,这是所有人都知道的可以提高可靠性的原始办法。这种思路的弊端和前面提到的方法一样,需要付出多个时钟周期为代价。 最后看fDATA这个参数,它是发送时钟域的数据变化率,似乎也是由系统决定的,设计者也无法做太多改变。
借助于存储器
为了达到可靠的数据传输,借助于存储器来完成跨时钟域通信也是很常用的手段。 早期的跨时钟域设计中,在两个处理器间添加一个双口RAM或者FIFO来完成相互间的数据交换是很常见的做法。 如今的FPGA大都集成了一些用户可灵活配置的存储块,因此,使用开发商提供的免费IP核可以很方便地嵌入一些常用的存储器来完成跨时钟域数据传输的任务。 使用内嵌存储器和使用外部扩展存储器的基本原理是一样的,如图2.54所示。 双口RAM更适合于需要可通信的设计、只要双方对地址做好适当的分配.那么剩下的工作只要控制好存储器的读/写时序 。 FIFO本身的特性(先进先出)决定了它更适合于单向的数据传输。 总之,借助千存储器进行跨时钟域传输的最大好处在于,设计者不需要再花时间和精力考虑如何处理同步问题,因为这些工作都交给了存储器,设计者也不用关心存储器内部到底使用了怎样的工作机制来解决冲突问题(当然了,存储芯片内部肯定是有一套完善的同步处理机制),可以把更多的时间花在数据流以及存储器接口的控制上 。 借助于存储器的另一个优势,它可以大大提高通信双方的数据吞吐率,不像握手信号和逻辑同步处理机制那样在同步设 计上耗费太多的时钟周期,它的速度瓶颈基本就是存储器本身的速度上限。 不过,往往在得到便利的同时,也不得不以付出更多的成本作为代价。 下文将重点探讨异步FIFO在跨时钟域通信中的使用。 常见的异步FIFO接口如图2.55 所示,FlFO两侧会有相对独立的两套控制总线。 若写入请求 wrreq 在写人时钟 wrclk 的上升沿处于有效状态,那么FIFO将在该时钟沿锁存写入数据总线 wrdata 。 同理,若读请求 rdreq 在读时钟 rdclk 的上升沿处于有效状态, 那么FIFO将把数据放置到读数据总线 rddata 上 ,外部逻辑一般在下一个有效时钟沿读取该数据。 FIFO一般还会有指示内部状态的一些接口信号,如图2. 55中的空标志位 empty 、满标志位full,甚至还会有用多位数据线表示的FIFO当前数据量,这些状态标志保证了读/写控制不出现空读和满写的情况。 清除信号 aclr 在某些应用中也是需要的,它有效时能够清除当前 FlFO的数据。让FIFO复位到一个空的状态。 如图所示,SDRAM控制器中,就使用了两个FIFO。由于SDRAM需要定时预刷新,并且每次读/写时花费在起始控制的时间开销相对大一些,因此采用页读/写的方式可以大大地提高数据吞吐量,而页读/写方式需要对数据做一些缓存处理。另外,该SDRAM控制器所在的工程中涉及了多个时钟域。在写SDRAM端是一个25MHz的时钟,在读SDRAM端是一个50MHz的时钟,而SDRAM的控制则使用了100MHz的时钟。尽管实际工程里这3个时钟的相位关系固定,但是不做好多周期约束也很容易引起问题。 最终,选择在SDRAM控制器的写入端和读出端各使用一个异步FIFO,这既解决了数据缓存的问题,也能有效地完成跨时钟域地信号传输。
|