由于FPGA跨时钟域传输信号会出现亚稳态等问题,所以要用到异步设计用以处理跨时钟域数据传输的问题,尽量使得系统对亚稳态错误不敏感。
第一种:打两拍(慢时钟到快时钟)
(快时钟到慢时钟则先延长信号再打两拍)
FPGA在处理跨时钟域的数据有单bit和多bit之分,而打两拍的方式常见于处理单bit数据的跨时钟域问题。
打两拍的方式,其实说白了,就是定义两级寄存器,对输入的数据进行延拍,如下图所示:
应该很多人都会问,为什么是打两拍呢,打一拍、打三拍行不行呢?
先简单说下两级寄存器的原理:两级寄存是一级寄存的平方,两级并不能完全消除亚稳态的影响,但是提高了可靠性减少其发生概率。总的来讲,就是一级概率很大,三级改善不大。
这样说可能还是有很多人不够完全理解,那么请看下面的时序示意图:
data是Clk1 Domain的数据,需要传到Clk2 Domain进行处理(即上图的clk时钟),寄存器1和寄存器2使用的时钟都为clk。假设在clk的上升沿正好采到data的跳变沿(从0变1的上升沿,实际上的数据跳变不可能是瞬时的,所以有短暂的跳变时间),那这时作为寄存器1的输入(D1)到底应该是0还是1呢?这是一个不确定的问题,此时有可能会出现亚稳态问题。虽然Q1的值也不能确定,但至少可以保证,在clk的下一个上升沿,Q1基本可以满足第二级寄存器的保持时间和建立时间要求,作为寄存器2的输入(D2)出现亚稳态的概率得到了很大的改善。
如果再加上第三级寄存器,由于第二级寄存器对于亚稳态的处理已经起到了很大的改善作用,第三级寄存器在很大程度上可以说只是对于第二级寄存器的延拍,所以意义是不大的。
第二种:格雷码转换
对于单bit数据信号的跨时钟域处理办法我们知道可以用打两拍,然而这对多bit数据并不管用。首先,我们知道,使用DFF打两拍可以基本消除亚稳态的问题,但是无法保证采样得到的数据是正确的,因此,如果现在要采样的是一个多bit的跨时钟域信号,比如4bit信号,那么由于建立时间和保持时间的违例,虽然在打两拍之后可以得到一个稳定的数据,但该数据的每一个bit都不一定是正确的,所以其可能的值有2^4=16种,这显然是无法接受的,因此,对于多比特信号的跨时钟域处理,不能照搬。
一种可以解决多bit跨时钟域信号传输的方法就是格雷码。
格雷码(又称循环码),它具有以下两个特点:
1、相邻的两个编码之间只有一位是不一样的。
2、当第N位从0变到1时,之后的数的N-1位会关于前半段对称,而比N位高的是相同的。
二进制与格雷码转换真值表如下图所示:
二进制与格雷码转换verilog语言描述如下:
assign gray = (binary>>1) ^ binary; //binary to gray
assign bunary = {gray[2],gray[2]^gray[1],gray[2^gray[1]^gray[0]]};//gray to binary
由于格雷码相邻数据只有一个bit不同,因此,在进行跨时钟域传输时,只有发生变化的那个bit有可能处于亚稳态,而其余bit由于保持不变,因此是稳定的,故多比特格雷码的跨时钟域传输相当于单比特信号的跨时钟域传输,我们采用打两拍的方法即可处理。
第三种:异步fifo/异步双端口RAM
单bit信号我们可以打两拍,少数bit信号我们可以格雷码转换,多bit信号跨时钟域的最常用方法还是异步FIFO或者异步双端口RAM。简单来说,异步FIFO是双口RAM的一个封装而已,其存储容器本质上还是一个RAM,只不过对其添加了某些控制,使其能够实现先进先出的功能且不向双端口RAM那样读写需要地址线,由于这个功能十分的实用,因此得以广泛应用。 真双口RAM可以实现在一端存储,另一端读取的功能,两端的时钟可以不同,将数据存入一个容器,再取出来,这个过程在双口RAM的两端完全不存在亚稳态的问题。由于异步FIFO的实现中也存在数据的存取问题,和双口RAM类似,再加上空满信号的控制,存在跨时钟域的问题,因此只要处理好,空满信号的判断中的跨时钟域问题,就可以使用FIFO解决多比特信号的跨时钟域问题。封装的异步fifo如下图所示:
由于是异步FIFO的设计,读写时钟不一样,在产生读空信号和写满信号时,会涉及到跨时钟域的问题,如何解决?
跨时钟域的问题:由于读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO的读写时钟域不同,是异步的,要是将读时钟域的读指针与写时钟域的写指针不做任何处理直接比较肯定是错误的,因此我们需要进行同步处理以后再进行比较
解决方法:加两级寄存器同步 + 格雷码(目的都是消除亚稳态)
1.使用异步信号进行使用的时候,好的设计都会对异步信号进行同步处理,同步一般采用多级D触发器级联处理。这种模型大部分资料都说的是第一级寄存器产生亚稳态后,第二级寄存器稳定输出概率为90%,第三极寄存器稳定输出的概率为99%,如果亚稳态跟随电路一直传递下去,那就会令自我修护能力较弱的系统直接崩溃。
2.将一个二进制的计数值从一个时钟域同步到另一个时钟域的时候很容易出现问题,因为采用二进制计数器时所有位都可能同时变化,在同一个时钟沿同步多个信号的变化会产生亚稳态问题。而使用格雷码只有一位变化,因此在两个时钟域间同步多个位不会产生问题。所以需要一个二进制到gray码的转换电路,将地址值转换为相应的gray码,然后将该gray码同步到另一个时钟域进行对比,作为空满状态的检测。文章来源:https://www.toymoban.com/news/detail-477085.html
异步fifo的RTL设计与TestBench可参考如下资源内部文件:
基于UVM的异步fifo验证平台设计文章来源地址https://www.toymoban.com/news/detail-477085.html
到了这里,关于FPGA设计中跨时钟域问题的处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!