ECEn 320

VGA Synchronization Controller

Purpose: The purpose of this laboratory is to design a circuit for generating the VGA synchronization and timing signals. You will use this controller to create a "color bar" on the display. You will also use this controller in future labs to display other things on a VGA compatible display.

Preparation

Before proceeding, carefully read pages 23-27 of the Spartan-3 Board User's Manual. This section describes the VGA port and how it is hooked up to the FPGA. Answer each of the following questions on the Blackboard lab write-up assignment before proceeding with the lab.

Exercise #1: VGA Timing

Create a new VHDL file named vga_timing.vhd that contains the entity for the timing generator for your VGA controller. Create an entity with the following input ports and output ports:

Inputs
Port Bits Purpose
clk 1 Input clock (50 MHz)
rst 1 Asynchronous reset. All synchronous elements should reset when this signal is asserted.

Outputs
Port Bits Purpose
HS 1 Low asserted horizontal sync VGA signal
VS 1 Low asserted vertial sync VGA signal 
pixel_x 10 Indicates the column of the current VGA pixel.
pixel_y 10 Indicates the row of the current VGA pixel.
last_column 1 indicates that the current pixel corresponds to the last visible column
last_row 1 indicates that the last visible line is being displayed
blank 1 Indicates that the current pixel is part of a horizontal or vertical retrace and that the output color must be blanked. The VGA pixel must be set to "black" during blanking.



After you have created your entity, create your architecture that implements the VGA timing. Follow these guidelines as you create your VGA timing controller. Address each of these items in order.
  1. For the 640x480 VGA resolution that we are implementing, the pixels change at a frequency of 25 MHz. This is half the frequency of the 50 MHz clock that is provided with our board. You need a way of "ignoring" every other clock cycle. Create a signal named "pixel_en" that can be used by internal synchronous circuitry to "enable" an update. With a 50 MHz input clock, this pixel_en signal should be asserted every other clock cycle. During one clock cycle, pixel_en is asserted and all internal circuitry is updated. During the next clock cycle, pixel_en is de-asserted and all internal circuitry keeps its old value. This synchronous signal should be set to zero when the rst signal is asserted. This pixel_en allows you to use a single synchronous clock (see section 9.1.3 in the book for a more detailed description of this approach).
  2. Create a horizontal pixel "column" counter. This counter is used to sequence through the horizontal sync phases and indicate the current pixel being displayed. This counter should reset to zero when rst is asserted. Also, this counter should only update when the pixel_en signal is asserted (the counter should hold its value when pixel_en is not asserted). This counter should be designed to count through the full sequence of pixel columns including the retrace pixel columns. For the 640x480, this counter should count from 0 to 799 (i.e. 640 displayed pixels, 16 front porch pixels, 48 back porch pixels, and 96 "pulse" pixels). When this counter is 0, it  indicates that the first visible pixel is being displayed. When the counter value is 639, the counter is indicating that the last visible pixel is being displayed. When the counter is greater than 639, it indicates a column associated with the retrace phase. The output of the counter should used to drive the pixel_x outputs of your synchronization module.
  3. Decode the horizontal counter to generate the HS sync signal. You will need to refer to the timing diagrams in the board user's manual to determine when the HS sync signal should be asserted. Remember to order your back porch, pulse width, and front porch correctly. Decode the horizontal counter to generate the "last_column" output signal. This signal should be asserted when the last visible pixel in a row is being displayed (i.e. when the current column is 639).
  4. Create a vertical pixel "row" counter. This counter is used to sequence through the vertical sync phases and indicate the current line being displayed. This counter should reset to zero when rst is asserted. Like the horizontal counter, this counter should only update when the pixel_en signal is asserted (the counter should hold its value when pixel_en is not asserted). When this counter is 0, it should indicate that the first visible line is being displayed. When the counter value is 479, the counter should indicate that the last visible line is being displayed. The output of this counter should be used to drive the pixel_y outputs of your module.
  5. Generate the "blank" signal based on the values of the pixel_x and pixel_y counters. This signal should be asserted whenever the controller is pointing to a location that is not visible.
  6. Decode the vertical counter to generate the VS sync signal (again, refer to the manual for timing). Also, decode the vertical counter to generate the "last_row" output signal. This signal should be asserted when the last visible row is being displayed (i.e. during row 479).

