抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

FIFO

FIFO(First In First Out)是一种数据缓冲器

异步FIFO

同步FIFO可以看做异步FIFO的一个特例

异步FIFO可以分为

  1. 写时钟域地址管理
  2. 读时钟域地址管理
  3. 读时钟域读地址到写时钟域的格雷码同步
  4. 写时钟域写地址到读时钟域的格雷码同步
  5. 写时钟域的满和将满信号的产生
  6. 读时钟域的空和将空信号的产生

格雷码

避免采样时钟问题

引入格雷码,格雷码相邻地址只有1bit​跳变

格雷码的原理:从右往左,每2位异或

0000​->0000

0010​​->0011​​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//以FIFO深度16,格雷码编解码情况核心代码
//编码
always@(posedge clka or posedge reset)
if(reset)
b<=4'b00;
else
b<=a^(a>>1);
//异步采样
always@(posedge clka or posedge reset)
if(reset)
c<=4'b00;
else
c<=b;
//解码
always@(posedge clka or posedge reset)
if(reset)
d<=4'b00;
else
begin
d[3]=c[3];
d[2]=c[3]^c[2];
d[1]=c[2]^c[1];
d[0]=c[1]^c[0];
end

注意,先将clka​时钟的地址Gray​编码,然后用b​时钟采样Gray​编码地址并暂存,最后用b​时钟对暂存的Gray​编码地址进行译码。

省略b​时钟采样暂存的Gray​编/解码是没有任何意义的。

格雷码的问题

并不是一定要用格雷码做读写指针,而是当深度为2次幂的时候列好格雷码满足消除亚稳态的需求
在非2次幂深度情况下,格雷码已经不再适用,此时的解决方法通常有

  • 若深度为偶数,可采用最接近的2次幂的格雷码编码,在此基础上修改;
  • 深度为一般数值时,可自行设计一种逻辑电路,或者查找表,以实现指针每次只跳变一次的功能;
  • 以上方法通常在设计层面较为复杂,若无特定需求,可将FIFO深度设置为2次幂,浪费一些存储空间,来化简控制电路的复杂度。

FIFO深度

吞吐量相同满足

(A/B) * f1=(Y/X) * f2

深度计算公式

fifo_depth=data_length-(data_length/f1) * [(Y/X) * f2]