01_VGA display driver design and verification

1. VGA

1.1 Introduction to VGA

insert image description here

1.2 VGA interface and pin definition

insert image description here
insert image description here

1.3 VGA display principle

insert image description here

1.4 VGA Timing Standards

insert image description here

1.4.1 Hsync line synchronization

The unit of the line scanning period is the pixel
insert image description here

1.4.2 Vsync field synchronization

The unit of field scanning period is line, a complete line scanning period
insert image description here

1.4.3 The overlapping part is the display part

insert image description here

1.5 VGA display mode and related parameters

insert image description here
640 * 480 @ 60
640: One line: 640 pixels in the horizontal scan cycle.
480: Each frame image has 480 lines.
60: In this mode, the image is displayed 60 times per second and refreshed 60 times.

Calculation of Clock Frequency
insert image description here

2. Experimental objectives

Experiment goal: write VGA driver, use FPGA development board to drive VGA display to display ten-color equal-width color bars, VGA display mode is 640x480@60.
insert image description here

3. Principles of VGA hardware resources

Weight resistor network digital to analog conversion
insert image description here
RGB 565 r:5 g:6 b:5 16 bits wide [15:0]
insert image description here

4. Functional modules

4.1 Top-level modules

The block diagram of the entire system
locked is active high
insert image description here
insert image description here

4.2 Clock Generation Module

This experiment uses the classic VGA display mode 640x480@60, and the theoretical clock frequency should be 25.175MHz. In order to facilitate clock generation, we use a 25MHz clock instead of a 25.175MHz clock, which will not affect the experiment. In this experimental project, the incoming clock frequency of the board crystal oscillator is 50MHz. The role of the clock generation module is to divide the 50MHz crystal oscillator clock into 25MHz VGA working clock.
insert image description here
insert image description here

4.3 VGA timing control module

insert image description here
insert image description here
Generate line and field signals, and output the input image information pix_data to output rgb
insert image description here
Pix_x, Pix_y is the coordinates in the video image used to generate the image

4.4 Image data generation module

insert image description here
insert image description here

5. Waveform diagram

5.1 VGA timing control module

insert image description here
It can be seen from the timing standard that the line and field signals are pulled high during the synchronization phase, and the line and field signal counters are set.
insert image description here
Effective signal of image
insert image description here
It can be known from the above that the image will be displayed correctly only when the image data is sent into the effective display area of ​​VGA, so when can the image data be sent in? We can declare a valid signal, assign a high level to the effective display area of ​​the image, and assign a low level to the non-effective display area of ​​the image, use this signal as a constraint condition, control the correct input of the image signal, and define this signal as the effective signal for image display (rgb_valid).
When the two counters count to the effective display area of ​​the image, rgb_valid assigns a high level, otherwise it assigns a low level. 0-34, 0-144
insert image description here
pix_x insert image description here
pix_y, scan the line first, and then scan
insert image description here
the RGB
insert image description here
of the scanning field because this experiment is a display of VGA multi-color bar. The image data generation module VGA_PIC needs to assign the PIX_DATA signal with the coordinates (pix_x, pix_y) as the constraint. The assignment of X_Data will be lagging behind to meet the clock cycle at a time, showing that there will be problems with the image.
In order to solve this problem, we need to declare a new image data request signal pix_data_req, which should be
one clock cycle ahead of the image display valid signal (rgb_valid) to offset the problem caused by pix_data timing logic assignment.
insert image description here
insert image description here

5.2 Image data generation module

insert image description here
insert image description here

6. RTL

6.1 vga_ctrl

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 , //输出有效显示区域像素点 X 轴坐标
    output wire [9:0]   pix_y , //输出有效显示区域像素点 Y 轴坐标
	// pix_x 和 pix_y 目的就是为了 rgb 的有效显示
    output wire [15:0]  rgb, //输出像素点色彩信息
	
    output wire         hsync , //输出行同步信号
    output wire         vsync  //输出场同步信号
	
);


//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_req ; //像素点色彩信息请求信号

//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'd1 ;
		
