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即可)

 

 

新功能:顯示特定區域。

實現:設定參數來界定區域。