前言
对VGA相关的基础内容进行整理,部分图文内容来自参考文献。
1、VGA接口
目前常见的电路板上的VGA接口是这样的,单独使用R、G、B三条线控制颜色。FPGA直接将RGB颜色信息通过VGA串口进行传输。
或者是这样的,增加一个电阻网络来使可以控制的颜色更加丰富。
下图是采用VGA驱动芯片来进行数据输出,即FPGA将RGB颜色信息等信号传输给ADC7123芯片,然后该芯片将RGB信息通过VGA串口进行传输。
R | 表述是红色信号。图一的R只有一位,图二R[3:0],图三R[7:0]。 |
G | 表述是绿色信号。图一的G只有一位,图二G3:0],图三G[7:0]。 |
B | 表述是蓝色信号。图一的B只有一位,图二B[3:0],图三B[7:0]。 |
H_SYNC | VGA的水平同步信号,又称行同步信号 |
V_SYNC | VGA的垂直同步信号,又称场同步信号 |
VGA_CLK | ADV7123KSTZ140芯片的管脚,是VGA显示的主时钟,它的频率决定了VGA显示的分辨率。 |
VGA_BLANK | ADV7123KSTZ140芯片的管脚,VGA显示时默认置1 |
VGA_SYNC | ADV7123KSTZ140芯片的管脚,VGA显示时默认置0 |
2、VGA显示时序
VGA驱动时钟,直接采用上图的Pixel Clock=25.175MHZ=25MHZ即可。
关于VGA驱动时钟,也有下图的计算方式。
具体FPGA实现中,需要关心几个参数
帧长 | 行帧长=800Pixels,行计数器cnt_x[9:0];列帧长=525lines,列计数器cnt_y[9:0]。 |
同步脉冲 | 同步脉冲=Sync Time。 |
显示后沿 | 显示后沿=Back Porch+Top/Left Border。 |
显示前沿 | 显示前沿=Bottom/Right Border + Front Porch。 |
下图中的同步脉冲Hsync和Vsync,有的是高电平有效,有的是低电平有效。本文是高电平有效。
3、VGA 模块Verilog代码设计
首先,关键参数定义
//-------------------------------------------------//
// 扫描参数的设定 640*480 60Hz VGA
//-------------------------------------------------//
parameter H_SYNC_END = 96; //行同步脉冲结束时间
parameter V_SYNC_END = 2; //列同步脉冲结束时间
parameter H_SYNC_TOTAL = 800; //行扫描总像素单位
parameter V_SYNC_TOTAL = 525; //列扫描总像素单位
parameter H_SHOW_START = 144; //显示区行开始像素点
parameter V_SHOW_START = 35; //显示区列开始像素点
其次,行列寄存器。
参考章节2中的VGA显示时序,定义行计数器cnt_x[9:0]、列计数器cnt_y[9:0]。
行计数器 cnt_x[9:0]从0-800循环计数。当计数到0-96之间时,拉高hsync;否则,hsync=0。
列计数器cnt_y[9:0]从0-525循环计数。当计数到0-2之间时,拉高vsync;否则,vsync=0。
//水平扫描
always@(posedge clk_25M or negedge RSTn)
if(!RSTn) x_cnt <= 10'd0;
else if (x_cnt == H_SYNC_TOTAL) x_cnt <= 10'd0;
else x_cnt <= x_cnt + 1'b1;
//垂直扫描
always@(posedge clk_25M or negedge RSTn)
if(!RSTn) y_cnt <= 10'd0;
else if (y_cnt == V_SYNC_TOTAL) y_cnt <= 10'd0;
else if (x_cnt == H_SYNC_TOTAL) y_cnt <= y_cnt + 1'b1;
else y_cnt <= y_cnt;
//H_SYNC信号
always@(posedge clk_25M or negedge RSTn)
if(!RSTn) hsync <= 1'd0;
else if (x_cnt == 10'd0) hsync <= 1'b1;
else if (x_cnt == H_SYNC_END) hsync <= 1'b0;
else hsync <= hsync;
//V_SYNC信号
always@(posedge clk_25M or negedge RSTn)
if(!RSTn) vsync <= 1'd0;
else if (y_cnt == 10'd0) vsync <= 1'b1;
else if (y_cnt == V_SYNC_END) vsync <= 1'b0;
else vsync <= vsync;
最后,RGB输出的颜色,RGB数据的位宽,自己根据需要设计即可。
参考文献