FPGA-08FPGAVGA彩条显示

(1)VGA简介

VGA的全称是Video Graphics Array,即视频图形阵列,是一个使用模拟信号进行视频传输的标准。早期的CRT显示器由于设计制造上的原因,只能接收模拟信号输入,因此计算机内部的显卡负责进行数模转换,而VGA接口就是显卡上输出模拟信号的接口。如今液晶显示器虽然可以直接接收数字信号,但是为了兼容显卡上的VGA接口,也大都支持VGA标准。

 

在VGA视频传输标准中,视频图像被分解为红、绿、蓝三原色信号,经过数模转换之后,在行同步(HSYNC)和场同步(VSYNC)信号的同步下分别在三个独立通道传输。VGA在传输过程中的同步时序分为行时序和场时序。

从上面两幅图中我们可以看到VGA传输过程中的行同步时序和场同步时序非常类似,一行或一场(又称一帧)数据都分为四个部分:低电平同步脉冲、显示后沿、有效数据段以及显示前沿。

行同步信号HSYNC在一个行扫描周期中完成一行图像的显示,其中在a段维持一段时间的低电平用于数据同步,其余时间拉高;在有效数据期间(c段),红绿蓝三原色数据通道上输出一行图像信号,其余时间数据无效。

与之类似,场同步信号在在一个场扫描周期中完成一帧图像的显示,不同的是行扫描周期的基本单位是像素点时钟,即完成一个像素点显示所需要的时间;而场扫描周期的基本单位是完成一行图像显示所需要的时间。

早期的VGA特指分辨率为640X480的显示模式,后来根据分辨率的不同,VGA又分为VGA(640x480)、SVGA(800x600)、XGA(1024x768)、SXGA(1280x1024)等。不同分辨率的VGA显示时序是类似的,仅存在参数上的差异

需要注意的是,即便分辨率相同,刷新速率(每秒钟图像更新次数)不一样时,对应的VGA像素时钟及时序参数也存在差异。例如,显示模式“640*480@75”刷新速率为75hz,与相同分辨率下刷新速率为60hz的“640*480@60”模式相比,像素时钟更快,其他时序参数也不尽相同。

(2)实验任务

开发板上的VGA接口在显示器上显示彩条,要求分辨率为640*480,刷新速率为60hz。

(3)硬件设计

FPGA管脚输出的颜色数据位宽为16bit,数据格式为RGB565,即数据高5位表示红色,中间6位表示绿色,低5位表示蓝色。RGB565格式的数据一共可表示65536种颜色,此外常用的颜色数据格式还有RGB888,数据位宽越大,可以表示的颜色种类就越丰富。

由前面的简介我们知道,VGA传输的是模拟信号,因此需要对FPGA输出的RGB565颜色数据进行数模转换。此过程可以通过专用的视频转换芯片(如ADV7123)来实现,在这里我们采用另外一种更简单的方案——利用电阻匹配网络来实现数字信号到模拟信号的转换。

(4)程序设计

VGA时序包含三个要素:像素时钟、行场同步信号、以及图像数据,由此我们可以大致规划出系统结构如图 所示。其中时钟分频模块负责产生像素时钟,VGA驱动模块产生行场同步信号,VGA显示模块输出图像数据。

由系统框图可知,FPGA部分包括四个模块,顶层模块(vga_colorbar)、时钟分频模块(vga_pll)、VGA显示模块(vga_display)以及VGA驱动模块(vga_driver)。其中在顶层模块中完成对另外三个模块的例化。

module vga_driver(
    input           vga_clk,      //VGA驱动时钟
    input           sys_rst_n,    //复位信号
    //VGA接口                          
    output          vga_hs,       //行同步信号
    output          vga_vs,       //场同步信号
    output  [15:0]  vga_rgb,      //红绿蓝三原色输出
    
    input   [15:0]  pixel_data,   //像素点数据
    output  [ 9:0]  pixel_xpos,   //像素点横坐标
    output  [ 9:0]  pixel_ypos    //像素点纵坐标    
    );                             
                                                        
//parameter define  
parameter  H_SYNC   =  10'd96;    //行同步
parameter  H_BACK   =  10'd48;    //行显示后沿
parameter  H_DISP   =  10'd640;   //行有效数据
parameter  H_FRONT  =  10'd16;    //行显示前沿
parameter  H_TOTAL  =  10'd800;   //行扫描周期

