Hello Everybody,
I am fairly new to Xilinx tools and PYNQ and I am working on porting DPU-PYNQ 1.4.0
to a custom board with a ZU+ XCZU11EG series
SoC FPGA.
PYNQ image build for the custom board
I managed to build the PYNQ 2.7.0
image for the custom board using an Ubuntu 18.04.6
VM set up with a modified version of the Vagrant file provided in the git repo to give it more space. I used Xilinx 2020.2
tools and applied the Y2k22_patch
and built the image from a BSP
for the board.
The board boots up and I am able to access the Jupyter Notebooks
server, no problem there.
DPU-PYNQ test build for ZCU104
Before attempting the porting to the custom board, I rebuilt the DPU-PYNQ hardware for a ZCU104 board
following this tutorial on the VM used for the PYNQ image build. Since DPU-PYNQ requires Vitis 2021.1
I modified the Make files to work with my Vitis 2020.2.
The test build for the ZCU104 worked fine and I was able to deploy it by copying the DPU-PYNQ folder from the VM to /home/xilinx/DPU-PYNQ
and running pip3 install /home/xilinx/DPU-PYNQ --no-build-isolation
in a terminal opened in the Jupyter Notebook server
. I fetched the notebooks by executing
cd $PYNQ_JUPYTER_NOTEBOOKS
pynq get-notebooks pynq-dpu -p .
The examples ran just fine on the ZCU104.
Porting to the custom board
Following this post about How to run DPU examples custom platform I created the necessary files for the custom board using the commits on the Github repo
linked under the post. I added my board’s name to the supported boards and I added the configuration options based on the board name to the Make files. For the files I used the exact same ones as in the git repo.
I ran the make BOARD=<board>
command with my custom board which finished without a problem. In the git repo
there were 2 bash scripts
that I used to copy the necessary files from the host to the target device (deploy2board.sh
) and to move the .bit
, .hwh
, .tcl
and .xclbin
files to the correct folder for the dpu.py
file (deploy.sh
) on the target device after running pip3 install /home/xilinx/DPU-PYNQ --no-build-isolation
in a terminal opened in the Jupyter Notebook server
as before.
As in the post mentioned above, the pynq get-notebooks pynq-dpu -p .
command didn’t work for me either on the custom board so I copied the notebooks
folder from /usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq_dpu
to $PYNQ_JUPYTER_NOTEBOOKS
and renamed it to dpu-pynq
.
Running the examples
I tried running the dpu_resnet50.ipynb
notebook which failed with a RuntimeError: Invalid length found
(details of the error below). I tried moving the files for the dpu overlay
to the default location of Overlays in PYNQ and calling DpuOverlay('/home/xilinx/pynq/overlays/dpu/dpu.bit')
instead which produced the ParseError
. The same errors occur for the other notebooks as well.
Does anyone have an idea what could be the cause of these errors?
I would have expected the same errors for both instances. I suspect that there is an issue with the dpu.bit
file generated for the custom board. I edited the source code for embedded_device.py
to get the mismatched values and I found length = 23580908, offset = 117, len(contents) = 16777216
on ln 92
in embedded_device.py
before the RuntimeError
is triggered.
I am thinking that the dpu.bit
file is not valid due to incorrect configuration of the DPU
(?). However, I don’t know how to identify any configuration issues (I thought any configuration issue would break the build in the first place).
Any help would be highly appreciated on the matter.
Thank you, Mario
Details of the RuntimeError
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-10-7434525267f0> in <module>
1 from pynq_dpu import DpuOverlay
2 test_path = '/home/xilinx/pynq/overlays/dpu/dpu.bit'
----> 3 overlay = DpuOverlay("dpu.bit")
4 # overlay = DpuOverlay(test_path)
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq_dpu/dpu.py in __init__(self, bitfile_name, dtbo, download, ignore_version, device)
90 else:
91 raise FileNotFoundError('Cannot find {}.'.format(bitfile_name))
---> 92 super().__init__(abs_bitfile_name,
93 dtbo=dtbo,
94 download=download,
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/overlay.py in __init__(self, bitfile_name, dtbo, download, ignore_version, device)
338 self._register_drivers()
339
--> 340 self.parser = self.device.get_bitfile_metadata(self.bitfile_name)
341
342 self.ip_dict = self.gpio_dict = self.interrupt_controllers = \
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py in get_bitfile_metadata(self, bitfile_name)
602
603 def get_bitfile_metadata(self, bitfile_name):
--> 604 parser = _get_bitstream_handler(bitfile_name).get_parser()
605 if parser is None:
606 raise RuntimeError("Unable to find metadata for bitstream")
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py in get_parser(self)
197 else:
198 return None
--> 199 parser.bin_data = self.get_bin_data()
200 parser.xclbin_data = xclbin_data
201 parser.dtbo_data = self.get_dtbo_data()
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py in get_bin_data(self)
206 def get_bin_data(self):
207 bit_data = self._filepath.read_bytes()
--> 208 return bit2bin(bit_data)
209
210
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py in bit2bin(bit_data)
102
103 """
--> 104 bit_dict = parse_bit_header(bit_data)
105 bit_buffer = np.frombuffer(bit_dict['data'], 'i4')
106 bin_buffer = bit_buffer.byteswap()
/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py in parse_bit_header(bit_data)
91 bit_dict['length'] = str(length)
92 if length + offset != len(contents):
---> 93 raise RuntimeError("Invalid length found")
94 bit_dict['data'] = contents[offset:offset + length]
95 else:
RuntimeError: Invalid length found
Details of the ParseError
Traceback (most recent call last):
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3441, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-1-fbf35c2459f5>", line 4, in <module>
overlay = DpuOverlay(test_path)
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq_dpu/dpu.py", line 92, in __init__
super().__init__(abs_bitfile_name,
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/overlay.py", line 340, in __init__
self.parser = self.device.get_bitfile_metadata(self.bitfile_name)
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py", line 605, in get_bitfile_metadata
parser = _get_bitstream_handler(bitfile_name).get_parser()
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/embedded_device.py", line 194, in get_parser
xclbin_parser = XclBin(xclbin_data=xclbin_data)
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/xclbin_parser.py", line 371, in __init__
_xclbin_to_dicts(filename, xclbin_data)
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/xclbin_parser.py", line 282, in _xclbin_to_dicts
ip_dict = _xclxml_to_ip_dict(
File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/pl_server/xclbin_parser.py", line 56, in _xclxml_to_ip_dict
xml = ElementTree.fromstring(raw_xml)
File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 1321, in XML
return parser.close()
File "<string>", line unknown
ParseError: no element found: line 1, column 0