Hi all!
I am using a Pynq Z2 and I was attempting accelerating a FIR filter function as detailed in this tutorial: How to accelerate a Python function with PYNQ - FPGA Developer
I wish to implement an interpolating filter, which seems to increase the output data rate by a the zero-packing factor.
I have configured the IP as such to have a interpolation rate value of 4.
On the DMA configuration side, it seems like the output data width is correctly updated to match the higher data rate - the Stream Data width is 128-bit, 4 times of the input data width.
I also disabled the scatter-gather engine as the above tutorial mentioned that Pynq-Z2 does not support this option.
Subsequently, I created this top level block design including the Zynq PS:
I added a concat with a AXI interrupt controller to the DMA controller, as I read that “Interrupt” interferes with importing some underlying Pynq framwork (correct me if my implementation is wrong)
After generating bitstream, I call the hardware function as follows:
# Import the hardware overlay
from pynq import Overlay
import pynq.lib.dma
overlay = Overlay('/home/xilinx/pynq/overlays/fir_interpolation/fir_interpolation.bit')
dma = overlay.filter.fir_dma
sendstatus = dma.sendchannel.running
recvstatus = dma.recvchannel.running
print("DMA Channel status: Send: ", sendstatus, " Recv: ", recvstatus)
overlay?
The print statement returns the following, showing that initially, the DMA channel is running.
DMA Channel status: Send: True Recv: True
The result of the overlay?
is:
Type: Overlay
String form: <pynq.overlay.Overlay object at 0xac352a30>
File: /usr/local/lib/python3.6/dist-packages/pynq/overlay.py
Docstring:
Default documentation for overlay /home/xilinx/pynq/overlays/fir_interpolation/fir_interpolation.bit. The following
attributes are available on this overlay:
IP Blocks
----------
filter/fir_dma : pynq.lib.dma.DMA
axi_intc_0 : pynq.overlay.DefaultIP
Hierarchies
-----------
filter : pynq.overlay.DefaultHierarchy
Interrupts
----------
None
Oddly enough, the FIR_compiler IP does not appear in the overlay list, and interrupts are not reflected either.
I have included a .hwh
file in the same directory as the .bit
file imported above, with the same file name.
Subsequently, I execute the following:
# Test the overlay
from pynq import Xlnk
import numpy as np
# Allocate buffers for the input and output signals
xlnk = Xlnk() # create a Xlnk object, xlnk.
in_buffer = xlnk.cma_array(shape=len(x_in), dtype=np.int32)
out_buffer = xlnk.cma_array(shape=len(x_in*rate), dtype=np.int32)
# Copy the samples to the in_buffer
np.copyto(in_buffer, x_in)
# Trigger the DMA transfer and wait for the result
print("Sending")
dma.sendchannel.transfer(in_buffer)
print("Recieving")
dma.recvchannel.transfer(out_buffer)
print("Waiting for buffers to be idle")
dma.sendchannel.wait()
dma.recvchannel.wait()
print("Output:", out_buffer)
# Free the buffers!
in_buffer.close()
out_buffer.close()
However, this returns:
Sending
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-23-a63a2d2d630f> in <module>()
17 # Trigger the DMA transfer and wait for the result
18 print("Sending")
---> 19 dma.sendchannel.transfer(in_buffer)
20 print("Recieving")
21 dma.recvchannel.transfer(out_buffer)
/usr/local/lib/python3.6/dist-packages/pynq/lib/dma.py in transfer(self, array)
118 array.nbytes, self._size))
119 if not self.running:
--> 120 raise RuntimeError('DMA channel not started')
121 if not self.idle and not self._first_transfer:
122 raise RuntimeError('DMA channel not idle')
RuntimeError: DMA channel not started
This is a rather obscure warning error. What could be causing it?
Thanks in advance for the help and advice!