• 基于FPGA的VGA图像显示


    基于FPGA的VGA图像显示

    引言:本文我们介绍利用FPGA实现VGA图像显示,主要介绍VGA硬件接口、VGA接口时序原理以及FPGA代码实现VGA接口时序、仿真等内容。

    01 VGA硬件接口介绍

    VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排,每排5个孔,显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号以及同步信号(水平和垂直信号)。

    在这里插入图片描述

    图1、VGA接口

    管脚信号信号描述
    1RED红基色
    2GREEN绿基色
    3BLUE蓝基色
    4ADDR_CODE地址码
    5RES自测试(各家定义不同)
    6RED_GND红地
    7GREEN_GND绿地
    8BLUE_GND蓝地
    9RES保留(各家定义不同)
    10DIG_GND数字地
    11ADDR_CODE地址码
    12ADDR_CODE地址码
    13HS行同步信号
    14VS场同步信号
    15ADDR_CODE地址码

    常见的VGA分辨率如图2所示。
    在这里插入图片描述

    图2、常见的VGA分辨率

    02 VGA接口时序及显示原理

    VGA显示主要取决于R、G、B三基色,也即三原色。根据R、G、B位宽的不同,VGA显示的效果也不同,常见有24bit(R/G/B各8bit)、16bit(R 5bit、G 6bit、B 6bit)、12bit(R/G/B各4bit)。

    对于分辨率600×400@60Hz,该参数显示的是VGA有效数据参数,即VGA显示刷新率60帧,每帧600×400个像素点。VGA接口实际传输的数据比此数值要大。

    VGA显示器逐行扫描原理:逐行扫描是扫描从屏幕左上角一点开始,从左至右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置。在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号HS进行同步;当扫描完所有的行,形成一帧,用场同步信号VS进行帧同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。

    从逐行扫描的原理中,我们可以了解,当一行扫描完成后,切换到下一行时,需要行同步信号及行消隐时间;当一帧扫描完成后,切换到下一帧时,需要场同步信号及场消隐时间,这样就形成了VGA扫描时序,如图3所示。

    在这里插入图片描述

    图3、VGA行场时序图
    如图3所示,Sync为同步信号,Back Porch为显示后肩时间,Active Video为有效视频,Front Porch为显示前肩时间。Sync+Back Porch+Active Video+Front Porch构成一个完整行周期。

    在这里插入图片描述

    图4、VGA图像帧定义

    图4定义了一帧图像的时序定义。图中场信号的定义与行信号定义类似。行信号以像素点为单位,场信号以行为单位。VGA图像时序的编写即是对图4中各个时序段进行定时。

    03 VGA接口时序关键代码编写

    下面以1920×1080@60Hz分辨率介绍VGA时序定义。在VESA表准中给出了该分辨率的参数定义,如图5所示。

    在这里插入图片描述

    图5、1920×1080@60Hz分辨率图像参数

    在图5中,需要注意蓝色标记的HS/VS信号极性,这在VESA标准中有规定要求,图3只是给出了其中一种HS/VS信号极性,其他3种请参考VESA标准。

    根据图5所示,我们需要关注的参数如图中各个颜色标记所示。

    `ifdef  VIDEO_1920_1080   //一帧图像参数定义
    //行周期参数定义
    parameter  H_ACTIVE        = 1920;// 行数据有效像素点数
    parameter  H_FRONT_PORCH   = 88;  // 行消隐前肩像素点数
    parameter  H_SYNC_TIME     = 44;  // 行同步信号像素点数
    parameter  H_BACK_PORCH    = 148; // 行消隐后肩像素点数 
    //场周期参数定义                
    parameter  V_ACTIVE        = 1080;// 场数据有效像素点数
    parameter  V_FRONT_PORCH   = 4;   // 场消隐前肩像素点数
    parameter  V_SYNC_TIME     = 5;   // 场同步信号像素点数
    parameter  V_BACK_PORCH    = 36;  // 场消隐后肩像素点数
    `endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    根据一帧图像参数定义,进一步定义行、场扫描计数器,这两个计数器可以用来产生HS行同步信号、VS场同步信号、图像有效数据使能信号DE以及图像有效数据坐标。

    parameter  H_TOTAL_TIME   = H_ACTIVE + H_FRONT_PORCH + H_SYNC_TIME + H_BACK_PORCH; 
    parameter  V_TOTAL_TIME   = V_ACTIVE + V_FRONT_PORCH + V_SYNC_TIME + V_BACK_PORCH;
    
    //行扫描计数器
    always@(posedge i_clk) begin
      if(h_syn_cnt >= H_TOTAL_TIME-1)  h_syn_cnt <= 0;
      else h_syn_cnt <= h_syn_cnt + 1;
    end
    
    // 场扫描计数器
    always@(posedge i_clk) begin
      if(h_syn_cnt >= H_TOTAL_TIME-1) begin
            if(v_syn_cnt >= V_TOTAL_TIME-1)
                v_syn_cnt <= 0;
            else
                v_syn_cnt <= v_syn_cnt + 1;
      end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    HS行同步信号、VS场同步信号Verilog代码。

    // 行同步信号
    always@(posedge i_clk) begin
        if(h_syn_cnt < H_SYNC_TIME)
            o_hsyn <= 0;
        else
            o_hsyn <= 1;
    end
    
    // 场同步信号
    always@(posedge i_clk) begin
        if(v_syn_cnt < V_SYNC_TIME)
            o_vsyn <= 0;
        else
            o_vsyn <= 1;
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    图像有效数据使能信号DE。

    //有效数据使能信号DE
    always@(posedge i_clk) begin
        if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
        begin
            if(h_syn_cnt >= H_SYNC_TIME + H_BACK_PORCH && h_syn_cnt < H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE)
                o_en_pos <= 1;
            else
                o_en_pos <= 0;
        end
        else
            o_en_pos <= 0;
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    图像有效数据坐标产生x_pose、y_pose。

    //x坐标数据
    always@(posedge i_clk) begin
        if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
        begin
            if(h_syn_cnt >= H_SYNC_TIME + H_BACK_PORCH && h_syn_cnt < H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE)
                o_x_pos <= h_syn_cnt - (H_SYNC_TIME + H_BACK_PORCH);
            else
                o_x_pos <= 0;
        end
        else
            o_x_pos <= 0;
    end
    
    //y坐标数据
    always@(posedge i_clk) begin
        if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
            o_y_pos <= v_syn_cnt - (V_SYNC_TIME + V_BACK_PORCH);
        else
            o_y_pos <= 0;
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    04 FPGA工程实现框架

    FPGA实现VGA显示功能框架如图6所示。

    在这里插入图片描述

    图6、FPGA实现VGA显示功能框图

    如图6所示,整个工程由四个模块组成:PLL模块、vga_timing_ctrl模块、video_source模块和hdmi_interface_dir模块。由于实验电路板上没有VGA接口,因此采用HDMI接口实现最终图像显示。图中video_source输出的信号可以直接送入视频DAC芯片,如ADV7123实现VGA图像显示。

    PLL模块:产生VGA图像像素时钟pixclk和pixclk_x5时钟(HDMI接口串行时钟);

    vga_timing_ctrl模块:实现VGA时序产生和控制;

    video_source模块:产生VGA图像数据;

    hdmi_interface_dir模块:实现HDMI接口驱动功能。

    05 Modelsim软件仿真与测试

    编写Testbench测试文件,功能仿真如图7所示。

    在这里插入图片描述

    图7、VGA时序Modelsim仿真

    06 硬件测试与验证

    硬件平台:XC7Z035FFG676-2

    Vivado软件:2017.4

    工程编译完成后,下载bit文件到电路板,测试结果如图所示。

    在这里插入图片描述

    图8、VGA时序图像显示

    本文来源于微信公众号:FPGA技术实战,参考原文:《基于FPGA的VGA图像显示》

  • 相关阅读:
    【C#设计模式】单例模式
    C# 异步执行操作
    Pytorch实战教程(十一)-卷积神经网络
    北京化工大学2022-2023-1 ACM集训队每周程序设计竞赛(10)题解
    计算机毕业设计Java艾灸减肥管理网站(源码+系统+mysql数据库+lw文档)
    LCR 170. 交易逆序对的总数
    『现学现忘』Docker常用命令 — 19、容器常用命令(一)
    Linux系统内核作用
    2022-02-02-Vue和Element
    JDBC学习笔记(2)事务
  • 原文地址:https://blog.csdn.net/qq_21794157/article/details/126470882