Lesson40 FIFO的配置与使用

一、FIFO的基本工作原理讲解

FIFO( First Input First Output),简单说就是指“先进先出”。为了适应数据处理的高速缓存活临时缓存的需求,今天的FPGA中内嵌了丰富的存储单元,这些存储单元可以灵活的配置为RAM、双口RAM、ROM和FIFO。

在FPGA设计中,为了增加数据传输率、处理大量数据流、匹配不同的传输速率,常常需要用到FIFO存储器,以提高系统性能。FIFO存储器是一个先入先出的双口缓冲器,即第一个进入其内的数据第一个被移出,其中一端是存储器的输入,另一端是存储器的输出。FIFO可分为同步FIFO和异步FIFO,这个同步和异步,主要是针对输入和输出两端的时钟是否相同而已的。输入输出同时钟源,称为同步FIFO;输入输出时钟不同,称为异步FIFO。
在这里插入图片描述
1、FIFO和RAM的区别:FIFO和RAM都会在FPGA内部开辟存储空间。对于RAM来说,写入存储空间的数据,即使被读出了,它也还会存在储存空间。直到写入新数据,原来的数据才会消失。而FIFO不一样,写入的数据一旦被读出,则不会再存在,会消失。
2、FIFO的使能信号决定着数据是否有效。
3、Flag 是标志FIFO空还是满状态的信号。
4、prog-flag 是标志FIFO可编程的信号。
5、common clock 是指FIFO的写时钟和读时钟一样
6、independent clock 是指FIFO的写时钟和读时钟不一样

二、Vivado中FIFO IP的添加和基本配置

1、想用FIFO用在ARM的话,可以选择AXI总线。native是基础总线。
“实现”方式可以选择。其中“common clock”和“independent clock”指的是写时钟和读时钟是否一样。这里选择最后一个,“写时钟和读时钟不一致的内建FIFO”
在这里插入图片描述
2、standard FIFO 指标准FIFO,读使能来了之后,要一定时间,第一个要读出的数据才会出现在数据总线,这个时间就是 read latency,单位是时钟周期。如果选择 first word fall through,则读使能还没到时,第一个要读出的数据就已经出现在数据总线了。
在这里插入图片描述
3、write width 是数据位宽,选择8。而write depth 指的是深度,即FPGA的FIFO使用多少个位宽为8的寄存器。由于分辨率是 640×480 ,也就是水平方向需要640个寄存器,所以需要至少640深度,但是可以留多点余量,比如1024,以防不够。在这里插入图片描述
4、rd_en 信号拉高后,则表示数据dout有效,standard FIFO会经过一个时钟延迟 read latency,这个数据才会出现在数据总线。而vaild是一个数据输出有效的信号标志,这个信号和dout信号完全同步。single programmable full threshold constant 表示单个可编程全阈值常数,也就是FIFO写满后,一起输出。这里设置为640,指的是一行的640个寄存器全写满后,再一起输出。在这里插入图片描述
5、最后再看看总结,OK在这里插入图片描述
在这里插入图片描述

三、IP文档资料的获取方法

怎么系统学习Xilinx的官方文档?如果安装了相关软件,则可以点开查看product guide 查看,如果没有下载,则可以去网站查看。在这里插入图片描述在这里插入图片描述

四、编写测试脚本

1、复制 FIFO 的例化模板。

在这里插入图片描述

2、新建存放FIFO仿真文件的文件夹

2、在 testbench 文件夹下面新建一个 tb_fifo_img 文件夹,这个文件夹专门存放仿真 fifo 相关的文件。可以把之前的仿真自动化模板文件复制到 tb_fifo_img
在这里插入图片描述

3、全部的仿真代码

这是完整的测试代码

4、仿真代码解释

