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】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论