zoukankan      html  css  js  c++  java
  • FIFO

    FIFO存储器 FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。  在系统设计中,以增加数据传输率、处理大量数据流、匹配具有不同传输率的系统为目的而广泛使用FIFO存储器,从而提高了系统性能.

    FIFO参数:

    FIFO的宽度,the width,指FIFO一次读写操作的数据位;

    FIFO深度,THE DEEPTH,指FIFO可以存储多少个N位的数据;

    满标志,FIFO已满或将要满时送出的一个信号,以阻止FIFO的血操作继续向FIFO中写数据而造成溢出(overflow);

    空标志,阻止FIFIO的读操作;

    1.quartus中直接调用FIFO IP核

    2.verilog

    异步FIFO代码:

    module fifo_module
    (
        input CLK,
         input RSTn,
         
         input Write_Req,
         input [7:0]FIFO_Write_Data,
         
         input Read_Req,
         output [7:0]FIFO_Read_Data,
         
         output Full_Sig,
         output Empty_Sig,
         
         /**********************/
         
         output [7:0]SQ_rS1,
         output [7:0]SQ_rS2,
         output [7:0]SQ_rS3,
         output [7:0]SQ_rS4,
         output [2:0]SQ_Count
         
         /**********************/
    );
    
        /************************************/
         
         parameter DEEP = 3'd4;
         
         /************************************/
      
        reg [7:0]rShift [DEEP:0];
         reg [2:0]Count;
         reg [7:0]Data;
         
         always @ ( posedge CLK or negedge RSTn )
              if( !RSTn )
                  begin
                    
                        rShift[0] <= 8'd0; rShift[1] <= 8'd0; rShift[2] <= 8'd0;
                         rShift[3] <= 8'd0; rShift[4] <= 8'd0;
                         Count <= 3'd0;
                         Data <= 8'd0;
                         
                    end
              else if( Read_Req && Write_Req && Count < DEEP && Count > 0 )
                  begin
                        rShift[1] <= FIFO_Write_Data;
                         rShift[2] <= rShift[1];
                         rShift[3] <= rShift[2];
                         rShift[4] <= rShift[3];
                         Data <= rShift[ Count ];    //若深度较大,则需多行代码,且存储器间存在频繁的数据转移     
                    end
             else if( Write_Req && Count < DEEP )
                  begin
                    
                        rShift[1] <= FIFO_Write_Data;
                         rShift[2] <= rShift[1];
                         rShift[3] <= rShift[2];
                         rShift[4] <= rShift[3];
                         
                         Count <= Count + 1'b1;
                    end
            else if( Read_Req && Count > 0 )
                  begin     
                         Data <= rShift[Count]; 
                         Count <= Count - 1'b1;
                    end
    
                    
        /************************************/
         
         assign FIFO_Read_Data = Data;
         assign Full_Sig = ( Count == DEEP ) ? 1'b1 : 1'b0;
         assign Empty_Sig = ( Count == 0 ) ? 1'b1 : 1'b0;
         
         /************************************/
         
         assign SQ_rS1 = rShift[1];
         assign SQ_rS2 = rShift[2];
         assign SQ_rS3 = rShift[3];
         assign SQ_rS4 = rShift[4];
         assign SQ_Count = Count;
         
         /************************************/
    
    endmodule

    第一,FIFO 的调用绝对需要控制信号
    第二,Full_Sig  和  Empty_Sig  是不适合同步 FIFO 的写操作

    改进同步FIFO,放弃了  Empty_Sig  和  Full_Sig,取而代之的是  Left_Sig  。作用如
    名字般,该信号用来反馈出  FIFO  目前的“空格数目”

    module fifo_module_2
    (
        input CLK,
         input RSTn,
         
         input Write_Req,
         input [7:0]FIFO_Write_Data,
         
         input Read_Req,
         output [7:0]FIFO_Read_Data,
         
         output [2:0]Left_Sig
    );
    
           /************************************/
         
         parameter DEEP = 3'd4;
         
         /************************************/
      
        reg [7:0]rShift [DEEP:0];
         reg [2:0]Count;
         reg [7:0]Data;
         
         always @ ( posedge CLK or negedge RSTn )
              if( !RSTn )
                  begin
                    
                        rShift[0] <= 8'd0; rShift[1] <= 8'd0; rShift[2] <= 8'd0;
                         rShift[3] <= 8'd0; rShift[4] <= 8'd0;
                         Count <= 3'd0;
                         Data <= 8'd0;
                         
                    end
              else if( Read_Req && Write_Req && Count < DEEP && Count > 0 )
                  begin
                        rShift[1] <= FIFO_Write_Data;
                         rShift[2] <= rShift[1];
                         rShift[3] <= rShift[2];
                         rShift[4] <= rShift[3];
                         Data <= rShift[ Count ];
                    end
             else if( Write_Req && Count < DEEP )
                  begin
                    
                        rShift[1] <= FIFO_Write_Data;
                         rShift[2] <= rShift[1];
                         rShift[3] <= rShift[2];
                         rShift[4] <= rShift[3];
                         
                         Count <= Count + 1'b1;
                    end
            else if( Read_Req && Count > 0 )
                  begin     
                         Data <= rShift[Count]; 
                         Count <= Count - 1'b1;
                    end
    
                    
        /************************************/
         
         assign FIFO_Read_Data = Data;
         assign Left_Sig = DEEP - Count;
         
         /************************************/
    
    endmodule

    仿真激励文本

    `timescale 1 ps/ 1 ps
    module fifo_module_2_simulation();
    
        reg CLK;
         reg RSTn;
    
        reg Write_Req;
        reg [7:0]FIFO_Write_Data;
    
        reg Read_Req;
         
        wire [7:0]FIFO_Read_Data;
                                             
        wire [2:0]Left_Sig;
         
         /*******************/
                    
        fifo_module_2 U1 
         (
             .CLK(CLK),
              .RSTn( RSTn ),
              .Write_Req(Write_Req),
              .FIFO_Write_Data(FIFO_Write_Data),
             .Read_Req(Read_Req),
             .FIFO_Read_Data(FIFO_Read_Data),
              .Left_Sig(Left_Sig)
        );
         
         /*******************/
    
        initial                                                
        begin                                                  
            RSTn = 0; #10; RSTn = 1;
            CLK = 0; forever #10 CLK = ~CLK;          
        end    
    
        /*******************/
         
         reg [4:0]i;
         
        always @ ( posedge CLK or negedge RSTn )    
             if( !RSTn )
                  begin
                      
                      i <= 5'd0;
                      Write_Req <= 1'b0;
                      Read_Req <= 1'b0;
                      FIFO_Write_Data <= 8'd0;
                      
                    end
              else 
                  case( i )
                        
                         /**********/
                         
                        0:
                         begin Write_Req <= 1'b1; Read_Req <= 1'b0; FIFO_Write_Data <= 8'd1; i <= i + 1'b1; end
                        
                         1:
                         begin Write_Req <= 1'b1; Read_Req <= 1'b0; FIFO_Write_Data <= 8'd2; i <= i + 1'b1; end
                         
                         2:
                         begin Write_Req <= 1'b1; Read_Req <= 1'b0; FIFO_Write_Data <= 8'd3; i <= i + 1'b1; end
                         
                         3:
                         begin Write_Req <= 1'b1; Read_Req <= 1'b0; FIFO_Write_Data <= 8'd4; i <= i + 1'b1; end
                         
                         /**********/
                         
                         4:
                         begin Write_Req <= 1'b0; Read_Req <= 1'b1; i <= i + 1'b1; end
                         
                         5:
                         begin Write_Req <= 1'b0; Read_Req <= 1'b1; i <= i + 1'b1; end
                         
                         6:
                         begin Write_Req <= 1'b0; Read_Req <= 1'b1; i <= i + 1'b1; end
                         
                         7:
                         begin Write_Req <= 1'b0; Read_Req <= 1'b1; i <= i + 1'b1; end
                         
                         /**********/
                         
                         8: // 0 + 1 < 1
                         if( Left_Sig <= 1 ) begin Write_Req <= 1'b0; i <= i + 1'b1; end
                         else begin Write_Req <= 1'b1; Read_Req <= 1'b0; FIFO_Write_Data <= FIFO_Write_Data + 1'b1; end
                        
                        9: // >  DEEP - 1
                         if( Left_Sig >= 3 )begin Read_Req <= 1'b0; i <= i + 1'b1; end    
                         else begin Write_Req <= 1'b0; Read_Req <= 1'b1; end 
                         
                         /**********/
                         
                         10:
                         if( Left_Sig >= 1 ) begin Write_Req <= 1'b1; FIFO_Write_Data <= 8'd5; i <= i + 1'b1; end
                         else begin Write_Req <= 1'b0; i <= i + 1'b1; end
                         
                         11:
                         if( Left_Sig >= 1 ) begin Write_Req <= 1'b1; FIFO_Write_Data <= 8'd6; i <= i + 1'b1; end
                         else begin Write_Req <= 1'b0; i <= i + 1'b1; end
                         
                         12:
                         begin 
                         
                             if( Left_Sig >= 1 ) begin Write_Req <= 1'b1; FIFO_Write_Data <= 8'd7; end
                              else Write_Req <= 1'b0;
                              
                              if( Left_Sig <= 3 ) begin Read_Req <= 1'b1; end
                              else Read_Req <= 1'b0;
                              
                              i <= i + 1'b1; 
                              
                         end
                         
                         13: 
                         begin 
                         
                             if( Left_Sig >= 1  ) begin Write_Req <= 1'b1; FIFO_Write_Data <= 8'd8; end
                              else Write_Req <= 1'b0;
                              
                              if( Left_Sig <= 3 ) begin Read_Req <= 1'b1; end
                              else Read_Req <= 1'b0;
                              
                              i <= i + 1'b1; 
                              
                         end
                         
                         14:
                         if( Left_Sig <= 3 ) begin Write_Req <= 1'b0; Read_Req <= 1'b1; i <= i + 1'b1; end
                         else begin Read_Req <= 1'b0; i <= i + 1'b1; end
                         
                         15:
                         if( Left_Sig <= 3 ) begin Read_Req <= 1'b1; i <= i + 1'b1; end
                         else begin Read_Req <= 1'b0; i <= i + 1'b1; end
                         
                         16:
                         begin Read_Req <= 1'b0; i <= 5'd16; end
                    
                    endcase
    
         
    endmodule
  • 相关阅读:
    各数据库连接maven配置
    在 windows 下配置 git 公共库
    java笔记2(观察者模式、内部类、输入输出)
    linux 常用命令的应用笔记
    Setting Up Google Code And Github With Git
    java笔记3(单元测试中的模式)
    Apache的配置
    Ubuntu安装常用工具
    MongoDB笔记1(安装配置、用户管理、查询与SQL比较)
    Redis的安装与配置
  • 原文地址:https://www.cnblogs.com/shaogang/p/4272936.html
Copyright © 2011-2022 走看看