1. 程式人生 > >fpga學習之vga驅動

fpga學習之vga驅動

一、什麼是vga?
vga:(Video Graphics Array,視訊圖形陣列),是 IBM 於 1987 年提出的一個使用類比訊號的電腦顯示標準。VGA 是最多製造商所共同支援的一個低標準,個人電腦在載入自己的獨特驅動程式之前,都必須支援 VGA 的標準。
二、vga掃描方式
顯示器掃描方式分為逐行掃描和隔行掃描:逐行掃描是掃描從螢幕左上角一點開始,從左向右逐點掃描,每掃描完一行, 電子束回到螢幕的左邊下一行的起始位置,在這期間, CRT 對電子束進行消隱,每行結束時,用行同步訊號進行同
步;當掃描完所有的行,形成一幀,用場同步訊號進行場同步,並使掃描回到螢幕左上方,同時進行場消隱,開始下一幀。 隔行掃描是指電子束掃描時每隔一行掃一線,掃完一屏後再返回來掃描剩下的線,隔行掃描的顯示器閃爍快速,可能會使使用者眼睛疲勞。在實際應用中,多數使用逐行掃描,本實驗就採用逐行掃描。
三、vga的顯示標準
在這裡插入圖片描述


四、vga顯示時序
1、行掃描時序:
在這裡插入圖片描述
2、場掃描時序
在這裡插入圖片描述
根據上述顯示器的掃描引數以及掃描時序,例如 800[email protected] 的顯示模式,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*[email protected],實現點亮整個螢幕,並顯示為全綠色。
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*
[email protected]
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*[email protected]  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顯示漢字,顯示圖片,顯示數字等。。。。。。,大家可以思考一下噢!