赞
踩
基于 ISE14.7 的 LogiCORE IP FIFO Generator 仿真学习,主要在于IP核的时序、使用以及注意事项,不会过多介绍FIFO的作用以及配置。
IP核的配置根据自己的实际情况选择,这里我选择标准的FIFO,使用Native Interface FIFOs 接口,而AXI Interface接口,数据位宽和FIFO深度根据实际需要选择。
整体的配置如下图所示:
需要注意的是,在FIFO复位后,是不能马上写数据的,从仿真结果可以看出,full信号和almost_full信号在复位过程中,以及复位结束后的几个CLK内,都为断言状态。
其写入时序可参考数据手册,可以看到:
写入的数据来源于仿真时随机生成的数据,本次写入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信号,不然可能会造成数据丢失。
其读取时序可参考数据手册,可以看到:
根据手册,仿真代码比较简单,拉高读取使能持续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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。