PYNQ-Z1 peripherals control with an Overlay created from Vivado

This post is an extension of “Creating a simple overlay for PYNQ-Z1 board from Vivado HLx“, which presented an Overlay creation methodology for an accelerator block. The implemented block only communicates with Zynq Processing System (PS) and does not explain the PYNQ peripherals management. This work was developed with the help of Wagner Wesner.

The “base” Overlay found inside the PYNQ package is composed of the basic structures needed to handle PYNQ functionalities. The Vivado project (built on Vivado 2016.1) used to develop the “base” Overlay can be reconstructed from the Tcl file and observed:

base_blockd

 

For the proof of concept, an Overlay that controls PYNQ LEDs and Switches is developed. The “IP” responsible to control the LEDs and Switches is found and zoomed:

axi_gpio.png

The base Overlay uses an “AXI GPIO” IP to interface the LEDs and Switches “GPIO” pins with the  “AXI” bus protocol. The ARM processor inside the Zynq chip uses the AXI bus to communicate the Processing System with the Programmable Logic.

With reverse engineering, the implementation starts by opening Vivado (2017.2) and creating a new project with the “xc7z020clg400-1” part.

vivado_hlx

xc7part

In the “IP INTEGRATOR” tab, select “Create Block Design”, the “Diagram” window opens. Right-click inside the “Diagram” window and add “ZYNQ7 Processing System” and “AXI GPIO” IPs:

zynq_block

axi_gpio_ip

Change “AXI GPIO” IP settings to match the base Overlay IP:axi_gpio_settings.png

Then run Block and Connection automation:

block_automation

The result after regenerating the layout should look as this:

led_block_diagram

Remember to change the name of the GPIO pins on the “AXI GPIO” block to match the names used on the “base” Overlay. These namings are important to virtually connect the pins to the physical peripherals.

axi_gpio

The next step is creating an HDL wrapper to the design. On the “Sources” tab viewed from the “Diagram” window, right-click on the “design_1” with “design_1.bd” attached (or something similar) and select “Create HDL wrapper.” Keep the option “Let Vivado manage wrapper and auto-update” selected.

The “AXI GPIO” pins need a constraint file to prevent possible damage to the board, without it the bitstream generation would return DRC errors. The “base” Overlay repository contains all the constraints for its diagram. Inside the constraints file (top.xdc), it is possible to find the lines corresponding to the LEDs and Switches. A new constraint file is created with those lines:

constraints_file

The new constraints file is imported at Vivado with “PROJECT MANAGER->Add Sources”.

To generate the Overlay files:

  • Select “Generate Bitstream”
  • “File->Export->Export Bitstream File…”
  • On Tcl Console -> “write_bd_tcl filename”

Both files should have the same name to be inter-referenced in the PYNQ environment.

led_sw_overlay

Before moving to the PYNQ board, its is necessary to check the address assigned to the placed IP inside the “Address Editor” tab:

led_address.png

Since the “AXI GPIO” block came within the Vivado package, there is not a straight forward file indicating the address to control the GPIO pins. For the reference, the “base” overlay repository contains drivers for those pins management. Inside the drivers files, there are addresses assigned to control the LEDs luminosity and read the Switch positions:

LEDs:

led_pynq

Switches:

switch_read

For some reason, the switch reads a value from a default address on the “_mmio.read()” function, “_mmio” is an object of the “MMIO” class.

With all files and information required, transfer the overlay data (‘.bit’ and ‘.tcl’) to the PYNQ board and open it on a browser to visualize the Jupyter notebooks.

The Overlay class is used to download the created files on the PYNQ Programmable Logic. MMIO class is used to facilitate the communication between Programmable Logic and the Processing System. The time class will be used further to relieve the processor.

from pynq import Overlay
from pynq import MMIO
from time import sleep

Indicate the path of the Overlay files and download it:

ol = Overlay("/home/xilinx/jupyter_notebooks/control_led_overlay/led_sw_overlay.bit")

ol.download()

Instantiate the “AXI GPIO” IP with its address and memory size:

led_sw_ip = MMIO(0x41200000,0x10000)

To write a value on the LEDs, indicate a single hexadecimal number. For example, “0xC” would turn first two LEDs on and last two LEDs off (C = 1100). Use the address found inside the “base” Overlay drivers.

led_sw_ip.write(0x8,0xC)

The line below will print a single number from 0 to 3 indicating both Switches position (00-01-10-11).

print(led_sw_ip.read())

To play with both peripherals at the same time, a program that light two LEDs accordingly to the Switches position is shown below:

while (cont<300):
write_led = "0x"+str(led_sw_ip.read())
write_led = int(write_led,16)
led_sw_ip.write(0x8,write_led)
sleep(1)
cont=cont+1

Source files can be found in:

https://github.com/YangTavares/PYNQ/tree/master/custom_overlays/control_led_overlay

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s