[FPGA] 异步FIFO的FPGA实现

[复制链接]
75|30
gaochy1126 发表于 2026-3-31 19:45 | 显示全部楼层 |阅读模式
本文大部分内容来自Clifford E. Cummings的《Simulation and Synthesis Techniques for Asynchronous FIFO Design》,同时加上一些自己的一些理解,有兴趣的朋友可以阅读原文。
一、FIFO简介
  FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
用途1:
  异步FIFO读写分别采用相互异步的不同时钟。在现代集成电路芯片中,随着设计规模的不断扩大,一个系统中往往含有数个时钟,多时钟域带来的一个问题就是,如何设计异步时钟之间的接口电路。异步FIFO是这个问题的一种简便、快捷的解决方案,使用异步FIFO可以在两个不同时钟系统之间快速而方便地传输实时数据。
用途2:
  对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。
二、分类
  同步FIFO是指读时钟和写时钟为同一个时钟,在时钟沿来临时同时发生读写操作;
  异步FIFO是指读写时钟不一致,读写时钟是互相独立的。
三、FIFO的常见参数
  • FIFO的宽度:即FIFO一次读写操作的数据位;
  • FIFO的深度:指的是FIFO可以存储多少个N位的数据(如果宽度为N)。
  • 满标志:FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出(overflow)。
  • 空标志:FIFO已空或将要空时由FIFO的状态电路送出的一个信号,以阻止FIFO的读操作继续从FIFO中读出数据而造成无效数据的读出(underflow)。
  • 读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。
  • 写时钟:写操作所遵循的时钟,在每个时钟沿来临时写数据。
===============================分   隔    符 ==============================
  • 读写指针的工作原理
  读指针:总是指向下一个将要被写入的单元,复位时,指向第1个单元(编号为0)。
  写指针:总是指向当前要被读出的数据,复位时,指向第1个单元(编号为0)

  • FIFO的“空”/“满”检测
  FIFO设计的关键:产生可靠的FIFO读写指针和生成FIFO“空”/“满”状态标志。
  当读写指针相等时,表明FIFO为空,这种情况发生在复位操作时,或者当读指针读出FIFO中最后一个字后,追赶上了写指针时,如下图所示:
          

  当读写指针再次相等时,表明FIFO为满,这种情况发生在,当写指针转了一圈,折回来(wrapped around)又追上了读指针,如下图:
        

    为了区分到底是满状态还是空状态,可以采用以下方法:
    方法1:在指针中添加一个额外的位(extra bit),当写指针增加并越过最后一个FIFO地址时,就将写指针这个未用的MSB加1,其它位回零。对读指针也进行同样的操作。此时,对于深度为2n的FIFO,需要的读/写指针位宽为(n+1)位,如对于深度为8的FIFO,需要采用4bit的计数器,0000~1000、1001~1111,MSB作为折回标志位,而低3位作为地址指针。

    • 如果两个指针的MSB不同,说明写指针比读指针多折回了一次;如r_addr=0000,而w_addr = 1000,为满。
    • 如果两个指针的MSB相同,则说明两个指针折回的次数相等。其余位相等,说明FIFO为空;
3.二进制FIFO指针的考虑
  将一个二进制的计数值从一个时钟域同步到另一个时钟域的时候很容易出现问题,因为采用二进制计数器时所有位都可能同时变化,在同一个时钟沿同步多个信号的变化会产生亚稳态问题。而使用格雷码只有一位变化,因此在两个时钟域间同步多个位不会产生问题。所以需要一个二进制到gray码的转换电路,将地址值转换为相应的gray码,然后将该gray码同步到另一个时钟域进行对比,作为空满状态的检测。
   

4.
  • 使用gray码进行对比,如何判断“空”与“满”

  使用gray码解决了一个问题,但同时也带来另一个问题,即在格雷码域如何判断空与满。
  对于“空”的判断依然依据二者完全相等(包括MSB);
  而对于“满”的判断,如下图,由于gray码除了MSB外,具有镜像对称的特点,当读指针指向7,写指针指向8时,除了MSB,其余位皆相同,不能说它为满。因此不能单纯的只检测最高位了,在gray码上判断为满必须同时满足以下3条:
  • wptr和同步过来的rptr的MSB不相等,因为wptr必须比rptr多折回一次。
  • wptr与rptr的次高位不相等,如上图位置7和位置15,转化为二进制对应的是0111和1111,MSB不同说明多折回一次,111相同代表同一位置。
  • 剩下的其余位完全相等。
      
