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.
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.
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).
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.
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:
print("Initialize frame buffer data...");
//Disable the data cache to initialize the frame buffer with a blue color
//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)
//Re-enable the data cache
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.
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:
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.
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.