一、什么是vga?
vga:(Video Graphics Array,视频图形阵列),是 IBM 于 1987 年提出的一个使用类比讯号的电脑显示标准。VGA 是最多制造商所共同支持的一个低标准,个人电脑在加载自己的独特驱动程式之前,都必须支持 VGA 的标准。
二、vga扫描方式
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行, 电子束回到屏幕的左边下一行的起始位置,在这期间, CRT 对电子束进行消隐,每行结束时,用行同步信号进行同
步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。 隔行扫描是指电子束扫描时每隔一行扫一线,扫完一屏后再返回来扫描剩下的线,隔行扫描的显示器闪烁快速,可能会使使用者眼睛疲劳。在实际应用中,多数使用逐行扫描,本实验就采用逐行扫描。
三、vga的显示标准
四、vga显示时序
1、行扫描时序:
2、场扫描时序
根据上述显示器的扫描参数以及扫描时序,例如 800600@60 的显示模式,60 指得是显示器图像的刷新频率,时钟 40MHz 指得是一个像素输出的频率。800600 为 VGA 的分辨率,指有效显示区域为时序中的 c 段只有 800600,也就是行计数在[216,1016],列计数在[27,627],在这个范围内,给 RGB 色值才会有效。
2、显示时序要求(显示步骤):以800600 为 VGA 的分辨率
行:行同步信号上电拉高,在行同步计数为 0 时拉低 a 个时钟周期,即 128,之后拉高,在行同步计数到 1055 时,
行同步计数器清零,场同步计数器加 1。在行扫描时序中,扫描计数时,周期就是一个像素点的时间。
场:在场同步计数为 0 时拉低场同步 a 个时钟周期,即 4,之后拉高,在场同步计数到 627 时,场同步计数器清零。
3、三基色的控制(R,G,B)既是:红,绿,蓝。
在vga接口中,还需要控制三个接口,即三基色。它们使用8bit,16bit的最多(我们在本实验中采用八位,16位跟八位没什么本质上的区别),8bit的三基色:R为3bit,G为3bit,B为2bit,可以显示2^8种颜色 ;
16bit的三基色:R为5bit,G为6bit,B为5bit。分别可以显示2^16种颜色;
四、设计目的及源码设计
1、设计目的:
本设计选择的 VGA 显示标准为 800*600@60Mhz,实现点亮整个屏幕,并显示为全绿色。
2、源码设计:
a、rtl原理图
b、源码设计
顶层设计
module vga_display (
input clk , //系统时钟50Mhz
input rst_n , //系统时钟复位
output vga_vs , //VGA场同步信号
output vga_hs , //VGA行同步信号
output [7:0] vga_rgb //VGA场红绿蓝三基色
);
//----------------VGA时序-----------------------------------
// 显示模式 时钟
// 800*600@60 40MHz
//行/场 同步(a) 消隐后沿(b) 有效显示(c) 消隐前沿(d) 扫描时间(e)
//hs 128 88 800 40 1056
//vs 4 23 600 1 628
wire vga_clk;
//锁相环分频模块
vga_pll vga_pll_dut(
.areset(~rst_n),
.inclk0(clk),
.c0(vga_clk)
);
//vga驱动控制模块
vga_control vga_control_dut(
.vga_clk(vga_clk),
.rst_n(rst_n),
.vga_hs(vga_hs),
.vga_vs(vga_vs),
.vga_rgb(vga_rgb)
);
endmodule
vga控制模块设计
module vga_control (
input vga_clk , //系统时钟40Mhz
input rst_n , //系统复位
output reg vga_vs , //VGA场同步信号
output reg vga_hs , //VGA行同步信号
output [7:0] vga_rgb //VGA场红绿蓝三基色
);
//----------------VGA时序-----------------------------------
// 显示模式 时钟
// 800*600@60 40MHz
//行/场 同步(a) 消隐后沿(b) 有效显示(c) 消隐前沿(d) 扫描时间(e)
//hs 128 88 800 40 1056
//vs 4 23 600 1 628
// 行(Horizontal)扫描 Parameter (像素)
parameter H_A = 128;
parameter H_B = 80;
parameter H_C = 800;
parameter H_D = 40;
parameter H_E = 1056;
// 场(Vertical)扫描 Parameter (行数)
parameter V_A = 4;
parameter V_B = 23;
parameter V_C = 600;
parameter V_D = 1;
parameter V_E = 628;
//行扫描计数器,
reg [10:0] hcnt;
always @ (posedge vga_clk or negedge rst_n)
begin
if (!rst_n)
hcnt <= 11'd0;
else
begin
if (hcnt == (H_E - 1'b1)) //扫描完一行像素
hcnt <= 11'd0;
else
hcnt <= hcnt + 1'b1;
end
end
//场扫描计数器
reg [12:0] vcnt;
always @ (posedge vga_clk or negedge rst_n)
begin
if (!rst_n)
vcnt <= 11'd0;
else if (vcnt == (V_E - 1'b1))
vcnt <= 11'd0;
else if (hcnt == (H_E - 1'b1))
vcnt <= vcnt + 1;
end
//行同步输出
always @ (posedge vga_clk or negedge rst_n)
begin
if (!rst_n)
vga_hs <= 1'b1;
else if (hcnt < H_A)
vga_hs <= 1'b0;
else
vga_hs <= 1'b1;
end
//场同步输出
always @ (posedge vga_clk or negedge rst_n)
begin
if (!rst_n)
vga_vs <= 1'b1;
else if (vcnt < V_A)
vga_vs <= 1'b0;
else
vga_vs <= 1'b1;
end
wire rgb_en;
assign rgb_en = (hcnt >= H_A + H_B && hcnt < H_A + H_B + H_C) &&
(vcnt >= V_A + V_B && vcnt < V_A + V_B + V_C) ? 1'b1 : 1'b0;
//判断使能信号是否有效,1有效显示绿色,0无效显示黑色
assign vga_rgb = rgb_en ? 8'b000_111_00 : 8'b0000_0000;
endmodule
仿真模块设计
`timescale 1ns/1ps //仿真时间精度时间单位
module vga_display_tb;
reg clk ; //系统时钟
reg rst_n ; //系统复位
wire vga_vs ; //VGA场同步信号
wire vga_hs ; //VGA行同步信号
wire [7:0] vga_rgb ; //VGA场红绿蓝三基色
//初始化数据,并附相应初值
initial begin
clk = 0;
rst_n = 0;
#200.1 rst_n = 1;
end
vga_display vga_display_inst (
.clk(clk),
.rst_n(rst_n),
.vga_hs(vga_hs),
.vga_vs(vga_vs),
.vga_rgb(vga_rgb)
);
always #10 clk = ~clk; //50MHz时钟描述
endmodule
仿真图
注:本实验的分频模块采用pll(锁相环分频),所以需要添加ip核,否则会出错。这是基本的vga驱动,大家可以在这个基础上做一些好玩的东西,例如利用vga显示汉字,显示图片,显示数字等。。。。。。,大家可以思考一下噢!