//hsync:行同步信号
assign hsync = (cnt_h <= H_SYNC - 1'd1) ? 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_v == V_TOTAL - 1'd1) && (cnt_h == H_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_req:像素点色彩信息请求信号,超前 rgb_valid 信号一个时钟周期
assign pix_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_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_req == 1'b1)
				? (cnt_h - (H_SYNC + H_BACK + H_LEFT - 1'b1)) : 10'h3ff;


assign pix_y = (pix_data_req == 1'b1)
				? (cnt_v - (V_SYNC + V_BACK + V_TOP)) : 10'h3ff;
				
//rgb:输出像素点色彩信息
assign rgb = (rgb_valid == 1'b1) ? pix_data : 16'b0 ;

		



endmodule

6.2 vga_pic

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

parameter H_VALID = 10'd640 , //行有效数据
          V_VALID = 10'd480 ; //场有效数据

parameter RED = 16'hF800, //红色
          ORANGE = 16'hFC00, //橙色
          YELLOW = 16'hFFE0, //黄色
          GREEN = 16'h07E0, //绿色
          CYAN = 16'h07FF, //青色
          BLUE = 16'h001F, //蓝色
          PURPPLE = 16'hF81F, //紫色
          BLACK = 16'h0000, //黑色
          WHITE = 16'hFFFF, //白色
          GRAY = 16'hD69A; //灰色

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//

//pix_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
always@(posedge vga_clk or negedge sys_rst_n)
     if(sys_rst_n == 1'b0)
        pix_data <= 16'd0;
     else if((pix_x >= 0) && (pix_x < (H_VALID/10)*1))
        pix_data <= RED;
     else if((pix_x >= (H_VALID/10)*1) && (pix_x < (H_VALID/10)*2))
        pix_data <= ORANGE;
     else if((pix_x >= (H_VALID/10)*2) && (pix_x < (H_VALID/10)*3))
        pix_data <= YELLOW;
     else if((pix_x >= (H_VALID/10)*3) && (pix_x < (H_VALID/10)*4))
        pix_data <= GREEN;
     else if((pix_x >= (H_VALID/10)*4) && (pix_x < (H_VALID/10)*5))
        pix_data <= CYAN;
     else if((pix_x >= (H_VALID/10)*5) && (pix_x < (H_VALID/10)*6))
        pix_data <= BLUE;
     else if((pix_x >= (H_VALID/10)*6) && (pix_x < (H_VALID/10)*7))
        pix_data <= PURPPLE;
     else if((pix_x >= (H_VALID/10)*7) && (pix_x < (H_VALID/10)*8))
        pix_data <= BLACK;
     else if((pix_x >= (H_VALID/10)*8) && (pix_x < (H_VALID/10)*9))
        pix_data <= WHITE;
     else if((pix_x >= (H_VALID/10)*9) && (pix_x < H_VALID))
        pix_data <= GRAY;
     else
        pix_data <= BLACK;

endmodule


6.3 vga_colorbar

module vga_colorbar(

    input wire sys_clk , //输入工作时钟,频率 50MHz
    input wire sys_rst_n , //输入复位信号,低电平有效
    
    output wire hsync , //输出行同步信号
    output wire vsync , //输出场同步信号
    output wire [15:0] rgb //输出像素信息

);
 
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//

//wire define
wire vga_clk ; //VGA 工作时钟,频率 25MHz
wire locked ; //PLL locked 信号
wire rst_n ; //VGA 模块复位信号
wire [9:0] pix_x ; //VGA 有效显示区域 X 轴坐标
wire [9:0] pix_y ; //VGA 有效显示区域 Y 轴坐标
wire [15:0] pix_data; //VGA 像素点色彩信息

//rst_n:VGA 模块复位信号
assign rst_n = (sys_rst_n & locked);

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//

//------------- clk_gen_inst -------------
ip_pll	ip_pll_inst
(
    .areset (~sys_rst_n ), //输入复位信号,高电平有效,1bit
    .inclk0 (sys_clk ), //输入 50MHz 晶振时钟,1bit
    
    .c0 (vga_clk ), //输出 VGA 工作时钟,频率 25MHz,1bit
    .locked (locked ) //输出 pll locked 信号,1bit
);

//------------- vga_ctrl_inst -------------
vga_ctrl vga_ctrl_inst
(
    .vga_clk (vga_clk ), //输入工作时钟,频率 25MHz,1bit
    .sys_rst_n (rst_n ), //输入复位信号,低电平有效,1bit
    .pix_data (pix_data ), //输入像素点色彩信息,16bit
    
    .pix_x (pix_x ), //输出 VGA 有效显示区域像素点 X 轴坐标,10bit
    .pix_y (pix_y ), //输出 VGA 有效显示区域像素点 Y 轴坐标,10bit
    .hsync (hsync ), //输出行同步信号,1bit
    .vsync (vsync ), //输出场同步信号,1bit
    .rgb (rgb ) //输出像素点色彩信息,16bit
 );
 
 //------------- vga_pic_inst -------------
 vga_pic vga_pic_inst
 (
    .vga_clk (vga_clk ), //输入工作时钟,频率 25MHz,1bit
    .sys_rst_n (rst_n ), //输入复位信号,低电平有效,1bit
    .pix_x (pix_x ), //输入 VGA 有效显示区域像素点 X 轴坐标,10bit
    .pix_y (pix_y ), //输入 VGA 有效显示区域像素点 Y 轴坐标,10bit
    
    .pix_data (pix_data ) //输出像素点色彩信息,16bit
 );
 
 endmodule

7. Testbench

7.1 tb_vga_ctrl

`timescale 1ns/1ns
module tb_vga_ctrl();
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//wire define
wire locked ;
wire rst_n ;
wire vga_clk ;
reg sys_clk ;
reg sys_rst_n ;
reg [15:0] pix_data ;

//********************************************************************//
//**************************** Clk And Rst ***************************//
//********************************************************************//

//sys_clk,sys_rst_n 初始赋值
initial
   begin
      sys_clk = 1'b1;
      sys_rst_n <= 1'b0;
      #200
      sys_rst_n <= 1'b1;
   end

//sys_clk:产生时钟
always #10 sys_clk = ~sys_clk;

//rst_n:VGA 模块复位信号
assign rst_n = (sys_rst_n & locked);

//pix_data:输入像素点色彩信息
always@(posedge vga_clk or negedge rst_n)
   if(rst_n == 1'b0)
     pix_data <= 16'h0000;
   else
     pix_data <= 16'hffff;

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//

//------------- clk_gen_inst -------------
ip_pll	ip_pll_inst
(
    .areset (~sys_rst_n ), //输入复位信号,高电平有效,1bit
    .inclk0 (sys_clk ), //输入 50MHz 晶振时钟,1bit
    .c0 (vga_clk ), //输出 VGA 工作时钟,频率 25MHz,1bit
    .locked (locked ) //输出 pll locked 信号,1bit
);

//------------- vga_ctrl_inst -------------
vga_ctrl vga_ctrl_inst
(
    .vga_clk (vga_clk ), //输入工作时钟,频率 25MHz,1bit
    .sys_rst_n (rst_n ), //输入复位信号,低电平有效,1bit
    .pix_data (pix_data ), //输入像素点色彩信息,16bit
    
    .pix_x (pix_x ), //输出 VGA 有效显示区域像素点 X 轴坐标,10bit
    .pix_y (pix_y ), //输出 VGA 有效显示区域像素点 Y 轴坐标,10bit
    .hsync (hsync ), //输出行同步信号,1bit
    .vsync (vsync ), //输出场同步信号,1bit
    .rgb (rgb ) //输出像素点色彩信息,16bit
);

endmodule

7.2 tb_vga_colorbar

`timescale 1ns/1ns

module tb_vga_colorbar();
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//wire define
wire hsync ;
wire [15:0] rgb ;
wire vsync ;

//reg define
reg sys_clk ;
reg sys_rst_n ;

//********************************************************************//
//**************************** Clk And Rst ***************************//
//********************************************************************//

//sys_clk,sys_rst_n 初始赋值
initial
   begin
     sys_clk = 1'b1;
     sys_rst_n <= 1'b0;
     #200
     sys_rst_n <= 1'b1;
   end

//sys_clk:产生时钟
always #10 sys_clk = ~sys_clk ;

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//

//------------- vga_colorbar_inst -------------
vga_colorbar vga_colorbar_inst
(
    .sys_clk (sys_clk ), //输入晶振时钟,频率 50MHz,1bit
    .sys_rst_n (sys_rst_n ), //输入复位信号,低电平有效,1bit
    
    .hsync (hsync ), //输出行同步信号,1bit
    .vsync (vsync ), //输出场同步信号,1bit
    .rgb (rgb ) //输出 RGB 图像信息,16bit
);

endmodule

Guess you like

Origin blog.csdn.net/HeElLose/article/details/131391916