同步FIFO和异步FIFO设计

本文详细介绍了同步FIFO和异步FIFO的设计,包括它们的接口、地址逻辑、空满信号的判断方法,以及格雷码在异步设计中的应用。同时提供了相应的RTL代码和testbench示例。
摘要由CSDN通过智能技术生成


前言

本文详细介绍同步FIFO和异步FIFO设计并且附详细rtl设计代码和testbench代码,供大家参考


一、FIFO是什么?

FIFO (先入先出, First In First Out )存储器,在 FPGA 和数字 IC 设计中非常常用。 根据接入的读写时钟信号是否同步,可以分为同步 FIFO 和异步 FIFO 。FIFO 底层基于双口 RAM 。同步 FIFO 的读写时钟一致,异步 FIFO 读时钟和写时钟不同。
同步FIFO 主要应用于速率匹配(数据缓冲)
异步 FIFO 主要用于多 bit 信号的跨时钟域处理。

二、同步FIFO设计

FIFO底层基于双端口RAM实现

1.接口说明

图片来自牛客网
在这里插入图片描述
在这里插入图片描述
根据同步 FIFO 的接口和双口 RAM 的接口,在借助双口 RAM 实现同步 FIFO 时,只需要加入读、写控制逻辑即可。在写逻辑中,用于产生写地址和写满信号; 在读逻辑中,用于产生读地址和读空信号。 读写控制逻辑还需要受到读写使能信号的控制。

2.读写地址逻辑

对于写地址而言:

(1) 写使能有效(要写入);

(2) 没写满(能写入);

//写数据逻辑
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_waddr <= 'd0;
    else if(i_wr_en && !o_wfull)
        r_waddr <= r_waddr + 'd1;
    else
        r_waddr <= r_waddr;
end

对于读地址而言:

(1) 读使能有效(要读出);

(2) 没读空(能读出);

//读数据逻辑
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_raddr <= 'd0;
    else if(i_rd_en && !o_rempty)
        r_raddr <= r_raddr + 'd1;
    else
        r_raddr <= r_raddr;
end

2.空满信号

判断空满的方式有多种,非常常用的一种是 扩展 1 bit 的读写地址方法,将flag 指示信号和原本 N 位的读写地址结合,使用 N+1 位的读写地址,其中最高位用于判断空满信号,其余低位还是正常用于读写地址索引。
在这里插入图片描述
使用低 2 位来进行双口 RAM 的地址索引,高位用于判断空满。 对于空信号,可以知道当 FIFO 里没有待读出的数据时产生。 也就是说,此时读追上了写,把之前写的数据刚刚全部都出,读地址和写地址此时指向相同的位置,读地址 - 写地址 =0
对于写满信号,当写入后还没被读出的数据恰好是 FIFO 深度的时候,产生满信号,即写地址 - 读地址 = FIFO 深度 = 4 。此时对于双口 RAM 的 2 bit 的地址来说,读写地址一致; 对于最高位来所,写是 1 而读是 0 (即相反)。

assign o_wfull  = r_raddr == {!r_waddr[clogb2(P_ADDR_DEPTH-1)],r_waddr[clogb2(P_ADDR_DEPTH-1)-1:0]};
assign o_rempty = r_raddr == r_waddr;

完整代码以及测试TB文件获取地址:https://github.com/shun6-6/FIFO_AND_RAM

二、异步FIFO设计

1、格雷码与二进制之间的转换

参考:https://zhuanlan.zhihu.com/p/451408535
格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO 或者 RAM 地址寻址计数器中。
格雷码属于可靠性编码,是一种错误最小化的编码方式,因为虽然二进制码可以直接由数/模转换器转换成模拟信号,但在某些情况,例如从十进制的 3 转换为 4 时二进制码的每一位都要变,能使数字电路产生很大的尖峰电流脉冲。而格雷码则没有这一缺点,它在相邻位间转换时,只有一位产生变化。它大大地减少了由一个状态到下一个状态时逻辑的混淆。
在这里插入图片描述

1.1、二进制码转换为二进制格雷码

二进制码转换成二进制格雷码,其法则是保留二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或,而格雷码其余各位与次高位的求法相类似。
在这里插入图片描述

1.2、二进制格雷码转换成二进制码

二进制格雷码转换成二进制码,其法则是保留格雷码的最高位作为自然二进制码的最高位,而次高位自然二进制码为高位自然二进制码与次高位格雷码相异或,而自然二进制码的其余各位与次高位自然二进制码的求法相类似。
在这里插入图片描述
研究完格雷码即可开始异步FIFO的设计

2、设计框图

在这里插入图片描述

  1. 双端口RAM
  2. 写时钟域:写数据地址逻辑以及写满信号判断逻辑
  3. 读时钟域:读数据地址逻辑以及读空信号判断逻辑
  4. 读地址指针(格雷码)跨时钟域(打俩拍)
  5. 写地址指针(格雷码)跨时钟域(打俩拍)
    与同步FIFO不同之处在于:
    1、读写地址指针需要转化为格雷码并且进行跨时钟域处理
    2、读空和写满信号需要按照格雷码进行判断,写满时,写指针比读指针多循环RAM一周,此时读写指针的最高位和次高位都相反,其余位相同,FIFO为满;读空时和同步FIFO判断条件一致
    在这里插入图片描述
assign o_wfull  = r_gray_waddr == {~r_gray_raddr_2d[P_ADDR_WIDTH:P_ADDR_WIDTH-1],r_gray_raddr_2d[P_ADDR_WIDTH-2:0]};
assign o_rempty = r_gray_raddr == r_gray_waddr_2d;

完整代码:https://github.com/shun6-6/FIFO_AND_RAM/tree/main

总结

  • 36
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺子学不会FPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值