In this Video Series we will see how we can integrate the AXI VDMA IP configured in Triple Buffer Mode into a Video Pipeline in a Vivado design.
The design will be made for a Zynq®-7000 SoC ZC702 Evaluation Kit using the PS DDR. However, the same steps could be applied to other Zynq based video designs such as the example from the previous video series on the PYNQ™ board.
Tutorial – Adding a VDMA in Triple Buffer mode to a Video Design
Note: This tutorial and the attached files are intended to be used only with Vivado Design Suite 2018.1, and only with a ZC702 evaluation board.
In the Tcl console, cd into the unzipped directory (cd <path>/XVES_0024).
In the Tcl console, source the script tcl (source ./create_proj.tcl).
Note: A valid license for the Test Pattern Generator is required to build the design.
Add an AXI VDMA to the Video Pipeline
Disconnect the AXI4-Stream interface between the AXI4-Stream Subset Converter and the AXI4-Stream to Video Out.
Add an AXI Video Direct Memory Access (VDMA) to the Block Design (BD).
Connect the S_AXIS_S2MM input of the AXI VDMA to the M_AXIS output of the AXI4-Stream Subset Converter and connect the M_AXIS_MM2S output of the VDMA to the video_in output of the AXI4-Stream to Video Out.
Connect the AXI VDMA to the memory (PS DDR)
To connect the AXI VDMA to the PS DDR we need to go through the Zynq Processor and enable an AXI Memory Mapped input on the Zynq processing system.
Double click on the ZYNQ7 Processing System to open its configuration GUI.
In the PS-PL Configuration Section, enable the S AXI HP0 interface under HP Slave AXI Interface. Click OK to close the Zynq configuration GUI.
Connect the S_AXI_HP0_ACK input to the FCLK_CLK0 output from the ZYNQ processing system.
Click on Run Connection Automation to let Vivado automatically connect the interfaces of the AXI VDMA.
In the Run Connection Automation window, make sure All Automation is selected and click OK.
Vivado might suggest the Run Connection Automation option again for the M_AXI_S2MM interface. If this is the case, click on Run Connection Automation again, make sure All Automation is selected, and click OK.
Note: In this example, we are only using one clock and one memory for the full design.
As a result, in the Run Connection Automation option, we do not have many options. With a more complex design, you might need to be careful when using this feature.
Configure the VDMA
Validate the BD. You will receive the following warning:
CRITICAL WARNING: [BD 41-237] Bus Interface property TDATA_NUM_BYTES does not match between /v_axi4s_vid_out_0/video_in(2) and /axi_vdma_0/M_AXIS_MM2S(4)
This is because we are missing one configuration in the AXI VDMA: the width of the AXI4-Stream interface to match the design.
Double click on the AXI VDMA to open its configuration GUI. Change the Stream Data Width parameter for the Read Channel to 16. Click OK to close the AXI VDMA configuration GUI (keep all of the other parameters at their default values).
Note: By default, the AXI VDMA is configured with 3 frame buffers (this is why we called it Triple Buffer Mode, which is the most common use case for this IP)
Re-validate the BD. You should have no warnings or errors. Save the BD.
Generate the design
Right click on the BD in the sources window and click Generate Output Products.
When the output product generation is over, right click on the BD in the sources window and click Generate HDL wrapper.
Run Synthesis and Implementation, and Generate the Bitstream.
Export the Hardware to SDK. Click File > Export > Export Hardware.
Make sure Include Bitstream is enabled and change the export location to <path>/XVES_0024/sdk_export.
Create the Software Application
Start the Xilinx Software Command Line Tools (XSCT) 2018.1.
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 needs to be set).
In xsct, cd to the path of the extracted folder. Then enter the command source create_SW_proj.tcl.
Open SDK and select XVES_0024/sdk_workspace as the workspace.
Manage the memory
One thing to be careful of when using memory for data is to make sure that the processor is not using the same part of the memory.
Double click on the linker script ld under the vdma_zc702_app to open it.
In the Section to Memory Region Mapping table in the linker script, we can see that the processor will be using the PS DDR. We can restrict the amount of memory available to the processor to make sure there is no overlap.
In the Available Memory Region, change the size of the ps7_ddr_0 to 0xEFFFFF and save the linker script.
In the design, the PS memory (1G) is mapped from 0x0 to 0x3FFF_FFFF. This means that we can use the memory from 0x100_0000 to 0x3FFF_FFFF for the video data from the VDMA without having the processor code at the same location.
Configure and Start the AXI VDMA
To configure the VDMA we can follow the General Use Case from page 72 of (PG020) starting with the write channel:
Configure S2MM_VDMACR (30h) to 8Bh using the following code:
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x8B);
For the frame size address, we need to know how much memory we will need for a frame. The width of the AXI4-Stream going to/from the VDMA is 2 bytes and our image size is 800x600. The amount of memory we need for one frame is as follows:
2 * 800 * 600 = 960,000 bytes (0xEA600).
If our first frame buffer is placed at the address 0x1000_0000, we will need to place the second frame buffer at 0x100E_A600 or higher.
We can try to keep some margin and place the frame buffers every 0xF0000. This give us the following addresses:
Frame buffer 1 -> 0x1000_0000
Frame buffer 2 -> 0x100F_0000
Frame buffer 3 -> 0x101E_0000
Configure the start address for the three frame buffers with the following code:
Then we need to configure the STRIDE and the HSIZE. I will explain the use of the HSTRIDE in a future use case.
For most cases, it can have the same value as HSIZE. This is what we will use in this application. Note that HSIZE and STRIDE need to be entered in bytes. As we have a 2-byte wide stream interface, we need to multiply the horizontal size by 2.
Configure the STRIDE and HSIZE with the following code: