Connected users can download this tutorial in pdf
Create a VGA controller for the ZedBoard
Introduction
In this tutorial we will create a VGA controller to display an image on a monitor using the ZedBoard and Xilinx Vivado 2017.2 (but it should work with any other release of Xilinx Vivado). The controller will be coded using VHDL.
Download the VHDL files for the project (zip file): here
Introduction to video display
What is an image?
An image is an array of pixel (for picture (x) elements). For a Black and white image, a pixel is defined by one value representing the luminosity. If this value is high, the pixel will be bright (white) and if it is low, the pixel will be dark (black). For a colour image, in most cases the pixel is composed of three values: its level of Red, its level of Green and its level of Blue (this is why we usually call colour images RGB images (for Red Green and Blue)). The combination of these 3 values will give the final colour of the pixel. For example, in a lot a software tools, you can create customs colours by setting the value of Red, Green and Blue. As shown in the Figure 1, if you select the maximum value for Green and Blue (255 in this case) and 0 for Red, you obtain the colour cyan.
Figure 1 - Example of custom colour definition tool
To display an image on a monitor, the image is sent line per line, starting with the top one and each line is sent pixel per pixel, starting with the left one.
For example, the Figure 2 shows how a 3x3 pixels image could be sent to a monitor using 3 data lanes (Red Green Blue).
Figure 2 - Example of how an image is sent to a monitor
Introduction to VGA on the ZedBoard
A colour VGA video signal is composed by 5 different signals: two synchronization signals (HSYNC and VSYNC) and three analog colour signals (R, G, B).
A video frame (one single image of a video) comprises active video and blanking periods (no data sent). The vertical (VSYNC) and horizontal (HSYNC) synchronization signals describe the video frame timing.
Figure 3 - Example Video Frame and Synchronization Signals
The Figure 3 shows an example of a video frame along with the synchronization signals. During the Active Video period, the data are sent to the monitors. During the Horizontal and Vertical blanking, no data are sent and after a defined period (which depends on the output video format) synchronisation pulses (HSYNC and VSYNC) are sent to the monitor. These pulses can be positives or negatives (depending on the output video format). The periods before a synchronisation signal and after a synchronisation signal are called respectively Front Porch and Back Porch.
Figure 4 - VGA connector schematic on the ZedBoard
In VGA, the colour data are voltage value between +0V and +3.3V. On the ZedBoard, these values are sent using a 4-bit input Digital to Analog converter as shown on the Figure 4.
Figure 5 - VGA Connector on the ZedBoard
The Figure 5 shows how the signals are connected to the VGA connector of the ZedBoard. From the ZedBoard user guide (link) we can see that the red signal is connected to the ports V20, U20, V19 and V18 of the FPGA, the green signal is connected to AB22, AA22, AB21 and AA21, the blue signal is connected to Y21, Y20, AB20 and AB19, the HSYNC is connected to AA19 and VSYNC is connected to Y19.
Timing information (1680 x 1050 @60Hz)
For this tutorial, we will output a VGA signal with the output format 1680 x 1050 @60Hz. In this format the pixel are send with a 147.14 MHz frequency.
Horizontal timing
With the output format 1680 x 1050@60Hz, the size of the active line is 1680 pixels, the horizontal synchronisation signal, which is negative, is sent after 104 clock signals in the blanking period, and last 184 clock signals and there are 288 clock signals between the horizontal synchronisation signal and a new active line. The Table 1 summarise the horizontal timing.
Line Part |
Clock Signals |
Time [µs] |
Visible area |
1680 |
11.417697431018 |
Front porch |
104 |
0.70680984096779 |
Sync pulse |
184 |
1.2505097186353 |
Back porch |
288 |
1.9573195596031 |
Whole line |
2256 |
15.332336550224 |
Table 1 - 1680 x 1050 @ 60 Hz Horizontal timing
Vertical Timing
With the output format 1680 x 1050@60Hz, the size of the active frame is 1050 lines, the vertical synchronisation signal, which is positive, is sent after a period corresponding to 1 line signals in the blanking period, and last for a period of 3 lines. This synchronisation signals is followed by a period corresponding to 33 lines before a new active frame. The Table 2 summarise the vertical timing.
Frame Part |
Lines |
Time [ms] |
Visible area |
1050 |
16.098953377735 |
Front porch |
1 |
0.015332336550224 |
Sync pulse |
3 |
0.045997009650673 |
Back porch |
33 |
0.5059671061574 |
Whole frame |
1087 |
16.666249830094 |
Table 2 - 1680 x 1050 @ 60 Hz Vertical timing
Clocking on the ZedBoard
According to the ZedBoard Hardware User’s Guide: “An on-board 100 MHz oscillator, IC17, Fox 767-100-136, supplies the PL subsystem clock input on bank 13, pin Y9”. As we need a 147.14 MHz frequency clock we will use the clocking wizard to generate the needed clock using an MMCM.
Create the timing controller
Open Vivado 2017.2 and create a new RTL project targeting the ZedBoard.
Firstly, we have a 100MHz clock in input but we need to convert it to a 147.14MHz (pixel clock). To do this, we will use the Xilinx IP Clocking Wizard. In the flow navigator, click on “IP Catalog”. In the search bar, enter “clocking” and then double click on the “Clocking Wizard” IP to add it to the project.
Figure 6 - Add a Clocking Wizard IP to the project
A GUI window should appear to customize the IP. The component name for this IP should be clk_wiz_0. In the page “Clocking Option”, check that the Primary Input clock frequency is set to 100MHz.
Figure 7 - Clocking Wizard GUI - Clocking Options
In the “Output Clocks” page, set 147.14MHz for the requested frequency for clk_out1 and disable “reset” and “locked” in the “Enable Optional Inputs / Outputs for MMCP/PLL” and then click OK.
Figure 8 - Clocking Wizard GUI - Output Clocks
A “Generate Outputs Products” window should appear. Select “Out of context per IP” and click “Generate”.
Figure 9 - Generate Outputs Products Window
Add the VDHL files hdl/TOP_LEVEL, hdl/VGA_timing_controller.vhd and hdl/reset_synchronizer.vhd to the project. You should see the hierarchy showed in the Figure 10 in the Sources window.
Figure 10 - Project Hierarchy
The file reset_synchronizer.vhd contains a simple reset synchronizer, the file VGA_timing_controller.vhd contains a code used to generate the horizontal and vertical pulses and a signal which indicates when the timing is in the “Active Video” part. The file TOP_LEVEL outputs values for the signals R, G and B when the video is active.
Try the project on board
Add the constraint file constr/phys_const.xdc to the project and generate the Bitstream.
When the Bitstream has been generated, open Hardware Manger in Vivado and program the FPGA. Connect the ZedBoard to a monitor. Make sure that the SW0 (used as reset) is on position ‘0’. You should see a green screen on the monitor. If this is not working, try the Bitstream from the downloaded folder.
Figure 11 - Green screen displayed on the monitor
Post a comment
Only connected users can post comments