fpga学习之vga驱动

一、什么是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、显示时序要求(显示步骤):以800
600 为 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显示汉字,显示图片,显示数字等。。。。。。,大家可以思考一下噢!

猜你喜欢

转载自blog.csdn.net/qq_38428056/article/details/85119282