异步FIFO的FPGA实现

EDN电子技术设计 2020-04-29 00:00

本文大部分内容来自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.读写指针的工作原理


读指针:总是指向下一个将要被写入的单元,复位时,指向第1个单元(编号为0)。

写指针:总是指向当前要被读出的数据,复位时,指向第1个单元(编号为0)


2.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.总体实现


系统的总体框图如下:

        

1)顶层模块 

  module AsyncFIFO
#(parameter ASIZE = 4,    //地址位宽
  parameter DSIZE = 8)    //数据位宽 (    input  [DSIZE-1:0] wdata,    input              winc, wclk, wrst_n,  //写请求信号,写时钟,写复位
   input              rinc, rclk, rrst_n,  //读请求信号,读时钟,读复位
   output [DSIZE-1:0] rdata,    output             wfull,    output             rempty
);wire [ASIZE-1:0] waddr, raddr;wire [ASIZE:0]   wptr, rptr, wq2_rptr, rq2_wptr;        /************************************************************
* In order to perform FIFO full and FIFO empty tests using
* this FIFO style, the read and write pointers must be
* passed to the opposite clock domain for pointer comparison
*************************************************************//*在检测“满”或“空”状态之前,需要将指针同步到其它时钟域时,使用格雷码,可以降低同步过程中亚稳态出现的概率*/sync_r2w I1_sync_r2w(
   .wq2_rptr(wq2_rptr),
   .rptr(rptr),
   .wclk(wclk),
   .wrst_n(wrst_n));
sync_w2r I2_sync_w2r (
   .rq2_wptr(rq2_wptr),
   .wptr(wptr),
   .rclk(rclk),
   .rrst_n(rrst_n));/**  DualRAM
*/DualRAM #(DSIZE, ASIZE) I3_DualRAM(
   .rdata(rdata),
   .wdata(wdata),
   .waddr(waddr),
   .raddr(raddr),
   .wclken(winc),
   .wclk(wclk));    /**  空、满比较逻辑*/rptr_empty #(ASIZE) I4_rptr_empty(
   .rempty(rempty),
   .raddr(raddr),
   .rptr(rptr),
   .rq2_wptr(rq2_wptr),
   .rinc(rinc),
   .rclk(rclk),
   .rrst_n(rrst_n));
wptr_full #(ASIZE) I5_wptr_full(
   .wfull(wfull),
   .waddr(waddr),
   .wptr(wptr),
   .wq2_rptr(wq2_rptr),
   .winc(winc),
   .wclk(wclk),
   .wrst_n(wrst_n));endmodule

 

2)DualRAM模块

module DualRAM
#(    parameter DATA_SIZE = 8,   // 数据位宽
   parameter ADDR_SIZE = 4   // 地址位宽)
(    input                       wclken,wclk,    input      [ADDR_SIZE-1:0]  raddr,     //RAM read address
   input      [ADDR_SIZE-1:0]  waddr,     //RAM write address
   input      [DATA_SIZE-1:0]  wdata,    //data input
   output     [DATA_SIZE-1:0]  rdata      //data output);    localparam RAM_DEPTH = 1 << ADDR_SIZE;   //RAM深度 = 2^ADDR_WIDTH
       reg [DATA_SIZE-1:0] Mem[RAM_DEPTH-1:0];        always@(posedge wclk)begin
    if(wclken)
        Mem[waddr] <= wdata;endassign rdata =  Mem[raddr];endmodule


3)同步模块

module sync_r2w
#(parameter ADDRSIZE = 4)
(    output reg [ADDRSIZE:0] wq2_rptr,    input      [ADDRSIZE:0] rptr,    input                       wclk, wrst_n
);reg [ADDRSIZE:0] wq1_rptr;always @(posedge wclk or negedge wrst_n)    if (!wrst_n)
       {wq2_rptr,wq1_rptr} <= 0;    else
       {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};endmodule


4)同步模块2


module sync_w2r
#(parameter ADDRSIZE = 4)
(    output reg  [ADDRSIZE:0] rq2_wptr,    input         [ADDRSIZE:0] wptr,    input         rclk, rrst_n
);        reg [ADDRSIZE:0] rq1_wptr;always @(posedge rclk or negedge rrst_n)    if (!rrst_n)
       {rq2_wptr,rq1_wptr} <= 0;    else
       {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};endmodule


