
This post lists step-by-step instructions for creating an AXI slave Central Data Management Access (CDMA) controller, integrating the slave into a Zynq-7000 system using Vivado, writing a driver that exercises the CDMA, and running everything on a ZC702. More commonly referred to as DMA, DMA's are useful for passing data between a CPU (in this case, the Processing System (PS)) and external peripherals. DMA allows the PS to be idle while transfers are happening, freeing up the PS to do other things, and access the data when it's convenient for the PS to do so. Use cases include reading/writing to memory, to a radio controller, HDMI, Serial Busses, etc.
As shown in the high-level diagram below, this design uses general-purpose AXI to interface the ARM A9 processor with the CDMA, and high-performance AXI to interface the CDMA with DDR memory on a ZC702 prototype board. Pseudo-random data is stored and read back in a two transaction CDMA transfer. The returned data is compared with the sent data to verify the CDMA transaction completed successfully.

Credit: Xilinx
Versions Used
Xilinx Vivado 2018.2 & SDK 2018.2
ZC702 Rev 1.1
Windows 10 Professional v1909
Before you Start
Review the ZC702 JTAG and serial port set up instructions @ [link]. These instructions are also reviewed below.
Contents
Part 1: Create the Vivado Project
Part 2: Create the Zynq-7000 in IP Integrator
Part 3: Create the CDMA AXI Slave and Concat IP blocks
Part 4: Connect the Interrupt Lines
Part 5: Configure the PS High Performance AXI buses
Part 6: Configure the CDMA
Part 7: Automate remaining connections
Part 8: Address configuration
Part 9: Create a Top-Level HDL Wrapper
Part 10: Synthesize and Generate the Bitstream
Part 11: Export the Design and Open the SDK
Part 12: Install the USB-to-UART Driver and Get the COM Assignment
Part 13: Configure the Board to Boot from JTAG, Connect it to the PC and Power it On
Part 14: Create the Test App and BSP
Part 15: Test Debug Run + Further Config
Part 16: Test the CDMA Module
Part 1: Create the Vivado Project
Step 1:
A: Press Start
B: Expand Xilinx Design Tools

Step 2: Select Vivado 2018.2

Step 3: Select Create Project

Step 4: Click Next

