时序约束连载06~预防亚稳态的方法

本文为明德扬原创文章,转载请注明出处!

预防亚稳态的方法

本文讲讲减少亚稳态危害的方法,首先明确亚稳态是不可避免的,即如果输入异步信号,可能会出现亚稳态,不可能完全避免亚稳态的产生。因此工程师要做一些预防措施,减小亚稳态出现的机率,把亚稳态危害减少到最小,这是才是一个正确的思路。

回顾上文有可能出现亚稳态的几种情况,只要建立时间或者保持时间要求不满足,都有可能出现亚稳态。但并不是说建立时间或者保持时间不满足时,就一定会出现亚稳态,而是有可能会出现亚稳态,所以建立时间保持时间不满足,就可能出现亚稳态。那什么时候会不满足呢?

回顾上文,第一个就是时序不满足时,例如系统本来要求工作在100MHz,由于电路中组合逻辑延时过大,导致信号在建立时间内发生了变化,此时建立时间不满足,那可能出现亚稳态。第二种是不同时钟域的信号时,例如异步信号、按键、20MHz时钟使用了10MHz时钟域下面的信号、200MHz时钟域使用100MHz时钟域下的信号时,这种异步时钟域下信号的传递,就有可能出现亚稳态。因为两个时钟是异步,相位和频率是没有任何关系的,那么原时钟域下的信号就有可能在新时钟域的任何时间点发生变化,当然有可能在新时钟域的时钟上升沿发生变化,那么此时建立时间就不满足,可能出现亚稳态。第三种就是来自FPGA芯片之外的一些异步信号,比如按键、外部芯片的读写等信号,相对于FPGA内部的时钟随时都可能发生变化,都可能出现亚稳态。所以在时钟上升沿变化的信号就有可能出现亚稳态。

接下来看一下减少亚稳态危害方法。

第1节预防亚稳态的方法

减少亚稳态危害的方法有哪些呢?一般有这三种方法。

第一种、对于单比特的信号信号传输,建议用同步机制,比如打两拍或打三拍,有时候要打三拍。每个项目的项目组的要求都是不一样的,一般打两拍或者三拍。

第二种、对于多比特信号流,建议用异步FIFO,因为异步FIFO内部会做相关的同步机制,也可以用双口RAM,原理几乎一致,具体看需求。

第三种、还有一种少量的,发送可控的数据流,可以通过增加指示信号的方法去做。第二种更常用,第三种是对于一些类似CPU接口等异步接口场合会用得到。

1.1 单比特跨时钟域传输

时序约束连载06~预防亚稳态的方法

图1 单比特数据同步

单比特的控制信号通过打两拍实现同步,如图1,aclk时钟和bclk是异步时钟,频率和相位都没有关系。adat是在aclk时钟域下生成的,将adat给bclk时钟使用,bclk不能直接使用adat,因为adat相对于bclk是异步信号,可以随时发生变化,可能出现亚稳态,那怎么办呢?首先经过一个D触发器把adat信号打一拍得到bdat1,再用个D触发器把bdat1信号再打一拍得到bdat2。在这个过程中bdat2相对于adat延迟2个bclk时钟,也就是打了两拍,在这个过程中是不能使用adat和bdat1这两个信号,它们出现亚稳态的机率比较大。bdat2就可以直接使用,比如if (bdat2==1)等等,这是没问题的。这就是同步机制。

注意bdat1不能作为条件去使用,只能直接使用bdat2,为什么会这样子呢?

时序约束连载06~预防亚稳态的方法

图2 不满足D触发器建立时间要求

假设上图dout_a就是adat,dout_a1就是bdat1,dout_a2就是bdat2,CLKB就是bclk。adat刚好在bclk上升沿时由低电平变为高电平,导致建立时间不满足,则bdat1就可能出现亚稳态,并且亚稳态持续的时间可能比较长,此过程中可能并不能准确判断该信号是高电平还是低电平。如果直接使用bdat1,在时钟上升沿对bdat1进行判断时,有可能认为是高电平也有可能认为是低电平,如果一部分电路认为bdat1是高电平,另一部分电路认为是低电平,那么电路状态会崩溃。对bdat1打一拍得到bdat2,bdat2信号出现亚稳态的机率就很低了。其实信号经过一个D触发器出现亚稳态的机率是比较低的,那么信号连续经过2个D触发器后,亚稳态出现的概率就极低了。bdat2信号就认为是adat信号同步后的信号,亚稳态出现的机率极小,就可以使用了,这就是单比特信号同步的方法。

