2204 views|4 replies

824

Posts

3

Resources
The OP
 

08. Anlu SparkRoad Domestic FPGA Evaluation [Learning] VGA Display [Copy link]

 This post was last edited by 1nnocent on 2022-7-30 09:19

This routine is mainly divided into three modules, which are used to realize the VGA drive display function. The top module instantiates the VGA clock module, VGA driver module and VGA display test module.

The vga clock module generates the VGA drive clock by calling the PLL IP core. It should be noted that different resolutions require different drive clocks. The drive clock corresponding to each resolution and the line and field signal information can be found on the VESA official website. Here is the " VESA and Computer Display Monitor Timing (DMT) Industry Standards and Guidelines ": VESA-DMT-1.12.pdf (747.23 KB, downloads: 3)


The vga driver module is used to drive the VGA display. Users can change the timing parameters of VGA resolution (here the timing parameters refer to the line field signal, where the line signal mainly includes: line display synchronization signal, line display front edge, line display valid data, line display back edge , where the line display valid data is the specific value of the resolution, such as 1920; field signal includes: field display synchronization signal, field display front edge, field display valid data, field display back edge , where the field display valid data is the specific value of the resolution, such as 1080; line synchronization signal uses specific pixel points as the basic unit [for example, the line display valid data has 1920 pixels], and field synchronization signal uses field synchronization signal as the basic unit [for example, the field display valid data has 1080 signals, here the basic unit is line position, a line signal contains not only valid data, but also front edge, back edge, etc., which is a complete line signal]) to realize different resolutions. The following figure can help you understand (the network picture found on the Internet):

I have used an oscilloscope to capture the line and field signals before, and I have posted them here for easy understanding (Figure 1 is the sum of the field signal [red], the line signal [yellow], and the enable signal [blue]; Figure 2 is the line signal and the enable signal. Figure 2 shows the display leading edge, valid data, that is, the blue enable signal, the display trailing edge, and the line synchronization signal):


The vga display module is used to test the VGA display.

Now analyze the code: the input interface is: system clock clk_24m, external button reset rst_n; the output interface is: pixel clock vga_clk (used to drive the display frequency), line synchronization signal vga_hs, field synchronization signal vga_hs, output data enable vga_de, red data channel vga_r, green data channel vga_g, blue data channel vga_b.

First is the PLL module. The PLL input clock is the system clock 24MHz, which generates a 108MHz clock to drive the display. By looking up the above-mentioned "VESA and Computer Display Monitor Timing (DMT) Industry Standards and Guidelines", we can know that this frequency is used to drive 1280x1024@60Hz resolution.

Next is the display driver module (Driver.v), which is used to generate line and field signals. 1. The module defines hcnt to count the horizontal synchronization signal. After the resolution counts 1688 times, hcnt is cleared and counted again. 2. When hcnt counts H_SYNC (112) times, the horizontal synchronization signal is generated, and lcd_hs is pulled high. 3. Define vcnt to count the field synchronization signal. After counting 1066 times, vcnt is cleared and counted again. When vcnt is self-incremented, it must also meet the requirement that the horizontal signal counts 1688 times. 4. When vcnt counts V_SYNC (3) times, the field synchronization signal is generated and lcd_vs is pulled high. 5. When hcnt meets the valid data interval of the line (hcnt >= H_SYNC + H_BACK - H_AHEAD && hcnt < H_SYNC + H_BACK + H_DISP - H_AHEAD), and vcnt meets the valid data interval of the field (vcnt >= V_SYNC + V_BACK && vcnt < V_SYNC + V_BACK + V_DISP) pulls up the data enable signal lcd_en, and then sends pixel data to the display.

