赞
踩
本文使用 Zhihu On VSCode 创作并发布
异步FIFO用来在两个异步时钟域间传输数据。
如上图所示,两个系统“System X” 和 “System Y” 分别工作在两个不同的时钟域,“System X”将数据写入 FIFO,“System Y” 将数据从FIFO中读出。“fifo_full” 和 “fifo_empty” 信号负责对上溢(overflow)和下溢(underflow)的控制,如果在“fifo_full”为高时,不应该再写入数据,否则会将之前写入的数据覆盖掉。当“fifo_empty” 信号为高时,不应该读取数据,否则会读出无效的数据。FIFO数据“先进先出”,先写入的数据先读取。
异步FIFO结构如上图所示
读写指针
当读写指针相等时,表示写入的数据都被读取出来,此时FIFO为空。
当读写指针第四位相等,而最高位相反时,表示写指针比读指针多循环了一次,此时FIFO为满。
对于异步FIFO,需要将写指针从写时钟域同步到读时钟域,产生空信号,需要将读指针从读时钟域同步到写时钟域,产生满信号。上述结构框图中4,5部分使用两级同步器来减小跨时钟域产生亚稳态的概率。
由于需要同步多位宽的指针信号,如果指针继续使用二进制计数器,当指针从 11111 跳变到 00000 时,每以位数据都需要同步,产生亚稳态的概率会很高。5bit数据每一位都有可能采集出错,可能会将五位数据任何可能的组合采样并同步到新的时钟域中。
可以使用格雷码代替二进制数进行跨时钟域的传输。
格雷码的特点:
格雷码和二进制数的转换:
二进制数转格雷码:
- wire [4:0] gray;
- wire [4:0] bin;
- assign gray = {bin[4], bin[4:1] ^ bin[3:0]}
格雷码转二进制数:
- wire [4:0] gray;
- reg [4:0] bin;
- integer i;
- always @ (gray)
- begin
- bin[4]=Gry[4];
- for(i=3;i>=0;i=i-1)
- bin[i]=bin[i+1]^gray[i];
- end
我们使用二进制数器作为RAM地址信号,将其转换为格雷码进行跨时钟域传输。
空满信号产生
如上图所示,使用4位格雷码作为深度为8的FIFO的读写指针。
将格雷码转换成四位二进制数,使用二进制数低三位作为访问RAM的地址。
使用移位寄存器实现同步器。
设计一个深度位宽可调的双口RAM,默认参数深度为16,位宽为8。
设计和测试文件见文章末尾。
仿真波形:
链接:https://pan.baidu.com/s/1d7HPLnj1pjXMPgWE5epdvQ
提取码:pxgc
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。