Introduction: Design of a Simple VGA Controller in VHDL and Verilog
In this instructable, we are going to design a simple VGA Controller in RTL. VGA Controller is the digital circuit designed to drive VGA displays. It reads from Frame Buffer (VGA Memory) which represents the frame to be displayed, and generates necessary data and sync signals for display purpose.
If you are looking for Verilog/System verilog code: Visit my blog VGA Controller and Video System in Verilog
Step 1: Interface of a VGA Controller
Following are the main interface signals in a VGA Controller
- Pixel Clock or VGA Clock
- HSYNC and VSYNC signals
For the VGA display chosen, you have to first calculate the frequency of Pixel Clock needed to drive it. It depends on 3 parameters: Total Horizontal Pixels, Total Vertical Pixels, Screen Refresh Rate.
Typically, F = THP * TVP * Refresh Rate
Find the documentation on pixel clock needed for various VGA displays, in the attached RAR.
HSYNC and VSYNC signals are generated from Pixel clock. The timing of HSYNC and VSYNC signals depend on number of parameters: Horizontal and Vertical Frontporch, Horizontal and Vertical Backporch, Horizontal and Vertical Display Pixels, Horizontal and Vertical Sync Pulse Widths and Polarities.
These parameters are standardized for a chosen VGA display. Find these documents in the attached RAR.
These parameters are configurable parameters in our VGA Controller IP.
Step 2: Integrating VGA Controller With a VGA Display
The figure shows how to integrate VGA Controller with a VGA display. You need two more components to complete the system:
- Frame Buffer : Memory that holds the frame to be displayed.
- Video DAC : DAC that converts RGB digital data and drives the VGA Display with RGB analog signals at appropriate voltage level.
One of the simplest and popular Video DACs is ADV7125. It is an 8-bit DAC that converts RGB digital words to 0-0.7 V analog signals and drive the VGA display.
Step 3: Frame Buffer Design
It is the memory that 'stores' the image to be displayed. It is typically a RAM or sometimes ROM. We will discuss how to design a frame buffer to represent an image. Frame buffer passes this digital info to a Video DAC on command from VGA Controller.
First we have to decide the pixel depth needed. It decides the quality of the image, the variety of colors a pixel can represent. For an 8-bit DAC, we need to represent the primary color components of a pixel: R, G, and B in 8 bits each. It means, a pixel is of 24-bit.
Each pixel is stored in a contiguous manner in Frame Buffer memory locations.
Suppose an image to be displayed is 800x600 pixels.
Therefore Frame Buffer needed is 800x600 = 480000 x 24 bits memory
Total size of the memory is 800x600x24 = 1400 kB approx.
If black and white image, 800x600x1 = 60 kB approx.
Block RAMs maybe used to represent a Frame Buffer in Xilinx FPGAs.
Step 4: Notes
- Additional signals are needed on VGA Controller depending on the DAC chosen. I have used ADV7125.
- Add cycle delays thru flip-flops on VSYNC and HSYNC before driving VGA display. This is because of DAC and Memory latencies. The pixel signals should be synchronised with HSYNC and VSYNC. In my case, it was 2 cycle delay.
- If Frame Buffer of given size cannot be designed on FPGA due to block ram size limitation, use smaller memory to represent the image and simply edit the code to roll over the address on the available memory's boundary, rather than the full frame's boundary. This will replicate same image over and over along the whole screen. Another method is pixel scaling in which each pixel is replicated to show the entire image in full screen, in a lesser resolution. This can be done by tweaking address incrementation logic in the code.
- The IP is completely portable across all FPGAs and is timing verified up to 100 MHz on Virtex-4 FPGA.
Step 5: Attached Files
The RAR contains:
- VGA Controller code
- PDFs of VGA standards.