时序约束连载06~预防亚稳态的方法

图3 单比特信号同步

这种同步机制的原理是什么?出现亚稳态的概率是很低的,连续两次出现的概率就更低了,所以bdat2出现亚稳态的机率远小于bdat1信号出现亚稳态的机率。当然在bdat2再加一个D触发器,即打三拍,出现亚稳态的概率就更低了。

所有电路都将D触发器输出Q判断错误是不可怕的,通过设计的方式就可以解决。比如D触发器输入信号在时钟上升沿之前一点由低电平变为了高电平。按照电路的设计,D触发器应该输出高电平,实际上D触发器输出了低电平。后面电路都会认为该D触发器输出的是低电平。这种错误其实对电路的影响不大,通过更改设计就可以解决,为什么呢?可以将输入信号持续的时间变长。这种从设计上就可以避免,其实对电路并没有太大的影响。可怕的是什么问题?

比如用bdat1作为后续电路的条件判断,可能有部分认为bdat1是低电平,有部分电路认为bdat1是高电平。由前一篇文章知,有部分电路认为是低电平,有部分电路认为是高电平,就会导致电路的逻辑行为与理论不一致,这才是真正可怕的事情。因此bdat1有可能出现亚稳态,bdta2可能出现错误,但都没有关系。

1.2 多比特数据流传输

对于多比特数据流,建议用FIFO对数据进行同步,比如模块A的时钟为100MHz,模块B的时钟为80MHz,可以通过一个异步FIFO将模块A的多比特数据同步到模块B。使用官方的异步FIFO,官方已经对输入输出的数据做了异步握手的处理,可以节约开发者的时间。并且读写两个时钟域下面的空、满等指示信号也是做了异步处理的。官方的IP都是经过大量验证的,要注意一些指示信号在做异步处理之后,就会有一些延时,这是无法避免的。所以多比特信号建议用异步FIFO。

时序约束连载06~预防亚稳态的方法

图4 多比特信号同步

1.3可控数据流传输

对少量多比特信号,例如CPU的接口、部分USB接口,这些接口一般是不会给FPGA提供时钟信号的,通过片选信号、读使能、写使能等指示信号来确定数据信号是否有效。如何发送一组异步信号呢?如图5所示,clka可以认为是CPU时钟信号,clkb是FPGA的时钟信号,data是CPU发送给FPGA的多比特信号,vld是data信号的指示信号,vld为高电平时表示data信号是有效的,并且这段时间内data是保持不变的。此时FPGA如何去接收数据呢?

时序约束连载06~预防亚稳态的方法

图5 外部芯片与FPGA芯片通信

其实FPGA就是对vld信号做一个检测,vld信号是clka时钟域下的信号,对于FPGA的时钟clkb来说是异步信号,所以FPGA在对vld检测之前,应该先通过打两拍的方式同步到clkb时钟域。Vld同步后得到vld_ff1信号,由于要检测vld信号的上升沿,所以还要将vld_ff1打一拍。当vld_ff2为低电平,而vld_ff1为高电平时,表示检测到了vld的上升沿。当检测到vld上升沿,就可以把data信号的数据保存到FPGA内部的dout信号,同时把vld_out拉高一个clkb时钟宽度,表示此时dout信号的数据是有效的,通过这种方式同步多比特信号为什么可以避免亚稳态?

这个过程中vld_ff0信号可能出现亚稳态,vld_ff1信号的出现亚稳态的概率就很低了,可以认为vld_ff1是vld的同步信号了。data信号在此过程保持不变,在检测到vld信号上升沿之前,FPGA不会取data信号的数据。而vld同步化之后并且检测到vld信号上升沿之后,立刻取data信号的数据,data在这个过程是绝对不会变的信号。虽然data对于FPGA是异步信号,但FPGA采集data信号时肯定会满足建立时间和保持时间的,所以能够避免亚稳态。前提是在这段时间内data信号要保持不变。

