电子说
同步复位和异步复位
异步复位
异步复位是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。
RTL代码如下:
always @ (posedge clk or negedge rst_n) if(!rst_n) b <= 1'b0; else b <= a;
综合后如下:
我们可以看到FPGA的寄存器都有一个异步的清零端(CLR),在异步复位的设计中这个端口一般就是接低电平有效的复位信号rst_n。即使说你的设计中是高电平复位,那么实际综合后会把你的复位信号反向后接这个CLR端。公众号:OpenFPGA
同步复位
同步复位是指只有在时钟上升沿到来时才会对复位信号进行采样,也就是只有在时钟上升沿时,复位信号才有效。
其RTL代码如下:
always @ (posedge clk) if(!rst_n) b <= 1'b0; else b <= a;
综合后如下:
和异步复位相比,同步复位没有用上寄存器的CLR端口,综合出来的实际电路只是把复位信号rst_n作为了输入逻辑的使能信号。那么,这样的同步复位势必会额外增加FPGA内部的资源消耗。
那么同步复位和异步复位到底孰优孰劣呢?
只能说,各有优缺点。同步复位的好在于它只在时钟信号clk的上升沿触发进行系统是否复位的判断,这降低了亚稳态出现的概率;它的不好上面也说了,在于它需要消耗更多的器件资源,这是我们不希望看到的。FPGA的寄存器有支持异步复位专用的端口,采用异步复位的端口无需额外增加器件资源的消耗,但是异步复位也存在着隐患,特权同学曾说过从没有意识到也没有见识过。异步时钟域的亚稳态问题同样的存在与异步复位信号和系统时钟信号之间。公众号:OpenFPGA
上面的分析似乎都让人意识到同步复位和异步复位都不可靠,那么如何将两者结合,取长补短呢?
异步复位、同步释放
所谓异步复位,同步释放就是在复位信号到来的时候不受时钟信号的同步,而是在复位信号释放的时候受到时钟信号的同步。
如下图,单独看方框左的复位策略,是一个异步复位电路,即复位信号有效时不管时钟信号是否处于有效沿,输出都会被复位,但是如果复位信号在时钟信号的上升沿撤销时,这时候的输出就是亚稳态。
首先看一下怎么实现异步复位:当rst_async_n有效时,第二个D触发器的输出rst_sync_n就是低电平,方框左中的异步复位端口有效,输出被复位。
然后是同步释放:假设rst_async_n在clk的上升沿时撤除,那么第一级触发器处于亚稳态,但是由于两级触发器的缓冲作用,第二级触发器的输入为clk到来前第一级触发器的输出,即为低电平。因此,此时第二级触发器的输出一定是稳定的低电平,方框左中触发器仍然处于复位状态。在下一个clk到来时,第一级触发器的输出已经是稳定的高电平了,故rst_sync_n已经是稳定的高电平,此时复位释放。也就是同步释放。公众号:OpenFPGA
通过上面分析可知:异步复位、同步释放其最显著特征是既保留了异步复位的功能,又避免了异步复位释放时所面临的recovery或者removal违例问题。
那异步复位同步释放是如何避免recovery和removal违例问题的呢?如下代码所示,是异步复位同步释放的RTL code。
always @ (posedge clk, negedge rst_async_n) if (!rst_async_n) begin rst_s1 <= 1'b0; rst_s2 <= 1'b0; end else begin rst_s1 <= 1'b1; rst_s2 <= rst_s1; end assign rst_sync_n = rst_s2; endmodule
从上述代码可以看出,rst_async_n=0时,rst_sync_n会被立即复位为0,输出到后续电路用于异步复位;rst_async_n=1时,假设此时恰好在时钟沿附近,会造成recovery或者removal的违例,但经过DFF1和DFF2的两级同步,rst_sync_n释放沿与时钟沿同步,送入到后续电路不会再有recovery和removal违例出现。
问题1
如果没有前面两级触发器的处理。异步信号直接驱动系统的触发器。会出现什么情况?
回答:很多人只知道触发器D端口来源是异步的话,会因为建立保持时间的时序违反而在触发器Q端口产生亚稳态。但是不清楚,异步复位信号为什么会导致亚稳态的产生。
首先,回顾理论教材里介绍的建立保持时间违反分析,教材一般都是拿没有复位端口的D触发器举例。
然后,画出带有异步复位端口的D触发器,下图带异步复位Rd,并带有异步置位端口Sd。公众号:OpenFPGA
由此得知,异步复位信号或者异步置位信号,跟数据端口D信号,没有什么区别,都会存在建立保持时间的违反,从而时序冲突,引发输出亚稳态。
问题2
复位信号存在亚稳态,有危险吗?
回答:
亚稳态,出现的问题或者麻烦,是在信号变化的时候,不能保证第一拍采样的值是固定的。
如果信号稳定,不会出现亚稳态的。就是采样后的跳变,时刻不确定,也许早,也许晚。
系统不希望这样的未知状态发生,系统希望知道在某一个时刻,后续逻辑需要的输入信号,是稳定值。公众号:OpenFPGA
二级触发器同步后,第二季触发器的输出基本上是稳定值。后续逻辑根据稳定值,会有稳定的行为。这就是追求的系统稳定性。
最好是系统一起复位释放,但是时钟域不同,不可能保证系统一起复位释放。一般来说,系统复位释放的顺序,是需要保证的。否则系统就是不安全的。公众号:OpenFPGA
举个例子,系统启动时,内核读取启动指令,要powerdown某外设;但是powerdown的逻辑要求外设和内核没有通信请求正在发生。此时,外设比内核先释放复位的情况(复位释放的时刻,外设有可能已经开始与内核发生请求),与内核比外设先释放复位的情况(复位释放的时刻,外设肯定与内核没有发生请求),是不一样的,powerdown也许不能处理成功。
这也是异步复位信号需要同步释放的原因,目的都是为了避免亚稳态的产生。
问题3
如果只做一级触发器同步,如何?
回答:不可以。第一级触发器的输出,永远存在亚稳态的可能。亚稳态,导致系统不会复位初始化到已知状态。
当第一级触发器采样异步输入之后,允许输出出现的亚稳态可以长达一个周期,在这个周期内,亚稳态特性减弱。在第二个时钟沿到来时,第二级同步器采样,之后才把该信号传递到内部逻辑中去。第二级输出是稳定且已被同步了的。如果在第二级采样时保持时间不够,第一级的输出仍然处于很强的亚稳态,将会导致第二级同步器也进入亚稳态,但这种故障出现的概率比较小。公众号:OpenFPGA
一般情况下,两级同步器总体的故障概率是一级同步器故障概率的平方。在大部分的同步化设计中,两级同步器足以消除所有可能的亚稳态了。
问题4
两级触发器同步,就能消除亚稳态吗?
回答:不能。大大降低概率,如果几十年出现一次,也无所谓了。毕竟芯片不会用几十年,早就老化严重淘汰了。
问题5
第一级触发器的数据端口为什么是1’b1?回答:
如果第一级触发器的数据端口,使用rst_async_n。综合后的第一级触发器电路图如下
如果第一级触发器的数据端口,使用1’b1。综合后的第一级触发器电路图如下:
考虑到电路实现的资源,还是第2种方案最节省,为最佳设计。
参考资料
https://blog.csdn.net/cainiaoyizhiyang/article/details/98479356https://blog.csdn.net/wordwarwordwar/article/details/79889725
编辑:hfy
全部0条评论
快来发表一下你的评论吧 !