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

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

3天内不再提示

基于寄存器的同步FIFO

OpenFPGA 来源:OpenFPGA 2023-06-14 09:02 次阅读

FIFO 是FPGA设计中最有用的模块之一。FIFO 在模块之间提供简单的握手和同步机制,是设计人员将数据从一个模块传输到另一个模块的常用选择。

在这篇文章中,展示了一个简单的 RTL 同步 FIFO,可以直接在自己的设计中配置和使用它,该设计是完全可综合的。

为什么要自己设计FIFO

那么,为什么呢?网上有很多关于 FIFO 的 Verilog/VHDL 代码的资源,过去,我自己也使用过其中的一些。但令人沮丧的是,它们中的大多数都存在问题,尤其是在上溢出和下溢出条件下。所以想一劳永逸地解决这些问题。

FIFO 规格性能

同步,单时钟

基于寄存器的 FIFO,适用于中小型 FIFO。

Full、Empty、Almost-full、Almost-empty 标志。

完全可配置的数据宽度、深度和标志。

完全可综合的系统 Verilog 代码。

/*===============================================================================================================================
Design:Single-clockSynchronousFIFO

Description:Fullysynthesisable,configurableSingle-clockSynchronousFIFObasedonregisters.
-ConfigurableDatawidth.
-ConfigurableDepth.
-ConfigurableAlmost-fullandAlmost-emptysignals.
===============================================================================================================================*/

modulemy_fifo#(
parameterDATA_W=4,//Datawidth
parameterDEPTH=8,//DepthofFIFO
parameterUPP_TH=4,//UpperthresholdtogenerateAlmost-full
parameterLOW_TH=2//LowerthresholdtogenerateAlmost-empty
)

(
inputclk,//Clock
inputrstn,//Active-lowSynchronousReset

inputi_wren,//WriteEnable
input[DATA_W-1:0]i_wrdata,//Write-data
outputo_alm_full,//Almost-fullsignal
outputo_full,//Fullsignal

inputi_rden,//ReadEnable
output[DATA_W-1:0]o_rddata,//Read-data
outputo_alm_empty,//Almost-emptysignal
outputo_empty//Emptysignal
);


/*-------------------------------------------------------------------------------------------------------------------------------
InternalRegisters/Signals
-------------------------------------------------------------------------------------------------------------------------------*/

logic[DATA_W-1:0]data_rg[DEPTH];//Dataarray
logic[$clog2(DEPTH)-1:0]wrptr_rg;//Writepointer
logic[$clog2(DEPTH)-1:0]rdptr_rg;//Readpointer
logic[$clog2(DEPTH):0]dcount_rg;//Datacounter

logicwren_s;//WriteEnablesignalgeneratediffFIFOisnotfull
logicrden_s;//ReadEnablesignalgeneratediffFIFOisnotempty
logicfull_s;//Fullsignal
logicempty_s;//Emptysignal


/*-------------------------------------------------------------------------------------------------------------------------------
SynchronouslogictowritetoandreadfromFIFO
-------------------------------------------------------------------------------------------------------------------------------*/
always@(posedgeclk)begin

if(!rstn)begin

data_rg<= '{default: '0} ;
      wrptr_rg  <= 0              ;
      rdptr_rg  <= 0              ;      
      dcount_rg <= 0              ;

   end

   else begin

      ready_rg <= 1'b1 ;
      
      /* FIFO write logic */            
      if (wren_s) begin                          
         
         data_rg [wrptr_rg] <= i_wrdata ;        // Data written to FIFO

         if (wrptr_rg == DEPTH - 1) begin
            wrptr_rg <= 0               ;        // Reset write pointer  
         end

         else begin
            wrptr_rg <= wrptr_rg + 1    ;        // Increment write pointer            
         end

      end

      /* FIFO read logic */
      if (rden_s) begin         

         if (rdptr_rg == DEPTH - 1) begin
            rdptr_rg <= 0               ;        // Reset read pointer
         end

         else begin
            rdptr_rg <= rdptr_rg + 1    ;        // Increment read pointer            
         end

      end

      /* FIFO data counter update logic */
      if (wren_s && !rden_s) begin               // Write operation
         dcount_rg <= dcount_rg + 1 ;
      end                    
      else if (!wren_s && rden_s) begin          // Read operation
         dcount_rg <= dcount_rg - 1 ;         
      end

   end

end


/*-------------------------------------------------------------------------------------------------------------------------------
   Continuous Assignments
-------------------------------------------------------------------------------------------------------------------------------*/

// Full and Empty internal
assign full_s      = (dcount_rg == DEPTH) ? 1'b1 : 0 ;
assign empty_s     = (dcount_rg == 0    ) ? 1'b1 : 0 ;

// Write and Read Enables internal
assign wren_s      = i_wren & !full_s                ;  
assign rden_s      = i_rden & !empty_s               ;

// Full and Empty to output
assign o_full      = full_s                          ;
assign o_empty     = empty_s                         ;

// Almost-full and Almost Empty to output
assign o_alm_full  = (dcount_rg >UPP_TH)?1'b1:0;
assigno_alm_empty=(dcount_rg< LOW_TH) ? 1'b1 : 0 ;

