. . . VGA一、 设计目的1、利用VHDL语言的描述方法进行设计完成VGA显示的系统设计;2、自行选择VGA显示模式;3、通过FPGA产生VGA Monitor的控制时序;4、通过FPGA产生彩条图形,在VGA显示器上显示;5、扩展要求:可以在拨动开关控制下,通过FPGA+VGA接口的系统在屏幕上显示不同图像二、 设计原理1、VGA简要介绍显示绘图阵列(video graphic array,VGA)接口是LCD液晶显示设备的标准接口,大多应用在显示器与显卡之间,同时还可以用在等离子电视输入图像的模数转换上VGA显示输出RGB三原色信号,RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以与它们相互之间的叠加来得到各式各样的颜色,目前在图像显示领域中应用非常广泛2、VGA的显示特点(1)扫描格式繁多,分辨率从320×200一直延伸到1280×102,行频15.8~70Hz,场频50~100Hz常见的行频有31.4Hz,37.8Hz,57.9Hz,62.5Hz等,常见场频有50Hz,60Hz,70Hz,100Hz,16700K之分。
(2)显示器的显示方式有两种:A/N显示方式和APA显示方式,即文本显示方式和图形显示方式A/N方式已淘汰不用,目前微机都采用APA图形方式 (3)VGA接口为显示器提供两类信号,一类是数据信号,一类是控制信号数据信号包括红(Red)、绿(Green)、蓝(Blue)信号,简称RGB信号,控制信号包括水平同步信号和垂直同步信号输出不同分辨率时,水平同步信号和垂直同步信号的频率也不相同3、VGA显示原理常见的彩色显示器一般由CRT(阴极射线管)构成,彩色是由R(红)、G(绿)、B(蓝)三种基色组成显示是采用逐行扫描的方式,阴极射线枪发出的电子束打在涂有荧光粉的荧光屏上,产生RGB三色基,最后合成一个彩色图像从荧幕的左上方开始自左向右扫描,每扫完一行图像电子束回到下一行的最左端,每行完毕后电子枪回扫的过程中进行消隐然后重新开始行扫描,消隐,直到扫到荧幕的右下方,电子束回到荧幕的左上方重新开始新的图像扫描,并且在回到荧幕左上方的过程中进行消隐在消隐过程中不发射电子束每一行扫描完毕时,用HS(行同步)信号进行同步;扫描完所有的行后用VS (场同步)信号进行同步它的行场扫描时序示意图如图1所示。
现以正极性为例,说明CRT的工作过程:R、G、B为正极性信号,即高电平有效当VS=0,HS=0时,CRT显示的容为亮的过程,即正向扫描过程约为26us当一行扫描完毕,行同步HS=1,约需6us,期间,CRT扫描产生消隐,电子束回到CRT的左边下一行的起始位置(X=0,Y=1);当扫描完480行后,CRT的场同步VS=1,产生场同步是扫描线回到CRT的第一行第一列(C=0,Y=0处,约为两个行周期)HS和VS的时序图T1为行同步消隐(约为6us);T2为行显示时间(约为26us),T3为场同步消隐(两行周期);T4为场显示时间(480行周期)图1 行场扫描时序图4、时序分析通过对VGA显示基本工作原理的分析可知,要实现VGA显示就要解决数据来源、数据存储、时序实现等问题,其中关键还是如何实现VGA时序基于像素时钟,VGA时序控制器必须产生HS和VS时序信号像素时钟定义了用于显示一个像素信息的时间,VS信号定义了显示的刷新频率,通常刷新频率在50Hz到120Hz之间给定刷新频率后即定义了水平扫描频率即HSVGA的标准参考显示时序如图2所示:图2VGA时序图行时序和帧时序都需要产生同步脉冲(Sync)、显示后沿(Back porch)、显示时序段(Display interval)和显示前沿(Front porch)四个部分。
其中场频定义了显示的刷新频率,指定场频后所要扫描的行数指定了水平回扫频率即行频几种常用模式的时序参数如表1所示:表1 VGA时序参考表根据VGA的频率图在此选择时钟为40Hz,水平时序则对应着H_SYNC的变化,垂直时序则对应V_SYNC的变化三、 设计步骤1、建立VGA工程文件图3建立工程直接单击[Next]进入下一步,一直点击[Next]直到[Finish]完成2、建立VGA的VHDL文件在Sources窗口中显示工程文件夹以与工程所用芯片右击新建文件,选择“VHDL Module”类型,输入VGA点击[Next],之后点击[Finish]完成输入要运行的程序,这样一个工程就建立完成了代码编写好后,点击保存,然后检查看编写代码是否有错误,Synthesize – XST, Check Syntax, 点击检查后是绿色的勾,则代码没有错误,可以进行下一步功能仿真图4 代码编译3、根据板子锁定引脚,并生成下载文件CLK选择板子上的40M晶振源,所以锁定p82脚;选用拨码开关1作为复位信号RESET,即p20脚;VGA的各个端口:H_SYNC锁定为P140脚,V_SYNC锁定为P144脚,R通道锁定为P147脚,G通道锁定为P146脚,B通道锁定为P145脚。
四、 仿真结果1、 仿真测试图5由图5可以得出,当RESET信号为低时进行正常计数当count_h计数到达即1050的时候count_v加一并且H_SYNC变为低电平图6由图6可以得出,当count_h计数到128的时候,H_SYNC变为高电平图7由图7可以得出,当count_v计数到8的时候,V_SYNC变为高电平图8由图8可以得出,当count_v计数到1001110100即628的时候,V_SYNC变为低电平图9 仿真总览图由图9可以看出,当V_SYNC为高电平的时候,经过一定时间后便分别赋给R、G、B值图10 由图10可知,当RESET为高电平时,停止计数,所有信号为0五、 设计体会VGA的设计主要是要理解它的时序,理解过后设计便变得简单了VS与HS信号具有严格的时序匹配,即VS信号必须为HS信号的整数倍,以保证在场频信号有效期间,能够完整数行的扫描,利用对行频信号进行计数分频来产生场频信号不过这是一个显示用的器件,在仿真上不容易确定其正确性,在之后进过下载板验证之后才能发现是否有不足之处六、 代码1、VGA代码:`timescale 1ns / 1psmodule VGA(CLK,RESET,H_SYNC,V_SYNC,R,G,B,count_h,count_v);input CLK;//40Minput RESET;output H_SYNC;output V_SYNC;output R,G,B;output[10:0] count_h;//计数output[9:0] count_v;reg H_SYNC,V_SYNC,R,G,B;reg[10:0] count_h;//计数reg[9:0] count_v;always (posedge CLK or posedge RESET)begin if(RESET) begin H_SYNC <= 0; V_SYNC <= 0; count_h <= 0; count_v <= 0; R <= 0; G <= 0; B <= 0; end else begin count_h <= count_h+1; if(count_h == 11'b) begin count_h <= 0; H_SYNC <= 0; count_v <= count_v+1; if(count_v == 10'b1001110100) begin count_v <= 0; V_SYNC <= 0; end else if(count_v == 10'b0000001000) V_SYNC <= 1; else V_SYNC <= V_SYNC; end else if(count_h == 11'b) H_SYNC <= 1; else H_SYNC <= H_SYNC; if((count_v >= 10'b0000011011)&&(count_h <= 11'b)&& (count_h >= 11'b)&&(count_v <= 10'b1001110011)) begin R <= 1'b1; G <= 0; B <= 0; end else if((count_v >= 10'b0000011011)&&(count_h <= 11'b)&& (count_h >= 11'b)&&(count_v <= 10'b1001110011)) begin R <= 0; G <= 1'b1; B <= 0; end else if((count_v >= 10'b0000011011)&&(count_h <= 11'b)&& (count_h >= 11'b)&&(count_v <= 10'b1001110011)) begin R <= 0; G <= 0; B <= 1'b1; end else if((count_h >= 11'b)&&(count_v >= 10'b1001110011)) begin R <= 0; G <= 0; B <= 0; end else begin R <= 0; G <= 0; B <= 0; end endendendmodule2、激励文件: `timescale 1ns / 1psmodule VGA_test; // Inputs reg CLK; reg RESET; // Outputs wire H_SYNC; wire V_SYNC; wire R; wire G; wire B; wire[10:0] count_h;//计数 wire[9:0] count_v; // Instantiate the Unit Under Test (UUT) VGA uut ( .CLK(CLK), .RESET(RESET), .H_SYNC(H_SYNC), .V_SYNC(V_SYNC), .R(R), .G(G), .B(B), .count_h(count_h), .count_v(count_v) ); initial begin CLK = 0; forever #12 CLK = ~CLK; end initial begin RESET = 1; #50 RESET 。