文章目录
概要
VGA(Video Graphics Array)作为经典的视频显示接口标准,至今仍在FPGA图像处理、嵌入式显示系统等领域广泛应用。它不仅支持CRT显示器,也兼容LCD液晶屏,具有时序清晰、驱动简单、分辨率灵活等特点。本文将系统介绍VGA的成像原理、时序参数,并结合一个完整的Verilog控制器设计与仿真调试实例,帮助读者深入理解VGA驱动实现的全流程。
一、VGA成像原理与基本时序

1.1 VGA接口与显示原理
VGA是一种模拟视频接口,采用RGB三原色分量传输图像信号。在CRT显示器中,电子束从左到右、从上到下逐行扫描荧光屏,通过控制RGB电子枪的强度合成彩色像素。液晶显示器虽无电子枪,但为兼容VGA标准,其内部电路会模拟相同的时序行为。
1.2 同步与消隐信号
行同步(HSync):指示一行扫描结束,电子束返回左侧。
场同步(VSync):指示一场(一帧)扫描结束,电子束返回左上角。
消隐期(Blank):在行/场回扫期间关闭电子束,避免显示干扰信号。
1.3 时序参数详解
VGA一行的时序包含以下阶段(以像素时钟为单位)
同步脉冲(Sync Pulse)
后消隐(Back Porch)
左边界(Left Border)
有效数据显示区(Visible Area)
右边界(Right Border)
前消隐(Front Porch)
一场的时序则以行为单位,结构类似。
1.4 常见分辨率标准

二、VGA控制器Verilog设计(以800×480为例)
2.1 设计目标
设计一个VGA控制器,能输出符合VGA时序的同步信号(HSync、VSync)、消隐信号(BLK)和RGB数据。
2.2 核心信号
h_sync, v_sync:行、场同步信号
vga_blk:数据有效标志(高电平表示在有效显示区)
vga_data[23:0]:RGB888格式像素数据(R[23:16], G[15:8], B[7:0])
2.3 时序参数计算(800×480@60Hz)
像素时钟:33MHz
行总周期:1056 像素时钟
HSync脉冲宽度:128
后消隐:88
有效像素:800
前消隐:40
场总行数:525 行
VSync脉冲宽度:2
后消隐:25
有效行数:480
前消隐:2
2.4 Verilog代码段
c
`timescale 1ns / 1ps
module VGA(
clk_33m,
reset_n,
data_in,
hcount,
vcount,
VGA_HS,
VGA_VS,
VGA_DATA,
VGA_CLK,
VGA_BLK
);
input clk_33m;
input reset_n;
input [23:0]data_in;
output [11:0]hcount;//行扫描位置
output [11:0]vcount;//场扫描位置
output VGA_HS;//VGA行同步信号
output VGA_VS;//VGA场同步信号
output [23:0]VGA_DATA;
output VGA_CLK;
output VGA_BLK;
parameter HS_end = 11'd127,
Hdat_begin = 11'd215,
Hdat_end = 11'd1015,
Hsync_end = 11'd1055,
VS_end = 11'd1,
Vdat_begin = 11'd34,
Vdat_end = 11'd514,
Vsync_end = 11'd524;
reg [11:0] hcount_r;
reg [11:0] vcount_r;
//行计数器 hcount_r(横向扫描)
always@(posedge clk_33m or negedge reset_n)
if(!reset_n)
hcount_r <= 11'd0;
else if(hcount_r == Hsync_end)
hcount_r <= 11'd0;
else
hcount_r <= hcount_r +1'd1;
//场计数器 vcount_r(纵向扫描)
always@(posedge clk_33m or negedge reset_n)
if(!reset_n)
vcount_r <= 11'd0;
else if (hcount_r == Hsync_end)
begin
if(vcount_r == Vsync_end)
vcount_r <= 11'd0;
else
vcount_r <= vcount_r + 1'd1;
end
else
vcount_r <= vcount_r;
assign VGA_CLK = ~clk_33m;//把内部像素时钟 clk_33m 输出到显示端当像素时钟
assign VGA_BLK = ((hcount_r >= Hdat_begin) && (hcount_r < Hdat_end) && (vcount_r >= Vdat_begin) && (vcount_r < Vdat_end))?1'b1:1'b0;//显示有效区 VGA_BLK,只有在有效显示区内,才让 VGA_BLK = 1
assign hcount = VGA_BLK ? (hcount_r - Hdat_begin):10'd0;//把"整行计数"转换成"屏幕 X 坐标"
assign vcount = VGA_BLK ? (vcount_r - Vdat_begin):10'd0;//把"整帧行计数"转换成"屏幕 Y 坐标"
assign VGA_HS = (hcount_r > HS_end)?1'b1:1'b0;//行同步信号 HS(给显示器的"行开始脉冲")
assign VGA_VS = (vcount_r > VS_end)?1'b1:1'b0;//场同步信号 VS(给显示器的"帧开始脉冲")
assign VGA_DATA = (VGA_BLK)?data_in : 24'h000000;//在显示区:输出你的 data_in(RGB888),不在显示区:输出黑色(防止消隐区乱闪)
endmodule
三、仿真调试
c
`timescale 1ns / 1ps
module VGA_tb;
reg clk_33m;
reg reset_n;
reg [23:0]data_in;
wire [11:0]hcount;
wire [11:0]vcount;
wire VGA_HS;
wire VGA_VS;
wire VGA_BLK;
wire VGA_CLK;
wire [23:0] VGA_DATA;
VGA VGA(
.clk_33m (clk_33m ),
.reset_n (reset_n ),
.data_in (data_in ),
.hcount (hcount ),
.vcount (vcount ),
.VGA_HS (VGA_HS ),
.VGA_VS (VGA_VS ),
.VGA_BLK (VGA_BLK ),
.VGA_CLK (VGA_CLK ),
.VGA_DATA (VGA_DATA )
);
initial clk_33m = 1;
always #15 clk_33m= ~clk_33m; //周期30ns,所以这里是15,实现15ns翻转
initial begin
reset_n = 0;
#201;
reset_n = 1;
#200000000;
$stop;
end
always @ (posedge clk_33m or negedge reset_n)
if (!reset_n)
data_in <= 0;
else if (!VGA_BLK)
data_in <= data_in;
else
data_in <= data_in + 1;
endmodule
四、仿真分析
1、HS信号分析

低脉冲时间:实测3.84μs,计算得3840/30=128个时钟周期,与800×480时序参数表中
的HS脉冲宽度128⼀致
2、VS信号分析

低脉冲时间:实测63.36μs,计算得63360/30/1056=2⾏扫描时间,与标准参数⼀致
3、数据的起始位置

⾏数据验证:hcount从0开始计数,输出数据0-799(共800个像素),每个像素对应⼀
个时钟周期
小结
本文从VGA成像原理出发,详细解析了其时序结构,并以800×480分辨率为例,给出了完整的Verilog控制器设计、仿真与验证流程。VGA驱动是FPGA图像处理的基础模块,掌握其时序设计与调试方法,可为后续摄像头显示、视频叠加、GUI界面等应用打下坚实基础。