VGA設計(原理說明。Verilog程式碼實現,模擬結果)
各類顯示器的顯示原理大部分是利用人眼的視覺暫留效應。比如之前的數碼管顯示就是設計每個周期內各個小段按順序顯示,來達到顯示一個數字的效果。
VGA同理,顯示器在顯示時是一個像素一個像素地顯示,在人眼看來所有像素是同時顯示的,便構成了一幅圖片。
①顯示器的解析度越高(如4k屏:3840*2160),顯示的影像越清晰。
②顯示器的刷新率(即每秒能夠顯示幾幅圖片)越高,顯示器越不卡,性能更好。(一個周期內,每個像素點顯示的時間長度和顯示器的解析度以及驅動電路的系統時鐘頻率決定了顯示器的刷新率。
系統時鐘頻率越高,顯示器的刷新率越高。)
顯示器的顯示原理:逐個像素點輸出RGB值,通過設計時序可以達到這個目的。通過行掃描+列掃描達到顯示所有像素點的目的。
VGA是一種顯示標準,VGA介面即電腦採用VGA標準輸出數據的專用介面。
VGA介面共有15針,分成3排,每排5個孔,顯示卡上應用最為廣泛的介面類型,絕大多數顯示卡都帶有此種介面。它傳輸紅、綠、藍模擬訊號[23:0]RGB_data以及同步訊號(水平和垂直訊號)(horizontal_sig和vertical_sig)。
VGA可以實現1080p,但是想實現4k解析度基本不可能,因為數據量太大了。
設計過程:利用計數器來輸出每一個像素以及輸出同步訊號。
案例:
要求:640*480的顯示器
程式碼:
module VGA(
clk,
reset,
content_data_request,//數據請求訊號
horizontal_sig,//horizontal 水平的
vertical_sig, //vertical 垂直的
content_data,//要顯示的內容數據
RGB_data,//輸出的內容數據
vis_sig//內容顯示同步訊號(高電平時顯示)
);
input clk ;
input reset ;
output reg content_data_request ;//數據請求訊號
output reg horizontal_sig ;
output reg vertical_sig ;
input [23:0]content_data ;
output reg [23:0]RGB_data ;
output reg vis_sig ;//內容顯示同步訊號
reg h_vis_sig ;//行內容顯示同步訊號
reg v_vis_sig ;//列內容顯示同步訊號
//定義時間節點參數
//行參數
parameter h_pulse_start = 0 ; //行起始脈衝開始訊號
parameter h_pulse_end = 96 ;// 行起始脈衝結束訊號 96
parameter h_content_start = 96 + 40 + 8 ;//行內容開始訊號 144
parameter h_content_end = 96 + 40 + 8 + 640 ;//行內容結束訊號 784
parameter h_end = 96 + 40 + 8 + 640 + 8 + 8;//行結束訊號 800
//列參數
parameter v_pulse_start = 0 ; //列起始脈衝開始訊號
parameter v_pulse_end = 2 ;//列起始脈衝結束訊號 2
parameter content_start = 2 + 25 + 8 ;//列內容開始訊號 35
parameter content_end = 2 + 25 + 8 + 480 ;//列內容結束訊號 515
parameter v_end = 2 + 25 + 8 + 480 + 2 + 8;//列結束訊號 525
//行與列 計數器
reg [9:0]h_cnt ;
reg [9:0]v_cnt ;
always@(posedge clk or negedge reset)//行計數
if(!reset)
h_cnt <= 0 ;
else if ( h_end - 1 <= h_cnt )//0-799
h_cnt <= 0 ;
else
h_cnt <= h_cnt + 1 ;
always@(posedge clk or negedge reset)//列計數
if(!reset)
v_cnt <= 0 ;
else if (( v_end - 1 <= v_cnt ) && ( h_end - 1 <= h_cnt ))//0-524
v_cnt <= 0 ;
else if (( h_end - 1 <= h_cnt ) && ( v_end - 1 > v_cnt ))
v_cnt <= v_cnt + 1 ;
//產生行起始脈衝
always@(posedge clk or negedge reset)//
if(!reset)
horizontal_sig <= 1 ;
else if( h_cnt == 0 )
horizontal_sig <= 0 ;//1-96 共96
else if ( h_cnt == 96 )
horizontal_sig <= 1 ;
//產生列起始脈衝
always@(posedge clk or negedge reset)//
if(!reset)
vertical_sig <= 1 ;
else if(( v_cnt == 0 )&& ( h_end - 1 <= h_cnt ) )
vertical_sig <= 0 ;//1-2 共2
else if (( v_cnt == 2 )&& ( h_end - 1 <= h_cnt ) )
vertical_sig <= 1 ;
//產生行顯示同步訊號
always@(posedge clk or negedge reset)//
if(!reset)
h_vis_sig <= 0 ;
else if (( 144 - 2 <= h_cnt ) && ( 784 - 1 - 2 >= h_cnt )) //提前兩拍保證輸出在第145拍開始
h_vis_sig <= 1 ;//146 - 785共
else
h_vis_sig <= 0 ;
//產生列顯示同步訊號
always@(posedge clk or negedge reset)//
if(!reset)
v_vis_sig <= 0 ;
else if (( 35 <= v_cnt ) && ( 515 >= v_cnt ) && ( ( h_end - 1 <= h_cnt ) ) )
v_vis_sig <= 1 ;
else if (( 35 > v_cnt ) || ( 515 < v_cnt ) )
v_vis_sig <= 0 ;
//請求訊號
always@(posedge clk or negedge reset)
if(!reset)
content_data_request <= 0 ;//
else if ( ( v_vis_sig ) && ( h_vis_sig ) )
content_data_request <= 1 ;
else
content_data_request <= 0 ;
//顯示同步訊號
always@(posedge clk or negedge reset)//
if(!reset)
vis_sig <= 0 ;
else if ( content_data_request )
vis_sig <= 1 ;
else
vis_sig <= 0 ;
//顯示
always@(posedge clk or negedge reset)//
if(!reset)
RGB_data <= 0 ;
else if ( content_data_request )
RGB_data <= content_data ;
else
RGB_data <= 0 ;
endmodule
`timescale 1ns / 1ns
module VGB_tb(
);
reg clk ;
reg reset ;
wire horizontal_sig ;
wire vertical_sig ;
reg [23:0]content_data ;
wire [23:0]RGB_data ;
wire content_data_request ;//數據請求訊號 ;
wire vis_sig ;
VGA VGA_sim(
clk,
reset,
content_data_request,//數據請求訊號
horizontal_sig,//horizontal 水平的
vertical_sig, //vertical 垂直的
content_data,//要顯示的內容數據
RGB_data,//輸出的內容數據
vis_sig //內容顯示同步訊號
);
initial clk = 1 ;
always #20 clk = ! clk ;//25MHz
initial begin
reset = 0 ;
content_data = 0 ;
#201
reset = 1 ;
#70000000;
$stop;
end
always@(posedge clk or negedge reset)//
if(!reset)
content_data <= 0 ;
else if (content_data_request )
content_data <= content_data + 1 ;
endmodule
結果:
需要驗證的點:同步訊號的長度,脈衝訊號的長度,顯示行的時間長度,顯示列的長度。(通過觀察行計數器h_cnt和列計數器v_cnt即可)
新功能:顯示特定區域。
實現:設定參數來界定區域。