(15)vga成像原理与时序分析
vga显示器成像原理
常见的vga成像接口显示器一般是基于CRT(阴极射线管)实现,阴极射线枪将电子束打在涂有荧光粉的荧光屏上,产生RGB三原色,合成一个彩色像素,显示采用逐行扫描的方式,扫描从屏幕左上方开始,从左向右,从上到下
每行扫描结束后,使用行同步信号进行行同步,让电子枪都会回到下一行最左侧的起始位置
在回扫(右下至左上)的过程中电子枪不能发射电子,否则会影响图像的显示,因此必须要进行行消隐,简单来说就是关闭电子枪
当整个屏幕的所有行都扫描完成后,使用场同步信号进行场同步,使扫描回到屏幕左上方
同样,为了避免电子枪在回到左上方的过程中破坏已有图像,该过程也需要进行场消隐
目前大多数显示器为液晶显示器,其成像原理与CRT显示器并不相同,主要是通过改变像素点的电压来改变其透光性,由于液晶技术晚于 CRT 显示技术诞生,在液晶显示器出现的时候,计算机显示接口已经确定,很难再突然改变。所以为了能够兼容传统的显示接口,液晶显示器通过内部电路实现了对 VGA 接口的完全兼容,因此。因此,在使用显示器时,只要该显示器带有标准的 VGA 接口,就不用去关注其成像原理,直接使用标准的 VGA 时序即可驱动。
当使用 VGA 接口传输图像时,显示驱动芯片(如显卡)输出的 RGB 数据先要经过 DAC转换为 3 路分别代表 R、G、B 颜色分量的模拟信号,送到 VGA 接口,这些模拟信号经由 VGA线缆到达显示器的 VGA 接口:对于模拟的 CRT 显示器,这些信号会直接被放大后用于驱动电子枪发射电子;而对于液晶显示器,则需要显示器使用专门的模拟数字转换芯片将模拟信号再转换为数字信号后,去驱动 RGB 接口的液晶显示屏显示图像。
vga时序详解
下图的图像是我们希望显示在屏幕上的图像内容,我们的目的是让该图像恰好完全的显示在屏幕上,上文已经介绍了电子枪的成像过程,因此对于这幅图像,我们可以理解为是横向的很多行图像向下依次平铺构成的,而每一行图像,又可以理解为由多个像素点从左向右依次平铺构成的
CRT行扫描过程
虽然扫描的时候是按照一行一行的方式进行的,但不是扫描完一行有效数据段之后就立马返回,而是会继续向右扫描一段区域,这个区域称为右边界区域(horizontal right border),该区域已经不在有效的显示范围内(物理上理解为是显示器的黑边)
同样的,显示器左边也有这样一段黑边,在开始显示有效数据之前,电子枪扫描到的这段区域同样也是没有荧光粉的,不会显示图像, 这个区域称为左边界区域(horizontal left border)。
因此,当电子枪扫描一行图像到达荧光屏的最右端后,其并不会自动回到最左边准备下一行,而是需要有一个通知信号,通知其回去,这个通知信号就是行同步信号脉冲(horizontal sync pulse)。
当该脉冲出现后,电子枪的指向会在一定时间内从最右侧回到显示屏的最左侧。而这个回去的过程需要耗费一定的时间,这个时间就称为horizontal back porch
当电子枪扫描过了右侧没有荧光粉的区域后,还没有收到回到最左侧的命令(行同步信号脉冲)之前,电子枪需要关闭以实现消隐,这个消隐的时间段就称为 horizontal front porch,直观一点理解就是完成了一行图像的扫描,但还没收到回到最左侧命令之前的一段时间
CRT场扫描过程
CRT 在扫描一行图像的时候,电子枪的水平位置是保持稳定不变的,而当一行图像扫描完成,开始扫描下一行图像的时候,电子枪的水平位置会向下调整一定的值。因此,我们可以认为,场时序就是在垂直方向上从上往下依次扫描。
在垂直方向上也不是扫描完所有行的图像后就立马返回最上方,而是会继续向下扫描一段区域,这个区域称为下边界区域(vertical bottom border),同样,显示器上边也有这样一段黑边,这个区域称为上边界区域(vertical top border)。
当电子枪扫描一场图像到达荧光屏的最下方后,其并不会自动回到最上边准备下一场,而是需要有一个通知信号,通知其回去,这个通知信号就是场同步信号脉冲(vertical sync pulse)
同样,这个回去的过程需要耗费一定的时间,这个时间就称为 vertical back porch。即出现场同步信号后,电子枪从显示屏最下方回到最上方的时间。
当电子枪扫描过了下方没有荧光粉的区域后,还没有收到回到最上方的命令(场同步信号脉冲)之前,电子枪需要关闭以实现消隐,这个消隐的时间段就称为vertical front porch
vga时序标准
行扫描时序:
场扫描时序:
上面两幅图中每个参数的大小并不是固定的,而是需要根据扫描的有效区域的大小来确定的(一般用分辨率表示),例如标准的vga分辨率为640*480个像素点(横轴640个像素点,纵轴480行)
各分辨率常见时序参数
下表给出了若干个常见分辨率对应的行场时序中各个参数的具体数值,注意,这些参数值中,行相关的参数都是以像素的更新频率,也就是像素时钟作为单位,而场相关的参数,则是以行作为单位。
上表中,大部分参数都来源于视频电子标准协会VESA(Video Electronics Standards Association)制定的显示器时序标准(Monitor Timing Standard),当然,也有部分分辨率是该协会没有制定,由显示设备厂家自己定义并世界范围内流通的标准
vga控制器设计与验证
HS、VS、BLK、DATA(RGB三路)
注:关于BLK的解释说明:在有效图像输出时为高电平,在无效图像输出时为低电平
需要找到各个信号和数据变化的时间节点
以640*480标准为例
行信号 | 像素时钟(pclk) |
---|---|
行同步脉冲开始位置HS_begin | 0 |
行同步脉冲结束位置HS_end | 96 |
行数据开始输出位置Hdata_begin | 96+40+8 |
行数据停止输出位置Hdata_end | 96+40+8+640 |
行同步信号结束位置Hsync_end | 96+40+8+640+8+8 |
注:行同步信号结束位置Hsync_end是指在输出完visible area中的像素数据后,hsync信号还需要保持一段的时间,这段时间在物理上等于right border与front porch之和,在这段时间结束后,就是下一个循环的开始,简单来说就是一行结束的位置
场信号 | 行数(line) |
---|---|
场同步脉冲开始位置HS_begin | 0 |
场同步脉冲结束位置VS_end | 2 |
场数据开始输出位置Vdata_begin | 2+25+8 |
场数据停止输出位置Vdata_end | 2+25+8+480 |
场同步信号结束位置Vsync_end | 2+25+8+480+8+2 |
场同步信号结束位置Vsync_end就是一幅画面结束,该数值等于一幅画面的所有行数(包括有效的和无效的)
代码设计
VGA_CTRL.V
点击查看代码
module VGA_CTRL(
clk ,
rst_n ,
data_in ,
hsync ,
vsync ,
blk ,
data
);
parameter Hsync_end = 800;
parameter HS_end = 96;
parameter Vsync_end = 525;
parameter VS_end = 2;
parameter Hdata_begin = 144;
parameter Hdata_end = 784;
parameter Vdata_begin = 35;
parameter Vdata_end = 515;
input clk ;
input rst_n ;
input [23:0] data_in ;
output hsync ;
output vsync ;
output blk ;
output [23:0] data ; //[7:0]R、[7:0]G、[7:0]B
reg [9:0] hcnt ;
reg [9:0] vcnt ;
//行计数器
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
hcnt <= 0;
end
else if (hcnt >= Hsync_end - 1) begin
hcnt <= 0;
end
else begin
hcnt <= hcnt + 1;
end
end
//水平同步信号
assign hsync = (hcnt < HS_end - 1) ? 0:1;
//场计数器
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
vcnt <= 0;
end
else if (hcnt == Hsync_end - 1) begin
if(vcnt >= Vsync_end - 1) begin
vcnt <= 0;
end
else begin
vcnt <= vcnt + 1;
end
end
else begin
vcnt <= vcnt;
end
end
//垂直同步信号
assign vsync = (vcnt < VS_end - 1) ? 0:1;
//消隐信号
assign blk = ((vcnt >= Vdata_begin - 1) && (vcnt <= Vdata_end -1 ) && (hcnt >= Hdata_begin - 1) && (hcnt <= Hdata_end -1 )) ? 1:0;
//数据输出
assign data = blk ? data_in : 0;
endmodule
VGA_CTRL_tb.v
点击查看代码
`timescale 1ns/1ps
module VGA_CTRL_tb();
reg clk ;
reg rst_n ;
reg [23:0] data_in ;
wire hsync ;
wire vsync ;
wire blk ;
wire [23:0] data ;
initial clk = 1;
always #20 clk = ~clk; //对于640*480时钟频率25MHz
initial begin
rst_n = 0;
#201
rst_n = 1;
#200000000
$stop;
end
always @(posedge clk) begin
if(!rst_n) begin
data_in <= 0;
end
else if(!blk)
begin
data_in <= data_in;
end
else begin
data_in <= data_in + 1;
end
end
VGA_CTRL u_VGA_CTRL(
.clk (clk ) ,
.rst_n (rst_n ) ,
.data_in (data_in) ,
.hsync (hsync ) ,
.vsync (vsync ) ,
.blk (blk ) ,
.data (data )
);
/*iverilog */
initial
begin
$dumpfile("wave.vcd"); //生成的vcd文件名称
$dumpvars(0, VGA_CTRL_tb); //tb模块名称
end
/*iverilog */
endmodule
第一行像素的仿真
从图中可清楚观察到blk、hsync信号以及数据读取的过程,可以看到一行的有效像素个数为640,与我们之前的理论相同