本项目用于测试Vivado提供的FIFO IP核不同配置的时序与逻辑,以供设计参考。
芯片型号:Artix-7 xc7a35tfgg484-2L
开发板:ALINX AX7035
开发环境:vivado 2019.1
首先新建Vivado工程,配置如下:
例化同步FIFO IP核,参数如下图所示,输入输出使用同一时钟,位宽为4,深度32。
仿真测试代码见tb_FIFO_syn.v,其中核心代码如下:
initial begin
rst = 1'b1;
wr_en = 1'b0;
rd_en = 1'b0;
# 1010
rst = 1'b0;
wr_en = 1'b1;
# 10
# 700
rd_en = 1'b1;
# 300
wr_en = 1'b0;
# 800
$finish;
end
如下见两放大图:
从仿真波形可以看出:
1、data_count的计数是准确且及时的,且对于深度为32的同步FIFO,data_count为4位,其最大值为31,故当FIFO满时count归0。
2、full和empty是准确的,almost_full和almost_empty信号都在数值差1时有效。
3、valid信号在输出数据有效时为高,当FIFO空了之后,即使有rd_en信号,valid信号仍然无效。
同上述实验一致,只是将FIFO从normal模式转变为了first word fall through模式,此时read latency为0,得到的仿真波形图如下:
可见两者的区别是:
(1)在normal模式下data计数器在rd_en信号后一拍才会减1;而在first word fall through模式下,data计数器减1和rd_en是同时进行的。
(2)empty信号比normal下的慢2个周期,与almost_empty同步;而data_count始终是准确的。
如下见异步FIFO IP核的配置参数:写位宽4, 深度63;读位宽8,深度31
在仿真中,写时钟为20ns,读时钟为12ns
仿真代码见tb_FIFO_asyn.v,核心部分如下所示:
initial begin
wr_clk = 1'b1;
rd_clk = 1'b1;
rst = 1'b1;
wr_en = 1'b0;
rd_en = 1'b0;
# 30
rst = 1'b0;
wait((~wr_rst_busy)&(~wr_clk));
wr_en = 1'b1;
# 1500
rd_en = 1'b1;
# 200
wr_en = 1'b0;
# 300
$finish;
end
FIFO IP核的例化模板如下
FIFO_2 FIFO_2_asyn (
.rst(rst), // input wire rst
.wr_clk(wr_clk), // input wire wr_clk
.rd_clk(rd_clk), // input wire rd_clk
.din(din), // input wire [3 : 0] din
.wr_en(wr_en), // input wire wr_en
.rd_en(rd_en), // input wire rd_en
.dout(dout), // output wire [7 : 0] dout
.full(full), // output wire full
.almost_full(almost_full), // output wire almost_full
.empty(empty), // output wire empty
.almost_empty(almost_empty), // output wire almost_empty
.valid(valid), // output wire valid
.rd_data_count(rd_data_count), // output wire [4 : 0] rd_data_count
.wr_data_count(wr_data_count), // output wire [5 : 0] wr_data_count
.wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy
.rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy
);
由于FIFO核初始化需要时间,在rst电平拉低后,仍不能进行读写,直到wr_rst_busy和rd_rst_busy信号拉低后才能开始进行读写。
下面观察从零开始写数据的波形图: 1、根据官方说明,wr_data_count从不少报,而rd_data_count从不多报。
2、从上如中可以看出,刚开始写时wr_data_count是及时的,而rd_data_count延后了,即少报了。
3、empty信号和almost_empty信号在此处也滞后了。
再观察后半部分: 1、由于异步时序问题,wr_data_count和rd_data_count变化并不平滑,且真实数据在两者之间,其误差较小可以接受。
2、empty信号和full信号分别与rd和wr时钟同步,且与相应的data_count相吻合。
3、dout和din能匹配上。