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!

Showing results for 
Search instead for 
Did you mean: 

Adam Taylor’s MicroZed Chronicles, Part 119: VDMA software

Xilinx Employee
Xilinx Employee
0 5 150K


By Adam Taylor


Having successfully completed the build of VDMA hardware in Vivado in the previous MicroZed Chronicles blog (see “Adam Taylor’s MicroZed Chronicles, Part 118: VDMA Hardware”), we now need to write some software to ensure the drivers are correctly configured so that we can get an image from the test-pattern generator to the screen.


To do this we need to:


  1. Configure the test-pattern generator to output an 800x600-pixel test pattern: We do this using the "xv_tpg.h" and "xvidc.h" libraries. We also need to define the color space being used by the test-pattern generator and we need to enable auto restart to ensure that the test pattern is continually generated.
  2. Configure the VDMA to read and write frames from the target memory: This is what we will be focusing upon in this blog post.


VDMA works in two modes: the WRITE, which transfers from the AXI stream to a memory-mapped buffer store, and READ, which transfers from the memory-mapped store to the AXI stream. We will want to be able to use the VDMA in either direction, or both. Therefore, when we need to configure both the write and read paths of the VDMA IP block. Rather helpfully, Xilinx provides a VDMA API which we can add into our project. This API significantly simplifies our task. For more complex instantiations, we can adapt this API because it serves as a good template of what’s needed.


We can find this API in the example directory of our SDK installation, which is available under <SDK>\data\embeddedsw\XilinxProcessorIPLib\drivers\axivdma_v6_0\examples.


While this API is designed to configure the VDMA for both reads and writes using three frame buffers, we can easily adapt it for operation in only one direction. Before we do that, we want to ensure that it works and that the test pattern displays on our monitor.


To use the API, we need to add it to our project source directory and call the function run_triple_frame_buffer() with an instance of the VDMA, the location of the memory-mapped store, and the size of the image to be processed. In this case, the size is 800x600 pixels and the memory-mapped store’s address is set to XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x100000, or 0x00200000.


Because this is a triple-buffered VDMA instantiation, there will be three buffers within the memory-mapped store. The addresses are contained within the MM2S and S2MM Start address registers (remember the VDMA is being used to read and write). In this application the address of the three frames are:


  • 0x00200000 – first frame
  • 0x0035F900 – second frame
  • 0x004BF200 – third Frame


Putting all this together in SDK, we can then build, download the application (we want to download a debug build), and see the test pattern running on the screen.


Interestingly, because we are using a debug build, we can also stop the execution of the application and explore the memory contents using the memory watch window. Within this window, we can see not only the configuration of the Test-Pattern Generator and the VDMA but also the image in the memory mapped store.


Looking at the three addresses above you can see that each frame in memory holds the same image contents, as you can see below:





Frame Store 1





Frame Store 2





Frame Store 3



We can see that all three frame images contain the same information. However, we need to ensure that the memory contents align with the test-pattern generator.


If you remember, the hardware definition contained several ILA (Integrated Logic Analyzer) blocks. One ILA block is on the Test-Pattern Generator’s output. Running this, we can see that each line of the video pixel output goes through the following sequence, outputting 100 pixels in the following sequence:



0xFFFFFF, 0xFF00FF, 0x00FFFF, 0x0000FF, 0xFFFF00, 0xFF0000, 0x00FF00, 0x000000



The snapshot below from the ILA connected to the test pattern generator shows this:







We see that it takes 3 bytes to store a pixel. Each line in memory therefore requires 2400 bytes, so each line is separated by 0x960. You can see this as well by looking through the memory-watch window. The software application also reads out three complete lines from image store zero to verify the contents and testing shows that it agrees with the test-pattern generator video.



I have uploaded the code and an archive of the Vivado design on the github repository.





The code is available on Github as always.


If you want E book or hardback versions of previous MicroZed chronicle blogs, you can get them below.




  • First Year E Book here
  • First Year Hardback here.



 MicroZed Chronicles hardcopy.jpg




  • Second Year E Book here
  • Second Year Hardback here



 MicroZed Chronicles Second Year.jpg




You also can find links to all the previous MicroZed Chronicles blogs on my own Web site, here.





Tags (3)