After creating your VHDL, remove all compilation errors and perform a few simple tests to see if the circuit is working as you expect it to. When you are satisfied with the operation of your circuit, proceed to the next testbench exercise.

Exercise #2: Testbench

Like the previous labs, a testbench has been provided for you to test your receiver under a number of conditions. This testbench will simulate your vga timing controller and measure your signals to see if they follow the appropriate timing.  Create a .tcl file that sets up your simulation within the testbench. Note that this testbench should require about 45.5 ms to simulate. Make sure you simulate until the "DONE" message is printed. Simulate your design until you receive the DONE message and there are no errors.

tb_vga_timing.vhd

Once your vga timing controller has passsed all of the tests, modify your my320pkg.vhd package to include a component declaration for your VGA controller component. Submit your modified package on blackboard.

Exercise #3: Top-Level Design and Synthesis: Color Bar Test

The next design exercise will use the VGA timing controller to create a circuit that produces a "color bar" on the VGA display. A color bar is often used to test displays and video transmission. An example of a color bar for SMPTE is shown below:

Color Bar


You are going to create a top-level circuit that uses the VGA timing controller to generate a color bar. This top-level design will use the signals from the VGA timing controller to generate the proper RBG signals to the display. You are going to use your VGA timing controller to generate the following simple displays. 
  1. When no buttons are pressed, display any non-blanked screen of your choosing (i.e., the screen cannot be all black).
  2. When button 0 is pressed, blank the screen (i.e., the screen should be black).
  3. When button 1 is pressed, fill the screen with the RGB value indicated by switches 2-0.
  4. When button 2 is pressed, create a vertical "color bar" that displays 8 columns of colors: (Black, Blue, Green, Cyan, Red, Magenta, Yellow, White). The width of each color bar should be 80 pixels (i.e. 640 / 8 colors = 80 pixels per bar).
  5. When button 3 is pressed, create a horizontal "color bar" that displays 8 rows of colors: (Black, Blue, Green, Cyan, Red, Magenta, Yellow, White).  The height of each color bar should be 60 pixels (i.e. 480 / 8 colors = 60 pixels per bar).

Create a new  top-level color bar design. Follow these guidelines as you create your top-level design.

  1. Instance the VGA controller you created in the previous design exercise.
  2. Generate a reset signal that is asserted during the first clock cycle to initialize the VGA timing module and deasserted in all subsequent clock cycles.  Refer to previous labs to remind yourself how to create a temporary reset signal.
  3. Create a circuit to decode the current pixel column and pixel row (pixel_x and pixel_y from your timing module) and output the appropriate Red, Green, and Blue values to the VGA monitor.  If the signal "blank" is asserted, R,G, and B must each be '0'.  Register the R,G, and B values along with the HS and VS signals so that no glitches are generated.
Simulate your design carefully to demonstrate that the proper colors are being displayed. Once you have simulated your design, synthesize the design and complete your lab report on the design operating parameters.

Exercise #4: Download and FPGA Editor

Once your circuit has simulated properly, synthesize your circuit and test it on the board. Plug in a VGA monitor (the monitors on top of the oscilloscopes) and see if your circuit works.

After successfully downloading your design, complete the following "FPGA Editor" questions and report your results on blackboard:

Personal Exploration

Spend some additional time in this lab by exploring new concepts, ideas, and design modifcations for your seven segment display. Ideas for personal exploration include:

Note that you do not need to submit any of the code you developed as part of your personal exploration. Provide a simple summary of the ideas you explored.

Pass Off

Demonstrate the following to a TA to passoff your lab:

  1. Show your VGA timing controller testbench simulation (Design Exercise #2)
  2. Demonstrate a working color bar display on the VGA

Lab Write-Up

Complete your laboratory write-up on blackboard.