Forums

VGA signal generator using CPLD

Started by RF November 28, 2004
Hello,

I am new with CPLD and Verilog. I have made some code and posted
on comp.lang.verilog but nobody responded.

I need help. I don't know if this code works. I don't know how
to make a test module. (I am using ISE Webpack 4.2 and MXE).

Thanks.

---
http://www.terra.es/personal9/listaco/VGAsignal.html (Project)


Here goes:
======================================================================
/*
 * VGA 800x600 @ 60 Hz Signal Generator using Verilog
 * ==================================================
 * 
 * Date: 25 November 2004
 * 
 * Intended CPLD: Xilinx XC9536XL (or XC9572XL)
 * Clock source: 40 Mhz (25 nanoseconds per pixel)
 * Posted on comp.lang.verilog and es.ciencia.electronica
 *

  Timing diagrams:
  ================

  (For more detailed information on timing, see:

     http://www.epanorama.net/documents/pc/vga_timing.html)

  A) Horizontal Line:
  ===================
  
  A1 --->  800 pixels (20   us)	Horizontal active display
  A2 --->   40 pixels ( 1   us)	Horizontal front porch
  A3 --->  128 pixels ( 3.2 us) Horizontal Sync.
  A4 --->   88 pixels ( 2.2 us) Horizontal back porch
           ==================================================
	  1056 pixels (26.4 us) Total Horizontal line (about 37.879 KHz)

  B) Vertical timing:
  ===================

  (A1+A2+A3+A4) * 600 lines --> (15840   us) Vertical active display
  B  (1 line) ----------------> (   26.4 us) Vertical front porch
  C  (4 lines) ---------------> (  105.6 us) Vertical Sync.
  D (23 lines) ---------------> (  607.2 us) Vertical back porch
                                =====================================
                                 16579.2 us  Total VGA Frame (about 60.31 Hz)

*/


module VGAsignal (clock, reset, RGB, Hsync, Vsync);

input clock;
input reset;
output RGB, Hsync, Vsync;
reg RGB, Hsync, Vsync;

reg [10:0] Xcounter;		// 2^11 = 2048
reg  [9:0] Ycounter;		// 2^10 = 1024

parameter A1=0, A2=1, A3=2, A4=3, B=4, C=5, D=6;

reg [2:0] CurrentState, NextState;


always @(Xcounter or Ycounter or CurrentState)	// Next state logic
begin
  NextState = A1;
    case (CurrentState)
		A1 : begin
				if (Xcounter == 800) NextState = A2;
				else NextState = A1;
		     end
		A2 : begin
				if (Xcounter == 840) NextState = A3;
				else NextState = A2;
	   	  end
		A3 : begin
				if (Xcounter == 968) NextState = A4;
				else NextState = A3;
		     end
		A4 : begin
				if ((Xcounter == 1056) & (Ycounter == 600)) NextState = B;
				else NextState = A4;
		     end
		B  : begin
				if (Ycounter == 602) NextState = C;
				else NextState = B;
		     end
		C  : begin
				if (Ycounter == 606) NextState = D;
				else NextState = C;
		     end
		D  : begin
				if (Ycounter == 628) NextState = A1;
				else NextState = D;
		     end
    endcase
end


always @(posedge clock or posedge reset)	// Current state logic
begin
  if (reset)
    begin
		CurrentState = A1;
		Xcounter = 0;
		Xcounter = 0;
    end
  else
    begin
		CurrentState = NextState;
		if (Xcounter == 1057) Xcounter = 0;
		  else Xcounter = Xcounter + 1;
		if (Ycounter == 629) Ycounter = 0;
		  else Ycounter = Ycounter + 1;
    end
end


always @(CurrentState)		// Output logic
begin
  case (CurrentState)
	A1 : begin
			RGB = 1; Hsync = 0; Vsync = 0;	// Active RGB
	     end
	A2 : begin
			RGB = 0; Hsync = 0; Vsync = 0;	// Horizontal Front Porch
	     end
	A3 : begin
			RGB = 0; Hsync = 1; Vsync = 0;	// Horizontal Sync.
	     end
	A4 : begin
			RGB = 0; Hsync = 0; Vsync = 0;	// Horizontal Back Porch
	     end
	B  : begin
			RGB = 0; Hsync = 0; Vsync = 0;	// Vertical Front Porch
	     end
	C  : begin
			RGB = 0; Hsync = 0; Vsync = 1;	// Vertical Sync.
	     end
	D  : begin
			RGB = 0; Hsync = 0; Vsync = 0;	// Vertical Back Porch
	     end
	default: begin
			RGB = 0; Hsync = 0; Vsync = 0;  // Is this needed?
			end
  endcase
