Continuing on from the first workshop in the series, this Element 14 workshop session

PYNQ-Z2 Workshop: Getting Up and Running with PYNQ (Win a $500 Gift Card for Your Embedded Vision Project!)

builds upon what was previously learnt about working with the PYNQ framework on the Tul Corporation PYNQ-Z2 development board.


The lab exercise this time was to create a custom PYNQ overlay using Xilinx Vivado and then to use it in a PYNQ project running in Jupyter Notebooks on the PYNQ-Z2 development board.


The design borrowed existing code from another PYNQ overlay and used high level synthesis to create new IP blocks which could then be combined with existing IP blocks distributed with Vivado in order to create an embedded vision project.


Some may suggest that the goal of the PYNQ framework is supposed to avoid the need to use the likes of Vivado FPGA design tools and to allow the design engineer to work from within the Python language, however that assumes the designer always has access to an appropriate PYNQ overlay which contains all the necessary FPGA design to match the project requirements. Sooner or later this will likely not be the case and as such having at least an overview of the overlay design process can still increase design productivity.


I found myself in this situation recently where I had been following along with a tutorial which was exploring the use of memory-mapped AXI GPIO on the PYNQ-Z2 development board. The PYNQ overlay being used included design elements for the push buttons, switches, and LEDs but not for the two RGB LEDs. The supplied block diagram confirmed this to be the case:


block diagram showing AXI GPIO to buttons, switches and LEDs

(original design from Xilinx PYNQ Workshop Session 4  )


With my knowledge gained from the recent PYNQ-Z2 Embedded Vision Workshop, this turned out not to be a significant problem, as I decided to have a go at creating my own version of the overlay but with the additional AXI GPIO block for the RGB LEDs added and then to access it via memory-mapped registers using the PYNQ framework.


The resulting design in Vivado looked like this:


block diagram showing AXI GPIO for buttons, switches, LEDs and RGB LEDs

(enhanced design with additional AXI GPIO for the RGB LEDs added and routed to the on-board RGB LEDs)


Creating the design from scratch in Vivado turned out to be really easy, with most of the 'wiring' being done via automation. I required to adjust a few settings as I wanted to try and keep the routing and addresses the same as the previous design which I was trying to enhance. However validation of the block diagram passed without problem, the HDL wrapper was created, and the bitstream generated.


But one question still remained, would it actually work ?


Copying the overlay files over to the PYNQ-Z2 using the SMB network share allowed for work to continue in Jupyter Notebooks...


First we need to download the newly created overlay into the FPGA fabric:


Then we check that the address locations programmatically match what was assigned within the Vivado design:


screenshot of addresses from Vivado

It is looking good so far. The 'rgbleds' at address 0x41230000 is the newly added feature.


Now to import the MMIO class and create instances for each of the GPIO devices:


Remember to configure the tri-state registers at offset 0x4 to set the direction to input or output:


Finally try turning the LEDs and RGB LEDs on and reading the buttons and switches:


Everything works. Success !

The new overlay both replicates the functionality of the original overlay, plus it now adds access to the RGB LEDs.