闲庭信步使用图像验证平台加速FPGA的开发:第十六课——图像五行缓存的FPGA实现
(本系列只需要modelsim即可完成数字图像的处理,每个工程都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真,大大降低了初学者的门槛!!!!如需要该系列的工程文件请关注知识星球:成工fpga,https://t.zsxq.com/DMeqH,关注即送200GB学习资料,链接已置顶!)
前面我们实现了图像三行数据的缓存,文件是data_cache.sv,有了这个文件,处理起来3x3的各种算子都不在话下。那现在问题来了,对于5x5的算子,使用data_cache.sv就不可以了。其实这都不是事,既然有了开发data_cache.sv的经验,那就稍微修改一下,新建一个data_cache5.sv的文件,能支持5x5即可。
下面详细说明一下数据缓存的方法,由于要缓存5行图像的数据,那就要有5个ram,分别是ram0-ram4。行计数器从0-4反复的计数,方便数据的存取;需要的5x5的区域像素存在chnl0-chnl4中,chnl0-chn4都是5字节长度的,chnl0存放第0行的5个像素数据,chnl1存放第1行的5个像素数据,chnl2存放第2行的5个像素数据,chnl3存放第3行的5个像素数据,chnl4存放第4行的5个像素数据。
设计要点就是当前行的数据一定是5x5的最后一行,所以直接给到chnl4即可。每一行都是1个ram在写,4个ram在读,由于5个ram是循环读写的,可以根据行计数器确定这5个ram中数据的排列顺序,比如行计数为0时,ram1存放的是第0行数据,ram2存放的是第1行数据,ram3存放的是第2行数据,ram4存放的是第3行数据,ram0存放的是第4行数据。
还有一个问题就是5x5的行缓存,图像外围要补两圈的0才能让所有5x5因子的计算一致。前两行补零是通过先缓2行图像数据再读数来实现的,这时候还有两个ram没有写进数据,就可以读出来两行的0;最后两行的补零是通过增加两行的数据有效信号来实现的,新增加的两行写0,就可以实现最后两行都是0。而前两列和后两列的补零是通过将数据读有效信号打两拍作为输出有效信号来实现的,每行的像素数据是通过左移位进入chnl0-chnl4的,由于行信号延时了两拍,输出信号有效时,已经有3个数据缓存到chnl0-chnl4,chnl0-chnl4的高16位还是0,这样就可以实现前两列的0,而后两列直接通过延时的两拍有效信号来实现。
解释起来可能不太清晰,我们直接在代码中讲解。在\src\cache文件夹下新建data_cache5.sv文件,考虑到通用,文件采用参数化设计的思路。而且5x5因子输出25个图像数据变量有些多,直接使用数组输出。
相关的变量的位宽也使用参数来定义。
通过组合逻辑实现ram读写相关信号和输出信号,场同步和行同步信号不仅延时四个时钟周期,还要多延时两行。
实现列数和行数的计数,其中156-166行主要实现增加两个数据行有效active信号。
数据行有效信号的延时打拍,用于数据的读取和列补零;新增加的两行数据直接给0,实现新增的最后两行数据是0。
如下实现了行计数从0-4的功能,start信号用来控制先缓存两行数据在读数据,主要用来实现前两行的补零。
以第一行数据的缓存为例,根据行号sel_cnt来确定需要读取哪个ram的数据,最后260行的active_d0=0,而 active_d1和active_d2还拉高时补最后两列的0。
最后一行数据的读写和前四行不太一样,直接读当前的图像数据即可。
最后例化五个ram即可。
同样,成工也把三行缓存的data_cache.sv模块修改成了data_cache3.sv,也是加入了对于的参数。
在top文件中,例化了rgb2ycbcr模块和data_cache5模块。
在tb_image_sim文件中的第二个initial块中,进行相关的图像读取和存储的操作。
双击sim文件夹下的top_tb.bat文件,完成系统的自动化仿真。
可以加入相关的波形查看。如下是先缓存两行数据再开始读数操作。
我们看一下读取的第一个数组数据,前两行和前两列都加上了0。
再看看最后的增加了两个active信号,此时数据是0。
而输出的最后一个数组数据,最后两行和两列都是0。