end

endmodule

RF <listacoESPAM@terra.es> wrote in
news:43sqd.175936$r4.8918469@news-reader.eresmas.com: 

> > Hello, > > I am new with CPLD and Verilog. I have made some code and posted > on comp.lang.verilog but nobody responded. > > I need help. I don't know if this code works. I don't know how > to make a test module. (I am using ISE Webpack 4.2 and MXE).
We have a simple VGA circuit that we implemented on XC9572 CPLDs and XC4000 FPGAs described at http://www.xess.com/appnotes/vga.pdf. We also have a newer VGA design for Spartan2/3 described at http://www.xess.com/appnotes/an-101204-vgagen.pdf. This one uses a FIFO made from a BlockRAM as an input buffer, but you can strip that out and use the VGA generator at its core. The timing values for your horizontal and vertical sync look correct. But your logic seems to increment both the Xcounter and Ycounter on each clock edge. (I'm not very conversant in Verilog, so I could be wrong.) You need to increment the Ycounter only when the Xcounter is reset to zero at the end of each scanline. A clock enable is the best way to do this. Your state machine looks like it does the horizontal timing and then tries to do the vertical timing after that. These are not sequential processes. The horizontal and vertical timing proceed in parallel together. Your code looks like it outputs a single horizontal scanline and then it waits for the Ycounter to increment and overflow to start a new frame. Probably not what you want. Also, you need to set RGB to 1 (indicating active video, I guess) when Xcounter is less than 800 and Ycounter is less than 600. This is the active video portion of the frame. You don't want active video during the vertical or horizontal retrace and it looks like you only test for the horizontal. As for testing, you only have two inputs: clock and reset. Just give it a clock in your simulator and see what the horizontal and vertical syncs look like. That will tell you immediately if you have a problem. If you need to test actual hardware, there are several boards that have VGA ports you can use to drive a monitor. We even have a few at www.xess.com.
> > Thanks. > > --- > http://www.terra.es/personal9/listaco/VGAsignal.html (Project) > > > Here goes: > ====================================================================== > /* > * VGA 800x600 @ 60 Hz Signal Generator using Verilog > * ================================================== > * > * Date: 25 November 2004 > * > * Intended CPLD: Xilinx XC9536XL (or XC9572XL) > * Clock source: 40 Mhz (25 nanoseconds per pixel) > * Posted on comp.lang.verilog and es.ciencia.electronica > * > > Timing diagrams: > ================ > > (For more detailed information on timing, see: > > http://www.epanorama.net/documents/pc/vga_timing.html) > > A) Horizontal Line: > =================== > > A1 ---> 800 pixels (20 us) Horizontal active display > A2 ---> 40 pixels ( 1 us) Horizontal front porch > A3 ---> 128 pixels ( 3.2 us) Horizontal Sync. > A4 ---> 88 pixels ( 2.2 us) Horizontal back porch > ================================================== > 1056 pixels (26.4 us) Total Horizontal line (about 37.879 KHz) > > B) Vertical timing: > =================== > > (A1+A2+A3+A4) * 600 lines --> (15840 us) Vertical active display > B (1 line) ----------------> ( 26.4 us) Vertical front porch > C (4 lines) ---------------> ( 105.6 us) Vertical Sync. > D (23 lines) ---------------> ( 607.2 us) Vertical back porch > ===================================== > 16579.2 us Total VGA Frame (about > 60.31 Hz) > > */ > > > module VGAsignal (clock, reset, RGB, Hsync, Vsync); > > input clock; > input reset; > output RGB, Hsync, Vsync; > reg RGB, Hsync, Vsync; > > reg [10:0] Xcounter; // 2^11 = 2048 > reg [9:0] Ycounter; // 2^10 = 1024 > > parameter A1=0, A2=1, A3=2, A4=3, B=4, C=5, D=6; > > reg [2:0] CurrentState, NextState; > > > always @(Xcounter or Ycounter or CurrentState) // Next state logic > begin > NextState = A1; > case (CurrentState) > A1 : begin > if (Xcounter == 800) NextState = A2; > else NextState = A1; > end > A2 : begin > if (Xcounter == 840) NextState = A3; > else NextState = A2; > end > A3 : begin > if (Xcounter == 968) NextState = A4; > else NextState = A3; > end > A4 : begin > if ((Xcounter == 1056) & (Ycounter == 600)) > NextState = B; else NextState = A4; > end > B : begin > if (Ycounter == 602) NextState = C; > else NextState = B; > end > C : begin > if (Ycounter == 606) NextState = D; > else NextState = C; > end > D : begin > if (Ycounter == 628) NextState = A1; > else NextState = D; > end > endcase > end > > > always @(posedge clock or posedge reset) // Current state logic > begin > if (reset) > begin > CurrentState = A1; > Xcounter = 0; > Xcounter = 0; > end > else > begin > CurrentState = NextState; > if (Xcounter == 1057) Xcounter = 0; > else Xcounter = Xcounter + 1; > if (Ycounter == 629) Ycounter = 0; > else Ycounter = Ycounter + 1; > end > end > > > always @(CurrentState) // Output logic > begin > case (CurrentState) > A1 : begin > RGB = 1; Hsync = 0; Vsync = 0; // Active RGB > end > A2 : begin > RGB = 0; Hsync = 0; Vsync = 0; // Horizontal Front > Porch > end > A3 : begin > RGB = 0; Hsync = 1; Vsync = 0; // Horizontal Sync. > end > A4 : begin > RGB = 0; Hsync = 0; Vsync = 0; // Horizontal Back > Porch > end > B : begin > RGB = 0; Hsync = 0; Vsync = 0; // Vertical Front > Porch > end > C : begin > RGB = 0; Hsync = 0; Vsync = 1; // Vertical Sync. > end > D : begin > RGB = 0; Hsync = 0; Vsync = 0; // Vertical Back > Porch > end > default: begin > RGB = 0; Hsync = 0; Vsync = 0; // Is this needed? > end > endcase > end > > endmodule >
-- ---------------------------------------------------------------- Dave Van den Bout XESS Corp. PO Box 33091 Raleigh NC 27636 Phn: (919) 363-4695 Fax: (801) 749-6501 devb@xess.com http://www.xess.com

