查看: 563|回复: 0

[经验] 【转】FIFO 总结

[复制链接]

582

主题

3

好友

1万

积分

翰林

Rank: 7Rank: 7Rank: 7

  • TA的每日心情
    擦汗
    2014-2-12 10:49
  • 签到天数: 150 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2017-7-25 16:00:44 |显示全部楼层


    • 何为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
    复制代码
    仿真波形:
    index5.png


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

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

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

    手机版|爱板网 |网站地图  

    GMT+8, 2017-8-24 14:42 , Processed in 0.484972 second(s), 10 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部