5)空判断逻辑

module rptr_empty
#(parameter ADDRSIZE = 4)
(    output reg rempty,    output     [ADDRSIZE-1:0] raddr,    output reg [ADDRSIZE :0]  rptr,    input       [ADDRSIZE :0] rq2_wptr,    input       rinc, rclk, rrst_n);

reg  [ADDRSIZE:0] rbin;wire [ADDRSIZE:0] rgraynext, rbinnext;wire  rempty_val;//-------------------// GRAYSTYLE2 pointer: gray码读地址指针//-------------------always @(posedge rclk or negedge rrst_n)    if (!rrst_n)
       begin
           rbin <= 0;
           rptr <= 0;        end
   else
       begin
           rbin <= rbinnext ;
           rptr <= rgraynext;        end// gray码计数逻辑assign rbinnext = !rempty ? (rbin + rinc) : rbin;assign rgraynext = (rbinnext>>1) ^ rbinnext;      //二进制到gray码的转换
       assign raddr = rbin[ADDRSIZE-1:0];//---------------------------------------------------------------// FIFO empty when the next rptr == synchronized wptr or on reset//---------------------------------------------------------------/**   读指针是一个n位的gray码计数器,比FIFO寻址所需的位宽大一位
*   当读指针和同步过来的写指针完全相等时(包括MSB),说明二者折回次数一致,FIFO为空
*    
*/assign rempty_val = (rgraynext == rq2_wptr);        always @(posedge rclk or negedge rrst_n)if (!rrst_n)
   rempty <= 1'b1;else
   rempty <= rempty_val;endmodule


6)满判断逻辑

module wptr_full
#(    parameter ADDRSIZE = 4)
(    output reg                wfull,    output     [ADDRSIZE-1:0] waddr,    output reg [ADDRSIZE :0]  wptr,    input      [ADDRSIZE :0]  wq2_rptr,    input                     winc, wclk, wrst_n);        

reg  [ADDRSIZE:0] wbin;wire [ADDRSIZE:0] wgraynext, wbinnext;wire wfull_val;// GRAYSTYLE2 pointeralways @(posedge wclk or negedge wrst_n)    if (!wrst_n)
   begin
       wbin <= 0;
       wptr <= 0;    end
   else
   begin
       wbin <= wbinnext;
        wptr <= wgraynext;    end//gray 码计数逻辑    assign wbinnext  = !wfull ? wbin + winc : wbin;assign wgraynext = (wbinnext>>1) ^ wbinnext;        assign waddr = wbin[ADDRSIZE-1:0];        /*由于满标志在写时钟域产生,因此比较安全的做法是将读指针同步到写时钟域*//**///------------------------------------------------------------------// Simplified version of the three necessary full-tests:// assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) &&// (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) &&// (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0]));//------------------------------------------------------------------assign wfull_val = (wgraynext=={~wq2_rptr[ADDRSIZE:ADDRSIZE-1],
                   wq2_rptr[ADDRSIZE-2:0]});always @(posedge wclk or negedge wrst_n)if (!wrst_n)
   wfull <= 1'b0;else
   wfull <= wfull_val;endmodule


P.S :在quartus中有异步FIFO IP核,为安全起见推荐使用IP核定制FIFO,本文的目的只是作为思路参考。


-END-
资源介绍了LCD1602字符显示设计,4位加减法设计,三位二进制乘法器设计,序列检测器设计,变模计数器设计,流水灯设计,简易电子时钟设计,简易计算器设计共8个小白入门常用的实验。


《写给小白们的FPGA入门(打包合集资料)


点击阅读原文可直接下载完整资料,如果您的手机下载出错,请使用电脑访问网站下载,下载链接:https://mbb.eet-china.com/download/19252.html

