VGA(Video Graphics Array)是IBM在1987年随PS/2机一起推出的一种视频传输标准,当时具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的应用。
VGA接口就是显卡上输出模拟信号的接口,也叫D-Sub接口。VGA接口是一种D型口,上面共有15针空,分成三排,每排五个。VGA接口是目前中低端电脑配置上的主流口。
VGA显示中,FPGA需要产生5个信号:R、G、B三基色信号,行同步信号HS,场同步信号VS。信号列表如表2-5。
表2.5 VGA信号列表
信号线 |
定义 |
HS |
行同步信号 (3.3V电平) |
VS |
场/帧同步信号(3.3V电平) |
R |
红基色(0-0.714V模拟信号) |
G |
绿基色(0-0.714V模拟信号) |
B |
蓝基色(0-0.714V模拟信号) |
VGA接口图如下:
图2-26 VGA接口实物图
以上接口的5个孔对应着我们FPGA中产生的5个重要的信号,其中R、G、B是数据信号;HS、VS是控制信号。
1. VGA色彩原理
像素是产生各种颜色的基本单元。根据物理学中的混色原理,三色发光的亮度比例适当,可呈现白色。适当的调整发光比例可以出现不同的颜色。
表2.6 三基色颜色编码表
颜色 |
黑 |
蓝 |
红 |
紫 |
绿 |
青 |
黄 |
白 |
R |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
G |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
B |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
以上RBG一共有8组合,也就是可以产生8种颜色。但显示器显示的色彩却是非常丰富,远远多于8种颜色,这是如何做到的呢?
原因就是对于显示器来说,RGB三个信号其实是模拟信号,其电平的高低,可以表示颜色的深浅。利用这个原理,我们就可以产生丰富的色彩。为了控制电压的高低,我们就必须用到DA芯片。例如下图中,FPGA产生RGB三种信号,这时RGB都是多位的数字信号。DA芯片根据数字信号的值,产生不同电压的模拟信号rgb。连接框图如图2-27
图2-27 FPGA与显示器的结构图
明德扬的第二代开发板,R由3位数字信号组成(VGA_R0,VGA_R1,VGA_R2);G由3位数字信号组成(VGA_G0,VGA_G1,VGA_G2);B由2位数字信号组成(VGA_B0,VGA_B1)。并通过电压进行分压,而得到不同的电平。实际电路如图2-28。
图2-28开发板RGB数模转换电路图
2. VGA显示
(1)显示原理
通用VGA显示卡系统主要由控制电路、显示缓存区和视频BIOS程序三个部分组成。控制电路主要完成时序发生、显示缓冲区数据操作、主时钟选择和D/A转换等功能;显示缓冲区提供显示数据缓存空间;视频BIOS作为控制程序固化在显示卡的ROM中。
实现VGA显示,除了实现时序控制,还必须有其他功能单元的支持才能实现完整的图像显示。
1)控制器:VGA显示有多种模式,需要通过控制器实现模式间切换,还需要对显示的内容进行接收、处理和显示。所以控制器的性能越高,数据更新和显示效果就越好。显示数据缓存区:VGA显示要求显存速度快、容量大。读速度要达到65MHz以下,存储容量至少要2MB。可采用高速SRAM或SDRAM作为显示数据缓存。
2)数模转换器DAC:VGA显示对数模转换DAC有如下要求:一是高速转换,转换的速度应该在80MHz或以上;二是同步性好,能保证 R、G、B三路信号的同步性;三是有相应的精度。可选择一种包括3路8位高速D/A的专用视频芯片。
3)数据源及其接口:要提高VGA显示的效率,就要不断更新数据,同时还要保证实时性,因此需要非常高的接口速度。VGA显示卡虽可达到100Mbps的数据更新速度,但是一般设备、特别是嵌入式设备达不到这么高的速度,而且大多数情况下也不需要这么高的数据更新率。目前常用接口为EPP接口、USB接口、 TCP/IP、RS232C/485等。其中TCP/IP、EPP接口和USB接口是基于计算机的,速度较快;TCP/IP、RS232C/485是基于网络通信的接口,其中RS485速度虽慢,但应用广泛且容易实现远程控制。
(2)扫描方式
显示器采用光栅扫描方式,即轰击荧光屏的电子束在CRT屏幕上从左到右(受水平同步信号 HSYNC 控制)、从上到下(受垂直同步信号 VSYNC 控制)做有规律的移动。电子束采用光栅扫描方式,从屏幕左上角一点开始,向右逐点进行扫描,形成一条水平线;到达最右端后,又回到下一条水平线的左端,重复上面的过程;当电子束完成右下角一点的扫描后,形成一帧。此后,电子束又回到左上方起点,开始下一帧的扫描。这种方法也就是常说的逐行扫描显示。
(3)扫描频率
完成一行扫描的时间称为水平扫描时间,其倒数称为行频率;完成一帧(整屏)扫描的时间称为垂直扫描时间,其倒数称为场频率,即刷新一屏的频率,常见的有60Hz,75Hz等等。标准的VGA显示的场频60Hz。
(4)数据宽度和格式
如果VGA显示真彩色BMP图像,则需要R、G、B三个分量各8位,即24位表示一个像素值,很多情况下还采用32位表示一个像素值。为了节省显存的存储空间,可采用高彩色图像,即每个像素值由16位表示,R、G、B三个分量分别使用5位、6位、5位,比真彩色图像数据量减少一半,同时又能满足显示效果。
(5)读SRAM地址的产生方法
主时钟作为像素点计数脉冲信号,同时提供显存SRAM的读信号和D/A转换时钟,它所驱动的计数器的输出端作为读SRAM的低位地址。行同步信号作为行数计数脉冲信号,它所驱动的计数器的输出端作为读SRAM的高位地址。由于采用两片SRAM,所以最高位地址作为SRAM的片选使用。由于信号经过CPLD内部逻辑器件时存在一定的时间延迟,在CPLD产生地址和读信号读取数据时,读信号、地址信号和数据信号不能满足SRAM读数据的时序要求。可以利用硬件电路对读信号进行一定的时序调整,使各信号之间能够满足读SRAM和为DAC输入数据的时序要求。
3. VGA支持的规格
我们以第一个分辨率640/480来分析,其刷新速率是60Hz,每幅图像有525行,每行有800个值。也就是说完成一幅图像约是1s/60=16.6ms,完成一行约为16.6ms/525=31.75us,完成一个像素传送约来31.75us/800=40ns。因此为了方便设计,接口的时候设为25MHz最方便,每个时钟送一个数据。
4. VGA接口项目
屏幕分辨率为640/480,刷新速率为60Hz,要求在屏幕中间显示一个200*200的绿色方块,屏幕其他地方均为黑色。
图2-29 显示效果图
(1)明确功能
明确VGA接口的行信号时序图。
明确VGA接口的场信号时序图:
图2-30 VGA接口时序图
从时序图我们可以知道,在第33~516个行周期中的第142~787个时钟周期间,VGA输入数据有效。另外,根据屏幕分辨率和刷新速率,我们可以得出使用25MHz系统时钟最适合。
表2.7 信号列表
信号名 |
I/O |
位宽 |
说明 |
clk |
I |
1 |
系统工作时钟25MHz |
rst_n |
I |
1 |
系统复位信号,低电平有效 |
hys |
O |
1 |
行同步信号 |
vys |
O |
1 |
场同步信号 |
rgb_data |
O |
8 |
输出显示的RGB数据 |
(2)功能波形
本项目的功能波形在上一步已经给出,只需要在VGA输入数据有效期间,根据题目要求把rgb_data变为绿色或黑色即可。
(3)计数结构
图2-31 计数结构图
因为从复位后开始,hys与vys不断循环产生波形,其顺序为同步脉冲、显示后沿、显示时序段和显示前沿,所以使用计数器hs_cnt与vs_cnt,分别用于计数clk个数和行周期个数。
(4)加一结束条件
hs_cnt的加一条件:由于hs_cnt在模块开始工作后不断计数,因此其加1条件为1;
vs_cnt的加一条件:在hs_cnt计数结束时加1,因此其加1条件为end_hs_cnt;
hs_cnt的结束条件:hs_cnt==800 – 1;
vs_cnt的结束条件:vs_cnt==525 – 1;
(5)定义特殊点
按要求,本题是黑色区域和绿色区域的组合,因此我们要定义好两个区域的边界。
图2-32 特殊点示意图
图2-32有几个特殊点,需要我们记住。
hs_cnt的结束条件:hs_cnt==800-1,定为end_hs_cnt。
vs_cnt的结束条件:vs_cnt==525-1,定为end_vs_cnt。
首先我们从时序图可知有效区域,为第33~516个行周期中的第142~787个时钟周期。由于
要在中间显示绿色,因此先计算屏幕中点位置:
由于绿色方框像素为200*200,即有
除此之外的有效区域其他部分均为黑色。
(6)完整性检查
1.计数器hs_cnt
hs_cnt的初值:0;
hs_cnt的加1条件:1;
hs_cnt的结束值:计数至hs_cnt==800 - 1;
2.计数器vs_cnt
vs_cnt的初值:0;
vs_cnt的加1条件:end_hs_cnt;
vs_cnt的结束值:计数至vs_cnt==525 - 1;
3.行信号hys
hys的初值:0;
hys由0变1:hs_cnt==10’d95 && add_hs_cnt;
hys由1变0:end_hs_cnt;
4.场信号vys
vys的初值:0;
vys由0变1:vs_cnt==1’d1 && add_vs_cnt;
vys由1变0:end_vs_cnt;
5.RGB数据信号rgb_data
rgb_data的初值:0;
rgb_data有效区域:hs_cnt_add && hs_cnt>=141 && hs_cnt<787 && vs_cnt>=32 && vs_cnt<516;
rgb_data为绿色:在有效区域且hs_cnt>=364 && hs_cnt<564 && vs_cnt>=174 && vs_cnt<374;
rgb_data为黑色:有效区域的其他部分;
(7)至简设计法计数器代码
2 if(rst_n==1'b0)begin
3 hs_cnt <= 0;
4 end
5 else if(add_hs_cnt)begin
6 if(end_hs_cnt) begin
7 hs_cnt <= 0;
8 end
9 else begin
10 hs_cnt <= hs_cnt+1;
11 end
12 end
13 end
14
15 assign add_hs_cnt = 1;
16 assign end_hs_cnt = add_hs_cnt&& hs_cnt==800-1;
17
18 always @(posedge clk or negedge rst_n)begin
19 if(rst_n==1'b0)begin
20 vs_cnt <= 0;
21 end
22 else if(add_vs_cnt)begin
23 if(end_vs_cnt) begin
24 vs_cnt <= 0;
25 end
26 else begin
27 vs_cnt <= vs_cnt+1;
28 end
29 end
30 end
31
32 assign add_vs_cnt = end_hs_cnt;
33 assign end_vs_cnt = add_vs_cnt&&vs_cnt==525-1;
34
完整代码:
2 assign hs_rise = add_hs_cnt && hs_cnt == 10'd95;
3
4 always @(posedge clk or negedge rst_n)begin
5 if(rst_n==1'b0)begin
6 hys <= 1;
7 end
8 else if(hs_rise)begin
9 hys <= 1;
10 end
11 else if(end_hs_cnt)begin
12 hys <= 0;
13 end
14 end
15
16 //按照第六步第4点,写出vys的代码
17 assign vs_rise = add_vs_cnt && vs_cnt == 1'd1;
18
19 always @(posedge clk or negedge rst_n)begin
20 if(rst_n==1'b0)begin
21 vys <= 1;
22 end
23 else if(vs_rise)begin
24 vys <= 1;
25 end
26 else if(end_vs_cnt)begin
27 vys <= 0;
28 end
29 end
30
31 //有效区域与显示绿色区域定义
32 parameter X0 = 141;
33 parameter X1 = 787;
34 parameter Y0 = 32 ;
35 parameter Y1 = 516;
36 parameter X_CENT = 464;
37 parameter Y_CENT = 274;
38 parameter GREEN = 8'b000_111_00;
39 parameter BLACK = 8'b000_000_00;
40
41 assign valid_area = add_hs_cnt&&hs_cnt>=X0 &&hs_cnt<X1&&vs_cnt>=Y0
42 && vs_cnt<Y1;
43 assign green_area = valid_area&&(hs_cnt>=X_CENT-100
44 && hs_cnt<X_CENT+100 && vs_cnt>=Y_CENT-100
45 &&vs_cnt<Y_CENT+100);
46
47 //按照第六步第5点,写出rgb_data的代码
48 always @(posedge clk or negedge rst_n)begin
49 if(rst_n==1'b0)begin
50 rgb_data <= 8'h00;
51 end
52 else if(valid_area)begin
53 if(green_area)begin
54 rgb_data <= GREEN;
55 end
56 else begin
57 rgb_data <= BLACK;
58 end
59 end
60 else begin
61 rgb_data <= 8'h00;
62 end
63 end
64
技术交流QQ群:764574006
更多FPGA技术资讯:明德扬科教