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.
Update 1: See the comments below. There is a solution. Update 2: the solution works, and I have amended this post. |
Two timers will generate interrupts. They are managed by an interrupt controller.
The purple rectangle shows the solution to an issue I had when I initially wrote this post.
The interrupt would fire twice, interfering with every other time a Pynq function was using it.
See: https://discuss.pynq.io/t/zynq-ps7-interrupts/198/10
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..
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
Steps:
- 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 |
PYNQ version 2.7 (Austin) is released |
PYNQ and Zynq: the Vitis HLS Accelerator with DMA training - Part 1: Turn C++ code into an FPGA IP |
PYNQ and Zynq: the Vitis HLS Accelerator with DMA training - Part 2: Add the Accelerated IP to a Vivado design |
PYNQ and Zynq: the Vitis HLS Accelerator with DMA training - Part 3: Use the Hardware Accelerated Code in Software |
PYNQ and Zynq: the Vitis HLS Accelerator with DMA training - Deep Dive: the data streams between Accelerator IP and ARM processors |
Use the ZYNQ XADC with DMA part 1: bare metal |
Use the ZYNQ XADC with DMA part 2: get and show samples in PYNQ |
VHDL: Convert a Fixed Module into a Generic Module for Reuse |