The PYNQ Z2 is a wonderful device. At the moment I’m trying to get AXI DMA to work, however, and it does not really want to.
My setup:
Pynq Z2
Linux 4.14-xilinx-v2018.3
Vivado 2019.1
pynq v2.5
numpy 1.17.2
matplotlib 3.1.1
I’m trying to feed a memory stream through a data FIFO that I will later replace with a custom HLS block. For now, the block design looks like this:
Note the interrupt pins from the 2 DMA blocks, mm2s_introut
and s2mm_introut
being connected through a Concat block to the IRQ_F2P
port of the PS.
This leads to an error when trying to talk DMA with this block design:
Python code i’m running:
import numpy as np
import pynq
from pynq import Overlay, MMIO
from pynq.lib import DMA
import pynq.lib.dma
from pynq import allocate
ol = Overlay('./11-tochwel.bit')
dma_send = ol.axi_dma_ps_to_pl
dma_recv = ol.axi_dma_pl_to_ps
from pynq import Xlnk
data_size = 15
xlnk = Xlnk()
input_buffer = xlnk.cma_array(shape=(data_size,), dtype=np.uint32)
output_buffer = xlnk.cma_array(shape=(data_size,), dtype=np.uint32)
for i in range(data_size):
input_buffer[i] = i + 0xcafe0000
dma_send = DMA(ol.ip_dict['axi_dma_ps_to_pl'])
dma_recv = DMA(ol.ip_dict['axi_dma_pl_to_ps'])
dma_send.sendchannel.start()
dma_recv.recvchannel.start()
dma_send.sendchannel.transfer(input_buffer)
dma_recv.recvchannel.transfer(output_buffer)
# dma_send.sendchannel.wait()
# dma_recv.recvchannel.wait()
for i in range(10):
print(hex(output_buffer[i]))
The error:
<ipython-input-45-b53b94401f56> in <module>()
1 import pynq.lib.dma
2
----> 3 dma_send = ol.axi_dma_ps_to_pl
4 dma_recv = ol.axi_dma_pl_to_ps
/usr/local/lib/python3.6/dist-packages/pynq/overlay.py in __getattr__(self, key)
335 """
336 if self.is_loaded():
--> 337 return getattr(self._ip_map, key)
338 else:
339 raise RuntimeError("Overlay not currently loaded")
/usr/local/lib/python3.6/dist-packages/pynq/overlay.py in __getattr__(self, key)
735 elif key in self._description['ip']:
736 ipdescription = self._description['ip'][key]
--> 737 driver = ipdescription['driver'](ipdescription)
738 setattr(self, key, driver)
739 return driver
/usr/local/lib/python3.6/dist-packages/pynq/lib/dma.py in __init__(self, description, *args, **kwargs)
188 'has been deprecated and moved to '
189 'pynq.lib.deprecated')
--> 190 super().__init__(description=description)
191
192 if 'parameters' in description and \
/usr/local/lib/python3.6/dist-packages/pynq/overlay.py in __init__(self, description)
600 self._gpio = {}
601 for interrupt, details in self._interrupts.items():
--> 602 setattr(self, interrupt, Interrupt(details['fullpath']))
603 for gpio, entry in self._gpio.items():
604 gpio_number = GPIO.get_gpio_pin(entry['index'])
/usr/local/lib/python3.6/dist-packages/pynq/interrupt.py in __init__(self, pinname)
96 self.number = PL.interrupt_pins[pinname]['index']
97 self.parent = weakref.ref(
---> 98 _InterruptController.get_controller(parentname))
99 self.event = asyncio.Event()
100 self.waiting = False
/usr/local/lib/python3.6/dist-packages/pynq/interrupt.py in get_controller(name)
157 if con.name == name:
158 return con
--> 159 ret = _InterruptController(name)
160 _InterruptController._controllers.append(ret)
161 return ret
/usr/local/lib/python3.6/dist-packages/pynq/interrupt.py in __init__(self, name)
175 """
176 self.name = name
--> 177 self.mmio = MMIO(PL.ip_dict[name]['phys_addr'], 32)
178 self.wait_handles = [[] for _ in range(32)]
179 self.event_number = 0
KeyError: ''
This error does not occur if I remove the Concat block and leave the DMA introut ports disconnected, however then I always retrieve the value 0xdec0dee3
back from the DMA.
Is this a bug in the pynq library?