UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 

Video Series 26: Examples of advanced uses of the AXI VDMA IP

Moderator
Moderator
3 0 1,994

Introduction

This Video Series 26 shows how the AXI Video Direct Memory Access (VDMA) IP can be used to realize a video crop, a picture in picture or a soft pattern generator features.


Example 1 – Video crop using the AXI VDMA IP

Video Crop

In some cases, you might need to have an output resolution which is smaller than the input resolution. One operation you can do with the AXI Video Direct Memory Access (VDMA) IP is a video crop.

A video crop is a “cut” of a specific part of the image. We can do this by reading only a part of the incoming video.

 

1.png

 

Implementation with the AXI VDMA IP

In this example, I am using the Test Pattern Generator (TPG) IP as source and the AXI VDMA IP is configured with read and write channels enabled. This is the same design as in the Video Series 24.

 

2.jpg

 

In the application, I am configuring the TPG IP to generate a video with a resolution of 1024x768 (while the HDMI output resolution is fixed to 800x600)

 

//Configure the TPG
app_hdmi_conf_tpg(&tpg_inst, 768, 1024, 0x2, XTPG_BKGND_COLOR_BARS);

The main configuration which must be done is for the AXI VDMA IP.

The write interface is configured to 1024x768

//S2MM Frame delay / Stride register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 1024*2);
// S2MM HSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 1024*2);
// S2MM VSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 768);

The read interface is configured to 800x600.

// MM2S Frame delay / Stride register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x58, 1024*2);
// MM2S HSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x54, 800*2);
// MM2S VSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x50, 600);

Note that the STRIDE parameter here does not equal the HSIZE parameter. This is one of the cases where we can really use this parameter.

If STRIDE is equal to HSIZE then the AXI VDMA IP reads into the frame buffer without any jump. However, as the input size is bigger than the output size, we need to jump between addresses to get correctly aligned with the start of the next line.

The STRIDE parameter is used to describe the number of address bytes between the first pixels of each video line.

 

2.png

 

If we want to move the crop window in the input frame, we just need to add an offset to the frame buffer address keeping the same value for the HSIZE and STRIDE parameters.

 

3.png

 

For example, if we want to center the crop window horizontally, we can add an offset of 224 to the frame buffer addresses for the read interface ( (hsize_in – hsize_out)/2 * bytes/pixel = (1024 - 800)/2 * 2 = 224).

 

// MM2S Start Address 1
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C, 0x10000000 + 224);
// MM2S Start Address 2
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x60, 0x10200000 + 224);
// MM2S Start Address 3
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x64, 0x10400000 + 224);

 

Note: In this example, the offset needs to be a multiple of the memory map data width bytes (32-bits) as “Allow Unaligned Transfers” is not enable in the AXI VDMA IP configuration.


Example 2 – Picture in picture using the AXI VDMA IP

Picture in Picture

If the input resolution in a design is smaller than the output resolution, a possible solution is to use picture in picture. For example, we can add a blue background and then center our input on it.

 

4.png

 

Implementation with the AXI VDMA IP

The hardware for the design is the same as in example 1.

In the application, the TPG IP is configured to generate a video with a resolution of 640x480 (while the HDMI output resolution is fixed to 800x600)

//Configure the TPG
app_hdmi_conf_tpg(&tpg_inst,480,640, 0x2, XTPG_BKGND_COLOR_BARS);

The first things that we need to do is to fill the frame buffers with the blue color for the background.

This is done with the following line in the code:

UINTPTR Addr1=0x10000000,Addr2=0x10200000,Addr3=0x10400000;
…
print("Initialize frame buffer data...");
//Disable the data cache to initialize the frame buffer with a blue color
Xil_DCacheDisable();
//Write a blue background in the memory
for(line=0; line < OUTPUT_HEIGHT; line++)
{
	for(column=0; column < OUTPUT_WIDTH/2; column++)
	{
		//Write the blue color to the frame buffer(0x6B1DFF1D in YUV422)
		Xil_Out32(Addr1, 0x6B1DFF1D);
		Xil_Out32(Addr2, 0x6B1DFF1D);
		Xil_Out32(Addr3, 0x6B1DFF1D);

		Addr1+=4;
		Addr2+=4;
		Addr3+=4;
	}

}
//Re-enable the data cache
Xil_DCacheEnable();
print("Done\n\r");

 

You can see that before writing the data into the memory, I disable the data cache (Xil_DCacheDisable()) and re-enable it when the write is completed.

Writing or reading into the cache memory instead of the DDR memory is a common mistake. When working with the memory you need to make sure that you are reading/writing from the correct location.

Then for the AXI VDMA IP configuration, we will do the opposite to what we did in example 1.

In this example, we use the stride (which is now different from the HSIZE) on the write interface (instead of the read interface as in the previous example)  to correctly write in memory on an 800*600 background.

For the buffer memory addresses, I have added an offset to center the input both horizontally and vertically.

//Offset to center the pattern on the buffer
offset = 0x177A0;
//S2MM Start Address 1
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, 0x10000000 + offset);
//S2MM Start Address 2
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB0, 0x10200000 + offset);
//S2MM Start Address 3
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB4, 0x10400000 + offset);
//S2MM Frame delay / Stride register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, OUTPUT_WIDTH*2);
// S2MM HSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 640*2);
// S2MM VSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 480);

Example 3 – Soft Pattern Generator with the AXI VDMA IP

Implementation with the AXI VDMA IP

In this example, the AXI VDMA IP is configured with only the read interface enabled.

A pattern is written in the DDR by the processor at the beginning of the application.

In the Vivado Design, I have removed the Test Pattern Generator:

3.jpg

 

Because we are reading a pattern which is not moving, the memory corresponding to the frame buffer will not be written at the same time as the AXI VDMA IP is reading into it. As a result, only one frame buffer is needed in the AXI VDMA IP.

 

4.jpg

 

The way that the memory is written is similar to in example 2, with the cache disabled while the DDR memory needs to be accessed.

Also note that when the MM2S interface of the AXI VDMA IP is configured, genlock is disabled.


Building the SDK workspaces and Vivado Designs

 

Note: These examples are targeting the ZC702 board only.

Building the SDK Project

  1. Download the tutorial files and unzip the folder

  2. Start the Xilinx Software Command Line Tool (XSCT) 2018.1
  • From the windows menu select the following:

Start > All Programs > Xilinx Design Tools > Xilinx Software Command Line Tool 2018.1

  • From the command line

Use the command xsct (the environment variables for SDK 2018.1 need to be set)

  1. In xsct, cd to the path of the example you want to build (example_x/sw).

    Then enter the command below:

    source create_SW_proj.tcl

  2. Open SDK and select example_x/sw/sdk_workspace as the workspace

Building the Vivado Design

  1. Open Vivado 2018.1

  2. In the Tcl console, cd into the unzipped directory (cd example_x/hw)

  3. In the Tcl console, source the script tcl (source ./create_proj.tcl)