VGA (Video Grapghics Array) is a standard protocol for video transmission using model signals. The RGB565 image mode is used here
VGA display principle
The VGA display does not directly display the image on the display, but scans the pixels that make up the image from top to bottom and from left to right under the synchronization of the horizontal synchronization signal and the vertical synchronization signal. Scan to the display screen in order from right to left.
Under the action of horizontal and vertical synchronous signals, the scanning coordinates are positioned to the coordinates of the first pixel point in the upper left corner. In the process of scanning, each pixel is assigned a value individually, so that each pixel displays the corresponding color information. When one frame of image scanning is completed, the scanning of the next frame of image starts, and the cycle repeats. When the scanning speed is sufficient Fast, coupled with the characteristics of human persistence of vision, the complete image will be displayed.
VGA Timing Standard
VGA timing is composed of two parts, line synchronization timing and field synchronization timing. The row synchronization timing is shown in the figure below.
The line scan cycle is divided into six parts, synchronization, trailing edge, left frame, active image, right frame, and leading edge. The field scanning period is similar, except for the upper and lower borders. After the scanning is completed, the image will only appear in the effective image range of the row and field.
VGA parameter setting
The picture above is one of the VGA display modes, 640×480@60. 640 means that the number of pixels of the effective line image is 640, and 480 means the number of pixels of the effective field image. 60 means that the VGA monitor refreshes the image 60 times per second, that is, the number of display frames is 60. 650×480=307200, that is, each frame of image contains 307200 pixels. The operating clock in this display mode is 25.175MHz. The clock period is equal to the line scan period × field scan period × refresh rate.
Programming
The overall design block diagram is shown in the figure below.
Clock generation module (pll): used to generate the clock for VGA work.
Image generation module (VGA_PIC): Determine the pixel points of each effective image area through the coordinate signal passed in by the control module. Enter image information. The image data generation module takes the pixel coordinates (pix_x, pix_y) passed in by the VGA timing control module as the constraint bar
file to generate the color information (pix_data) of the color bar image to be displayed
Image control module (VGA_CTRL): Longer line field synchronization signal, find out the effective image area and specify the zero point coordinates. Input RGB information and horizontal and vertical synchronization signals.
Image Control Module Code
module vga_ctrl ( input wire vga_clk , //input working clock, frequency 25MHz input wire sys_rst_n , //input reset signal, active low input wire [15:0] pix_data , //Input pixel color information output wire [9:0] pix_x , //output X-axis coordinates of pixels in VGA effective display area output wire [9:0] pix_y , //Output VGA effective display area pixel Y-axis coordinates output wire hsync , //Output line synchronization signal output wire vsync , //Output field sync signal output wire [15:0] rgb //output pixel color information ); parameter H_SYNC = 10'd96 , //line synchronization H_BACK = 10'd40 , //row timing trailing edge H_LEFT = 10'd8 , //Left border of row timing H_VALID = 10'd640 , //line valid data H_RIGHT = 10'd8 , //Right border of row timing H_FRONT = 10'd8 , //leading edge of row timing H_TOTAL = 10'd800 ; //line scan cycle parameter V_SYNC = 10'd2 , //field synchronization V_BACK = 10'd25 , // field timing trailing edge V_TOP = 10'd8 , //field timing top border V_VALID = 10'd480 , // field valid data V_BOTTOM = 10'd8 , //bottom frame of field timing V_FRONT = 10'd2 , //Front edge of field timing V_TOTAL = 10'd525 ; // field scan period wire rgb_valid ; //VGA effective display area wire pix_data_req ; //pixel color information request signal reg [9:0] cnt_h ; // line synchronization signal counter reg [9:0] cnt_v ; //Vertical sync signal counter 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; assign hsync = (cnt_h <= H_SYNC - 1'd1) ? 1'b1 : 1'b0 ; 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) & amp; & amp; (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; assign vsync = (cnt_v <= V_SYNC - 1'd1) ? 1'b1 : 1'b0 ; assign rgb_valid = (((cnt_h >= H_SYNC + H_BACK + H_LEFT) & amp; & amp; (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VALID)) & amp; & amp;((cnt_v >= V_SYNC + V_BACK + V_TOP) & amp; & amp; (cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID))) ? 1'b1 : 1'b0; assign pix_data_req = (((cnt_h >= H_SYNC + H_BACK + H_LEFT - 1'b1) & amp; & amp; (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1)) & amp; & amp;((cnt_v >= V_SYNC + V_BACK + V_TOP) & amp; & amp; (cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID))) ? 1'b1 : 1'b0; 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: output pixel color information assign rgb = (rgb_valid == 1'b1) ? pix_data : 16'b0 ; endmodule
Image generation module code
module vga_pic ( input wire vga_clk , //input working clock, frequency 25MHz input wire sys_rst_n , //input reset signal, active low input wire [9:0] pix_x , //Input the X-axis coordinates of pixels in the VGA effective display area input wire [9:0] pix_y , //Input the Y-axis coordinates of pixels in the VGA effective display area output reg [15:0] pix_data // output pixel color information ); parameter H_VALID = 10'd640 , //line valid data V_VALID = 10'd480 ; // field valid data parameter RED = 16'hF800, //red ORANGE = 16'hFC00, //Orange YELLOW = 16'hFFE0, //yellow GREEN = 16'h07E0, //green CYAN = 16'h07FF, //cyan BLUE = 16'h001F, //blue PURPPLE = 16'hF81F, //purple BLACK = 16'h0000, //black WHITE = 16'hFFFF, //white GRAY = 16'hD69A; // gray //pix_data: Output pixel color information, specify the current pixel color data according to the current pixel coordinates always@(posedge vga_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) pix_data <= 16'd0; else if((pix_x >= 0) & amp; & amp; (pix_x < (H_VALID/10)*1)) pix_data <= RED; else if((pix_x >= (H_VALID/10)*1) & amp; & amp; (pix_x < (H_VALID/10)*2)) pix_data <= ORANGE; else if((pix_x >= (H_VALID/10)*2) & amp; & amp; (pix_x < (H_VALID/10)*3)) pix_data <= YELLOW; else if((pix_x >= (H_VALID/10)*3) & amp; & amp; (pix_x < (H_VALID/10)*4)) pix_data <= GREEN; else if((pix_x >= (H_VALID/10)*4) & amp; & amp; (pix_x < (H_VALID/10)*5)) pix_data <= CYAN; else if((pix_x >= (H_VALID/10)*5) & amp; & amp; (pix_x < (H_VALID/10)*6)) pix_data <= BLUE; else if((pix_x >= (H_VALID/10)*6) & amp; & amp; (pix_x < (H_VALID/10)*7)) pix_data <= PURPPLE; else if((pix_x >= (H_VALID/10)*7) & amp; & amp; (pix_x < (H_VALID/10)*8)) pix_data <= BLACK; else if((pix_x >= (H_VALID/10)*8) & amp; & amp; (pix_x < (H_VALID/10)*9)) pix_data <= WHITE; else if((pix_x >= (H_VALID/10)*9) & amp; & amp; (pix_x < H_VALID)) pix_data <= GRAY; else pix_data <= BLACK; endmodule
top level module
module vga_colorbar ( input wire sys_clk , //input working clock, frequency 50MHz input wire sys_rst_n , //input reset signal, active low output wire hsync , //Output line synchronization signal output wire vsync , //Output field sync signal output wire [15:0] rgb // output pixel information ); wire vga_clk ; //VGA working clock, frequency 25MHz wire locked; //PLL locked signal wire rst_n ; //VGA module reset signal wire [9:0] pix_x ; //VGA effective display area X-axis coordinates wire [9:0] pix_y ; //VGA effective display area Y-axis coordinates wire [15:0] pix_data; //VGA pixel color information assign rst_n = (sys_rst_n & locked); clk_gen clk_gen_inst ( .areset (~sys_rst_n ), //Input reset signal, active high, 1bit .inclk0 (sys_clk ), //Input 50MHz crystal oscillator clock, 1bit .c0 (vga_clk ), //output VGA working clock, frequency 25Mhz, 1bit .locked (locked ) //Output pll locked signal, 1bit ); vga_ctrl vga_ctrl_inst ( .vga_clk (vga_clk ), //Input working clock, frequency 25MHz, 1bit .sys_rst_n (rst_n ), //Input reset signal, active low, 1bit .pix_data (pix_data ), //Input pixel color information, 16bit .pix_x (pix_x ), //Output X-axis coordinates of pixels in VGA effective display area, 10bit .pix_y (pix_y ), //Output Y-axis coordinates of pixels in VGA effective display area, 10bit .hsync (hsync ), //Output line synchronization signal, 1bit .vsync (vsync ), //Output field sync signal, 1bit .rgb (rgb ) //output pixel color information, 16bit ); vga_pic vga_pic_inst ( .vga_clk (vga_clk ), //Input working clock, frequency 25MHz, 1bit .sys_rst_n (rst_n ), //Input reset signal, active low, 1bit .pix_x (pix_x ), //Input the X-axis coordinates of pixels in the VGA effective display area, 10bit .pix_y (pix_y ), //Input the Y-axis coordinates of pixels in the VGA effective display area, 10bit .pix_data (pix_data ) //output pixel color information, 16bit ); endmodule
Simulation results
Refresh sixty times per second, about 16.6666ms each time, as shown in the figure above.