实验二-基于FPGA的VGA协议实现
实验内容
- 深入了解VGA协议,理解不同显示模式下的VGA控制时序参数(行频、场频、水平/垂直同步时钟周期、显示后沿/前沿等概念和计算方式)。
- 通过Verilog编程,在至少2种显示模式下(640480@60Hz,1024768@75Hz)分别实现以下VGA显示,并对照VGA协议信号做时序分析:1)屏幕上显示彩色条纹;2)显示自定义的汉字字符(姓名-学号);3)输出一幅彩色图像。
- 在Verilog代码中,将行、场同步信号中,故意分别加入一定 ms延时(用delay命令),观察会出现什么现象。
1、什么是VGA协议
VGA协议,即视频图形阵列(Video Graphics Array)协议,是一种由IBM在1987年推出用于计算机显示的标准。它广泛应用于个人电脑和显示器之间的连接,尽管随着技术的发展出现了更高分辨率和更先进的接口技术,但VGA仍然在许多设备上得到广泛使用。
VGA协议主要包含以下几方面的内容:
-
色彩原理:基于三基色原理,即通过红(R)、绿(G)、蓝(B)三种基本色来表达色彩空间。这三种颜色信号是相互独立的,任何一种基色都不能由其他两种颜色合成。
-
信号传输:VGA接口传输红、绿、蓝模拟信号以及同步信号(水平和垂直信号)。这些信号通过D型15针接口传输,其中包括RGB彩色分量信号和扫描同步信号HSYNC与VSYNC。
-
分辨率和刷新率:VGA支持多种分辨率和刷新率,例如800x600@60Hz等。在800x600@60Hz分辨率下,所需的时钟频率大约为40MHz。
-
扫描方式:VGA显示器通常采用逐行扫描方式,从屏幕左上角开始,逐行从左向右扫描,每扫描完一行后返回下一行的起始位置,直到形成一帧。
-
行场信号:VGA协议定义了行同步信号(HSYNC)和场同步信号(VSYNC),这些信号用于同步图像的显示,确保图像的稳定性。
-
接口设计:VGA接口是一种D型接口,上面共有15针孔,分成三排,每排五个。其中,包括RGB彩色分量信号、显示数据总线和同步信号等。
-
驱动电路:VGA驱动电路有多种设计方案,包括使用R-2R电阻模拟电路或专用视频转换DAC芯片实现VGA电路方案。
-
时序:VGA时序包括行时序和场时序,它们定义了同步脉冲、显示后沿、显示时序段和显示前沿等部分,以确保图像的正确显示。
VGA协议因其成本低廉、结构简单和应用灵活等优点,在彩色显示器领域得到了广泛应用。尽管现代显示技术不断进步,VGA作为一种成熟的显示接口,仍然在特定场合和应用中保持着其价值和地位。
2、不同显示模式下的VGA控制时序参数
VGA控制时序参数是确保图像正确显示在VGA显示器上的关键因素。不同的显示模式下,这些参数会有所变化。以下是一些基本概念和计算方式,以及它们在不同显示模式下的应用。
基本概念
-
行频(Horizontal Scanning Frequency):也称为水平扫描频率,指每秒在屏幕上从左到右扫描的行数,单位是kHz。
-
场频(Vertical Scanning Frequency):也称为垂直扫描频率,指屏幕的刷新频率,即每秒刷新的帧数,常见的有60Hz、75Hz等,但标准的VGA显示的场频为60Hz。
-
水平/垂直同步时钟周期:这些是用于同步图像的水平和垂直扫描的时钟周期。水平同步时钟周期决定了一行中的像素数量,而垂直同步时钟周期决定了一帧中的行数。
-
显示后沿(Back Porch):在一行或一帧的显示数据之后,有一个短暂的间隔,不显示图像,用于电子束返回起始位置。
-
显示前沿(Front Porch):在一行或一帧的开始之前,也有一个短暂的间隔,不显示图像。
计算方式
-
行频计算:行频可以通过总的行周期(包括同步脉冲、显示后沿、有效图像、显示前沿)乘以刷新频率来计算。
-
场频计算:场频通常指的是刷新频率,即屏幕每秒刷新的次数。
-
水平/垂直同步时钟周期:这些周期可以通过行频和场频来确定。例如,如果行频是31.5kHz,那么每个行周期的时间为1/行频。
3、VGA显示
要在Verilog中实现VGA显示,通常需要创建一个模块来生成VGA时序信号,并根据这些信号控制像素数据的输出。以下是在640x480@60Hz和1024x768@75Hz两种显示模式下实现指定显示内容的基本步骤和时序分析。
(1)彩色条纹显示
时序分析:
- 640x480@60Hz:
- 行频(HF):31.5 kHz
- 场频(VF):60 Hz
- 水平像素数:640(Active),总像素数:800(包括前后沿)
- 垂直行数:480(Active),总行数:525
- 1024x768@75Hz:
- 行频(HF):78.8 kHz
- 场频(VF):75 Hz
- 水平像素数:1024(Active),总像素数:1344(包括前后沿)
- 垂直行数:768(Active),总行数:806
Verilog实现:
module vga_controller(
input clk, // 时钟输入
output reg hsync, vsync, // 同步信号
output reg [11:0] hcount, vcount, // 计数器
output reg [23:0] rgb // RGB数据
// 其他信号定义...
);
// 时钟分频以得到行频和场频
always @(posedge clk) begin
if(/* 行频分频逻辑 */) hsync <= ~hsync;
if(/* 场频分频逻辑 */) vsync <= ~vsync;
end
// 计数器逻辑
always @(posedge clk) begin
if(hsync) hcount <= 0;
else hcount <= hcount + 1;
if(vsync) vcount <= 0;
else if(hcount == (/* 总水平像素数 */ - 1)) vcount <= vcount + 1;
end
// 彩色条纹逻辑
always @(posedge clk) begin
if(hcount < 640) begin
// 根据hcount的值生成红色和蓝色的交替条纹
rgb[23:16] <= (hcount[7] == vcount[7]) ? 255 : 0; // 红色
rgb[15:8] <= (hcount[6] != vcount[6]) ? 255 : 0; // 绿色(不变化)
rgb[7:0] <= (hcount[5] == vcount[5]) ? 255 : 0; // 蓝色
end
end
endmodule
(2)显示自定义汉字字符(姓名-学号)
时序分析:
- 与彩色条纹相同,但需要考虑字符的编码和在屏幕上的位置。
Verilog实现:
// 假设已经有了汉字字符的字模数据
always @(posedge clk) begin
// 定位到屏幕的特定位置
if(/* 定位逻辑 */) begin
// 输出姓名和学号的字模数据到rgb
rgb <= /* 姓名和学号的字模数据 */;
end
end
(3)输出一幅彩色图像
时序分析:
- 与彩色条纹相同,但需要根据图像数据更新像素值。
Verilog实现:
// 假设已经有了图像数据的存储和读取逻辑
always @(posedge clk) begin
if(/* 图像数据读取逻辑 */) begin
rgb <= /* 读取的图像数据 */;
end
end
4、加入延时会出现什么现象
在Verilog中,可以使用#
操作符来实现延时。在Verilog中,延时是按照仿真时间来计算的,而不是实际的硬件时间。例如,#10
意味着在仿真中等待10个时间单位,这些时间单位需要在仿真环境的设置中定义。
如果我们在生成行同步信号(hsync
)和场同步信号(vsync
)的代码中故意加入延时,这将影响屏幕的刷新和图像的显示。
实现延时的示例:
// 假设clk是时钟信号,time_unit是时间单位(比如1ns)
localparam time_unit = 1; // 根据仿真设置调整
always @(posedge clk) begin
if (/* 行同步信号的生成条件 */) begin
#(10 * time_unit); // 故意加入10个时间单位的延时
hsync <= ~hsync; // 切换行同步信号
end
end
always @(posedge clk) begin
if (/* 场同步信号的生成条件 */) begin
#(16.67 * 1000 * time_unit); // 故意加入大约1/60秒的延时(60Hz场频)
vsync <= ~vsync; // 切换场同步信号
end
end
观察到的现象:
-
屏幕闪烁:如果行同步信号的延时导致每行的刷新不同步,屏幕可能会出现水平的闪烁线。
-
图像滚动或偏移:如果场同步信号被延时,可能会导致图像在垂直方向上滚动或偏移,因为每帧的刷新不再与场频同步。
-
显示不稳定:延时可能导致显示内容不稳定,出现抖动或错位的现象。
-
刷新率变化:如果延时改变了行频或场频的周期,屏幕的刷新率会受到影响,可能导致显示内容闪烁或显示不正常。
-
显示器无法同步:在极端情况下,如果延时过长,显示器可能无法正确同步信号,导致无图像显示或显示器进入节能模式。