0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA设计过程中常用的FIFO

OpenFPGA 来源:OpenFPGA 作者:OpenFPGA 2022-09-20 09:10 次阅读

介绍

无论何时,在复杂的 FPGA 设计过程中,都不可避免地需要在模块之间发送数据,实现这一点的常用的是 FIFO。

FIFO

写入:当写入 FIFO 时,需要确保不要写入太多数据以致 FIFO 溢出。为了帮助解决这个问题,FIFO 通常有一个完整的计数标志,有时还可以使用一个watermark端口

watermark:本质上告诉 FIFO 中的项目何时超过一定数量,这时候应该放慢速度或不放入数据。但如果想发送特定数量的数据,将需要添加额外的步骤在状态机中管理“above watermark”的情况。在状态机上工作时,可能需要添加状态和寄存器来管理边缘情况(空满情况)。

full flag:比较棘手的信号,因为 full flag 可能会在输入数据的同一时钟变高。如果有流水线设计,则需要在检测到“full”状态时缓冲这些数据。

count:计数可以大致了解可以进入 FIFO 的数据量。计数的更新比watermark和full flag慢,并且会给你一个保守的 FIFO 内的空间计数。我很想经常使用它,但我发现我需要在状态机中添加一些状态来管理它。

Reading:从 FIFO 读取通常不会那么糟糕,只要在空标志不置位时不读取即可。

Double Buffer

我师傅让我考虑使用双端口block-ram 作为双缓冲器。就像 FIFO 一样,类似具有如下行为的读取器和写入器:

写入器:将数据写入block-ram,然后使用跨时钟域技术将数据的大小和状态发送给读取器。

读取器:读取写入器放入 RAM 的已知数据量。

这种方法的好处在于,写入器知道它可以写入多少空间,而读取器知道它可以读取多少数据。这非常适合流水线设计。另一个方面是写入器可以在读取器读取数据时开始处理block-ram 的后半部分。不过,这种方法并不是自由操作。以下是现在需要由写入器和读取器管理的一些事情:

写入器

ram中有多少空间(或ram的一半)

开始/结束地址指针

写入了多少数据

读取器

有多少数据可供读取

开始/结束地址指针

我喜欢这种双缓冲区给我的数据量的预知。这允许我编写内核,将已知数量的数据从双缓冲区的输出转储到另一个位置,如音频视频缓冲区。不幸的是,每个使用双缓冲器的模块都必须设计为能够处理上述所有问题以及更多的跨时钟域标志。

如果不需要担心 FIFO(满/空)的边缘情况,这将是最容易使用的机制。下面将这两种机制结合起来可能是最佳方案。

Ping Pong FIFO

Ping Pong FIFO 本质上是一个上面描述的双缓冲区,包裹起来看起来像一个 FIFO。所有地址指针和跨时钟域通信都包含在一个简单的模块中。模块如下所示:

modulePPFIFO
#(parameterDATA_WIDTH=8,
ADDRESS_WIDTH=4
)(

//universalinput
inputreset,

//writeside
inputwrite_clock,
outputreg[1:0]write_ready,
input[1:0]write_activate,
output[23:0]write_fifo_size,
inputwrite_strobe,
input[DATA_WIDTH-1:0]write_data,
outputstarved,

//readside
inputread_clock,
inputread_strobe,
outputregread_ready,
inputread_activate,
outputreg[23:0]read_count,
output[DATA_WIDTH-1:0]read_data,

outputinactive
);

有单独的写入端和读取端时钟,选通用于写入和读取数据。不过也有一些新的信号:

write_ready:这与双缓冲区有关,需要管理缓冲区的两侧。这2 bit信号告诉双缓冲区的哪一侧已准备好。

0:缓冲区的下半部分准备好

1:上半部分准备好

write_activate:用户告诉 Ping Pong FIFO 它想要拥有缓冲区的一侧

write_fifo_size:表示用户可以写入 Ping Pong FIFO(PPFIFO) 的字数。

注意:不需要在完成之前填充写入端,PPFIFO 将跟踪写入的元素数量并将此信息发送到读取端,作为将递增数字模式写入 PPFIFO 的简单模块示例

/*Module:ppfifo_source
*
*Description:PopulateaPingPongFIFOwithanincrementingnumberpattern
*/