`timescale 1ns/1ns
/* VGA参数配置表
************	clk		 	H_SYNC 		H_BACK 		H_DISP 		H_FRONT 	H_TOTAL 		V_SYNC 		V_BACK 		V_DISP 		V_FRONT 	V_TOTAL		*
640x480@60Hz	25.2MHz		96			48 			640 		16 			800 			2			33			480 		10			525		*
800x600@60Hz	40MHz		128			88 			800 		40 			1056			4			23			600 		1			628		*
1024x768@60Hz	65MHz		136			160 		1024 		24 			1344			6			29			768 		3			806		*
1280x720@60Hz	74.25MHz	40			220 		1280 		110			1650			5			20			720 		5			750		*
1280x1024@60Hz	108MHz		112			248 		1280 		48 			1688			3			38			1024		1			1066	*
1920x1080@60Hz	148.5MHz	44			148 		1920 		88 			2200			5			36			1080		4			1125	*
*/	
module Driver
#(
	parameter H_SYNC = 112	, 		// 行同步信号时间
	parameter H_BACK = 248	, 		// 行消隐后肩时间
	parameter H_DISP = 1280	, 		// 行数据有效时间
	parameter H_FRONT = 48	, 		// 行消隐前肩时间
	parameter H_TOTAL = 1688, 		// 行扫描总时间
			
	parameter V_SYNC = 3	, 		// 列同步信号时间
	parameter V_BACK = 38	, 		// 列消隐后肩时间
	parameter V_DISP = 1024	, 		// 列数据有效时间
	parameter V_FRONT = 1	, 		// 列消隐前肩时间
	parameter V_TOTAL = 1066  		// 列扫描总时间
)
(
	input  wire			clk,			//VGA clock
	input  wire			rst_n,     		//sync reset
	input  wire	[23:0]	lcd_data,		//lcd data
	
	//lcd interface
	output wire			lcd_dclk,   	//lcd pixel clock
	output wire			lcd_hs,	    	//lcd horizontal sync
	output wire			lcd_vs,	    	//lcd vertical sync
	output wire			lcd_en,			//lcd display enable
	output wire	[23:0]	lcd_rgb,		//lcd display data

	//user interface
	output wire	[11:0]	lcd_xpos,		//lcd horizontal coordinate
	output wire	[11:0]	lcd_ypos		//lcd vertical coordinate
);	
 
localparam	H_AHEAD = 	12'd1;

reg [11:0] hcnt; 
reg [11:0] vcnt;
wire lcd_request;

/*******************************************
		SYNC--BACK--DISP--FRONT
*******************************************/ 
//h_sync counter & generator
always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		hcnt <= 12'd0;
	else
	begin
        if(hcnt < H_TOTAL - 1'b1)		//line over			
            hcnt <= hcnt + 1'b1;
        else
            hcnt <= 12'd0;
	end
end 

assign	lcd_hs = (hcnt <= H_SYNC - 1'b1) ? 1'b0 : 1'b1; // line over flag

//v_sync counter & generator
always@(posedge clk or negedge rst_n)
begin
	if (!rst_n)
		vcnt <= 12'b0;
	else if(hcnt == H_TOTAL - 1'b1)	//line over
		begin
		if(vcnt == V_TOTAL - 1'b1)		//frame over
			vcnt <= 12'd0;
		else
			vcnt <= vcnt + 1'b1;
		end
end

assign	lcd_vs = (vcnt <= V_SYNC - 1'b1) ? 1'b0 : 1'b1; // frame over flag

// LED clock
assign	lcd_dclk = ~clk;

// Control Display
assign	lcd_en		=	(hcnt >= H_SYNC + H_BACK  && hcnt < H_SYNC + H_BACK + H_DISP) &&
						(vcnt >= V_SYNC + V_BACK  && vcnt < V_SYNC + V_BACK + V_DISP) 
						? 1'b1 : 1'b0;                   // Display Enable Signal
						
assign	lcd_rgb 	= 	lcd_en ? lcd_data : 24'h000000;	

//ahead x clock
assign	lcd_request	=	(hcnt >= H_SYNC + H_BACK - H_AHEAD && hcnt < H_SYNC + H_BACK + H_DISP - H_AHEAD) &&
						(vcnt >= V_SYNC + V_BACK && vcnt < V_SYNC + V_BACK + V_DISP) 
						? 1'b1 : 1'b0;
//lcd xpos & ypos
assign	lcd_xpos	= 	lcd_request ? (hcnt - (H_SYNC + H_BACK - H_AHEAD)) : 12'd0;
assign	lcd_ypos	= 	lcd_request ? (vcnt - (V_SYNC + V_BACK)) : 12'd0;

endmodule

The last one is the display module (Display.v): This module outputs pixel data to the display according to the coordinate rule while the data is valid. A total of four playback modes are defined here.

`timescale 1ns/1ns

// Define colors RGB--8|8|8
`define RED		24'hFF0000 
`define GREEN	24'h00FF00 
`define BLUE  	24'h0000FF 
`define WHITE 	24'hFFFFFF 
`define BLACK 	24'h000000 
`define YELLOW	24'hFFFF00 
`define CYAN  	24'hFF00FF 
`define ROYAL 	24'h00FFFF 

// Define Display Mode
// `define	VGA_HORIZONTAL_COLOR	// 八种颜色横彩条
// `define	VGA_VERTICAL_COLOR		// 八种颜色竖彩条
// `define	VGA_GRAY_GRAPH			// 红色彩条2x5
 `define	VGA_GRAFTAL_GRAPH		// lcd_data <= lcd_xpos * lcd_ypos;

module Display
#(
	parameter H_DISP = 1280,
	parameter V_DISP = 1024
)
( 
	input  wire	 		clk,	
	input  wire			rst_n,	
	input  wire	[11:0]	lcd_xpos,	//lcd horizontal coordinate
	input  wire	[11:0]	lcd_ypos,	//lcd vertical coordinate
	
	output reg  [23:0]	lcd_data	//lcd data
);

`ifdef VGA_HORIZONTAL_COLOR
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		lcd_data <= 24'h0;
	else
		begin
		if	(lcd_ypos >= 0 && lcd_ypos < (V_DISP/8)*1)
			lcd_data <= `RED;
		else if(lcd_ypos >= (V_DISP/8)*1 && lcd_ypos < (V_DISP/8)*2)
			lcd_data <= `GREEN;
		else if(lcd_ypos >= (V_DISP/8)*2 && lcd_ypos < (V_DISP/8)*3)
			lcd_data <= `BLUE;
		else if(lcd_ypos >= (V_DISP/8)*3 && lcd_ypos < (V_DISP/8)*4)
			lcd_data <= `WHITE;
		else if(lcd_ypos >= (V_DISP/8)*4 && lcd_ypos < (V_DISP/8)*5)
			lcd_data <= `BLACK;
		else if(lcd_ypos >= (V_DISP/8)*5 && lcd_ypos < (V_DISP/8)*6)
			lcd_data <= `YELLOW;
		else if(lcd_ypos >= (V_DISP/8)*6 && lcd_ypos < (V_DISP/8)*7)
			lcd_data <= `CYAN;
		else
			lcd_data <= `ROYAL;
		end
