这是本文档旧的修订版!
VGA驱动器设计
一、实验目的与意义
- 了解液晶显示器扫描原理和VGA接口时序。 
- 学习按照时序定义用FPGA实现VGA驱动器的设计。  
- 掌握VGA接口驱动设计的方法和思路。 
 
二、实验设备及平台
- iCore3 双核心板( FPGA型号为EP4CE10F17)。
 
 
- 转接板和40P的FPC连接线。
 
 
- iCore3(VGA)显示模块。
 
 
- Blaster(或相同功能的)仿真器和USB线缆。
 
 
- Micro USB线缆。
 
 
- QuartusII开发软件(本实验中使用的是13.1版本)。
 
 
- 带有VGA接口的主机和VGA接口分辨率1024 * 768@60Hz的液晶显示器。
 
 
 注意事项1: 注意FPC转接板和核心板之间引脚要对齐(如图29-1中①处所示,转接板和核心板边缘要对齐)。
注意事项1: 注意FPC转接板和核心板之间引脚要对齐(如图29-1中①处所示,转接板和核心板边缘要对齐)。
注意事项2: FPC软排线与FPC接口连接时,请确认软排线接口处蓝色绝缘皮朝上(如图29-1中②③所示)。
注意事项3: 下载程序前请确认FPC转接板和软排新与核心板的引脚连接无误,且iCore3核心板引脚与PIN.tcl文件中绑定引脚相互对应。
 
三、实验原理
1. VGA时序
VESA_VGA时序标准中关于1024 * 768@60Hz分辨率显示器接口时序定义如下所示:
 
- 根据VESA_VGA时序标准中框①提示,1024 * 768@60Hz的显示器,如上图框②中规定,行扫描周期需要扫描1344个像素点的时间。因此,可以对像素点的个数进行计数,每扫描1344个像素点我们就可以认为完成了一次行扫描。如上图红框③中提示,行同步信号Hsync(代码中定义的名字为Sync_H)可以在行扫描第136个像素点时给出,然后在行扫描的第296个像素点至第1320个像素点之间使像素输出有效,从而在屏幕上一行显示出1024个有效像素点。 
- 为什么是在第296个像素点使像素输出有效呢,从图中框⑥提示可以知道,从行扫描周期开始至行显示有效这段时间,结合框③可以计算:
 
 
sync+Back Porch+Top/left Border = (136+160+0)Pixes
既扫描296个像素的时间。
 
2. VGA接口的时钟频率计算
 1344 * 806 * 60≈65M
个像素点。每个时钟周期扫描一个像素点,要实现60Hz分辨率1024 * 768的屏幕刷新,则需要约65MHz的时钟信号,即VGA接口中定义的系统时钟频率。
 
3. RGB条纹显示控制原理
- 本实验中我们采用的RGB色彩是16位的,即构成一个像素色彩的R(红)、G(绿)、B(蓝)三种颜色成分所占的二进制位宽为5、6、5。即IMG_RGB[15:11]代表红色像素的灰度值,IMG_RGB[10:5]代表绿色像素的灰度值,IMG_RGB[4:0]代表蓝色像素的灰度值。所以我们可以通过对各个像素单独赋值来实现红、绿、蓝三种色彩的显示。 
- 由前面的分析可以知,每一帧图像是由768行有效行像素构成的,如果我们将一帧中的有效行像素按照行数进行划分,每个划分区间分别赋予不同颜色的RGB值,则可在屏幕上实现三种色彩的条纹显示。 
 
四、代码讲解
- RST_Ctrl模块为系统提供初始复位信号,代码较为简单。 
- PLL模块是ATLPLL IP核的例化,为系统提供65MHz时钟信号。  
- VGA_Display_Top模块是顶层模块,例化和连接各分模块。 
- RGB_display模块实现的功能是控制三色条纹的宽度和色彩。以行同步信号对一的行数进行计数,在行数区间内对IMG_RGB变量填充对应的颜色值,从而实现RGB三色彩条的显示。  
- VGA_Ctrl模块是我们根据VGA时序写的驱动,提供符合VGA接口规范的行同步信号和场同步信号,以及从PLL模块输入的VGA_CLK时钟信号。  
工程编译完成后,可以在Tools→netlist viewers→RTL Viewer 中查看RTL视图如下:
 
- 下面主要介绍一下VGA_Ctrl模块的其中一种实现方式 
- 由前面VGA显示原理可以知道,我们需要定义一个变量cnt_h,用来对时钟计数,当cnt_h计满1344个时钟,则表示行扫描的一个周期。因此我们对cnt_h计数满1344后清零。由VGA接口时序图上我们能看到,行同步信号的在时钟计数为136的时候,有个下降沿。因此,我们可以在cnt_h计数136个时钟之后,产生一个脉冲,然后以此脉冲作为行同步信号Sync_H_r。 
- 同理,建立一个变量cnt_v对行数进行计数,用于产生场同步信号Sync_V_r。此处有个需要注意的地方:由于我们是以行同步信号为基础产生的场同步信号,而行同步信号又不在行计数的最后一位,因此我们对场同步信号进行计数的时候要判断一下行扫描是否计数完毕,只有cnt_h计满1344个时钟后,我们才开始对行同步信号进行计数,这样确保每一帧的最后一行都是一个完整的行周期 
//--------------------Sync_V---------------------------------//
	reg [10:0] cnt_v = 11'd0; //场同步信号计数器
	always @(posedge CLK_65M or negedge RST_n)
		if (!RST_n)
			cnt_v <= 11'd0;
		else if (cnt_h == 1343) //当一行填充完1344个列像素后
			begin
				if (cnt_v == 805) //判断是否填充完805行
					cnt_v <= 11'd0; //若是则为零,重新开始下一场的列填充
				else
					cnt_v <= cnt_v + 1'd1; //否则,转到下一行继续列填充
			end
 
五、实验结果
六、拓展实验
- 改变显示条纹的方向,颜色和数量。 
- 在屏幕的某个区域显示单色。 
- 在屏幕上动态移动单色块。