基于FPGA的VGA协议实现
一、VGA简述
1.VCG接口
VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排,每排5个孔,显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号以及同步信号(水平和垂直信号)。
2.原理
常见接口之色差VGA接口(D-Sub接口)
说到VGA接口,相信很多朋友都不会陌生,因为这种接口是电脑显示器上最主要的接口,从块头巨大的CRT显示器时代开始,VGA接口就被使用,并且一直沿用至今,另外VGA接口还被称为D-Sub接口。
很多人觉得只有HDMI接口才能进行高清信号的传输,但这是一个大家很容易进入的误区,因为通过VGA的连接同样可以显示1080P的图像,甚至分辨率可以达到更高,所以用它连接显示设备观看高清视频是没有问题的,而且虽然它是种模拟接口,但是由于VGA将视频信号分解为R、G、B三原色和HV行场信号进行传输,所以在传输中的损耗还是相当小的 。
VGA接口产生原因: 显卡所处理的信息最终都要输出到显示器上,显卡的输出接口就是电脑与显示器之间的桥梁,它负责向显示器输出相应的图像信号。CRT显示器因为设计制造上的原因,只能接受模拟信号输入,这就需要显卡能输出模拟信号。VGA接口就是显卡上输出模拟信号的接口,VGA(Video Graphics Array)接口,也叫D-Sub接口。虽然液晶显示器可以直接接收数字信号,但很多低端产品为了与VGA接口显卡相匹配,因而采用VGA接口
3.显示器扫描
逐行扫描是扫描从屏幕左上角一点开始,从左像右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。
行(场)同步信号:电视信号发送端为了使接收端的行扫描与场扫描规律与其同步,在行(场)扫描正常结束后,向接收机发出一个脉冲信号,表示这一行(场)已经结束,这个脉冲信号就是行(场)同步信号。
行场消隐信号:电子枪所发出的电子 束从屏幕的左上角开始向右扫描,一行扫完需将电子束从右边移到左边以便扫描第二行。在移动期间就必须有一个信号加到电路上,使得电子束不能发出。不然这个扫线会破坏屏幕图像的。这个阻止扫线产生的信号就叫作消隐信号场信号的消隐也是一个道理。
扫描时间:完成一行扫描的时间称为水平扫描时间,其倒数称为行频率;完成一帧(整屏)扫描的时间称为垂直扫描时间,其倒数称为场频率,即刷新一屏的频率,常见的有60Hz,144Hz等等。
显示带宽:带宽指的显示器可以处理的频率范围。如果是60Hz刷新频率的VGA,其带宽达640x480x60=18.4MHz
4.VGA时序分析
VESA中定义行时序和场时序都需要同步脉冲(Sync a)、显示后沿(Back porch b)、显示时序段(Display interval c)和显示前沿(Front porch d)四部分。【同步脉冲要求是负脉冲】
消隐间隔就是上一个时序的显示前沿+本时序的同步脉冲+本时序的显示后沿。
每一行都有一个负极性行同步脉冲(Sync a),是数据行的结束标志,同时也是下一行的开始标志。在同步脉冲之后为显示后沿(Back porch b),在显示时序段(Display interval c)显示器为亮的过程,RGB数据驱动一行上的每一个像素点,从而显示一行。在一行的最后为显示前沿(Front porch d)。在显示时间段(Display interval c)之外没有图像投射到屏幕是插入消隐信号。同步脉冲(Sync a)、显示后沿(Back porch b)和显示前沿(Front porch d)都是在行消隐间隔内(Horizontal Blanking Interval),当消隐有效时,RGB信号无效,屏幕不显示数据
VGA_HS(行同步):在一个周期内,VGA_HS的低电平时间为96个VGA_CLK信号周期,高电平时间为704个VGA_CLK信号周期。VGA的数据信号在VGA_HS高电平的第49个VGA_CLK信号周期开始有效,一直持续到VGA_HS高电平的第688个VGA_CLK信号周期。
其中,96个Hsync脉冲低电平:Sync_pulse = 96;704个周期的Hsync的高电平由分为:Front Porch= 16周期,和BackFront Porch =48周期,剩余的704-16-48=640即为一行的有效数据周期(一个像素周期传送一个像素)
VGA_VS(场同步):在一个周期内,VGA_VS的低电平时间为2个VGA_HS信号周期,高电平时间为523个VGA_HS信号周期。VGA的数据信号在VGA_VS高电平的第34个VGA_HS信号周期开始有效,一直持续到高电平的第513个VGA_HS信号周期。
5.VGA时钟计算
对于640* 480@60即一帧图像的分辨率为640* 480,每秒60的频率帧刷新,则一帧的传输的全部像素个数为800* 525(注意分辨率640* 480指的是有效显示数据的分辨率,而计算时候需要用全分辨率),即
VGA_CLK=HS_total×VS_total×FPS。
6.不同分辨率的VGA参数
二、显示彩条
1.色彩原理
三基⾊是指通过其他颜⾊的混合⽆法得到的“基本⾊”由于⼈的⾁眼有感知红、绿、蓝三种不同颜⾊的锥体细胞,因此⾊彩空间通常可以由三种基本⾊来表达。这是⾊度学的最基本原理,即 三基⾊原理。三种基⾊是相互独⽴的,任何⼀种基⾊都不能有其它两种颜⾊合成。红绿蓝是三基⾊,这三种颜⾊合成的颜⾊范围最为⼴泛。我们的RGB信号真是三基⾊的运⽤,对这三个信号赋予不同的数值,混合起来便是不同的⾊彩。
设计RGB信号时,既可以R信号、G信号和B信号独⽴的赋值,最后连到端⼝上,也可以直接⽤RGB当做⼀个整体信号,RGB信号在使⽤时的位宽有三种常见格式:
- RGB_8,R:G:B = 3:3:2,即RGB332 RGB_16,
- R:G:B = 5:6:5,即RGB565
- RGB_24,R:G:B = 8:8:8,即RGB888
2.彩条输出
参数定义
`define vga_640_480
//`define vga_800_600
`ifdef vga_640_480
`define h_right_border 8
`define h_front_porch 8
`define h_sync_time 96
`define h_back_porch 40
`define h_left_border 8
`define h_data_time 640
`define h_total_time 800
`define v_bottom_border 8
`define v_front_porch 2
`define v_sync_time 2
`define v_back_porch 25
`define v_top_border 8
`define v_data_time 480
`define v_total_time 525
`elsif vga_1280_720
`define h_right_border 0
`define h_front_porch 110
`define h_sync_time 40
`define h_back_porch 220
`define h_left_border 0
`define h_data_time 1280
`define h_total_time 1650
`define v_bottom_border 0
`define v_front_porch 5
`define v_sync_time 5
`define v_back_porch 20
`define v_top_border 0
`define v_data_time 720
`define v_total_time 750
`elsif vga_1920_1080
`define h_right_border 0
`define h_front_porch 88
`define h_sync_time 44
`define h_back_porch 148
`define h_left_border 0
`define h_data_time 1920
`define h_total_time 2200
`define v_bottom_border 0
`define v_front_porch 4
`define v_sync_time 5
`define v_back_porch 36
`define v_top_border 0
`define v_data_time 1080
`define v_total_time 1125
`elsif vga_800_600
`define h_right_border 0
`define h_front_porch 40
`define h_sync_time 128
`define h_back_porch 88
`define h_left_border 0
`define h_data_time 800
`define h_total_time 1056
`define v_bottom_border 0
`define v_front_porch 1
`define v_sync_time 4
`define v_back_porch 23
`define v_top_border 0
`define v_data_time 600
`define v_total_time 628
`endif
VGA驱动
`include "vga_par.v"
module vga_ctrl(
input wire clk ,//VGA时钟25.2MHz
input wire rst_n ,//复位信号
input wire [23:00] data_dis ,//
output reg [10:00] h_addr ,//数据有效显示区域行地址
output reg [10:00] v_addr ,//数据有效显示区域场地址
output reg hsync ,//
output reg vsync ,//
output reg [07:00] vga_r ,//
output reg [07:00] vga_g ,//
output reg [07:00] vga_b , //
output reg vga_blk ,//vga消隐信号
output wire vga_clk //
);
//参数定义
parameter h_sync_sta = 1,
h_sync_sto = `h_sync_time,
h_data_sta = `h_left_border + `h_front_porch +`h_sync_time,
h_data_sto = `h_left_border + `h_front_porch +`h_sync_time + `h_data_time,
v_sync_sta = 1,
v_sync_sto = `v_sync_time,
v_data_sta = `v_top_border + `v_back_porch +`v_sync_time,
v_data_sto = `v_top_border + `v_back_porch +`v_sync_time + `v_data_time