5.总体实现
    系统的总体框图如下:
        

yorkbarney 发表于 2026-3-31 20:19 来自手机 | 显示全部楼层
相当全的资料,很适合初学者                                 

评论

赞一个  发表于 2026-3-31 20:58
albertaabbot 发表于 2026-3-31 20:19 来自手机 | 显示全部楼层
资料还是相当全面的,开发板也不错                                 

评论

赞一个  发表于 2026-3-31 20:59
elsaflower 发表于 2026-3-31 20:20 来自手机 | 显示全部楼层
以后多交流交流                  

评论

赞一个  发表于 2026-3-31 20:59
beacherblack 发表于 2026-3-31 20:20 来自手机 | 显示全部楼层
正准备学习的朋友推荐下载。                                 

评论

赞一个  发表于 2026-3-31 20:59
biechedan 发表于 2026-3-31 20:20 来自手机 | 显示全部楼层
资料很实用,谢谢楼主!                                 

评论

赞一个  发表于 2026-3-31 20:59
burgessmaggie 发表于 2026-3-31 20:21 来自手机 | 显示全部楼层
具有一定的参考价值,需要的朋友可以参考一下。

评论

赞一个  发表于 2026-3-31 20:59
olivem55arlowe 发表于 2026-3-31 20:21 来自手机 | 显示全部楼层
资料很实用,谢谢楼主!                                 

评论

赞一个  发表于 2026-3-31 20:59
hudi008 发表于 2026-3-31 20:22 来自手机 | 显示全部楼层
资料够全的,多谢分享                                 

评论

赞一个  发表于 2026-3-31 20:59
tifmill 发表于 2026-3-31 20:22 来自手机 | 显示全部楼层
谢谢lz分享,很有用                                 

评论

赞一个  发表于 2026-3-31 21:00
pentruman 发表于 2026-3-31 20:23 来自手机 | 显示全部楼层
资料很好。谢谢楼主!                                 

评论

赞一个  发表于 2026-3-31 21:00
ccook11 发表于 2026-3-31 20:23 来自手机 | 显示全部楼层
共享的资料比较详细  谢谢                                 

评论

赞一个  发表于 2026-3-31 21:00
primojones 发表于 2026-3-31 20:23 来自手机 | 显示全部楼层
谢谢你共享的资料!!                                 

评论

赞一个  发表于 2026-3-31 21:00
chenci2013 发表于 2026-3-31 20:24 来自手机 | 显示全部楼层
这些资料太全了!!!                 

评论

赞一个  发表于 2026-3-31 21:00
 楼主| gaochy1126 发表于 2026-3-31 21:28 | 显示全部楼层
读写指针分属不同时钟域,直接比较会导致亚稳态(Metastability)。需将指针通过格雷码转换和多级触发器同步(打两拍) 后再进行比较。
 楼主| gaochy1126 发表于 2026-3-31 21:28 | 显示全部楼层
即使使用格雷码和同步器,仍需遵循“保守设计”原则:允许空满标志短暂误判(如虚满/虚空),但禁止漏判
 楼主| gaochy1126 发表于 2026-3-31 21:28 | 显示全部楼层
对读写时钟进行时序约束,确保跨时钟域同步器的建立/保持时间满足要求;

避免过度使用FPGA资源(如LUT、触发器),可通过调整FIFO深度或位宽优化资源占用
 楼主| gaochy1126 发表于 2026-3-31 21:28 | 显示全部楼层
禁止在空状态下读取(避免无效数据)或满状态下写入(避免数据覆盖),需通过空满标志严格控制读写使能信号
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1329

主题

12852

帖子

27

粉丝
快速回复 在线客服 返回列表 返回顶部
0