You can interrupt the Zynq ARM side with a signal coming out of the FPGA part of the chip. In this post, I test this.

The FPGA part has a few blocks that will generate interrupts. In a Jupyter notebook, I'll try to show that they are detected by the processors and OS.


In this article, I try out an approach discussed on the Pynq forum. It doesn't use VHDL or Verilog.

The interrupts are generated from 2 Xilinx Timer IP blocks.

But they could as well be generated from your own IP (E.g.: you could generate it from one of the pins of the Johnson Counter used in a previous post).


Block Design


image: block design. Green blocks generate interrupts in the fabric. Red blocks are helpers to collect and format to a signal that's understood by the ARM/Linux part.


The processing system, reset and interconnect blocks are wired up as usual.

The design uses 3 masters in the interconnect. Two are used as interface with the 2 timers. The 3rd master talks to the interrupt controller.

These blocks will be addressable from Linux - in this case a Jupyter notebook.


There are boundaries when doing this on a system that runs stock Linux images for the Pynq ecosystem.

I take these into account in this design.

In the version of Pynq that I'm using (2.6), there is a practical issue: the interrupt fires twice from FPGA before the Python code in the Jupyter notebook resets it. This makes that every other time the code returns immediately after priming the interrupt. It's acknowledged by Pynq designers (see my comment in the Pynq forum thread I linked at the start of this frame.


Two timers will generate interrupts. They are managed by an interrupt controller.


The processor system is configured to accept interrupts

Not shown, but input for the interrupt controller: processor clock is 650 MHz (fixed on my board), fabric clock 0 is set to 100 MHz (configured for this project..


In the remainder of this post, I will hide the clock and reset lines.

I've shown them in overview image at the top of this post. You can also see them if you download the attached Vivado project.

It helps to focus on the design specific functionality:

Here's the regenerated "simplified" layout compared to the block design with all signals shown:



Catching the interrupts in the ARM/Linux part


When the bitstream of this design is loaded in the Zynq, there should be interrupts arriving each time one of the timers fires one.

In the spirit of the Pynq ecosystem, a Jupyter notebook is used to make this visible.

The notebook will execute a loop, that will be interrupted when the trigger of timer 1 fires.


image: interrupt path through fabric



  • register and configure the timer
  • define an interrupt handler wait_for_timer1()
  • create an event loop and have it interrupted by the handler.


This is the exact code of the Pynq forum thread I referred to above.

The exercise is successful if the last block of the notebook doesn't spin indefinitely, but completes.

You can see that if the annotation in the front of the block changes from [*] to [a number].


Vivado project (2020.2) and Jupyter notebook attached.


Pynq - Zync - Vivado series
Add Pynq-Z2 board to Vivado
Learning Xilinx Zynq: port a Spartan 6 PWM example to Pynq
Learning Xilinx Zynq: use AXI with a VHDL example in Pynq
VHDL PWM generator with dead time: the design
Learning Xilinx Zynq: use AXI and MMIO with a VHDL example in Pynq
Learning Xilinx Zynq: port Rotary Decoder from Spartan 6 to Vivado and PYNQ
Learning Xilinx Zynq: FPGA based PWM generator with scroll wheel control
Learning Xilinx Zynq: use RAM design for Altera Cyclone on Vivado and PYNQ
Learning Xilinx Zynq: a Quadrature Oscillator - 2 implementations
Learning Xilinx Zynq: a Quadrature Oscillator - variable frequency
Learning Xilinx Zynq: Hardware Accelerated Software
Automate Repeatable Steps in Vivado
Learning Xilinx Zynq: Try to make my own Accelerated OpenCV Function - 1: Vitis HLS
Learning Xilinx Zynq: Try to make my own Accelerated OpenCV Function - 2: Vivado Block Design
Learning Xilinx Zynq: Logic Gates in Vivado
Learning Xilinx Zynq: Interrupt ARM from FPGA fabric
Learning Xilinx Zynq: reuse and combine components to build a multiplexer