VGA设计(原理说明。Verilog代码实现,仿真结果)

各类显示屏的显示原理大部分是利用人眼的视觉暂留效应。比如之前的数码管显示就是设计每个周期内各个小段按顺序显示,来达到显示一个数字的效果。

VGA同理,显示屏在显示时是一个像素一个像素地显示,在人眼看来所有像素是同时显示的,便构成了一幅图片。
①显示器尺寸相同的情况下,分辨率越高(如4k屏:3840*2160),显示的图像越清晰。
②显示器的刷新率(即每秒能够显示几幅图片)越高,显示器越不卡,性能更好。(一个周期内,每个像素点显示的时间长度和显示屏的分辨率以及驱动电路的系统时钟频率决定了显示屏的刷新率。系统时钟频率越高,显示屏的刷新率越高。)

显示器的清晰度取决于像素密度,即PPI(每英寸内像素点的个数)。

显示器的显示原理:逐个像素点输出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即可)

 

 

新功能:显示特定区域。

实现:设定参数来界定区域。

 

posted @ 2022-07-20 17:06  little_breeze  阅读(482)  评论(0编辑  收藏  举报