ROM+VGA 图片显示
内容
1、将一幅图片制成mif文件,初始化rom,图片像素为 120 * 60
2、驱动VGA,将图片显示在屏幕上
1、VGA 时序
下面是我的笔记截图,感觉更好理解。
2、640*480 60hz
VGA 为什么要选用 25Mhz 的时钟进行驱动呢?
1s时间内显示60幅图像,每幅图像的像素总数为 800 *525 (640*480是指的有效像素,800*525是包含了所有的,具体情况见下图)
因此完成一幅图像的时间为 1s/60 =16.6ms
完成一行需要 16.6ms / 525 =31.75us
完成一个像素 16.6ms / 800 = 40 ns
40ns对应的时钟频率为25Mhz.
从上面这副图可以提取的信息如下,我们将它参数化
//行时序参数 `define H_FRONT 11'd16 //显示前沿 `define H_SYNC 11'd96 //同步脉冲 `define H_BACK 11'd48 //显示后沿 `define H_DISP 11'd640 //有效时间 `define H_TOTAL 11'd800 //总的 //场时序参数 `define V_FRONT 11'd10 `define V_SYNC 11'd2 `define V_BACK 11'd33 `define V_DISP 11'd480 `define V_TOTAL 11'd525
行时序参数的单位是像素,场时序参数的单位是一行,根据这一点,设计两个计数器
//---------------------------------------------------------------------- //行时序设计 always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin h_cnt <= 0; end else if(h_cnt == `H_TOTAL - 1'b1)begin h_cnt <= 0; end else h_cnt <= h_cnt + 1'b1 ; end assign hs=(h_cnt >= 0 && h_cnt < `H_SYNC )? 1'b0 : 1'b1 ; //---------------------------------------------------------------------- //场时序设计 always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin v_cnt<=0; end else if(h_cnt == `H_TOTAL - 1'b1) begin if(v_cnt == `V_TOTAL - 1'b1) v_cnt <= 0; else v_cnt <= v_cnt + 1'b1; end end assign vs = (v_cnt >= 0 && v_cnt< `V_SYNC)? 1'b0 : 1'b1 ;
以上就完成了VGA的驱动,非常简单。
本次设计的难点在于rom地址的设计,什么情况下改变地址的值。
首先设计像素左标,640*480个有效像素,第一行第一个坐标为(0,0),第二个为(0,1)以此论推,横坐标为 x_pose ,纵坐标为 y_pose 。
至于为什么是 260 和 210太难解释了,不过我会把所有工程打包,提供下载,大家可以参考分析。
assign address_1 =(area_1)? (x_pose-260)+120*(y_pose-210) : 1'b0 ;
结果:
程序代码:链接:http://pan.baidu.com/s/1mi0eSNu 密码:8g64
由于资源的限制,只能显示很小的图片,表示很不舒服,我一定要学会设计SDRAM,走向巅峰!!