广州南沙区建设和交通局网站,免费下载教学设计的网站,个人网站免费模板,网络推广公司加盟文章目录 一、前言二、FPGA实现三行缓存的架构三、Verilog代码实现四、仿真验证五、输入图像数据进行仿真验证 一、前言 在 FPGA 做图像处理时#xff0c;行缓存是一个非常重要的一个步骤#xff0c;因为图像输入还有输出都是一行一行进行的#xff0c;即处理完一行后再处理… 文章目录 一、前言二、FPGA实现三行缓存的架构三、Verilog代码实现四、仿真验证五、输入图像数据进行仿真验证 一、前言 在 FPGA 做图像处理时行缓存是一个非常重要的一个步骤因为图像输入还有输出都是一行一行进行的即处理完一行后再处理下一行。行缓存可以存储当前行和前一行的数据以及多行的数据使得在处理当前行时能够方便地访问周围像素。许多图像处理的算法都需要几行的图像数据进行处理因此行缓存是非常重要的本文实现三行缓存多行缓存的思想也是一致的。
二、FPGA实现三行缓存的架构 由于图像数据一般都是从上到下从左到右一个一个输入进来因此我们优先考虑使用FIFO先进先出。按照一般想法我们只需要三个FIFO每个FIFO存储一行数据即可实现三行缓存这里可以节省资源只使用两个FIFO实现具体实现框框架如下 开始时图像数据的第0行写入到FIFO1中图像数据的第1行写入到FIFO2中。 当第2行数据到来时写入到FIFO2中同时输出写入的数据作为第二行同时读出FIFO2中的数据写入到FIFO1中并输出作为第一行同时读出FIFO1中的数据输出作为第0行。 同理当第三行数据来临时写入到FIFO2中同时输出写入数据作为第二行再同时读出FIFO2中的数据写入到FIFO1中并输出作为第一行同时读出FIFO2中的数据输出作为第0行。后面的行以此类推。
三、Verilog代码实现 先看输入接口输入为像素数据和有效信号输出为三行数据以及有效信号。 input sys_clk ,input sys_rst ,input [23:0] i_img_data ,input i_img_data_valid ,output [23:0] o_img_data_1line ,output [23:0] o_img_data_2line ,output [23:0] o_img_data_3line ,output o_img_data_valid 再次例化两个FIFO位宽就为一个像素位宽深度为一行中最多的像素数量。
img_line_buffer_fifo u0_img_line_buffer_fifo (.clk (sys_clk ), // input wire clk.srst (sys_rst ), // input wire srst.din (fifo1_wr_data ), // input wire [23 : 0] din.wr_en(fifo1_wr_en ), // input wire wr_en.rd_en(rd_en ), // input wire rd_en.dout (fifo1_q ), // output wire [23 : 0] dout.full (), // output wire full.empty() // output wire empty
);img_line_buffer_fifo u1_img_line_buffer_fifo (.clk (sys_clk ), // input wire clk.srst (sys_rst ), // input wire srst.din (fifo2_wr_data ), // input wire [23 : 0] din.wr_en(fifo2_wr_en ), // input wire wr_en.rd_en(rd_en ), // input wire rd_en.dout (fifo2_q ), // output wire [23 : 0] dout.full (), // output wire full.empty() // output wire empty
);然后根据架构图编写出剩下的代码编写仿真代码。
四、仿真验证 仿真我们先设置图像宽度为50*50这样仿真可以跑快一点然后写入数据流为每次都是0-49循环。就像一幅图像的第0行数据是0-49第1行的数据也是0-49每一行的数据都是0-49。按照想法我们每次输出的数据就是前三行的像素也就是3行的 0-49数据仿真代码如下
timescale 1ns / 1psmodule tb_img_3line_buffer();reg sys_clk ;
reg sys_rst ;
reg i_img_data_valid ;
reg [23:0] i_img_data ;
reg [12:0] cnt ;
wire [23:0] o_img_data_1line ;
wire [23:0] o_img_data_2line ;
wire [23:0] o_img_data_3line ;
wire o_img_data_valid ;initial beginsys_clk 0;sys_rst 1;i_img_data_valid 0;i_img_data d0;#200;sys_rst 0;
endalways #5 sys_clk ~sys_clk;always (posedge sys_clk) beginif(sys_rst 1b1)i_img_data_valid 1b0;else if(cnt 49)i_img_data_valid 1b0;elsei_img_data_valid 1b1;
endalways (posedge sys_clk) beginif(sys_rst 1b1)cnt d0;else if(cnt 49)cnt d0;else if(i_img_data_valid 1b1)cnt cnt 1b1;elsecnt cnt;
endalways (posedge sys_clk) beginif(sys_rst 1b1)i_img_data d0;else if(i_img_data 49)i_img_data d0;else if(i_img_data_valid 1b1)i_img_data i_img_data 1b1;elsei_img_data i_img_data;
endimg_3line_buffer#(.IMG_WIDTH ( 50 ),.IMG_HEIGHT ( 50 )
)u_img_3line_buffer(.sys_clk ( sys_clk ),.sys_rst ( sys_rst ),.i_img_data ( i_img_data ),.i_img_data_valid ( i_img_data_valid ),.o_img_data_1line ( o_img_data_1line ),.o_img_data_2line ( o_img_data_2line ),.o_img_data_3line ( o_img_data_3line ),.o_img_data_valid ( o_img_data_valid )
);endmodule 运行仿真 可以看到写入的每一行数据都是0-49写入两行后开始输出数据。 我们可以看到输出的三行数据都是0-49的数据。符合预期。我们修改一下仿真代码写入2500个数据对应50*50的图像大小数据为0-2499这样第0行的数据就是0-49第1行的数据就是50-99第2行的数据就是100-149第3行的数据就是150-199。输出的数据就应该是050100151101以此类推仿真代码如下
timescale 1ns / 1psmodule tb_img_3line_buffer();reg sys_clk ;
reg sys_rst ;
reg i_img_data_valid ;
reg [23:0] i_img_data ;
reg [12:0] cnt ;
wire [23:0] o_img_data_1line ;
wire [23:0] o_img_data_2line ;
wire [23:0] o_img_data_3line ;
wire o_img_data_valid ;initial beginsys_clk 0;sys_rst 1;i_img_data_valid 0;i_img_data d0;#200;sys_rst 0;
endalways #5 sys_clk ~sys_clk;always (posedge sys_clk) beginif(sys_rst 1b1)i_img_data_valid 1b0;else if(cnt 2499)i_img_data_valid 1b0;elsei_img_data_valid 1b1;
endalways (posedge sys_clk) beginif(sys_rst 1b1)cnt d0;else if(cnt 2499)cnt d0;else if(i_img_data_valid 1b1)cnt cnt 1b1;elsecnt cnt;
endalways (posedge sys_clk) beginif(sys_rst 1b1)i_img_data d0;else if(i_img_data 2499)i_img_data d0;else if(i_img_data_valid 1b1)i_img_data i_img_data 1b1;elsei_img_data i_img_data;
endimg_3line_buffer#(.IMG_WIDTH ( 50 ),.IMG_HEIGHT ( 50 )
)u_img_3line_buffer(.sys_clk ( sys_clk ),.sys_rst ( sys_rst ),.i_img_data ( i_img_data ),.i_img_data_valid ( i_img_data_valid ),.o_img_data_1line ( o_img_data_1line ),.o_img_data_2line ( o_img_data_2line ),.o_img_data_3line ( o_img_data_3line ),.o_img_data_valid ( o_img_data_valid )
);endmodule 运行仿真 验证完成和预期一致后续一些图像处理算法需要用到这个行缓存。
五、输入图像数据进行仿真验证 现在我们在仿真中输入一张图片然后通过三行缓存输出每次只取出第一行的数据写入到新的图片中 可以看出输出的图像和输入图像一模一样文件大小也是一模一样因此三行缓存是没问题的。