The Altera university program provides a number of hardware controllers, called cores, to control the video-to-analog converter (DAC) and display images on a monitor screen. These cores include a Pixel Buffer controller, a Character Buffer controller, and a VGA Controller. For a standard VGA display, there are 640 columns and 480 rows of pixels. The screen refreshing process begins at the top left corner and paints 1 pixel at a time from left to right
The Altera university program provides a number of hardware controllers, called cores, to control the video-to-analog converter (DAC) and display images on a monitor screen. These cores include a Pixel Buffer controller, a Character Buffer controller, and a VGA Controller. For a standard VGA display, there are 640 columns and 480 rows of pixels. The screen refreshing process begins at the top left corner and paints 1 pixel at a time from left to right
The Altera university program provides a number of hardware controllers, called cores, to control the video-to-analog converter (DAC) and display images on a monitor screen. These cores include a Pixel Buffer controller, a Character Buffer controller, and a VGA Controller. For a standard VGA display, there are 640 columns and 480 rows of pixels. The screen refreshing process begins at the top left corner and paints 1 pixel at a time from left to right
The Altera University Program provides a number of hardware controllers, called cores, to control the Video Graphics Array (VGA) Digital-to-Analog Converter (DAC) and display images on a monitor screen. These cores include a Pixel Buffer controller, a Character Buffer controller, and a VGA Controller, which are used together with SRAM and on-chip RAM and the generate images.
2. VGA Timing Overview
A VGA video signal contains 5 active signals [1]. Two signals compatible with TTL logic levels, horizontal sync and vertical sync, are used for synchronization of the video. Three analog signals with 0.7 to 1.0-Volt peak-to-peak levels are used to control the color. The color signals are Red, Green, and Blue. They are often collectively referred to as the RGB signals. By changing the analog levels of the three RGB signals all other colors are produced. The screen refreshing process begins at the top left corner and paints 1 pixel at a time from left to right. At the end of the first row, the row increments and the column address is reset to the first column. Each row is painted until all pixels have been displayed. Once the entire screen has been painted, the refresh process begins again. For a standard VGA display, there are 640 columns and 480 rows of pixels (or 640480 resolution) as shown in Fig. 1.
Fig. 1. VGA pixel layout (640480) [1]. 1
The video signal paints or refreshes the image using the following process. The vertical sync signal, as shown in Fig. 2 tells the monitor to start displaying a new image or frame, and the monitor starts in the upper left corner with pixel (0, 0). The horizontal sync signal, tells the monitor to refresh another row of 640 pixels. After 480 rows of pixels are refreshed with 480 horizontal sync active cycles, a vertical sync signal resets the monitor to the upper left comer and the process continues. During the time when pixel data is not being displayed and the beam is returning to the left column to start another horizontal scan, the RGB signals should all be set to the color black (all zeros).
Fig. 2. VGA timing for refreshing a frame (640480) [2].
The most important part of the VGA controller is the timing. To achieve the time durations of each section in Fig. 2 (B, C, D, E, P, Q, R S), a VGA clock signal is required. The VGA clock frequency is usually created with a Phase Lock Loop (PLL) component. The DE2-70 Media Computer contains a clock generator that derives the VGA clock signal. As shown in Fig. 2, each section can be approximated with a number of 25.175 MHz clock frequency. For example, there are 640 pixels in a row (section D), and each pixel can be synchronized with one 25.175 MHz clock cycle.
2
3. Video Output Subsystem in DE2-70 Media Computer
The video output sub-system of the DE2-70 Media computer is shown in Fig. 3. Hardware controllers shown in the gray boxes in Fig. 3 use streaming protocol (pipelining architecture) to quickly transfer pixel values form memory to the monitor. The screenshot of the video output sub-system of the DE2-70 Media computer is shown in Fig. 4.
Note that the users applications (C programs) interact with components shown in white boxes only. Other components are configured in Qsys.
Refer to reference [4] for descriptions of the RGB Resampler, VGA Scaler, Alpha Blender, and VGA Controller components.
Fig. 3. VGA output subsystem in the DE2-70 Media Computer.
4. Pixel Buffer
The Pixel Buffer retrieves and sends pixel color values from a memory buffer to Alpha Blending core, via an Avalon Streaming Interface. The pixel values are stored in the SRAM module and the starting address of the memory buffer within the SRAM module is selectable. With the default settings, pixel values consist of 16 bits and the starting address is the base address of the SRAM core (0x08000000). The pixel buffer can be configured to provide different resolutions via the Qsys tool. The default resolution is Generate Hsync and Vsync signals Pixel Buffer Pixel Buffer Controller Character Buffer and Controller 3
320x240 pixels (1/4 the resolution of the standard VGA resolution). This resolution is selected to reduce memory utilization in the system. To convert to a standard VGA resolution, a Pixel Scaler core is used as shown in Fig 3.
Fig. 4. Video output subsystem in the DE2-70 Media Computer [3].
An image (or video frame) consists of a rectangular array of picture elements, called pixels. Each pixel appears as a dot on the screen, and the entire screen consists of 320 columns by 240 rows of pixels, as illustrated in Fig. 5. Pixels are arranged in a rectangular grid, with the coordinate (0; 0) at the top-left corner of the screen.
4
Fig. 5. Pixel array [4].
This image grid is known as the pixel buffer which is stored in the SRAM module. To manipulate each pixel in the buffer, we can directly access the memory location of the pixel. For example, let m be the number bits required to specify a column address. Similarly, let n be the number bits required to specify a row address.
Question: What are the values of m and n?
= ( 2 ) = ( 2 320) = 9 = ( 2 ) = ( 2 240) = 8 where X and Y indicate the resolution of the VGA buffer.
The format of a pixel address is Y (n bits) X (m bits) 31 ..... 17 16 .. 9 8 .. 0
Fig. 6. Pixel address format [3].
The color of a pixel is a combination of three primary colors: red, green and blue. By varying the intensity of each primary color, any other color can be created. We use a 16- bit value to represent the color of a pixel. The five most-significant and least-significant 5
bits in this value represent the intensity of the red and blue components, respectively, while the remaining six bits represent the intensity of the green color component, as shown in Fig. 7.
Fig. 7. Pixel color format (16-bit color mode) [3].
Question: What is the value of a white pixel?
0xFFFF
Question: What is the value of a black pixel?
0x0000
Question: What is the value of a red pixel?
0xF800
If we use short int data type to access each pixel, we can treat each pixel as a 2-byte memory location. This works well because the SRAM module is configured as 2-byte word (word addressable). To determine the address of pixel (x, y) in the SRAM, we can perform
Address of pixel (x, y) = SRAM base address + offset = SRAM base address + ( (y << 9 ) + x)
Example: Draw and display red and white boxes on a black background.
6
Register Map
//Base Addresses from DE2-70 Media Computer with SD #define VGA_PIXEL_BUFFER_BASE_ADR 0x8000000 // SRAM base address #define VGA_BLACK 0x0000 // Black #define VGA_RED 0xF800 // Red #define VGA_WHITE 0xFFFF // Red
/* function prototypes */ void VGA_box (int x1, int x2, int x2, int y2, short color);
/* main loop */ while(1) {}// do nothing in this example
return 0; } /* Draw a filled rectangle on the VGA monitor */ void VGA_box(int x1, int y1, int x2, int y2, short pixel_color) { int offset, row, col; volatile short * pixel_buffer = (short *) VGA_PIXEL_BUFFER_BASE_ADR;
/* assume that the box coordinates are valid */ for (row = y1; row <= y2; row++) { for (col = x1; col <= x2; col++ ) { offset = (row << 9) + col; // compute offset *(pixel_buffer + offset) = (short) pixel_color; // set pixel } } } 7
The VGA pixel buffer module contains memory-mapped registers that are used to control the display. These registers are listed in the figure below.
Fig. 8. Control registers of the Pixel Buffer core [3].
The Resolution register provides the X resolution of the screen in bits 15-0, and the Y resolution in bits 31-16. The status register contains: m: width of the X coordinate (bits 31-24). Read only. n: width of the Y coordinate (bits 23-16). Read only. B: number of bytes of color: 1 (grayscale), 2 (16-bit color), 3 (24-bit color) or 4 (30-bit color). Read only. This field is configured in Qsys. A: address mode: 0 (X,Y), or 1 (consecutive). Read only. This field is configured in Qsys. We will mostly use XY mode. S: swap: 0 when swap is done, else 1. Read only. o This field can be used for Double Buffering technique which will be discussed later. o This field can also be used to signify a new refreshing cycle. The VGA controller refreshes the screen every 1/60 th of a second. It means that user programs should update the pixel buffer once every 1/60 th of a second. This is accomplished by writing any value to the Buffer register and waiting until bit S (or bit 0) of the Status register becomes 0. This signifies that a 1/60th of a second has passed since the last time an image was drawn on the screen.
The front buffer contains the memory starting address where the image currently visible on the screen is stored. The back buffer also contains the starting address of an image in SRAM. Initially, both buffers can point to the same image. If the Nios-II processor takes too much time to render a new image on screen which may appear to flicker, the back buffer can be 8
used for processing and the front buffer can be used for displaying. This technique is called double buffering.
Double Buffering
To enable double buffering, we need to separate the front buffer and the back buffer. For example, use half of the SRAM memory for the front buffer, and the other half for the back buffer. The Back buffer register allows the start address of the memory buffer to be changed under program control. To change the memory buffer address: The desired new address is first written into the Back buffer register. Then, a second write to read-only Buffer register is performed. It does not matter what value is written to Buffer register because the value is not used. A write operation to the Buffer register indicates a request to swap the contents of the Buffer and Back buffer registers. The swap does not occur immediately. Instead, the swap is done after the Pixel Buffer reaches the last pixel value associated with the screen currently being drawn by the VGA controller. While this screen is not yet finished, the bit S of the status register is set to 1. After the current screen is finished, the swap is performed and bit S is set to 0. User application should check for this bit when double buffering is utilized.
5. Character Buffer
The Character Buffer is used to draw text on the VGA screen. The Character Buffer retrieves and sends ASCII values from a memory buffer to the Alpha Blending core, via an Avalon Streaming Interface (hardware only). A Nios-II processor can send ASCII character codes to the Character Buffer using an Avalon interface called avalon_char_buffer_slave. This avalon_char_buffer_slave is the starting address of the on-chip memory module that is used by character buffer to draw text.
In the Character Buffer, the resolution is defined by the number of characters per line and the number of lines per screen. Each character occupies an 8x8 VGA pixel group on a VGA screen. So, based on a 640x480 VGA display, the on-chip memory module has a resolution of
80 x 60 characters.
Upon initialization or reset, the Character Buffer sets all the characters to space, so no characters will be displayed. This clear screen operation can take up to 5000 clock 9
cycles to finish. Each character in the buffer has a unique address. The coordinate system of the Character Buffer is illustrated in the figure below. As the figure indicates, each character location is identified by an (x, y) coordinate, with (0, 0) being the top-left corner of the screen.
Fig. 9. Memory layout of the Character Buffer core [3].
Question: How many characters can be displayed across the screen from left to right?
80
Question: How many characters can be displayed from top to bottom of the screen?
60
For 80x60 resolution, the address format is
Fig. 10. X-Y address format for the 80x60 resolution [3].
To determine the address of the character at location (x, y) in the on-chip memory, we can perform
Address of character (x, y) = avalon_char_buffer_slave base address + offset = avalon_char_buffer_slave base address + ((y << 7) + x) 10
Device drivers (c programs) control the Character Buffer through an Avalon memory mapped interface, named avalon_char_control_slave. The avalon_char_control_slave interface consists of the two registers shown in Table 1. The Control register provides the ability to clear the screen by using the R bit, which is bit 16 of this register. The R bit remains set to 1 until all characters have been cleared, and then R is set to 0. The Resolution register, which is read-only, provides two values: the number of characters per line, in bits 15-0, and the number of lines per screen, in bits 31-16.
Example: Develop a C program that draws a text string on a black background.
//Base Addresses from DE2-70 Media Computer with SD #define VGA_CHAR_BUFFER_BASE_ADR 0x09000000 // avalon_char_buffer_slave base addr
/* function prototypes */ void VGA_box (int x1, int x2, int x2, int y2, short color); void VGA_text (int top_x, int top_y, char * txt);
//Main function int main(void) { char text[17] = "EC463 - Example\0"; char text_row [81] = "01234567890123456789012345678901234567890123456789012345678901234567890123456789\0";
/* Write text strings to VGA */ VGA_text (30, 25, text); VGA_text (0, 29, text_row);
/* main loop */ while(1) {}// do nothing in this example return 0; }
11
6. References:
[1]. Chapter 10 in Rapid Prototyping of Digital Design book, SOPC Edition, 2008. [2]. Enoch Hwang, Build a VGA Monitor Controller, Circuit Cellar, Issue 172, Nov 2004. [3]. Altera, Media Computer System for the Altera DE-70 Board, for Quartus II v.13.0, May 2013. [4]. Altera, Video IP Cores for Altera DE-Series Boards, for Quartus II v.13.0, May 2013.
/* Function to send a string of text (end with a NULL) to the VGA monitor */ void VGA_text(int x, int y, char * text_ptr) { int offset; volatile char * char_buffer = (char *) VGA_CHAR_BUFFER_BASE_ADR;
/* compute offset and set character */ offset = (y << 7) + x; // compute offset while ( *(text_ptr) ) // make sure the text array ends with a NULL character { *(char_buffer + offset) = *(text_ptr); // write to the character buffer ++text_ptr; ++offset; } }