top of page

Zynq-7000 + AXI Slave CDMA controller on a ZC702

Updated: May 14, 2023


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]

bottom of page