一个简单的RTL同步FIFO设计

时间:2025-11-02  作者:Diven  阅读:0

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

一个简单的RTL同步FIFO设计

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

为什么要自己设计FIFO

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

FIFO 规格性能

同步,单时钟。

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

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

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

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

 

Module my_fifo #(                   parameter DATA_W           = 4      ,        // Data width                   parameter DEPTH            = 8      ,        // Depth of FIFO                                      parameter UPP_TH           = 4      ,        // Upper threshold to generate Almost-full                   parameter LOW_TH           = 2               // Lower threshold to generate Almost-empty                )                (                   input                   clk         ,        // Clock                   input                   rstn        ,        // Active-low Synchronous Reset                                      input                   i_wren      ,        // Write Enable                   input  [DATA_W - 1 : 0] i_wrdata    ,        // Write-data                   output                  o_alm_full  ,        // Almost-full signal                   output                  o_full      ,        // Full signal                   input                   i_rden      ,        // Read Enable                   output [DATA_W - 1 : 0] o_rddata    ,        // Read-data                   output                  o_alm_empty ,        // Almost-empty signal                   output                  o_empty              // Empty signal                );logIC [DATA_W - 1        : 0] data_rg [DEPTH] ;        // Data arraylogIC [$clog2(DEPTH) - 1 : 0] wrptr_rg        ;        // Write pointerlogic [$clog2(DEPTH) - 1 : 0] rdptr_rg        ;        // Read pointerlogic [$clog2(DEPTH)     : 0] dcount_rg       ;        // Data counter      logic                         wren_s          ;        // Write Enable signal generated iff FIFO is not fulllogic                         rden_s          ;        // Read Enable signal generated iff FIFO is not emptylogic                         full_s          ;        // Full signallogic                         empty_s         ;        // Empty signalalways @ (posedge clk) begin   if (!rstn) begin                     data_rg   <= '{default: '0} ;      wrptr_rg  <= 0              ;      rdptr_rg  <= 0              ;            dcount_rg <= 0              ;   end   else begin      ready_rg <= 1'b1 ;                              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            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            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   endend// Full and Empty internalassign full_s      = (dcount_rg == DEPTH) ? 1'b1 : 0 ;assign empty_s     = (dcount_rg == 0    ) ? 1'b1 : 0 ;// Write and Read Enables internalassign wren_s      = i_wren & !full_s                ;  assign rden_s      = i_rden & !empty_s               ;// Full and Empty to outputassign o_full      = full_s                          ;assign o_empty     = empty_s                         ;// Almost-full and Almost Empty to outputassign o_alm_full  = (dcount_rg > UPP_TH) ? 1'b1 : 0 ;assign o_alm_empty = (dcount_rg < LOW_TH) ? 1'b1 : 0 ;// Read-data to outputassign o_rddata    = data_rg [rdptr_rg]              ;   endModule

 

基于 RAM 的 FIFO

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


审核编辑:刘清

猜您喜欢

牛皮纸胶带是常见的包装材料,其主要特点是耐撕、易撕和环保。不同类型的牛皮纸胶带在性能和用途上存在一些区别。牛皮纸胶带的厚度不同。较厚的胶带通常具有更强的粘附力和...
2024-08-24 00:00:00

现代科技迅猛发展的背景下,各种配件在我们的日常生活中是愈发重要的配件。特别是在电子产品和机械设备中,配件不仅提升了产品的功能性,还改善了用户的使用体验。本文将重...
2025-04-26 09:01:18

电路保护元件的重要性日益凸显。自恢复保险丝作为能够自动恢复的过流保护装置,因其安全性高、使用寿命长等优点,受到市场青睐。科甜作为业内知名品牌,其自恢复保险丝产品...
2021-02-23 07:40:30

吹尘枪是专用于清洁和吹拂灰尘、污垢的工具,应用于电子设备、机械部件、办公环境等领域。其基本构造通常由气体源、喷嘴和手柄组成,通过高压气体将灰尘和杂物吹离表面,达...
2012-02-08 00:00:00

在现代家居与办公环境中,台灯灵活多变的应用领域成为不可少的光源。在书房,一盏明亮而不刺眼的台灯,为阅读者营造舒适的学习氛围;在工作室,可调节亮度的台灯,满足绘画...
2012-12-28 00:00:00

红外遥控接收头(IRM)是应用于家庭电器、玩具、安防系统等设备中的重要电子元件。主要功能是接收来自遥控器发出的红外信号,并将其转换为电信号,以便设备能够识别和执...
2011-04-22 00:00:00

随着人工智能(AI)的不断发展,它已经从早期的人工特征工程进化到现在可以从海量数据中学习,机器视觉、语音识别以及自然语言处理等领域都取得了重大突破。CNN(Co...
2018-07-10 10:49:00


红外光电探测器广泛应用于气体传感、气象遥感以及航天探测等领域。然而目前,传统的红外探测材料主要基于碲化铟、铟镓砷、碲镉汞等,需要分子束外延方法生长,以及倒装键和...
2023-11-20 09:03:00

贴片排阻作为电子元件中的重要组成部分,应用于各种电路设计中。TA-I(大毅)作为国内知名的贴片排阻品牌,优良的品质和丰富的规格赢得了市场的认可。本文将围绕TA-...
2015-03-23 19:38:30