moduleppfifo_source#(
parameterDATA_WIDTH=8
)(
inputclk,
inputrst,
inputi_enable,

//PingPongFIFOInterface
input[1:0]i_wr_rdy,
outputreg[1:0]o_wr_act,
input[23:0]i_wr_size,
outputrego_wr_stb,
outputreg[DATA_WIDTH-1:0]o_wr_data
);

//LocalParameters
//Registers/Wires
reg[23:0]r_count;
//Submodules
//AsynchronousLogic
//SynchronousLogic
always@(posedgeclk)begin
//De-assertStrobes
o_wr_stb<= 0;

  if (rst) begin
    o_wr_act        <=  0;
    o_wr_stb        <=  0;
    o_wr_data       <=  0;
    r_count         <=  0;
  end
  else begin
    if (i_enable) begin
      if ((i_wr_rdy >0)&&(o_wr_act==0))begin
r_count<=  0;
        if (i_wr_rdy[0]) begin
          //Channel 0 is open
          o_wr_act[0]  <=  1;
        end
        else begin
          //Channel 1 is open
          o_wr_act[1]  <=  1;
        end
      end
      else if (o_wr_act >0)begin
if(r_count< i_wr_size) begin
          //More room left in the buffer
          r_count   <=  r_count + 1;
          o_wr_stb  <=  1;
          //put the count in the data
          o_wr_data <=  r_count;
        end
        else begin
          //Filled up the buffer, release it
          o_wr_act  <=  0;
        end
      end
    end
  end
end

endmodule

正如所看到的,通过添加一个额外的寄存器来跟踪添加到 PPFIFO 的数据量,不必担心full flags、water marks 或者counts。

阅读方面更容易。PPFIFO 知道首先写入哪个缓冲区,因此用户只需要观察一个read_ready标志,然后使用read_activate告诉它我们有控制权。以下是从 PPFIFO 读取数据的示例:

这里有更具体的细节:

用户监视“read_ready”位:当“read_ready”信号为 1 时,ppfifo 为用户准备好一个数据块。

用户使用“read_activate”信号激活该块并使用“read_strobe”读取 NEXT 数据

“read_count”是缓冲区中数据元素的总数。

用户必须在将“read_activate”设置为低之前读取所有数据

/*Module:ppfifo_sink
*
*Description:WheneverdataisavailablewithintheFIFOactivateitandreaditall
*/

moduleppfifo_sink#(
parameterDATA_WIDTH=8
)(
inputclk,
inputrst,

//PingPongFIFOInterface
inputi_rd_rdy,
outputrego_rd_act,
input[23:0]i_rd_size,
outputrego_rd_stb,
input[DATA_WIDTH-1:0]i_rd_data
);

//LocalParameters
//Registers/Wires
reg[23:0]r_count;
//Submodules
//AsynchronousLogic
//SynchronousLogic
always@(posedgeclk)begin
//De-AssertStrobes
o_rd_stb<=  0;

  if (rst) begin
    o_rd_act          <=  0;
    r_count           <=  0;
    o_rd_stb          <=  0;
  end
  else begin
    if (i_rd_rdy && !o_rd_act) begin
      r_count         <=  0;
      o_rd_act        <=  1;
    end
    else if (o_rd_act) begin
      if (r_count < i_rd_size) begin
        o_rd_stb      <=  1;
        r_count       <=  r_count + 1;
      end
      else begin
        o_rd_act      <=  0;
      end
    end
  end
end
endmodule

下面设计一个简单的测试模块来演示 Ping Pong FIFO。

源代码地址:

https://github.com/CospanDesign/verilog_ppfifo_demo

下面是几个简单模拟的截图:

a16db632-387c-11ed-ba43-dac502259ad0.png

在读事务开始和下一个写事务开始时放大仿真区域:

a21b79a2-387c-11ed-ba43-dac502259ad0.png

在读取事务之间放大

a255998e-387c-11ed-ba43-dac502259ad0.png

半放大

a2bc99ea-387c-11ed-ba43-dac502259ad0.png

截图可能不清晰,建议自己仿真。

总结

PPFIFO除了上面用于解决FIFO的“痛处”外,常见的还是处理高速数据流处理,下面是一个10M数据流分成两个5M数据流的例子。

审核编辑:彭静

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1625

    文章

    21665

    浏览量

    601739
  • FPGA设计
    +关注

    关注

    9

    文章

    428

    浏览量

    26481
  • 数据
    +关注

    关注

    8

    文章

    6884

    浏览量

    88812
  • fifo
    +关注

    关注

    3

    文章

    387

    浏览量

    43539