// Read-data to output
assign o_rddata    = data_rg [rdptr_rg]              ;   


endmodule

/*=============================================================================================================================*/

基于 RAM 的 FIFO

在上面的步骤中,我们看到了一个基于寄存器的同步FIFO。接下来,我们来看看基于 RAM 的 FIFO。该 FIFO 在 RAM 而不是寄存器上实现其数据阵列。这适用于在硬件上实现大型 FIFO ;特别是在 FPGA 上,FPGA 里有大量的Block RAM 可用。这将降低资源利用率,也可以获得更好的时序性能。

详细代码:

https://github.com/iammituraj/FIFOs
责任编辑:彭菁

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

    关注

    31

    文章

    5290

    浏览量

    119787
  • 数据
    +关注

    关注

    8

    文章

    6795

    浏览量

    88730
  • fifo
    +关注

    关注

    3

    文章

    386

    浏览量

    43486

原文标题:【手撕代码】同步 FIFO、LIFO/Stack

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

收藏 人收藏

    评论

    相关推荐

    寄存器是什么?怎么操作寄存器点亮LED灯?

    寄存器,是集成电路中非常重要的一种存储单元,通常由触发组成。在集成电路设计中,寄存器可分为电路内部使用的寄存器和充当内外部接口的寄存器这两
    的头像 发表于 07-21 16:59 3805次阅读
    <b class='flag-5'>寄存器</b>是什么?怎么操作<b class='flag-5'>寄存器</b>点亮LED灯?

    寄存器与移位寄存器

    寄存器与移位寄存器 寄存器是用来寄存数码的逻辑部件,所以必须具备接收和寄存数码的功能。任何一种触发
    发表于 03-12 15:19 59次下载

    寄存器,寄存器是什么意思

    寄存器,寄存器是什么意思 寄存器定义  寄存器是中央处理内的组成部分。寄存器是有限存贮容量
    发表于 03-08 14:26 2.2w次阅读

    数据寄存器,数据寄存器是什么意思

    数据寄存器,数据寄存器是什么意思 数据寄存器数据寄存器包括累加AX、基址寄存器BX、计数
    发表于 03-08 14:38 1.2w次阅读

    移位寄存器,移位寄存器是什么意思

    移位寄存器,移位寄存器是什么意思 移位寄存器_
    发表于 03-08 14:50 1.7w次阅读

    寄存器与移位寄存器

    寄存器与移位寄存器:介绍寄存器原理和移位寄存器的原理及实现。
    发表于 05-20 11:47 0次下载

    移位寄存器的原理

    移位寄存器按照不同的分类方法可以分为不同的类型。 如果按照移位寄存器的移位方向来进行分类, 可以分为左移移位寄存器、移位寄存器和双向移位寄存器
    发表于 07-15 09:38 7.4w次阅读
    移位<b class='flag-5'>寄存器</b>的原理

    AD转换寄存器设置

    AD转换寄存器设置AD转换寄存器设置AD转换寄存器设置
    发表于 11-10 17:36 16次下载
    AD转换<b class='flag-5'>寄存器</b>设置

    MPU6050寄存器介绍

    MPU6050寄存器介绍电源管理寄存器1(0X6B)陀螺仪配置寄存器(0X1B)加速度传感配置寄存器(0X1C)
    发表于 12-06 11:51 20次下载
    MPU6050<b class='flag-5'>寄存器</b>介绍

    ARM通用寄存器及状态寄存器详解

    笔者来聊聊ARM通用寄存器以及状态寄存器的认识与理解。
    的头像 发表于 01-06 14:58 6840次阅读

    4 位 x16字 FIFO 寄存器-74HC40105

    4 位 x 16 字 FIFO 寄存器-74HC40105
    发表于 02-20 19:59 0次下载
    4 位 x16字 <b class='flag-5'>FIFO</b> <b class='flag-5'>寄存器</b>-74HC40105

    单片机工作寄存器作用 单片机常用专用寄存器

    除了通用寄存器(如累加、通用寄存器等),单片机中还会有特定功能的寄存器,如定时寄存器、中断控
    的头像 发表于 04-08 14:46 7215次阅读

    RAL寄存器模型操作图鉴

    寄存器模型操作,指的是通过寄存器模型对RTL中寄存器进行读写访问,或者同步寄存器模型与RTL中寄存器
    的头像 发表于 05-17 09:01 880次阅读
    RAL<b class='flag-5'>寄存器</b>模型操作图鉴

    RAL寄存器模型操作指南

    寄存器模型操作,指的是通过寄存器模型对RTL中寄存器进行读写访问,或者同步寄存器模型与RTL中寄存器
    的头像 发表于 07-12 09:37 1004次阅读
    RAL<b class='flag-5'>寄存器</b>模型操作指南

    寄存器分为基本寄存器和什么两种

    寄存器是计算机中用于存储数据的高速存储单元,它们是CPU内部的重要组成部分。寄存器可以分为基本寄存器和扩展寄存器两种类型。 一、基本寄存器
    的头像 发表于 07-12 10:31 1001次阅读