问题在于vld和data要保持多长时间呢?取决于什么因素呢?取决于clkb进行采样,最极端的方式是当clka和clkb上升沿重合时vld拉高,此时clkb采集vld为低电平,此时没有采集到数据,这是最恶劣的情况。如果clkb的上升沿滞后clka建立时间,那么经过两个clkb后vld完成同步,在经过一个clkb后检测到vld上升沿,此时将data信号保存到FPGA中,这是极端的情况,推测出vld和data信号需要保持至少三个clkb时钟长度不变。

对于这种同步情况,实际上在FPGA内部是不常用的,如果在FPGA内部有clka和clkb,直接用异步FIFO同步就好了。上述同步方式一般是用在FPGA与外部不提供时钟信号的芯片通信,比如CPU接口、USB芯片或者串口芯片等等,才需要用这种方式同步数据,否则千万不要用,也不要在FPGA内部使用。

总结上述同步方式,适用于不给FPGA提供时钟信号的一些接口信号的同步,如果外部芯片的数据传输带有时钟信号,那么就可以直接使用FIFO完成同步,使用此方式相比FIFO会麻烦很多。

1.4 不同时钟域同步方式

快时钟域到慢时钟域,慢时钟域到快时钟域传输信号,其实就要考虑两件事情,第一、接收端能不能检测到发送端的信号,这要求发送端数据保持时间达到一定要求。第二、接收端不能把一个发送端的信号检测多次,要求接收端检测到发送端指示信号有效边沿后保存数据。

1.模块A的时钟clka为100MHz,模块B的时钟clkb为300MHz。现在模块A要把32bit的数据送给模块B。数据要保持多长时间?

这种情况与1.3的原理一致,从100MHz的慢时钟域传输到300MHz的快时钟域,此时300MHz是可以检测到100MHz时钟域下的指示信号,只要对指示信号同步后,检测到指示信号上升沿时保存32bit数据信号即可。所以数据保持时间需要大于三个模块B的时钟宽度。

2.模块A的时钟clka为300MHz,模块B的时钟c1kb为100MHz。现在模块A要把32bit的数据送给模块B。数据要保持多长时间?

这种其实就是快时钟域到慢时钟域的数据传输,需要注意clka的周期约为3.3ns,而clkb时钟为10ns。如果模块A的数据只持续一个clka时钟,而模块B很可能检测不到vld指示信号的高电平。如下图所示,vld即使变化了,clkb依旧采集不到。

时序约束连载06~预防亚稳态的方法

图6 慢时钟域采集快时钟域

由于慢时钟域接收到快时钟域指示信号后,也需要先同步,然后检测指示信号上升沿。这个过程中需要data信号保持三个clkb时钟以上,换算成clka,推荐data信号保持10个clka信号长度。

3. 一块电路板上,有两个芯片,芯片A的时钟clka为100MHz,芯片B的时钟clkb为100MHz。现在芯片A要把32bit的数据送给芯片B。数据要保持多长时间?

芯片A和芯片B的时钟都是100MHz,由于是不同芯片,两个时钟产生的晶振不同,由于工艺关系,时钟也会存在细微差异,比如一个时钟真实频率可能是99.99MHz,一个时钟真实频率可能是100.01MHz。另外还可能两个时钟的相位不同,所以这两个时钟还是异步时钟。只要不是同一个晶振出来的,就一定会有偏差,就是异步时钟。

其实芯片A的数据保持时间与前文是一致的,同样要保持三个芯片B时钟宽度。

第2节总结

异步时序是企业很重视的一个内容,很多时候芯片的成败关键在接口上。当然要时刻提醒自己注意异步时序,有没有可能出现亚稳态,然后做一些对应的处理。

本文章内容,来源于配置的明德扬时序约束专题课视频。

时序约束连载06~预防亚稳态的方法

免责声明:文章内容来自互联网,本站仅提供信息存储空间服务,真实性请自行鉴别,本站不承担任何责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:时序约束连载06~预防亚稳态的方法 https://www.bxbdf.com/a/180310.shtml

上一篇 2025-04-10 14:30:08
下一篇 2025-04-10 14:37:06

猜你喜欢

联系我们

在线咨询: QQ交谈

邮件:362039258#qq.com(把#换成@)

工作时间:周一至周五,10:30-16:30,节假日休息。