fpga學習之vga驅動
阿新 • • 發佈:2018-12-20
一、什麼是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、顯示時序要求(顯示步驟):以800600 為 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顯示漢字,顯示圖片,顯示數字等。。。。。。,大家可以思考一下噢!