原文标题:乒乓操作实例讲解-FIFO

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA中常用的存储器资源

    本文主要介绍FPGA中常用的RAM、ROM、CAM、SRAM、DRAM、FLASH等资源,包括特性、工作原理、应用场景等。
    发表于 08-15 15:41 2712次阅读

    FPGA设计中常用的复位设计

    下面对FPGA设计中常用的复位设计方法进行了分类、分析和比较。针对FPGA在复位过程中存在不可靠复位的现象,提出了提高复位设计可靠性的4种方法,包括清除复位信号上的毛刺、异步复位同步释
    发表于 06-30 07:00

    平衡小车在移植过程中常见的问题有哪些?

    平衡小车在移植过程中常见的问题有哪些?
    发表于 11-10 06:19

    在嵌入式开发过程中常用的库函数有哪些

    在嵌入式开发过程中常用的库函数有哪些?有何优势?
    发表于 02-25 07:07

    基于FPGAFIFO设计和应用

    基于FPGAFIFO设计和应用 引 言   在利用DSP实现视频实时跟踪时,需要进行大量高速的图像采集。而DSP本身自带的FIFO并不足以支持系统中大量数据的暂时存储
    发表于 11-20 11:25 2207次阅读
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>FIFO</b>设计和应用

    LabVIEW FPGA模块实现FIFO深度设定

    为了解决基于LabVIEWFPGA模块的DMAFIFO深度设定不当带来的数据不连续问题,结合LabVIEWFPGA的编程特点和DMA FIFO的工作原理,提出了一种设定 FIFO 深度
    发表于 09-26 13:45 7312次阅读
    LabVIEW <b class='flag-5'>FPGA</b>模块实现<b class='flag-5'>FIFO</b>深度设定

    异步FIFO结构及FPGA设计

    异步FIFO结构及FPGA设计,解决亚稳态的问题
    发表于 11-10 15:21 4次下载

    绘制原理图和PCB图的过程中常遇到的一些问题

    绘制原理图和PCB图的过程中常遇到的一些问题.doc
    发表于 07-12 10:42 0次下载

    FPGA电路FIFO设计的源代码

    FPGA电路FIFO设计的源代码
    发表于 07-08 17:34 15次下载
    <b class='flag-5'>FPGA</b>电路<b class='flag-5'>FIFO</b>设计的源代码

    FPGA设计中常用的复位设计资料下载

    电子发烧友网为你提供FPGA设计中常用的复位设计资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子工程师们。
    发表于 04-10 08:40 40次下载
    <b class='flag-5'>FPGA</b>设计<b class='flag-5'>中常用</b>的复位设计资料下载

    FPGA调试中常用的TCL语法简介

    使用Jtag Master调试FPGA程序时用到tcl语言,通过编写tcl脚本,可以实现对FPGA的读写,为调试FPGA程序带来极大的便利,下面对FPGA调试
    的头像 发表于 02-19 19:44 2698次阅读

    AXI FIFO和AXI virtual FIFO两个IP的使用方法

    FIFO 是我们设计中常用的工具,因为它们使我们能够在进行信号和图像处理时缓冲数据。我们还使用异步FIFO来处理数据总线的时钟域交叉问题。
    发表于 11-04 09:14 4718次阅读

    FIFO使用及其各条件仿真介绍

    FIFO(First In First Out )先入先出存储器,在FPG设计中常用于跨时钟域的处理,FIFO可简单分为同步FIFO和异步FIFO
    的头像 发表于 04-25 15:55 3876次阅读
    <b class='flag-5'>FIFO</b>使用及其各条件仿真介绍

    光模块使用过程中常见的问题汇总

    光模块是一种较为敏感的光学器件,在使用过程中常常会出现很多问题,在本文中将光模块的一些常见问题进行了汇总。
    的头像 发表于 05-23 16:08 1526次阅读
    光模块使用<b class='flag-5'>过程中常</b>见的问题汇总

    封装过程中常用的检测设备

    封装过程中常用的检测设备 在软件开发过程中,封装是非常重要的一个概念。它不仅可以提高软件的可维护性,还可以增加程序员代码的复用性和安全性等。在封装过程中,需要使用一些检测设备对程序进行检测,以确保
    的头像 发表于 08-24 10:42 863次阅读