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
原文地址:https://www.cnblogs.com/shaogang/p/4272936.html