VGA驱动接口设计

项目名称

Vga驱动接口设计

项目说明

       VGA 图像显示方式是通过光栅扫描的方式,电子束在显示屏幕上有规律地从左到右、 从上到下的逐行扫描。即从屏幕左上角一点开始,从左像右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时, 用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。

     VGA 的时序包括水平时序和垂直时序,且两者都包含的时序参数有:水平(垂直)同步 脉冲、水平(垂直)同步脉冲结束到有效显示数据区开始之间的宽度(后沿)、有效显示区宽度、 有效数据显示区结束到水平(垂直)同步脉冲宽度开始之间的宽度(前沿)。水平有效显示区宽 度与垂直有效显示区宽度逻辑与的区域为可视区域,其他区域为消隐区。 标准 VGA 一共 15 个接口,真正用到的信号接口只有 5 个,HSYNC 是行同步信号,VSYNC 是场同步信号,VGA_R、VGA_G、VGA_B 是 RGB 三原色信号。

   常用的专用VGA视频编码芯片有ADV/GM7123,然后通过标准的VGA物理接口输出,实现与VGA显示器通信。本项目采用的adv7123视频编码芯片.

  本项目采用640*480@60的显示模式 

分辨率(长*宽@帧率) 时钟(mhz)   行时序(像素) 场时序(像素)
a b c d e a b c d e
640*480@60hz 25.175mhz 96 48 640 16 800 2 33 480 10 525

时序图

       

rgb三原色模型:一般包括rgb332,rgb565,rgb444,rgb888等,本项目采用rgb888的显示模式,可以显示的颜色种类有2^8*2^8*2^8 种

具体要求

显示任意颜色,比如红色

设计架构

                    

代码设计

verilog代码设计 

创建pll ipcore生成25m的vga驱动时钟

顶层模块设计

module vga_color_top(
	input				clk,
	input				rst_n,
	output  [23:0]	vga_rgb,
	output  			vga_hs,//行时序,计数一行中每列的像素
	output  			vga_vs,//场时序,计数一列中每行的像素
	
	output				lcd_dclk////adv7123像素时钟输入
//	output				lcd_blank,//显示空白输入
//	output				lcd_sync//显示同步引脚可以一直为低
);

wire clk_25m;
wire locked;
 my_pll my_pll (
	.areset(!rst_n),
	.inclk0(clk),
	.c0(clk_25m),
	.locked(locked)
);

vga_color  vga_color
(
	.clk(clk_25m),
	.rst_n(locked),
	.vga_rgb(vga_rgb),
	.vga_hs(vga_hs),//行时序,计数一行中每列的像素
	.vga_vs(vga_vs),//场时序,计数一列中每行的像素

	.lcd_dclk(lcd_dclk),////adv7123像素时钟输入
	.lcd_blank(),//显示空白输入
	.lcd_sync()//显示同步引脚可以一直为低
);
endmodule

vga控制模块设计

//640*480@60hz
module vga_color
(
	input					clk,
	input					rst_n,
	output reg[23:0]	vga_rgb,
	output reg			vga_hs,//行时序,计数一行中每列的像素
	output reg			vga_vs,//场时序,计数一列中每行的像素
	
	output				lcd_dclk,////adv7123像素时钟输入
	output				lcd_blank,//显示空白输入
	output				lcd_sync//显示同步引脚可以一直为低
);

localparam red=24'hff0000;
localparam green=24'h00ff00;
localparam blue=24'h0000ff;
localparam white=24'hffffff;
localparam black=24'h000000;
localparam yellow=24'hffff00;

reg [10:0] cnt1;//行像素计数器
reg [10:0] cnt2;//列像素计数器

//行时序计满799,从0开始计数
always@(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt1<=11'd0;
	else if(cnt1<11'd799)
		cnt1<=cnt1+1'b1;
	else
		cnt1<=11'd0;
//场时序计满524
always@(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt2<=11'd0;
	else if(cnt1==11'd799)begin
		if(cnt2<11'd524)
			cnt2<=cnt2+1;
		else
			cnt2<=0;
	end
	else
		cnt2<=cnt2;
				
//行同步时序
always@(*)
	if(!rst_n)
		vga_hs<=0;
	else if(cnt1==11'd0)
		vga_hs<=0;
	else if(cnt1==11'd96)  //0-95总共120个像素点为低电平,计数到96同步输出高电平
		vga_hs<=1;
//场同步时序
always@(*)
	if(!rst_n)
		vga_vs<=0;
	else if(cnt2==11'd0)
		vga_vs<=0;
	else if(cnt2==11'd2)
		vga_vs<=1;
//显示区域
reg flag;//显示区域标志信号
always@(*)
	if(!rst_n)
		flag<=0;
	else if((cnt1>=11'd144 && cnt1<11'd784) && (cnt2>=11'd35 && cnt2<11'd515))
		flag<=1;
	else 	
		flag<=0;
		
always@(*)
	if(!rst_n)
		vga_rgb<=0;
	else if(flag)
		vga_rgb<=red;
	else
		vga_rgb<=0;
		
assign lcd_sync=1'd0;
assign lcd_blank=vga_hs & vga_vs;
assign lcd_dclk=~clk;		
	
	
		
		
endmodule

仿真代码

`timescale 1ns/1ns
module vga_color_top_tb;
	reg				clk;
	reg				rst_n;
	wire  [23:0]	vga_rgb;
	wire  			vga_hs;//行时序,计数一行中每列的像素
	wire  			vga_vs;//场时序,计数一列中每行的像素
	
	wire				lcd_dclk;////adv7123像素时钟输入
//	output				lcd_blank,//显示空白输入
//	output				lcd_sync//显示同步引脚可以一直为低

vga_color_top  vga_color_top(
	.clk(clk),
	.rst_n(rst_n),
	.vga_rgb(vga_rgb),
	.vga_hs(vga_hs),//行时序,计数一行中每列的像素
	.vga_vs(vga_vs),//场时序,计数一列中每行的像素
	
	.lcd_dclk(lcd_dclk)////adv7123像素时钟输入
//	output				lcd_blank,//显示空白输入
//	output				lcd_sync//显示同步引脚可以一直为低
);

initial clk=0;
always #10 clk=~clk;

initial begin
	rst_n=0;
	#200;
	rst_n=1;
end

endmodule

仿真结果

 行同步时序满足时序要求在0-95为低,96-799为高

 场时序也满足要求,仿真时间较长

标志信号也满足设计要求,由于仿真时间较长,不再赘述。

结果显示

 

猜你喜欢

转载自blog.csdn.net/weixin_43533751/article/details/106983098
VGA