>> Hello, >> >> I am new with CPLD and Verilog. I have made some code and posted >> on comp.lang.verilog but nobody responded. >> >> I need help. I don't know if this code works. I don't know how >> to make a test module. (I am using ISE Webpack 4.2 and MXE). > > We have a simple VGA circuit that we implemented on XC9572 CPLDs and > XC4000 FPGAs described at http://www.xess.com/appnotes/vga.pdf. > > We also have a newer VGA design for Spartan2/3 described at > http://www.xess.com/appnotes/an-101204-vgagen.pdf. This one uses a FIFO > made from a BlockRAM as an input buffer, but you can strip that out and > use the VGA generator at its core. > > The timing values for your horizontal and vertical sync look correct. > But your logic seems to increment both the Xcounter and Ycounter on each > clock edge. (I'm not very conversant in Verilog, so I could be wrong.) > You need to increment the Ycounter only when the Xcounter is reset to > zero at the end of each scanline. A clock enable is the best way to do > this. > > Your state machine looks like it does the horizontal timing and then > tries to do the vertical timing after that. These are not sequential > processes. The horizontal and vertical timing proceed in parallel > together. Your code looks like it outputs a single horizontal scanline > and then it waits for the Ycounter to increment and overflow to start a > new frame. Probably not what you want. > > Also, you need to set RGB to 1 (indicating active video, I guess) when > Xcounter is less than 800 and Ycounter is less than 600. This is the > active video portion of the frame. You don't want active video during > the vertical or horizontal retrace and it looks like you only test for > the horizontal. > > As for testing, you only have two inputs: clock and reset. Just give it > a clock in your simulator and see what the horizontal and vertical syncs > look like. That will tell you immediately if you have a problem. If you > need to test actual hardware, there are several boards that have VGA > ports you can use to drive a monitor. We even have a few at > www.xess.com.
Thank you for your comments. I am now trying to make a test module. I will post the results here in the group. Regards.