VGA signal generator using CPLD

Nov 28, 2004 2 Replies

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.


---

formatting link
(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:



formatting link



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 wrote in news:43sqd.175936$ snipped-for-privacy@news-reader.eresmas.com:

We have a simple VGA circuit that we implemented on XC9572 CPLDs and XC4000 FPGAs described at

formatting link

We also have a newer VGA design for Spartan2/3 described at

formatting link
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

formatting link

---------------------------------------------------------------- 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

Thank you for your comments. I am now trying to make a test module. I will post the results here in the group.

Regards.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required