show menu


Connected users can download this tutorial in pdf

Controlling the PL from the PS on Zynq-7000

Posted by Florent - 20 March 2017

Introduction

In this tutorial we will access the Programmable Logic (PL) of a Zynq-7000 from its Processor System (PS) to control the LEDs of the Xilinx Zynq Board ZC702. This tutorial is realized using Vivado 2016.2 but can easily be adapted for other releases. Also, even if this tutorial targets a ZC702, the same process can be used for other Zynq boards as the ZYBO or the ZedBoard.

Create the Hardware Design in Xilinx Vivado

Open Vivado 2016.2 and create a new RTL project. Create a new BD and add a ZYNQ7 PS IP. Connect the input M_AXI_GP0_ACLK of the ZYNQ7 PS to its output FCLK_CLK0 (these steps are explained in detail in the tutorial 8 - First use of the Zynq-7000 Processor System on a Zynq Board).

To access the LEDs of the ZC702 board from the PS we will use a bloc called AXI GPIO IP. Add the AXI GPIO IP using the IP catalog.

Figure 1 - Add the AXI GPIO IP using the IP catalog

An interesting feature in Vivado is “Run Connection Automation”. Clicking on this will ask the tool to connect the AXI GPIO IP to the ZYNQ7 PS IP for us. Click on “Run Connection Automation”.

Figure 2 - Vivado IPI - Run Connection Automation

Select “All Automation” in the “Run Connection Automation” window.

Figure 3 - “Run Connection Automation” window

Vivado has added two blocks, the Processor System Reset and the AXI Interconnect IPs, needed to connect the ZYNQ7 PS IP to the AXI GPIO IP

Figure 4 - Our system

Double click on the AXI GPIO IP to configure it. In the “board” part make sure that the board interface for “GPIO” is set to “Custom”.

Figure 5 - AXI GPIO IP customisation - Board

In the part IP configuration, select “All Outputs” and set the “GPIO Width” to 8 and close the AXI GPIO GUI.

Figure 6 - AXI GPIO GUI

Validate the design. You should have no error. If we open the “Address Editor” page in the BD, we can see the memory map of all the IPs in the design. We can see that Vivado as assigned the address 0x41200000 to our GPIOs.

Figure 7 - Address Editor

Generate the BD output products and create an HDL wrapper. Run synthesis and open the synthesized design. In the device editor, assign the gpio_sw output ports to the FPGA pins corresponding to the LEDs.

Ports name

Package Pin

I/O Std

User Led

Gpio_sw_tri_o[7]

E15

LVCMOS25

DS19

Gpio_sw_tri_o[6]

D15

LVCMOS25

DS20

Gpio_sw_tri_o[5]

W17

LVCMOS25

DS21

Gpio_sw_tri_o[4]

W5

LVCMOS25

DS22

Gpio_sw_tri_o[3]

V7

LVCMOS25

DS18

Gpio_sw_tri_o[2]

W10

LVCMOS25

DS17

Gpio_sw_tri_o[1]

P18

LVCMOS25

DS16

Gpio_sw_tri_o[0]

P17

LVCMOS25

DS15

 

Figure 8 - Assign Package Pins

Press “Ctrl+S” to save the constraints. As we don’t have any constraints file in our design, Vivado will suggest us to create a new constraints file to store the Pins constraints. Create a new file called “phys_const” and click OK.

Figure 9 - Create a new constraints file to store the created constraints

Generate the Bitstream, export the Hardware to SDK (including the Bitstream) and launch SDK.

Create the Software Project in Xilinx SDK

Create the application in SDK

Create a new application project (“File > New > Application Project”) with a new Board Support Package (BSP).

Figure 10 - New application project in Xilinx SDK

In the project templates, select “Hello World”. Launch the application on the board and see if you can get the “Hello World” in the UART console (this step is explained in detail in the tutorial 8 - First use of the Zynq-7000 Processor System on a Zynq Board).

Control the LEDs

To access the LEDs we have added an AXI GPIO IP in our PL design. The BSP created by SDK should contains the drivers to control this IP. Expand the BSP in your project (as shown in the Figure 11). Under “libsrc” you should see “gpio_v4_1” (with another version if you are using another version of Vivado/SDK).

Figure 11 - Content of the BSP

Open the file “helloworld.c” of your application project.

First we need to initialize the pointers to the GPIOs. For this, I have used the function int XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId) which is declared in the file xgpio.h (the content of the function can be found in the file xgpio_sinit.c).  This function needs two parameters, InstancePtr, which is the pointer to the GPIOs to be initialized and DeviceId. For the parameter InstancePtr, create a new structure called myGPIO of type XGpio and assign its adress to the function. For the parameter DeviceId, we can put the constant XPAR_AXI_GPIO_0_DEVICE_ID which is declared in the file xparameters.h.

Then to change the LEDs value, I have used the function void XGpio_DiscreteWrite(XGpio * InstancePtr, unsigned Channel, u32 Data) which is also declared in the file xgpio.h (the structure of the function can be found in the file xgpio.c). The parameter InstancePtr is the address of the XGpio structure created previously, set the parameter Channel to 1 and the parameter Data to the value (between 0x00 and 0xFF) you want to display on the LEDs.

You can find the content of my file in annexe of this document.

Run the Software in Debug mode

Launch a Xilinx C/C++ debug application (GDB) and run it (see tutorial 8 - First use of the Zynq-7000 Processor System on a Zynq Board). Execute the code step by steps using the “Step Over” icon  or by pressing “F6”.

After the line “success = XGpio_Initialize(&myGPIO, XPAR_AXI_GPIO_0_DEVICE_ID);” has been executed, look at the value of myGPIO in the variable window (if not on the screen, click Window > Show View > Variables). We can see that the value of myGPIO->BaseAddress is 0x41200000 (same value as we have seen previously in the “Address Editor” of Vivado).

Figure 12 - Variables window in SDK

Continue the execution of the code by pressing the “Resume” icon  or by pressing “F8”. You should see the value of the LEDs change on the ZC702 board.