parameter  V_SYNC   =  10'd2;     //场同步
parameter  V_BACK   =  10'd33;    //场显示后沿
parameter  V_DISP   =  10'd480;   //场有效数据
parameter  V_FRONT  =  10'd10;    //场显示前沿
parameter  V_TOTAL  =  10'd525;   //场扫描周期
          
//reg define                                     
reg  [9:0] cnt_h;
reg  [9:0] cnt_v;

//wire define
wire       vga_en;
wire       data_req; 

//*****************************************************
//**                    main code
//*****************************************************
//VGA行场同步信号
assign vga_hs  = (cnt_h <= H_SYNC - 1'b1) ? 1'b0 : 1'b1;
assign vga_vs  = (cnt_v <= V_SYNC - 1'b1) ? 1'b0 : 1'b1;

//使能RGB565数据输出
assign vga_en  = (((cnt_h >= H_SYNC+H_BACK) && (cnt_h < H_SYNC+H_BACK+H_DISP))
                 &&((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
                 ?  1'b1 : 1'b0;
                 
//RGB565数据输出                 
assign vga_rgb = vga_en ? pixel_data : 16'd0;

//请求像素点颜色数据输入                
assign data_req = (((cnt_h >= H_SYNC+H_BACK-1'b1) && (cnt_h < H_SYNC+H_BACK+H_DISP-1'b1))
                  && ((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
                  ?  1'b1 : 1'b0;

//像素点坐标                
assign pixel_xpos = data_req ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 10'd0;
assign pixel_ypos = data_req ? (cnt_v - (V_SYNC + V_BACK - 1'b1)) : 10'd0;

//行计数器对像素时钟计数
always @(posedge vga_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)
        cnt_h <= 10'd0;                                  
    else begin
        if(cnt_h < H_TOTAL - 1'b1)                                               
            cnt_h <= cnt_h + 1'b1;                               
        else 
            cnt_h <= 10'd0;  
    end
end

//场计数器对行计数
always @(posedge vga_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)
        cnt_v <= 10'd0;                                  
    else if(cnt_h == H_TOTAL - 1'b1) begin
        if(cnt_v < V_TOTAL - 1'b1)                                               
            cnt_v <= cnt_v + 1'b1;                               
        else 
            cnt_v <= 10'd0;  
    end
end

endmodule 
module vga_display(
    input             vga_clk,                  //VGA驱动时钟
    input             sys_rst_n,                //复位信号
    
    input      [ 9:0] pixel_xpos,               //像素点横坐标
    input      [ 9:0] pixel_ypos,               //像素点纵坐标    
    output reg [15:0] pixel_data                //像素点数据
    );    
    
parameter  H_DISP = 10'd640;                    //分辨率——行
parameter  V_DISP = 10'd480;                    //分辨率——列
localparam WHITE  = 16'b11111_111111_11111;     //RGB565 白色
localparam BLACK  = 16'b00000_000000_00000;     //RGB565 黑色
localparam RED    = 16'b11111_000000_00000;     //RGB565 红色
localparam GREEN  = 16'b00000_111111_00000;     //RGB565 绿色
localparam BLUE   = 16'b00000_000000_11111;     //RGB565 蓝色
    
//*****************************************************
//**                    main code
//*****************************************************
//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge vga_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)
        pixel_data <= 16'd0;                                  
    else begin
        if((pixel_xpos >= 0) && (pixel_xpos <= (H_DISP/5)*1))                                              
            pixel_data <= WHITE;                               
        else if((pixel_xpos >= (H_DISP/5)*1) && (pixel_xpos < (H_DISP/5)*2))
            pixel_data <= BLACK;  
        else if((pixel_xpos >= (H_DISP/5)*2) && (pixel_xpos < (H_DISP/5)*3))
            pixel_data <= RED;  
        else if((pixel_xpos >= (H_DISP/5)*3) && (pixel_xpos < (H_DISP/5)*4))
            pixel_data <= GREEN;  
        else 
            pixel_data <= BLUE;  
    end
end

endmodule 

(5)下载验证

  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值