The next key process is the timing of the horizontal and vertical sync pulses, and the blanking intervals. The line timing for VGA
is 31,770 ns per line with a window for displaying the data of 25,170 ns. If the FPGA is running at 100 MHz
(that is, a period of 10ns) then this means that each line requires 3,177 clock cycles with 2,517 for each line of pixel data, with 660 pulses in total for blanking (330 at either side). This also means that for a 640 pixel wide line, 39.3 ns are required for each pixel. We could round this up to 4 clock cycles per pixel. As you may have noticed, for the pixel retrieval we have a new internal clock signal called pclk
, and we can create a process that generates the appropriate pixel
) with this timing in place.
With this slightly elongated window, the blanking pulses must therefore reduce to 617 clock cycles and this means 308 before and 309 after the display window.
The horizontal sync pulse, on the other hand takes place between 26,110ns and 29,880 ns of the overall interval. This is 189 clock pulses less than the overall line time, and so the horizontal sync pulse goes low after 94 clock cycles and then at the end must return high 95 clock cycles prior to the end of the line. The difference between the outside and inside timings for the horizontal sync pulse is 377 clock cycles and so the sync pulse must return high 94 + 188 clock cycles and then return low 95 + 189 prior to the end of the window.
Thus the horizontal sync has the following basic behavior:
And this can be implemented using a process with a simple counter as follows:
The horizontal sync process manages the individual pixels in a line, and the vertical sync does the same for the lines as a whole to create the image. The period of a frame (containing all the lines) is defined as 16,784,000 ns. Within this timescale, the lines of the image are displayed (within 15,250,000 ns), then the vertical blanking interval is defined (up to the whole frame period of 16,784,000 ns) and finally the vertical sync pulse is defined as 1 until 15,700,000 ns at which time it goes to zero, returning to 1 at 15,764,000 ns.
Clearly it would not be sensible to define a clock of 10 ns for these calculations, so the largest common divisor is a clock of 2 µs, so we can divide down the system clock by 2000 to get a vertical sync clock of 2 µs to simplify the design and make it as compact as possible.
Where the vertical sync clock (vclk) is defined as a std_logic signal in the architecture, this can then be used to control the vsync pulses in a second process that now waits for the vertical sync derived clock:
Using this process, the vertical sync (frame synchronization) pulses are generated.
Horizontal and vertical blanking pulses
In addition to the basic horizontal and vertical sync pulse counters, we also have to define a horizontal blanking pulse which sets the line data low after 25,170 ns (2,517 clock cycles). This can be implemented as a simple counter in exactly the same way as the horizontal sync pulse and similarly for a vertical blanking pulse. The two processes to implement these are given in the following VHDL:
Calculating the correct pixel data
As we have seen previously, the data of reach pixel is retrieved from a memory location and this is obtained using the pixel clock (pclk). The pixel clock is simply a divided (by 4) version of the system clock and at each rising edge of this pclk signal, the next pixel data is obtained from the memory data stored in the signal called data and translated into the red, green and blue line signals. This is handled using the basic process given below:
This is a basic handler process that picks out the correct pixel data, but it does not include the video blanking signal and if this is included, then the simple VHDL changes slightly to this form:
This is the final step and completes the basic VHDL VGA handler.
This chapter has introduced the basics of developing a simple VGA handler in VHDL. While it is a simplistic view of the process, it has shown how a simple VGA interface can be developed using not very complex VHDL and a building block approach.
It is left to the reader to develop their own complete VGA routines for the specific monitor that they have using the techniques developed in this chapter as a basis.
Editor's Note: The full contents list for Design Recipes for FPGAs is as shown below. If you decide that you are interested in purchasing this book, you can Click Here to be taken to the appropriate page on the publisher's website. When you come to place your order, use code 91711 to receive a 20% discount.
PART 1: Introductory Materials
– Chapter 1: Introduction
– Chapter 2: An FPGA Primer
– Chapter 3: A VHDL Primer
– Chapter 4: Design Automation and Testing for FPGAs
PART 2: Applications
– Chapter 5: Images and High-Speed Processing
– Chapter 6: Embedded Processors
PART 3: Designer's Toolbox
– Chapter 7: Serial Communications
– Chapter 8: Digital Filters
– Chapter 9: Secure Systems
– Chapter 10: Memory
– Chapter 11: PS/2 Mouse Interface
– Chapter 12: PS/2 Keyboard Interface
– Chapter 13: A Simple VGA Interface
PART 4: Optimizing Designs
– Chapter 14: Synthesis
– Chapter 15: Behavioral Modeling in VHDL
– Chapter 16: Design Optimization
– Chapter 17: VHDL-AMS
– Chapter 18: Design Optimization Example: DES
PART 5: Fundamental Techniques
– Chapter 19: Counters
– Chapter 20: Latches, Flip-flops, and Registers
– Chapter 21: Serial-to-Parallel and parallel-to-Serial Conversion
– Chapter 22: ALU Functions
– Chapter 23: Decoders and Multiplexers
– Chapter 24: Finite State Machines in VHDL
– Chapter 25: Fixed-Point Arithmetic in VHDL
– Chapter 26: Binary Multiplication