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
责任编辑:彭菁

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

    关注

    30

    文章

    5028

    浏览量

    117719
  • 数据
    +关注

    关注

    8

    文章

    6511

    浏览量

    87599
  • fifo
    +关注

    关注

    3

    文章

    369

    浏览量

    43069

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

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

收藏 人收藏

    评论

    相关推荐

    解析CPU中的寄存器

    8位寄存器在16位寄存器中,而16位寄存器在32位寄存器中。
    发表于 09-19 10:10 2901次阅读

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

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

    如何正确更改移位寄存器FIFO的大小?

    我需要能够产生由24位字组成的数据流,它们之间没有间距。为了实现这一点,我使用一个移位寄存器-我正在写我的数据到它的FIFO,然后使电路加载先进的数据到移位寄存器(见示意图)。默认情况下,FI
    发表于 09-29 14:42

    SPI2_CONFIG寄存器FIFO深度是根据什么改变的?

    SPI2_CONFIG寄存器FIFO深度是根据什么改变的?是根据TRANSCTRL寄存器的WRTRANCNT和RDTRANCNT设置改变吗?为什么我设置了WRTRANCNT和RDTRANCNT,SPI2_CONFIG
    发表于 05-26 07:46

    FIFO的操作

    系统在上电复位时,SPI工作在标准SPI模式,禁止FIFO功能。FIFO寄存器SPIFFTX、SPIFFRX和SPIFFCT不起作用。通过将SPIFFTX寄存器中的SPIFFEN的位
    发表于 09-29 10:38 33次下载

    寄存器与移位寄存器

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

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

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

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

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

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

    32位寄存器,32位寄存器是什么意思  从X8086开始学了一年,第一个ASM的程序就是变32换16进制的程序,不过现在叫我从新开始写ASM程
    发表于 03-08 17:26 1.7w次阅读

    寄存器与移位寄存器

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

    MPU6050寄存器介绍

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

    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

    RAL寄存器模型操作图鉴

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

    RAL寄存器模型操作指南

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

    同步FIFO和异步FIFO的区别 同步FIFO和异步FIFO各在什么情况下应用

    同步FIFO和异步FIFO的区别 同步FIFO和异步FIFO各在什么情况下应用? 1.
    的头像 发表于 10-18 15:23 1013次阅读