• 同步FIFO学习


    在网上找的一个经典同步FIFO例子。

    一、前言

      FIFO (First-In-First-Out) 是一种先进先出的数据交互方式,在数字ASIC设计中常常被使用。FIFO按工作时钟域的不同又可以分为:同步FIFO和异步FIFO。

      同步FIFO的写时钟和读时钟为同一个时钟,FIFO内部所有逻辑都是同步逻辑,常常用于交互数据缓冲。异步FIFO的写时钟和读时钟为异步时钟,FIFO内部的写逻辑和读逻辑的交互需要异步处理,异步FIFO常用于跨时钟域交互。

      本文介绍同步FIFO的典型设计方法。

    二、原理

      典型同步FIFO有三部分组成: (1) FIFO写控制逻辑; (2)FIFO读控制逻辑; (3)FIFO 存储实体(如Memory、Reg)。

      FIFO写控制逻辑主要功能:产生FIFO写地址、写有效信号,同时产生FIFO写满、写错等状态信号;

      FIFO读控制逻辑主要功能:产生FIFO读地址、读有效信号,同时产生FIFO读空、读错等状态信号。

       

      如下图所示,FIFO读写过程的地址控制:

      (1)当FIFO初始化(复位)时fifo_write_addr与fifo_read_addr同指到0x0,此时FIFO处于空状态;

      (2)当FIFO进行写操作时,fifo_write_addr递增(增加到FIFO DEPTH时回绕),与fifo_read_addr错开,此时FIFO处于非空状态;

      (3)当FIFO进行读操作时,fifo_read_addr递增;

      

      FIFO空满状态产生:

      为产生FIFO空满标志,引入FIFO Count计数器,FIFO Count寄数器用于指示FIFO内部存储数据个数;

      (1)当只有写操作时,FIFO Count加1;只有读操作是,FIFO Count减1;其他情况下,FIFO Count保持;

      (2)当FIFO Count为0时,说明FIFO为空,fifo_empty置位;

      (3)当FIFO Count等于FIFO_DEPTH时,说明FIFO已满,fifo_full置位;

      

    三、代码

      1 //--====================================================================================--
      2 // THIS FILE IS PROVIDED IN SOURCE FORM FOR FREE EVALUATION, FOR EDUCATIONAL USE OR FOR 
      3 // PEACEFUL RESEARCH.  DO NOT USE IT IN A COMMERCIAL PRODUCT . IF YOU PLAN ON USING THIS 
      4 // CODE IN A COMMERCIAL PRODUCT, PLEASE CONTACT JUSTFORYOU200@163.COM TO PROPERLY LICENSE 
      5 // ITS USE IN YOUR PRODUCT. 
      6 // 
      7 // Project      : Verilog Common Module
      8 // File Name    : sync_fifo_ctrl.v
      9 // Creator(s)   : justforyou200@163.com
     10 // Date         : 2015/12/01
     11 // Description  : A sync fifo ctrl
     12 //
     13 // Modification :
     14 // (1) Initial design  2015-12-01
     15 //
     16 //
     17 //--====================================================================================--
     18 
     19 module SYNC_FIFO_CTRL
     20     (  
     21         clk           ,
     22         rst_n         ,
     23         fifo_wr_en    ,     
     24         fifo_rd_en    ,
     25         fifo_wr_data  ,  
     26         fifo_full     ,
     27         fifo_wr_err   ,
     28         fifo_empty    ,
     29         fifo_rd_err   ,
     30         fifo_data_cnt ,
     31         fifo_rd_data 
     32     );
     33  
     34 //PARA   DECLARATION
     35 parameter FIFO_DATA_WIDTH = 32   ; 
     36 parameter FIFO_ADDR_WIDTH = 8    ; 
     37 
     38 //INPUT  DECLARATION
     39 input                           clk          ; //fifo clock 
     40 input                           rst_n        ; //fifo clock reset (0: reset)
     41 input                           fifo_wr_en   ; //fifo write enable(1: enable)
     42 
     43 input                           fifo_rd_en   ; //fifo read enable(1: enable)
     44 input   [FIFO_DATA_WIDTH-1:0]   fifo_wr_data ; //fifo write data
     45 
     46 //OUTPUT DECLARATION
     47 output                          fifo_full    ; //fifo full status
     48 output                          fifo_wr_err  ; //fifo write error status
     49 output                          fifo_empty   ; //fifo empty status
     50 output                          fifo_rd_err  ; //fifo read error status
     51 output  [FIFO_ADDR_WIDTH  :0]   fifo_data_cnt; //fifo valid data cnt
     52 output  [FIFO_DATA_WIDTH-1:0]   fifo_rd_data ; //fifo read data
     53 
     54 //INTER  DECLARATION
     55 wire                            fifo_full    ; //fifo full status
     56 wire                            fifo_wr_err  ; //fifo write error status
     57 wire                            fifo_empty   ; //fifo empty status
     58 wire                            fifo_rd_err  ; //fifo read error status
     59 reg     [FIFO_ADDR_WIDTH  :0]   fifo_data_cnt; //fifo valid data cnt
     60 reg     [FIFO_DATA_WIDTH-1:0]   fifo_rd_data ; //fifo read data
     61 reg     [FIFO_ADDR_WIDTH-1:0]   fifo_wr_addr ; //fifo write addr
     62 reg     [FIFO_ADDR_WIDTH-1:0]   fifo_rd_addr ; //fifo write addr
     63 
     64 //FIFO MEMORY INSTANCE
     65 reg [FIFO_DATA_WIDTH-1:0] fifo_mem [{(FIFO_ADDR_WIDTH){1'b1}}:0] ;
     66 integer i ;
     67 
     68 //--========================MODULE SOURCE CODE==========================--
     69 
     70 //--=========================================--
     71 // SRAM INSTANCE :
     72 // You Can use Reg Memory or Memory model here;
     73 // FIFO Wdata & FIFO Rdata;
     74 //--=========================================--
     75 always @(posedge clk or negedge rst_n)
     76 begin
     77     if(rst_n == 1'b0)
     78     begin
     79         for(i=0;i<= {(FIFO_ADDR_WIDTH){1'b0}};i=i+1)
     80         fifo_mem[i] <= {(FIFO_DATA_WIDTH){1'b0}} ;
     81     end
     82     else if (fifo_wr_en & (~ fifo_full))
     83         fifo_mem[fifo_wr_addr] <= fifo_wr_data ;         
     84 end
     85 
     86 always @(posedge clk or negedge rst_n)
     87 begin
     88     if(rst_n == 1'b0)
     89         fifo_rd_data <= {(FIFO_DATA_WIDTH){1'b0}} ;
     90     else if (fifo_rd_en & (~ fifo_empty))
     91         fifo_rd_data <= fifo_mem[fifo_rd_addr] ;         
     92 end
     93 
     94 //--=========================================--
     95 // READ CONTROL :
     96 // Read address increase when read enable AND
     97 // Not empty;
     98 //--=========================================--
     99 always @(posedge clk or negedge rst_n)
    100 begin
    101     if(rst_n == 1'b0)
    102         fifo_rd_addr <= {(FIFO_ADDR_WIDTH){1'b0}} ;
    103     else if (fifo_rd_en & (~ fifo_empty))
    104         fifo_rd_addr <= fifo_rd_addr + 1'b1 ;         
    105 end
    106 
    107 //--=========================================--
    108 // WRITE CONTROL :
    109 // Write address increase when write enable AND
    110 // Not full.
    111 //--=========================================--
    112 always @(posedge clk or negedge rst_n)
    113 begin
    114     if(rst_n == 1'b0)
    115         fifo_wr_addr <= {(FIFO_ADDR_WIDTH){1'b0}} ;
    116     else if (fifo_wr_en & (~ fifo_full))
    117         fifo_wr_addr <= fifo_wr_addr + 1'b1 ;         
    118 end
    119 
    120 //--=========================================--
    121 // FIFO DATA CNT :
    122 // Valid Write Only, increase data cnt;
    123 // Valid Read Only, decrease data cnt;
    124 //--=========================================--
    125 always @(posedge clk or negedge rst_n)
    126 begin
    127     if(rst_n == 1'b0)
    128         fifo_data_cnt <= {(FIFO_ADDR_WIDTH + 1){1'b0}} ;
    129     else if (fifo_wr_en & (~ fifo_full) & (~(fifo_rd_en & (~fifo_empty)))) //Valid Write Only, increase data cnt;
    130         fifo_data_cnt <= fifo_data_cnt + 1'b1 ;   
    131     else if (fifo_rd_en & (~ fifo_empty) & (~(fifo_wr_en & (~fifo_full)))) //Valid Read Only, decrease data cnt;
    132         fifo_data_cnt <= fifo_data_cnt - 1'b1 ;     
    133 end
    134 
    135 //--=========================================--
    136 // FIFO Status :
    137 // 1. fifo_empty when cnt ==0 ;
    138 // 2. fifo full when cnt == MAX ;
    139 //--=========================================--
    140 assign fifo_empty  = (fifo_data_cnt == 0 ) ;
    141 assign fifo_rd_err = (fifo_data_cnt == 0 ) & fifo_rd_en ;
    142 
    143 assign fifo_full   = (fifo_data_cnt == ({(FIFO_ADDR_WIDTH){1'b1}} +1) ) ;
    144 assign fifo_wr_err = (fifo_data_cnt == ({(FIFO_ADDR_WIDTH){1'b1}} +1) ) & fifo_wr_en ;
    145 
    146 endmodule
  • 相关阅读:
    Android深入四大组件(九)Content Provider的启动过程
    mysql启动时报错:Starting MySQL... ERROR! The server quit without updating PID file (/opt/mysql/data/mysql.pid) 的解决方法
    定制rpm包-Yum环境搭建
    FPM定制RPM包实践
    nginx服务企业应用
    keepalived中的脑裂
    Linux 进程后台运行的几种方式(screen)
    ansible服务部署与使用
    HTTP服务原理
    KICKSTART无人值守安装
  • 原文地址:https://www.cnblogs.com/jiang-ic/p/8124766.html
Copyright © 2020-2023  润新知