EDN电子技术设计 EDN China电子技术设计为电子设计工程师和设计经理人提供前沿深度的电子资讯、设计实例应用方案。
评论
  • 随着数字化的不断推进,LED显示屏行业对4K、8K等超高清画质的需求日益提升。与此同时,Mini及Micro LED技术的日益成熟,推动了间距小于1.2 Pitch的Mini、Micro LED显示屏的快速发展。这类显示屏不仅画质卓越,而且尺寸适中,通常在110至1000英寸之间,非常适合应用于电影院、监控中心、大型会议、以及电影拍摄等多种室内场景。鉴于室内LED显示屏与用户距离较近,因此对于噪音控制、体积小型化、冗余备份能力及电气安全性的要求尤为严格。为满足这一市场需求,开关电源技术推出了专为
    晶台光耦 2025-01-13 10:42 112浏览
  • 随着全球向绿色能源转型的加速,对高效、可靠和环保元件的需求从未如此强烈。在这种背景下,国产固态继电器(SSR)在实现太阳能逆变器、风力涡轮机和储能系统等关键技术方面发挥着关键作用。本文探讨了绿色能源系统背景下中国固态继电器行业的前景,并强调了2025年的前景。 1.对绿色能源解决方案日益增长的需求绿色能源系统依靠先进的电源管理技术来最大限度地提高效率并最大限度地减少损失。固态继电器以其耐用性、快速开关速度和抗机械磨损而闻名,正日益成为传统机电继电器的首选。可再生能源(尤其是太阳能和风能
    克里雅半导体科技 2025-01-10 16:18 89浏览
  • PNT、GNSS、GPS均是卫星定位和导航相关领域中的常见缩写词,他们经常会被用到,且在很多情况下会被等同使用或替换使用。我们会把定位导航功能测试叫做PNT性能测试,也会叫做GNSS性能测试。我们会把定位导航终端叫做GNSS模块,也会叫做GPS模块。但是实际上他们之间是有一些重要的区别。伴随着技术发展与越发深入,我们有必要对这三个词汇做以清晰的区分。一、什么是GPS?GPS是Global Positioning System(全球定位系统)的缩写,它是美国建立的全球卫星定位导航系统,是GNSS概
    德思特测试测量 2025-01-13 15:42 65浏览
  • 流量传感器是实现对燃气、废气、生活用水、污水、冷却液、石油等各种流体流量精准计量的关键手段。但随着工业自动化、数字化、智能化与低碳化进程的不断加速,采用传统机械式检测方式的流量传感器已不能满足当代流体计量行业对于测量精度、测量范围、使用寿命与维护成本等方面的精细需求。流量传感器的应用场景(部分)超声波流量传感器,是一种利用超声波技术测量流体流量的新型传感器,其主要通过发射超声波信号并接收反射回来的信号,根据超声波在流体中传播的时间、幅度或相位变化等参数,间接计算流体的流量,具有非侵入式测量、高精
    华普微HOPERF 2025-01-13 14:18 94浏览
  • Snyk 是一家为开发人员提供安全平台的公司,致力于协助他们构建安全的应用程序,并为安全团队提供应对数字世界挑战的工具。以下为 Snyk 如何通过 CircleCI 实现其“交付”使命的案例分析。一、Snyk 的挑战随着客户对安全工具需求的不断增长,Snyk 的开发团队面临多重挑战:加速交付的需求:Snyk 的核心目标是为开发者提供更快、更可靠的安全解决方案,但他们的现有 CI/CD 工具(TravisCI)运行缓慢,无法满足快速开发和部署的要求。扩展能力不足:随着团队规模和代码库的不断扩大,S
    艾体宝IT 2025-01-10 15:52 155浏览
  • ARMv8-A是ARM公司为满足新需求而重新设计的一个架构,是近20年来ARM架构变动最大的一次。以下是对ARMv8-A的详细介绍: 1. 背景介绍    ARM公司最初并未涉足PC市场,其产品主要针对功耗敏感的移动设备。     随着技术的发展和市场需求的变化,ARM开始扩展到企业设备、服务器等领域,这要求其架构能够支持更大的内存和更复杂的计算任务。 2. 架构特点    ARMv8-A引入了Execution State(执行状
    丙丁先生 2025-01-12 10:30 109浏览
  • 新年伊始,又到了对去年做总结,对今年做展望的时刻 不知道你在2024年初立的Flag都实现了吗? 2025年对自己又有什么新的期待呢? 2024年注定是不平凡的一年, 一年里我测评了50余块开发板, 写出了很多科普文章, 从一个小小的工作室成长为科工公司。 展望2025年, 中国香河英茂科工, 会继续深耕于,具身机器人、飞行器、物联网等方面的研发, 我觉得,要向未来学习未来, 未来是什么? 是掌握在孩子们生活中的发现,和精历, 把最好的技术带给孩子,
    丙丁先生 2025-01-11 11:35 107浏览
  • 随着通信技术的迅速发展,现代通信设备需要更高效、可靠且紧凑的解决方案来应对日益复杂的系统。中国自主研发和制造的国产接口芯片,正逐渐成为通信设备(从5G基站到工业通信模块)中的重要基石。这些芯片凭借卓越性能、成本效益及灵活性,满足了现代通信基础设施的多样化需求。 1. 接口芯片在通信设备中的关键作用接口芯片作为数据交互的桥梁,是通信设备中不可或缺的核心组件。它们在设备内的各种子系统之间实现无缝数据传输,支持高速数据交换、协议转换和信号调节等功能。无论是5G基站中的数据处理,还是物联网网关
    克里雅半导体科技 2025-01-10 16:20 101浏览
  • 电动汽车(EV)正在改变交通运输,为传统内燃机提供更清洁、更高效的替代方案。这种转变的核心是电力电子和能源管理方面的创新,而光耦合器在其中发挥着关键作用。这些不起眼的组件可实现可靠的通信、增强安全性并优化电动汽车系统的性能,使其成为正在进行的革命中不可或缺的一部分。光耦合器,也称为光隔离器,是一种使用光传输电信号的设备。通过隔离高压和低压电路,光耦合器可确保安全性、减少干扰并保持信号完整性。这些特性对于电动汽车至关重要,因为精确控制和安全性至关重要。 光耦合器在电动汽车中的作用1.电池
    腾恩科技-彭工 2025-01-10 16:14 59浏览
  • 根据Global Info Research(环洋市场咨询)项目团队最新调研,预计2030年全球无人机电池和电源产值达到2834百万美元,2024-2030年期间年复合增长率CAGR为10.1%。 无人机电池是为无人机提供动力并使其飞行的关键。无人机使用的电池类型因无人机的大小和型号而异。一些常见的无人机电池类型包括锂聚合物(LiPo)电池、锂离子电池和镍氢(NiMH)电池。锂聚合物电池是最常用的无人机电池类型,因为其能量密度高、设计轻巧。这些电池以输出功率大、飞行时间长而著称。不过,它们需要
    GIRtina 2025-01-13 10:49 81浏览
  • 01. 什么是过程能力分析?过程能力研究利用生产过程中初始一批产品的数据,预测制造过程是否能够稳定地生产符合规格的产品。可以把它想象成一种预测。通过历史数据的分析,推断未来是否可以依赖该工艺持续生产高质量产品。客户可能会要求将过程能力研究作为生产件批准程序 (PPAP) 的一部分。这是为了确保制造过程能够持续稳定地生产合格的产品。02. 基本概念在定义制造过程时,目标是确保生产的零件符合上下规格限 (USL 和 LSL)。过程能力衡量制造过程能多大程度上稳定地生产符合规格的产品。核心概念很简单:
    优思学院 2025-01-12 15:43 147浏览
  • 说到福特,就要从亨利·福特(Henry Ford)这个人物说起。在发明大王爱迪生的电气工厂担任工程师的福特下班后,总是在自家仓库里努力研究和开发汽车。1896年,福特终于成功制造出一辆三轮车,开启了福特汽车的传奇。最初几年,福特都是独自制造汽车并同时进行销售。 (今天很多人都知道的精益管理中的5S方法,或多或少地受到了福特 CANDO方法的影响。)1903年,福特从牧师、律师、银行家、会计师等十一位股东那里筹集了十万美元,并在自家庭院成立了美国第五百零三家汽车公司——福特汽车公司(Fo
    优思学院 2025-01-10 11:21 29浏览
  • 在不断发展的电子元件领域,继电器——作为切换电路的关键设备,正在经历前所未有的技术变革。固态继电器(SSR)和机械继电器之间的争论由来已久。然而,从未来发展的角度来看,固态继电器正逐渐占据上风。本文将从耐用性、速度和能效三个方面,全面剖析固态继电器为何更具优势,并探讨其在行业中的应用与发展趋势。1. 耐用性:经久耐用的设计机械继电器:机械继电器依靠物理触点完成电路切换。然而,随着时间的推移,这些触点因电弧、氧化和材料老化而逐渐磨损,导致其使用寿命有限。因此,它们更适合低频或对切换耐久性要求不高的
    腾恩科技-彭工 2025-01-10 16:15 77浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