当前位置:   article > 正文

FPGA--VGA驱动

vga驱动

一.VGA显示原理

1.VGA的显示不是直接让图像在屏幕上显示出来,而是通过扫描的方式,将构成图像的像素点,在行场同步时序信号的控制下,按照从上到下,从左到右的顺序显示在屏幕上,其具体的流程可表示为如下的步骤”

1.在行场同步的作用下,扫描坐标定位到坐上角的第一个像素点坐标;

2.自左上角第一个像素坐标,向右逐个像素点进行扫描;

3.扫描到第一行最后一个数据,一行图像扫描完成吗,进行图像的消隐,之后开始第二行的第一个像素坐标自左向右的扫描;

4.重复若干次之后到最后一行的行尾,一帧图像扫描完成,进行消隐,之后跳到第一行,再次进行。

框图:(这一部分参考的野火教程,侵权就删)只用于自我学习的笔记加总结。
在这里插入图片描述

二.VGA时序

在这里插入图片描述

2.1 行场同步时序图

在这里插入图片描述
注:这里的行场时序一样,所以用一个图来表示

三.verilog代码实现

功能:驱动七寸800*480的lcd屏幕并显示彩条

3.1框图

在这里插入图片描述

3.2时序图

在这里插入图片描述

3.3verilog代码实现

module vga_ctrl(
    input wire          pexil_clk    ,
    input wire          sys_rst      ,
    input wire [15:0]   pexil_data   ,

    output wire         Hsync        ,
    output wire         Vsync        ,
    output wire [9:0]   pexil_x      ,
    output wire [9:0]   pexil_y      ,
    output wire [15:0]  rgb_data    
);

reg [9:0] Cnt_H         ;
reg [9:0] Cnt_V         ;
wire      rgb_valid     ;
wire      pexil_data_req;

/****************************************************************************
#参数定义:@行信号参数定义
			@场信号参数定义
			@数据信号的定义
*****************************************************************************/

parameter  H_SYNC  = 10'd96,
            H_BACK  = 10'd40,
            H_LEFT  =  10'd8,
            H_VALID =  10'd640,
            H_RIGHT =   10'd8,
            H_FRONT =   10'd8,
            H_TOTAL =  H_SYNC + H_BACK + H_LEFT + H_VALID + H_RIGHT + H_FRONT;
                       
parameter  V_SYNC  =  10'd2,
            V_BACK  =  10'd25,
            V_UP    =   10'd8,
            V_VALID = 10'd480, 
            V_DOWN  =  10'd8,
            V_FRONT =   10'd2,
            V_TOTAL = V_SYNC + V_BACK + V_UP + V_VALID + V_DOWN + V_FRONT;

parameter  WHITE      =    16'hffff      ,
			BLACK      =    16'h0000      ,
			RED        =    16'hf800      ,
			GREEN      =    16'h07E0      ,
			BLUE       =    16'h001f      ;          
/************************************************
#模块说明:行信号计数器,用于表示行信号的周期循环
           在时钟的上升沿加一,用于计数行信号。
           单位:像素

************************************************/
always @(posedge pexil_clk or negedge sys_rst) begin
    if(!sys_rst)
        Cnt_H <= 10'b0;
    else if(Cnt_H == H_TOTAL - 10'd1 )
        Cnt_H <= 10'b0;
    else    
        Cnt_H <= Cnt_H + 10'd1;
end
/************************************************
#模块说明:场信号计数器,用于表示场信号的周期循环
            在时钟的上升沿加一,用于计数场信号。
            单位:行

************************************************/
always @(posedge pexil_clk or negedge sys_rst) begin
    if(!sys_rst)
        Cnt_V <= 10'b0;
    else if((Cnt_V == V_TOTAL - 10'd1)&&(Cnt_H == H_TOTAL - 10'd1))
        Cnt_V <= 10'b0;
    else  if(Cnt_H == H_TOTAL - 10'd1)  
        Cnt_V <= Cnt_V + 10'd1;
    else 
        Cnt_V <= Cnt_V;
end


// 数据显示有效标志位:当Cnt_H范围在[同步信号+后沿+左边框,同步信号+后沿+左边框+显示的有效区域)
                //       Cnt_V范围在[同步信号+后沿+上边框,同步信号+后沿+左边框+显示的有效区域)时,该信号拉高
assign rgb_valid = ((Cnt_H >= H_SYNC + H_BACK + H_LEFT)
                        &&(Cnt_H < H_SYNC + H_BACK + H_LEFT + H_VALID )
                            &&(Cnt_V >= V_SYNC +V_BACK +V_UP)
                                &&(Cnt_V < V_SYNC +V_BACK +V_UP + V_VALID)) 
                                ? 1'b1 :1'b0 ;

// 数据显示请求有效标志位:当Cnt_H范围在[同步信号+后沿+左边框-1,同步信号+后沿+左边框+显示的有效区域-1)
                //              Cnt_V范围在[同步信号+后沿+上边框,同步信号+后沿+左边框+显示的有效区域)时,该信号拉高,
                        //            以达到提前一个时钟周期的效果
assign pexil_data_req = ((Cnt_H >= H_SYNC + H_BACK + H_LEFT - 1'b1)
                        &&(Cnt_H < H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1 )
                            &&(Cnt_V >= V_SYNC +V_BACK +V_UP)
                                &&(Cnt_V < V_SYNC +V_BACK +V_UP + V_VALID)) 
                                ? 1'b1 :1'b0 ;

// 有效显示区域坐标
assign pexil_x =  (pexil_data_req==1'b1) ? (Cnt_H - (H_SYNC + H_BACK + H_LEFT - 1'b1 )):10'd0;
assign pexil_y =   (pexil_data_req==1'b1) ? (Cnt_V - (V_SYNC + V_BACK + V_UP)  ):10'd0;


//同步信号拉高
assign  Hsync = (Cnt_H <= H_SYNC - 10'd1) ? 1'b1:1'b0;

assign  Vsync = (Cnt_V <= V_SYNC - 10'd1) ? 1'b1:1'b0;



assign rgb_data  =   (rgb_valid == 1'b1) ? pexil_data:16'h0000;

/************************************************
//下面是数据生成模块

always @(posedge pexil_clk or negedge sys_rst) begin 
    if(!sys_rst)
       pexil_data <=BLACK;
    else if((pexil_x >= 10'd0) && (pexil_x < (H_VALID /5)))
        pexil_data <= WHITE;
    else if((pexil_x >= (H_VALID /5)) && (pexil_x < (H_VALID /5)*2))
        pexil_data <= BLACK;
    else if((pexil_x >= (H_VALID /5)*2) && (pexil_x < (H_VALID /5)*3))
        pexil_data <= RED;
    else if((pexil_x >= (H_VALID /5)*3) && (pexil_x < (H_VALID /5)*4))
        pexil_data <= GREEN;
    else if((pexil_x >= (H_VALID /5)*4) && (pexil_x < H_VALID))
        pexil_data <= BLUE;
    else 
    	pexil_data <= BLACK;
end
***/







endmodule 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135

注:最后的数据生成模块意思是,可以在此模块中直接生成,而不需要外部的数据输入,当然代码也要进行相关的修改。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/799350
推荐阅读
相关标签
  

闽ICP备14008679号