VGA控制代码编写

        前面我们讲了VGA的显示原理,https://blog.csdn.net/qq_51264805/article/details/122305848        接下来我们进行代码的编写,代码分为四个模块:时钟生成模块;VGA时序控制模块;VGA图像数据生成模块;顶层模块。其中时钟生成模块可以用PLL锁相环二分频产生25MHz的VGA时钟信号,图像生成模块可以根据自己要显示的图形编写,顶层模块就是将前三个模块汇总,因此这三个模块就不过多赘述。这个理我们主要讲述VGA控制模块。

        VGA 时序控制模块,作用是驱动 VGA 显示器,将输入模块的彩条图形像素点信息,按照 VGA 时序扫描显示到 VGA 显示器上。

VGA控制代码编写_第1张图片

图 1 VGA控制模块框图

VGA控制代码编写_第2张图片

        图 2 VGA控制模块输入输出信号 

        输入信号中,时钟信号 vga_clk ,频率为 25MHz ,为 VGA 显示器工作时钟,由分频模块产生并输入;复位信号 sys_rst_n 为顶层模块的 rst_n 信号输入,低电平有效; pix_data 为要显示的图像像素点色彩信息,由图像数据生成模块产生并传入,在 VGA 有效图像显示区域赋值给信号 RGB 图像色彩信息 (rgb)
        输出信号(pix_x,pix_y) VGA 有效显示区域像素点坐标,由 VGA 时序控制模块生成并传入图像数据生成模块;hsync vsync VGA 行、场同步信号 ,通过 VGA 接口传输给VGA 显示器; rgb 为显示器要显示的图像色彩信息,传输给 VGA 显示器。

        根据前面那一张原理介绍,我们编写代码如下:

                 `timescale 1ns/1ns

module vga_ctrl
(
    input wire         vga_clk   ,   //输入工作时钟,25MHz
    input wire         sys_rst_n ,   //输入复位信号,低电平有效
    input wire  [15:0] pix_data  ,   //输入像素点色彩信息
    
    output wire [9:0]  pix_x ,   //输入VGA有效显示区域像素点X轴坐标
    output wire [9:0]  pix_y ,   //输入VGA有效显示区域像素点Y轴坐标
    output wire        hsync ,   //输出行同步信号
    output wire        vsync ,   //输出场同步信号
    output wire [15:0] rgb       //输出像素点色彩信息
);

//parameter define
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   =   10'd800 ;   //行扫描周期
parameter V_SYNC    =   10'd2   ,   //场同步
          V_BACK    =   10'd25  ,   //场时序后沿
          V_TOP     =   10'd8   ,   //场时序上边框
          V_VALID   =   10'd480 ,   //场有效数据
          V_BOTTOM  =   10'd8   ,   //场时序下边框
          V_FRONT   =   10'd2   ,   //场时序前沿
          V_TOTAL   =   10'd525 ;   //场扫描周期
          
//wire define
wire rgb_valid    ;    //VGA有效显示区域
wire pix_data_reg ;    //像素点色彩信息请求信号

//reg define
reg [9:0] cnt_h ;   //行同步计数器
reg [9:0] cnt_v ;   //场同步计数器

//cnt_h:行同步计数信器
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_h <= 10'd0 ;
    else if(cnt_h == H_TOTAL - 1'd1)
        cnt_h <= 10'd0 ;
    else cnt_h <= cnt_h + 1'b1 ;
    
//hsync:行同步信号
assign hsync = (cnt_h <= H_SYNC - 1'b1) ? 1'b1 : 1'b0 ;
    
//cnt_v:场同步计数信器
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_v <= 10'd0 ;
    else if((cnt_h == H_TOTAL - 1'd1) && (cnt_v == V_TOTAL - 1'd1))
        cnt_v <= 10'd0 ;
    else if(cnt_h == H_TOTAL - 1'd1)
        cnt_v <= cnt_v + 1'd1 ;
    else 
        cnt_v <= cnt_v ;

//vsync:场同步信号
assign vsync = (cnt_v <= V_SYNC - 1'd1) ? 1'b1 : 1'b0 ;

//rgb_valid:VGA有效显示区域
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_TOP) 
                    && (cnt_v <= V_SYNC + V_BACK + V_TOP + V_VALID))) ? 1'b1 : 1'b0 ;

//pix_data_reg:像素点色彩请求信号,超前rgb_valid一个周期
assign pix_data_reg = (((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_TOP) 
                    && (cnt_v <= V_SYNC + V_BACK + V_TOP + V_VALID))) ? 1'b1 : 1'b0 ;

//pix_x,pix_y:VGA有效显示区域像素点坐标
assign pix_x = (pix_data_reg == 1'b1)
                ? (cnt_h - (H_SYNC + H_BACK + H_LEFT - 1'b1)) : 10'h3ff ;
assign pix_y = (pix_data_reg == 1'b1)
                ? (cnt_v - (V_SYNC + V_BACK + V_TOP)) : 10'h3ff ;

//rgb:输出像素点色彩信息
assign rgb = (rgb_valid == 1'b1) ? pix_data : 16'h0 ;

endmodule

你可能感兴趣的:(EDA技术,FPGA,fpga开发)