Step 5:
A: Set Project name to cdmaslave
B: Set Project location to C:/vivadoprjs (create C:/vivadoprjs if it doesn't exist)
C: Click the Create project subdirectory checkbox
D: Click Next

Step 6:
A. Select RTL Project
B. Check the Do not specify sources at this time check box
C. Click Next

Step 7:
A. Click Boards
B. Type ZC702
C. Click on the ZYNQ-7 ZC702 Evaluation Board box
D. Click Next

Step 8: Click Finish

Part 2: Create the Zynq-7000 in IP Integrator
Step 1: Click Create Block Design

Step 2: Use defaults, click OK

Step 3: Click +

Step 4:
A. Type Zynq
B. Double-click on ZYNQ7 Processing System

Step 5: Click Run Block Automation

Step 6: Use defaults, click OK

You should see:

Part 3: Create the CDMA AXI Slave, Concat, and Timer IP blocks
Step 1: Click + again

Step 2:
A. Type CDMA
B. Double-click on AXI Central Direct Memory Access

You should now see:

Step 3: Click + a third time

Step 4:
A. Type concat
B. Double-click on Concat

You should now see:

Step 5: Click + one final time

Step 6:
A. Type timer
B. Double-click on AXI Timer

You should now see:

Part 4: Connect the Interrupt Lines
Step 1: Double click the ZYNQ block

Step 2: Enable IRQ_F2P[15:0]
A. Click Interrupts
B. Check the Fabric Interrupts checkbox
C. Expand the Fabric Interrupts drop-down
D. Expand the PL-PS Interrupt Ports
E. Check the IRQ_F2P[15:0] checkbox
F. Click OK

You should then see the IRQ_F2P[0:0] port on Zynq:

Step 3: Connect IRQ_F2P[0:0] to xlconcat_0 interrupt output
A: Click and hold mouse button on IRQ_F2P[0:0]
B: Drag and release mouse button on xlconcat_0 dout[1:0]

You should see:

Step 4: Connect axi timer interrupt to concatenate block
A: Click and hold mouse button on axi_timer_0 interrupt
B: Drag and release mouse button on xlconcat_0 In0[0:0]

You should see:

Step 5: Connect CDMA interrupt to concatenate block
A: Click and hold mouse button on axi_cdma_0 cdma_introut
B: Drag and release mouse button on xlconcat_0 In1[0:0]

You should see:

Part 5: Configure the PS High Performance AXI buses
Step 1: Double click the ZYNQ block

Step 2: Enable the High Performance AXI interfaces
A. Click PS-PL Configuration
B. Expand the HP Slave AXI Interface drop-down
C. Check the S AXI HP0 Interface checkbox
D. Check the S AXI HP2 Interface checkbox
E. Click OK

The PS7 should now look like this:

Part 6: Configure the CDMA
Step 1: Double click the CDMA

Step 2: Configure the CDMA
A: Uncheck Enable Scatter Gather
B: Set Write/Read Data Width to 1024
C: Set Write/Read Burst Size to 32
D: Click OK.

The CDMA IP block should now look like this:

Part 7: Automate remaining connections
Step 1: Click Run Connection Automation

The completed diagram should now look as follows:

Step 2: Click OK to close the Critical Message. We will correct the address mapping in the next section.

Part 8: Address configuration
Step 1: Select the Address Editor tab

Step 2: Adjust the high performance addresses
A: Expand axi_cdma_0
B: Expand Data
C: Adjust S_AXI_HP0 Offset Address to 0x2000_0000
D: Set S_AXI_HP0 Range to 256M
E: Adjust S_AXI_HP2 Offset Address to 0x3000_0000
F: Set S_AXI_HP2 Range to 256M

Part 9: Create a Top-Level HDL Wrapper
A. Click Sources
B. Right-click design_1 (design_1.bd) (1)
C. Click Create HDL Wrapper...

D. Leave Let Vivado manage wrapper and auto-update, click OK

After a little time you should see:

Part 10: Synthesize and Generate the Bitstream
Step 1: Click Run Synthesis

Step 2: Use defaults, click OK

You'll see the status in the upper right corner.
A sample of the output:

Step 3:
Wait approximately 10 min (using a custom built CPU with a Ryzen 5 2400G, M.2 SSD, and DDR4 Memory) until you see Synthesis Complete in the upper right corner...

...and click OK to Run Implementation

Step 4: Use defaults, click OK

Again, you'll see status in the upper right:

Step 5:
Wait approximately 10 min (using a custom built CPU with a Ryzen 5 2400G, M.2 SSD, and DDR4 Memory) until you see Implementation Complete in the upper right corner...

A. Select Generate Bitstream
B. Click OK

Step 6: Use defaults, click OK

Again, you should see the status in the upper right:

Step 7: Click Cancel

You may see this window pop-up:

Feel free to send feedback, set a reminder or click No. If you click No you may see:
...click OK to dismiss.

Part 11: Export the Design and Open the SDK
Step 1:
A. Click File
B. Click Export
C. Click Export Hardware...

Step 2:
A. Click the Include bitstream checkbox
B. Click OK

Step 3:
A. Click File
B. Click Launch SDK

Note: you can open the workspace directly from the SDK by opening the SDK and specifying C:\vivadoprjs\cdmaslave\cdmaslave.sdk as the workspace.
Step 4: Use defaults, click OK

You should see:

Part 12: Install the USB-to-UART Driver and Get the COM Assignment
Steps:
A. Goto [link] for the Silicon Labs CP210x USB to UART Bridge VCP Drivers
B. Download and unzip the correct installer for your OS
C. Install the driver (I did not need to restart on Windows 10 Professional)
D. Right-click the Windows Icon
E. Click Device Manager

F. Expand the Ports (COM & LPT)
G. You should see Silicon Labs CP210x USB to UART Bridge
H. Note the COM port # (you'll need this later)

Part 13: Configure the Board to Boot from JTAG, Connect it to the PC and Power it On
Step 1: Set SW16 to JTAG mode [mode documentation see p.16]

For the rest of the jumpers see the high-resolution photo of the board in the correct state at [link]. Step 2: Connect a Micro-B to Type-A (host connection) USB cable from U23 (Diglent USB JTAG interface) to the host PC
U23:

Micro-B connector:

Type-A connector:

Step 3: Connect a Mini-B to Type-A (host connection) USB cable from J17 (CP2103GM USB-to_UART Bridge) to the host PC.
J17:

Mini-B connector:

Type-A connector:

Step 4: Turn on the board

Part 14: Create the Test App and BSP
Step 1:
A. Click File
B. Click New
C. Click Application Project

Step 2:
A. Type testcdmaslave into Project name:
B. Ensure the Board Support Package: Create New radio button is clicked and the name given is testcdmaslave_bsp
C. Click Next

Step 3:
A. Click Hello World
B. Click Finish

You should see:

Part 15: Test Debug Run + Further Config
These instructions allow debugging to be set up more easily than entering the details manually. After running a debug session, the Debug Configuration is fixed up to reset the FPGA and program the bitstream. The debugger COM port is also configured so that output can be read and the steps to test it and see Hello World are listed.
Step 1:
A. Right-click testcdmaslave
B. Click Debug As
C. Click Launch on Hardware (System Debugger)

Step 2: Click OK (if you see this)

If you see this message click Yes. We'll handle this in the next part.

...click Yes.

You should see the Debug Perspective display the code broken on init_platform():
A. Debug context on main()
B. helloworld.c on init_platform()

Step 3:
A. Click Run
B. Click Debug Configurations...

Step 4:
A. Ensure System Debugger using Debug_testaxislave on Local is selected (it should be)
B. Click the Reset entire system checkbox
C. Click the Program FPGA checkbox
D. Click Apply
E. Click Close

Step 5: Configure Debug View COM
A. Click SDK Terminal
B. Click the '+' (Connect to serial port.)

Step 6: Set Debug View COM settings
A. Enter the COM# from above
B. Click OK

You should see:

Step 7: Make sure you see Hello World on the console
A. Click on the bug

B. Click OK

C. Wait for the system to hit the breakpoint on main()

D. Click Resume

E. Wait until you see exit():
F. Click on SDK Terminal
G. Observe Hello World

Part 16: Test the CDMA Module
Step 1: Click on the C/C++ view

Step 2:
A. Expand testcdmaslave
B. Expand src

Step 3:
A. Right-click on src
B. Hover over New
C. Click File

D. Type testcdma.c
E. Click Finish

F. Copy and paste the following code into testcdma.c. Note that this code comes directly from this [link] and has some minor modifications to conform with Linux Kernel Code Convention and to be able to use a header file in future steps.
Step 4:
A. Right-click on src
B. Hover over New
C. Click File

Step 5:
A. Type testcdma.h
B. Click Finish

Step 6: Copy and paste the following code into testexample.h
int testcdmaexample(void);
Step 9: Update helloworld.c
A. Double-click helloworld.c
B. Add #include "testcdma.h” as shown
C. Add testcdmaexample(); as shown

D. Click save-all

Step 7: Run it
A. Click on the bug

If you see WARNING pop-up this click OK

B. Click Yes to confirm the switch to the Debug perspective

C. You should see execution stopped at main(

D. Click Resume

E. You should see that the DMA transfer was successful.

References
· Xilinx logo found via https://twitter.com/xilinxinc at [link]
· Zynq-7000 All Programable SoC: Embedded Design Tutorial [link]
· Xilinx Design Files [link]