end
`endif

`ifdef VGA_VERTICAL_COLOR
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		lcd_data <= 24'h0;
	else
		begin
		if	(lcd_xpos >= 0 && lcd_xpos < (H_DISP/8)*1)
			lcd_data <= `RED;
		else if(lcd_xpos >= (H_DISP/8)*1 && lcd_xpos < (H_DISP/8)*2)
			lcd_data <= `GREEN;
		else if(lcd_xpos >= (H_DISP/8)*2 && lcd_xpos < (H_DISP/8)*3)
			lcd_data <= `BLUE;
		else if(lcd_xpos >= (H_DISP/8)*3 && lcd_xpos < (H_DISP/8)*4)
			lcd_data <= `WHITE;
		else if(lcd_xpos >= (H_DISP/8)*4 && lcd_xpos < (H_DISP/8)*5)
			lcd_data <= `BLACK;
		else if(lcd_xpos >= (H_DISP/8)*5 && lcd_xpos < (H_DISP/8)*6)
			lcd_data <= `YELLOW;
		else if(lcd_xpos >= (H_DISP/8)*6 && lcd_xpos < (H_DISP/8)*7)
			lcd_data <= `CYAN;
		else
			lcd_data <= `ROYAL;
		end
end
`endif

`ifdef VGA_GRAFTAL_GRAPH
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		lcd_data <= 24'h0;
	else
		lcd_data <= lcd_xpos * lcd_ypos;
end
`endif


`ifdef VGA_GRAY_GRAPH
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		lcd_data <= 24'h0;
	else
		begin
		if(lcd_ypos < V_DISP/2)
			lcd_data <= {lcd_ypos[7:0], lcd_ypos[7:0], lcd_ypos[7:0]};
		else
			lcd_data <= {lcd_xpos[7:0], lcd_xpos[7:0], lcd_xpos[7:0]};
		end
end
`endif

endmodule

The following are four display effects. I will post a practical article on VGA display later. The VGA output display mode is controlled by buttons (four types are shown below), and another button controls the resolution of VGA output:

This post is from Domestic Chip Exchange

Latest reply

PLL IP cannot generate arbitrary frequencies, and some frequencies may have errors, which can be seen in the IP configuration interface.  Details Published on 2022-8-4 09:40
 
 

6587

Posts

0

Resources
2
 

The four display effects are good, looking forward to the subsequent VGA display test

This post is from Domestic Chip Exchange

Comments

The frequency generated by the PLL IP core of this FPGA of Anlu is not very accurate. Currently, it can only switch between two resolutions. I originally wanted to make a button control switch of four or five resolutions. Of the five clocks generated, only two meet the requirements.  Details Published on 2022-8-4 08:55
 
 
 

824

Posts

3

Resources
3
 
Jacktang posted on 2022-8-4 07:35 The four display effects are OK, looking forward to the subsequent VGA display test

The frequency generated by the PLL IP core of this FPGA of Anlu is not very accurate. Currently, it can only switch between two resolutions. I originally wanted to make a button control switch of four or five resolutions. Of the five clocks generated, only two meet the requirements.

This post is from Domestic Chip Exchange

Comments

PLL IP cannot generate arbitrary frequencies, and some frequencies may have errors, which can be seen in the IP configuration interface.  Details Published on 2022-8-4 09:40
 
 
 

9716

Posts

24

Resources
4
 
1nnocent published on 2022-8-4 08:55 The frequency generated by the PLL IP core of this FPGA of Anlu is not very accurate. Currently, it can only switch between two resolutions. I originally wanted to make a key control with four or five resolutions...

PLL IP cannot generate arbitrary frequencies, and some frequencies may have errors, which can be seen in the IP configuration interface.

This post is from Domestic Chip Exchange

Comments

OK Understood   Details Published on 2022-8-4 11:09
 
 
 

824

Posts

3

Resources
5
 
littleshrimp posted on 2022-8-4 09:40 PLL IP cannot generate arbitrary frequencies. Some frequencies will have errors, which can be seen in the IP configuration interface.

OK

learn

This post is from Domestic Chip Exchange
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>
Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list