①、图像传感器端工作时钟是25M时钟,所以FIFO输入端是25M时钟。FIFO内部的图像采集模块时钟是50M时钟,所以FIFO输出端是50M时钟。
信号都有:
时钟,复位,写使能,写数据,读使能,读数据,
输出有效信号(即 fifo_dout_vld 拉高后,表示输出的数据才有效),满信号,空信号,写满640个寄存器后的标志信号。
写满 640个reg后,fifo_prog_full 拉高,然后一起读出。
在这里插入图片描述
②、例化的FIFO模块的复位端口(rst)是高电平有效,而外面的复位信号(rst_n)是低电平有效,所以取反。
在这里插入图片描述
③、时钟和复位信号的产生
在这里插入图片描述
④、
标出的地方,“1”是第一个上升沿,“2”是以末尾上升沿为一个repeat,“3“是在第640个repeat的末尾上升沿处,fifo_wren拉高,然后延迟1000个时间单位。
”4“是先拉高读使能,直到时钟上升沿到,才读数据,而数据是以头部上升沿为一个repeat的,读使能信号比读数据维持了稍微多一点的时间,就是第一个repeat的上升沿处。之后的代码也一样。。。。。

在这里插入图片描述
5、在 tb_fifo_img 文件夹下创建一个 output_file 文件,用来保存写入和读出的数据,这样便可以做对比。
在这里插入图片描述
再创建一个 fifo_wr_data.txt 文件,文件属性是读,”w“。
wfile = $fopen(“./output_file/fifo_wr_data.txt”,“w”);
在这里插入图片描述
fifo_wren拉高后,则把写入FIFO的数据,写入文件 fifo_wr_data.txt 中,
fifo_dout_vld拉高后,则把FIFO读出的数据,写入文件 fifo_wr_data.txt 中。

则测试文件完成!

5、为什么测试代码要加 #1000;这些延时?

5、由于复位信号,FIFO的状态信号,它们的切换过程是需要时间的,不是立刻切换后,就能达到稳定信号的,所以在每次切换时,最好给一定的时间。这样信号真实一些。

两次测试之间可以间隔长一些,方便观察,比如5000

在这里插入图片描述

五、修改自动化文件

1、compile.do文件

只修改一处:网表文件的路径
在这里插入图片描述
”1“是复制下来的路径,"2"是上一个文件残留下来的路径。
在这里插入图片描述
修改后
在这里插入图片描述

2、run_simulation文件

添加了这些内容,目的是可以在批处理窗口输入不同的数字,单独执行不同的仿真文件。实现了对单独模块的仿真。
在这里插入图片描述
在批处理窗口输入”2“,回车,自动执行仿真。

六、小意外

结果在这里有个问题,没有找到文件。。。。
在这里插入图片描述
一检查,发现是 compile.do 文件的路径写错了。少了个 img 。加上去后再重新仿真就没有问题了。
在这里插入图片描述

七、分析波形

1、初值维持时间
”1“指的是 在第1000ns处拉高复位信号
”2“指的是 复位信号(第1000ns处)后,再等待1000ns,所以是2000ns
"3"由于@(posedge clk_25m);即 25m的时钟上升沿触发后,才有信号,而第2000ns处没有上升沿,要再等待20ns才出现25m时钟的上升沿,所以综上所述,在第2020ns之前,输入的信号都处于初值。
在这里插入图片描述
2、fifo_wren使能,数据信号 fifo_din 有数据输入时(2020ns处),fifo_empty信号不会马上拉低,而是在2110ns处才被拉低。这个延迟相当于”反应时间“。第一个写入的数据是十六进制的数24(十进制是36)

可以看到,写使能和写入的数据是完全同步的。
在这里插入图片描述
3、读出使能和读出数据(浅色箭头标出的位置是十六进制的24)
在这里插入图片描述
读使能信号和读出的数据并不完全同步,它们之间有时间差,
与读出的数据完全同步的信号是fifo_dout_vld,

4、在27580ns处,最后一个数据才刚开始写入,但是写入是需要时间的,所以留给了一些时间。之后 fifo_prog_full 信号拉高,标志着 640 个数据都已经稳定地写入了 FIFO

在这里插入图片描述

八、分析文件

下载compare插件后再比较,发现全是绿色,说明全部一样。
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值