ISE 14.7 FIFO 仿真学习


ISE14.7 的 LogiCORE IP FIFO Generator 仿真学习

前言

基于 ISE14.7 的 LogiCORE IP FIFO Generator 仿真学习,主要在于IP核的时序、使用以及注意事项,不会过多介绍FIFO的作用以及配置。

IP核的配置

IP核的配置根据自己的实际情况选择,这里我选择标准的FIFO,使用Native Interface FIFOs 接口,而AXI Interface接口,数据位宽和FIFO深度根据实际需要选择。

在这里插入图片描述

整体的配置如下图所示:

在这里插入图片描述

仿真验证

复位后FIFO满标志

​ 需要注意的是,在FIFO复位后,是不能马上写数据的,从仿真结果可以看出,full信号和almost_full信号在复位过程中,以及复位结束后的几个CLK内,都为断言状态。

在这里插入图片描述

数据写入

其写入时序可参考数据手册,可以看到:

  1. 写使能为高时,数据写入FIFO,延迟一个时钟后,写响应信号拉高;
  2. 当FIFO写满时,FULL信号被拉高;
  3. 当FIFO写满时,再写数据将不会有写响应信号,而会出现OVERFLOW信号。

在这里插入图片描述

写入的数据来源于仿真时随机生成的数据,本次写入18个数据,FIFO深度为16个。

    for(i=0;i<18;i=i+1) begin
        @(posedge clk);
        wr_en = 1;
        din = ($random) % 256;
    end

从仿真结果可以看出,刚开始写入一个数据后,empty被拉高,写入两个数据后,almost_empty信号被拉高,这两个信号一般用于读取FIFO时使用。

在这里插入图片描述

当FIFO被写满以后,FULL信号被拉高,再向其中写入数据,OVERFLOW信号被拉高,其中两个数据 0xc5,0xaa理论上不会被写入FIFO。

在这里插入图片描述

​ 查看modelsim的仿真数据(从右向左看),可以看到,刚开始写入的0x24,0x81数据和最后写入的0xf9、0xc6数据,0xc5,0xaa由于FIFO写满未被写入FIFO。

因此在使用FIFO时,一定要注意full信号以及写响应wr_ack信号,不然可能会造成数据丢失。

数据读取

其读取时序可参考数据手册,可以看到:

  1. 都使能为高时,数据读出FIFO,延迟一个时钟后,数据dout和数据有效信号valid断言,读取Latency为1个时钟,在配置IP核的时候也能看见;
  2. 当FIFO为空时,EMPTY信号被拉高;
  3. 当FIFO为空时,再读取数据将不会有valid信号,而会出现UNDERFLOW信号。

在这里插入图片描述

根据手册,仿真代码比较简单,拉高读取使能持续18个时钟即可。

    rd_en = 1;
    repeat(18) @(posedge clk);
    rd_en = 0;

在这里插入图片描述

从仿真结果可以看出,写入的FIFO的数据被以此读出,如果FIFO为空时依旧读取数据,则输出为最后一次读取的数据,不会改变。

可编程满和可编程空信号

​ FIFO默认提供的满信号是FIFO写满或者只剩一个空间时的信号,但实际这种信号可能不能满足我们的需求,例如FIFO至少有8个数据时,我才开始读取数据,

那么总不能我们根据写入的数据个数来判断吧,这个时候就可以用到PROG_FULL信号,这个在配置IP核的时候会有该选项。

​ 比如你可以将FIFO满的阈值设置为7,那么,一旦FIFO写入的数据为7个时,PROG_FULL信号信号就被拉高,少于7个时,则会拉低。不过需要注意的是,此信号会有1个CLK的延迟

在这里插入图片描述

在这里插入图片描述

​ 同样也可以将PROG_FULL的阈值设置10拉高,少于7个拉低,同样注意有1个CLK的延迟

在这里插入图片描述

在这里插入图片描述

可编程空信号和可编程满信号同理,只不过一个判断空,一个判断满。

附录

软件版本

modelsim 使用10.4版本。

ISE为14.7版本。

在这里插入图片描述

仿真代码

module tb_fifo_indata;
// fifo_indata Parameters
parameter PERIOD  = 10;


// fifo_indata Inputs
reg   clk                                  = 0 ;
reg   rst_n                                = 0 ;
reg   [7 : 0]  din                         = 0 ;
reg   wr_en                                = 0 ;
reg   rd_en                                = 0 ;

// fifo_indata Outputs
wire  [7 : 0]  dout                        ;    
wire  full                                 ;    
wire  almost_full                          ;
wire  wr_ack                               ;
wire  overflow                             ;
wire  empty                                ;
wire  almost_empty                         ;
wire  valid                                ;
wire  underflow                            ;


initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*20) rst_n  =  1;
end

fifo_indata  u_fifo_indata (
    .clk                     ( clk                    ),
    .rst                     ( ~rst_n                 ),
    .din                     ( din           [7 :0]   ),
    .wr_en                   ( wr_en                  ),
    .rd_en                   ( rd_en                  ),

    .dout                    ( dout          [7 :0]   ),
    .full                    ( full                   ),
    .almost_full             ( almost_full            ),
    .wr_ack                  ( wr_ack                 ),
    .overflow                ( overflow               ),
    .empty                   ( empty                  ),
    .almost_empty            ( almost_empty           ),
    .valid                   ( valid                  ),
    .underflow               ( underflow              )
);

integer i;

initial
begin

    @(posedge rst_n);
    #(PERIOD*10);


    for(i=0;i<18;i=i+1) begin
        @(posedge clk);
        wr_en = 1;
        din = ($random) % 256;
    end
    @(posedge clk);
    wr_en = 0;


    #(PERIOD*20);

    rd_en = 1;
    repeat(18) @(posedge clk);
    rd_en = 0;

    #(PERIOD*20);
    $stop;
end
endmodule

参考资料

PG057-LogiCORE IP FIFO Generator

posted @ 2022-10-08 21:21  san_si  阅读(459)  评论(0编辑  收藏  举报