回答

收藏

【转】FIFO 总结

FPGA/DSP FPGA/DSP 3992 人阅读 | 0 人回复 | 2017-07-25



  • 何为FIFO .?

FIFO(First In First Out ) 先进先出是一个常用于数据缓存的一个数据缓冲器。


fifo主要有WRREQ(写信号)WRclk(写时钟)data(写数据)wrfull(写满标志)wrempty(写空标志)wrusedw(告知里面还有多少数据)
     Rdreq(读信号)rdclk(读时钟)rdfull(读满标志)rdempty(读空标志)rdusedw(告知里面数据个数)
  以上所有信号全是高电平有效。

  • 为什么要用fifo?

在项目设计中,我们通常需要在两个模块之间传输数据,如果两个模块的数据处理速率相同,那么自然没有什么问题,直接进行数据之间的对接就可以,可若是两个模块的数据处理速度不同呢?如果说数据接收模块和数据发送模块的速度不一致的话,必然会导致采集数据出现遗漏的现象,那么又该如何解决这一问题呢?
这里教大家一种比较简单的方法就是引用FIFO(先进先出)数据缓冲器,所有数据都先经过缓存器去缓存,然后再输入数据接收模块。这样就通过一个数据缓存的方法解决了速度不一致而导致的遗漏数据的问题。
  • 如何在quarters和ISE里调用FIFO IP核

先主要说一下quarters里面的调用,在IP核搜索区找到fifo选项,

然后写入IP核的名字,点击NEXT就可以进入配置页面,

在这里可以定义位宽和数据深度,因为同步FIFO用的不多,所以主要说一下异步FIFO,在下方的图片中可以定义写空写满和读空读满信号以及写使能和读使能等等。

其余几个页面不需要配置什么直接点击NEXT就可以。
另外需要注意的是:  读端口和写端口的输出会有几个时间差,这是由FIFO内部的结构导致的。
  • 读写控制信号的生成与fifo的应用

系统框架:

三个输入线和一个输出线
总共需要三个模块和一个顶层连线
代码展示:
写控制:
  1. module FIFO_wr(
  2. input        wire        wclk,
  3. input        wire        rst_n,
  4. input        wire        wrfull,
  5. input        wire        wrempty,
  6. output    reg        [7:0]wrdata,
  7. output    reg        wrreq
  8. );

  9. reg    [7:0]    state;

  10. always @(posedge wclk or negedge rst_n)
  11. begin
  12. if(!rst_n)
  13.     begin
  14.     wrdata<=0;
  15.     wrreq<=0;
  16.     state<=0;
  17.     end
  18. else
  19.     begin
  20.         case(state)
  21.                 0:begin
  22.                         if(wrempty)
  23.                                 begin
  24.                                     wrreq<=1    ;
  25.                                     wrdata<=0;
  26.                                     state<=1    ;   
  27.                                 end
  28.                         else   
  29.                                 state<=0;
  30.                         
  31.                     end  
  32.                 1:begin
  33.                         if(wrfull)
  34.                                 begin
  35.                                     state<=0;
  36.                                     wrreq<=0;
  37.                                     wrdata<=0;
  38.                                 end
  39.                         else
  40.                                 begin
  41.                                     wrreq<=1;
  42.                                     wrdata<=wrdata+1'b1;
  43.                                 end
  44.                     end  
  45.                 default:    state<=0;
  46.                 endcase
  47.         end
  48. end

  49. endmodule
复制代码
读控制:
  1. module     FIFO_rd(
  2. input            wire        rdclk,
  3. input            wire        rst_n,
  4. input            wire        rdempty,
  5. input            wire        rdfull,
  6. output        reg            rdreq
  7. );

  8. reg[2:0]state;

  9. always@(posedge rdclk or negedge rst_n)
  10.     begin
  11.         if(!rst_n)
  12.             begin
  13.                 state<=0;
  14.                 rdreq<=0;
  15.                
  16.             end
  17.         else
  18.           begin
  19.             case (state)
  20.                     0:begin
  21.                             if(rdfull)
  22.                              begin
  23.                                      state<=1;
  24.                                      rdreq<=1;
  25.                              end
  26.                             else   
  27.                                     state    <=0;
  28.                         end
  29.                     1:begin
  30.                             if(rdempty==0)
  31.                                 begin
  32.                                     state<=1;
  33.                                     rdreq<=1;
  34.                                 end
  35.                             else
  36.                                     begin
  37.                                     rdreq<=0;
  38.                                     state<=0;
  39.                                     end
  40.                         end
  41.             default:    state<=0;
  42.             endcase
  43.            end
  44.         end
  45. endmodule
复制代码
顶层连线:
  1. module     fifo_top(
  2.         input                wire            wrclk,
  3.         input                wire            rst_n,
  4.         input                wire            rdclk,
  5.         output            wire            [7:0]rdata   
  6.         );
  7.         
  8. wire            wrfull;
  9. wire            wrreq;
  10. wire            [7:0]wrdata;
  11. wire            wrempty;
  12. wire            rdfull;
  13. wire            rdempty;
  14. wire            rdreq;
  15.         
  16.         FIFO_wr        U1 (
  17.                           .wclk(wrclk)        ,
  18.                         .rst_n(rst_n)        ,
  19.                         .wrfull(wrfull)    ,
  20.                         .wrdata(wrdata)    ,
  21.                         .wrreq(wrreq)      ,
  22.                         .wrempty(wrempty)
  23.                     );
  24.         FIFO_rd        U2(
  25.                             .rdclk    (rdclk)        ,  
  26.                             .rst_n    (rst_n)        ,   
  27.                             .rdempty(rdempty)        ,
  28.                             .rdreq    (rdreq)        ,
  29.                             .rdfull    (rdfull)      
  30.                             );
  31.         my_fifo         U3(
  32.                             .data(wrdata)            ,
  33.                             .rdclk(rdclk)            ,
  34.                             .rdreq(rdreq)            ,
  35.                             .wrclk(wrclk)            ,
  36.                             .wrreq(wrreq)            ,
  37.                             .q(rdata)                ,
  38.                             .rdempty(rdempty)       ,
  39.                             .rdfull(rdfull)        ,
  40.                             .wrempty(wrempty)       ,
  41.                             .wrfull(wrfull)        
  42.                         );   
  43.                         
  44. endmodule
复制代码
测试文件:
  1. module    fifo_top_tb;

  2. reg            wrclk;
  3. reg            rdclk;
  4. reg            rst_n;

  5. wire            [7:0]    rdata;

  6. initial
  7. begin
  8. wrclk=1;
  9. rdclk=1;
  10. rst_n=0;
  11. #1000
  12. rst_n=1;
  13. #100000 $stop;
  14. end

  15. always #10 wrclk=~wrclk;
  16. always #20 rdclk=~rdclk;

  17. fifo_top    U1(   
  18.             .wrclk            (wrclk)            ,      
  19.             .rst_n            (rst_n)            ,      
  20.             .rdclk            (rdclk)            ,      
  21.             .rdata            (rdata)
  22. );
  23. endmodule
复制代码
仿真波形:


可以看到:
  当复位结束之前,写空标志为高电平,当有第一个数据写进去的时候,写空标志拉低,当数据写完的时候,写满标志拉高,延时了几拍后,读满标志拉高,当有第一个数据读出来以后,读满标志拉低,当数据读完后,读空标志由低变高,延时几拍后会出现写空标志,进行下一循环。
由上可以看到当读和写的时钟不一样的时候也能很方便的达到数据缓存的目的,不至于数据丢失。

关注下面的标签,发现更多相似文章
分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条