前言
项目算法需求,需要将RGB彩色图像转换为灰度图像,算法原理是很简单的,但是对于刚接触FPGA的宝宝来说,进行时序的设计和调试还是不那么容易的,为了省事儿,就按照上一篇中值滤波(http://www.cnblogs.com/happyamyhope/p/5577898.html)的结构进行设计。开始的开始,只能根据已经做好的设计照葫芦画瓢,否则调试还是很繁琐的,主要是因为目前还是掌握不了时序设计的精髓和思路,慢慢来吧。
实验步骤:
1.实验原理介绍;
2.编写各模块的代码;
3.调试仿真,并与matlab中rgb2gray函数的结果进行比较;
实验过程:
1.实验原理介绍;
matlab中rgb2gray函数的原理还是比较简单的,最后输出的灰度图像是RGB三种颜色通道的加权和;
rgb2gray converts RGB values to grayscale values by forming a weighted sum of the R, G, and B components: 0.2989 * R + 0.5870 * G + 0.1140 * B
上面就是MATLAB中rgb2gray函数的算法原理;
本模块输入的是8bits的三通道彩色图像数据,输出的也是8bits的数据,至于整体算法模块的小数,有待到时候进行一下整合,改变数据的位数。
为了不涉及到小数,我们将数据整体左移16位即乘以65536,根据matlab中的算法原理进行设计:
gray <= 19589 * red + 38469 * green + 7471 * blue; //gray <= 19595 * red + 38469 * green + 7472 * blue;
查看了一些资料,比如: http://www.cnblogs.com/diewcs/archive/2010/10/03/1841744.html
2.编写个模块的代码;
先将计数器控制模块和rgb2gray进行调试仿真,再将两个模块综合到一起进行调试仿真,得到最终的结果。
主要是计数器控制模块,如何正确得到正确时序的地址数据。
1)计数器控制模块:
module counter_ctrl( CLK, RSTn, iCall, iNxt_pix, oAddr, oDone ); input CLK; input RSTn; input iCall; input iNxt_pix; output [17:0] oAddr; output oDone; reg [17:0] imk; reg isDone ; reg start_sig_d; wire start_sig_rising_vld; always @ (posedge CLK or negedge RSTn) //Asynchronous reset if ( !RSTn ) start_sig_d <= 0; else start_sig_d <= iCall; assign start_sig_rising_vld = iCall & (~start_sig_d); always @ ( posedge CLK or negedge RSTn ) if ( !RSTn ) begin imk <= 18'd0; isDone <= 1'b0; end else if ( start_sig_rising_vld ) begin imk <= 18'b1; isDone <= 1'b1; end else if ( iNxt_pix ) // & ( imk != 166222 ) begin imk <= imk + 1'b1; isDone <= 1'b1; end else isDone <= 1'b0; assign oAddr = imk; assign oDone = isDone; endmodule