码迷,mamicode.com
首页 > 其他好文 > 详细

FPGA学习笔记之FIFO IP核

时间:2016-08-21 00:56:28      阅读:535      评论:0      收藏:0      [点我收藏+]

标签:

FIFO总结文档

  1. 何为FIFO .?

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

技术分享

 

fifo主要有WRREQ(写信号)WRclk(写时钟)data(写数据)wrfull(写满标志)wrempty(写空标志)wrusedw(告知里面还有多少数据)

     Rdreq(读信号)rdclk(读时钟)rdfull(读满标志)rdempty(读空标志)rdusedw(告知里面数据个数)

  以上所有信号全是高电平有效。

 

  1. 为什么要用fifo?

在项目设计中,我们通常需要在两个模块之间传输数据,如果两个模块的数据处理速率相同,那么自然没有什么问题,直接进行数据之间的对接就可以,可若是两个模块的数据处理速度不同呢?如果说数据接收模块和数据发送模块的速度不一致的话,必然会导致采集数据出现遗漏的现象,那么又该如何解决这一问题呢?

这里教大家一种比较简单的方法就是引用FIFO(先进先出)数据缓冲器,所有数据都先经过缓存器去缓存,然后再输入数据接收模块。这样就通过一个数据缓存的方法解决了速度不一致而导致的遗漏数据的问题。

  1. 如何在quarters和ISE里调用FIFO IP核

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

 技术分享

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

技术分享

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

 技术分享

其余几个页面不需要配置什么直接点击NEXT就可以。

另外需要注意的是:  读端口和写端口的输出会有几个时间差,这是由FIFO内部的结构导致的。

 

 

 

  1. 读写控制信号的生成与fifo的应用

系统框架:

技术分享

三个输入线和一个输出线

总共需要三个模块和一个顶层连线

代码展示:

写控制:

module FIFO_wr(
input        wire        wclk,
input        wire        rst_n,
input        wire        wrfull,
input        wire        wrempty,
output    reg        [7:0]wrdata,
output    reg        wrreq
);

reg    [7:0]    state;

always @(posedge wclk or negedge rst_n)
begin
if(!rst_n)
    begin
    wrdata<=0;
    wrreq<=0;
    state<=0;
    end 
else 
    begin
        case(state)
                0:begin
                        if(wrempty)
                                begin
                                    wrreq<=1    ;
                                    wrdata<=0;
                                    state<=1    ;    
                                end 
                        else    
                                state<=0;
                        
                    end  
                1:begin
                        if(wrfull)
                                begin
                                    state<=0;
                                    wrreq<=0;
                                    wrdata<=0;
                                end
                        else 
                                begin
                                    wrreq<=1;
                                    wrdata<=wrdata+1b1;
                                end 
                    end  
                default:    state<=0;
                endcase
        end 
end 

endmodule

读控制:

module     FIFO_rd(
input            wire        rdclk,
input            wire        rst_n,
input            wire        rdempty,
input            wire        rdfull,
output        reg            rdreq
);

reg[2:0]state;

always@(posedge rdclk or negedge rst_n)
    begin
        if(!rst_n)
            begin
                state<=0;
                rdreq<=0;
                
            end 
        else 
          begin
            case (state)
                    0:begin
                            if(rdfull)
                             begin
                                     state<=1;
                                     rdreq<=1;
                             end 
                            else    
                                    state    <=0;
                        end 
                    1:begin
                            if(rdempty==0)
                                begin
                                    state<=1;
                                    rdreq<=1;
                                end 
                            else 
                                    begin
                                    rdreq<=0;
                                    state<=0;
                                    end
                        end 
            default:    state<=0;
            endcase
           end 
        end 
endmodule 

顶层连线:

module     fifo_top(
        input                wire            wrclk,
        input                wire            rst_n,
        input                wire            rdclk,
        output            wire            [7:0]rdata    
        );
        
wire            wrfull;
wire            wrreq;
wire            [7:0]wrdata;
wire            wrempty;
wire            rdfull;
wire            rdempty;
wire            rdreq;
        
        FIFO_wr        U1 (
                          .wclk(wrclk)        , 
                        .rst_n(rst_n)        , 
                        .wrfull(wrfull)    ,
                        .wrdata(wrdata)    ,
                        .wrreq(wrreq)      ,
                        .wrempty(wrempty)
                    );
        FIFO_rd        U2(
                            .rdclk    (rdclk)        ,  
                            .rst_n    (rst_n)        ,   
                            .rdempty(rdempty)        ,
                            .rdreq    (rdreq)        ,
                            .rdfull    (rdfull)      
                            );
        my_fifo         U3(
                            .data(wrdata)            ,
                            .rdclk(rdclk)            ,
                            .rdreq(rdreq)            ,
                            .wrclk(wrclk)            ,
                            .wrreq(wrreq)            ,
                            .q(rdata)                ,
                            .rdempty(rdempty)       ,
                            .rdfull(rdfull)        ,
                            .wrempty(wrempty)       ,
                            .wrfull(wrfull)        
                        );    
                        
endmodule 

测试文件:

  

module    fifo_top_tb;

reg            wrclk;
reg            rdclk;
reg            rst_n;

wire            [7:0]    rdata;

initial
begin
wrclk=1;
rdclk=1;
rst_n=0;
#1000
rst_n=1;
#100000 $stop;
end 

always #10 wrclk=~wrclk;
always #20 rdclk=~rdclk;

fifo_top    U1(    
            .wrclk            (wrclk)            ,      
            .rst_n            (rst_n)            ,      
            .rdclk            (rdclk)            ,      
            .rdata            (rdata)
);




endmodule 

仿真波形:

  技术分享

可以看到:

   当复位结束之前,写空标志为高电平,当有第一个数据写进去的时候,写空标志拉低,当数据写完的时候,写满标志拉高,延时了几拍后,读满标志拉高,当有第一个数据读出来以后,读满标志拉低,当数据读完后,读空标志由低变高,延时几拍后会出现写空标志,进行下一循环。

由上可以看到当读和写的时钟不一样的时候也能很方便的达到数据缓存的目的,不至于数据丢失。

 

FPGA学习笔记之FIFO IP核

标签:

原文地址:http://www.cnblogs.com/zhouzheng/p/5791669.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!