How do you feel about this article? Help us to provide better content for you.
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
What do you think of this article?
Now that the hardware design is complete (refer to HDMI I/O Video-Processing System on the Artix-7 FPGA I - Hardware) Adam creates the software for the system. It generates a video output signal and writes data into the DDR 3 in (134-6477)  Nexys Video so that the VDMA can read this data and output it over HDMI.
Step 1: Define Video Frames
The first thing is to define the video frames, which are going to be stored in memory and output by the VDMA. To do this, Adam defines three frames within memory. Each is a two-dimensional array:
u8 frameBuf[DISPLAY_NUM_FRAMES][DEMO_MAX_FRAME];
where DISPLAY_NUM_FRAME is set to 3 and DEMO_MAX_FRAME is set to 1920 * 1080 * 3. This takes into account the maximum frame resolution and the final multiplication by 3 accommodates each pixel (8 bits each for red, green, and blue).
To access these frames, Adam uses an array of pointers to the each of the three frame buffers. This eases the interaction with the frames.
Step 2: Initialize and configure peripherals
After frames defined, the next step it is to initialize and configure the peripherals within the design. These are:
- VDMA – Uses DMA to move data from DDR 3 to the output video chain.
- Dynamic Clocking IP – Outputs the pixel clock frequency and multiples of this frequency for the HDMI output.
- Video Timing Controller 0 – Defines the output display timing depending upon resolution.
- Video Timing Controller 1 – Determines the video timing on the input received. In this demo, this controller grabs input frames from a source.
To ensure the VDMA functions correctly, Adam defines the stride. This is the separation between each line within the DDR memory. For this application, the stride is 3 * 1920, which is the maximum length of a line.
When it comes to the application, the user can set different display resolutions from 640x480 to 1920x1080. No matter what resolution is selected, users will be able to draw test patterns on the screen using software functions that write to the DDR 3. If functions are modified, VDMA, Video Timing Generator 0, and the dynamic clocking module are also required to be reconfigured.
Step 3: Generate video output
The next step is to generate a video output. The following functions generate, capture, and display video.Â
- Bar Test Pattern – Generates several color bars across the screen
- Blended Test Pattern – Generates a blended color test pattern across the screen
- Streaming from the HDMI input to the output
- Grab an input frame and invert colors
- Grab an input frame and scale to the current display resolution
Within each of these functions, Adam passes a pointer to the frame currently being output so that pixel values can be modified in memory. This can be done simply as shown in the code snippet below, which sets the red, blue, and green pixels. Each pixel color value is assigned 8 bits.
When Adam runs the application, he can choose which of the functions he wants to exercise through the menu output (over the UART terminal):
Setting the program to output color bars and the blended test gave the outputs below:
Users can generate a Mandelbrot pattern using this approach. The project file can be downloaded at Adam's Github
Â