# DPU-PYNQ custom ZU+ board porting

**URL:** <https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584>\
**Category:** Support\
**Created:** [August 24, 2022, 2:10pm UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584 "2022-08-24T14:10:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![MarioMihaly](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/mariomihaly/32/3501_2.png) [@MarioMihaly](https://discuss.pynq.io/u/MarioMihaly)\
**Post date:** [August 24, 2022, 2:10pm UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584/1 "2022-08-24T14:10:19Z")

</div>

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](https://github.com/Xilinx/DPU-PYNQ/tree/master/boards) 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](https://discuss.pynq.io/t/how-to-run-dpu-examples-custom-platform/3856) 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**

```python
---------------------------------------------------------------------------
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**

```python
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

```

---

<div class="post-metadata">

**Author:** ![haipnh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/haipnh/32/4439_2.png) [@haipnh](https://discuss.pynq.io/u/haipnh)\
**Post date:** [August 25, 2022, 4:30am UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584/2 "2022-08-25T04:30:46Z")

</div>

Hi,

What is the output after running `pip3 install /home/xilinx/DPU-PYNQ --no-build-isolation` ?

---

<div class="post-metadata">

**Author:** ![MarioMihaly](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/mariomihaly/32/3501_2.png) [@MarioMihaly](https://discuss.pynq.io/u/MarioMihaly)\
**Post date:** [August 25, 2022, 8:53am UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584/3 "2022-08-25T08:53:44Z")

</div>

> [@haipnh](#):
>
> `pip3 install /home/xilinx/DPU-PYNQ --no-build-isolation`

Hi @haipnh,

Thank you for your question. When running `pip3 install /home/xilinx/DPU-PYNQ --no-build-isolation` on a `clean PYNQ 2.7.0 image` the output is:

```pip3
root@pynq:/# pip3 install /home/xilinx/DPU-PYNQ --no-build-isolation
Processing /home/xilinx/DPU-PYNQ
  DEPRECATION: A future pip version will change local packages to be built in-place without first copying to a temporary directory. We recommend you use --use-feature=in-tree-build to test your packages with this new behavior before it becomes the default.
   pip 21.3 will remove support for this functionality. You can find discussion regarding this at https://github.com/pypa/pip/issues/7555.
    Preparing wheel metadata ... done
Collecting mnist
  Downloading mnist-0.2.2-py2.py3-none-any.whl (3.5 kB)
Requirement already satisfied: pybind11 in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq-dpu==1.4.0) (2.8.0)
Requirement already satisfied: CppHeaderParser in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq-dpu==1.4.0) (2.7.4)
Requirement already satisfied: pynq>=2.7.0 in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq-dpu==1.4.0) (2.7.0)
Requirement already satisfied: numpy in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq>=2.7.0->pynq-dpu==1.4.0) (1.20.3)
Requirement already satisfied: pandas in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq>=2.7.0->pynq-dpu==1.4.0) (1.3.3)
Requirement already satisfied: setuptools>=24.2.0 in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq>=2.7.0->pynq-dpu==1.4.0) (44.0.0)
Requirement already satisfied: cffi in /usr/local/share/pynq-venv/lib/python3.8/site-packages (from pynq>=2.7.0->pynq-dpu==1.4.0) (1.14.5)
Requirement already satisfied: pycparser in /usr/lib/python3/dist-packages (from cffi->pynq>=2.7.0->pynq-dpu==1.4.0) (2.19)
Requirement already satisfied: ply in /usr/lib/python3/dist-packages (from CppHeaderParser->pynq-dpu==1.4.0) (3.11)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/lib/python3/dist-packages (from pandas->pynq>=2.7.0->pynq-dpu==1.4.0) (2.7.3)
Requirement already satisfied: pytz>=2017.3 in /usr/lib/python3/dist-packages (from pandas->pynq>=2.7.0->pynq-dpu==1.4.0) (2019.3)
Building wheels for collected packages: pynq-dpu
  Building wheel for pynq-dpu (PEP 517) ... done
  Created wheel for pynq-dpu: filename=pynq_dpu-1.4.0-cp38-cp38-linux_aarch64.whlsize=1262038 sha256=683171942348c94a2b34f4da23035cd1457e96805a9722781de65e8c26596295
  Stored in directory: /root/.cache/pip/wheels/43/7b/cc/83d68b760e5e159fd5c698d8e6828a62de84dc1d7d8194560a
Successfully built pynq-dpu
Installing collected packages: mnist, pynq-dpu
Successfully installed mnist-0.2.2 pynq-dpu-1.4.0
WARNING: You are using pip version 21.2.1; however, version 22.2.2 is available.
You should consider upgrading via the '/usr/local/share/pynq-venv/bin/python3 -m pip install --upgrade pip' command.

```

I am not sure it is relevant, on the first boot of a clean image I am usually not able to access the `Jupyter Notebooks` server even though I get a response when running `ping <ip address>` on my `Windows 10 Pro` host machine. When I reboot the board I can access the server no problem.

---

<div class="post-metadata">

**Author:** ![MarioMihaly](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/mariomihaly/32/3501_2.png) [@MarioMihaly](https://discuss.pynq.io/u/MarioMihaly)\
**Post date:** [August 25, 2022, 1:37pm UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584/4 "2022-08-25T13:37:02Z")

</div>

**UPDATE**

I repeated the same steps as I described above with the main difference that I had a colleague standing next to me as I repeated the steps. This time I was able to run the example notebooks without a problem using the `.xmodel` files provided for the `ZCU104` board.

* * *

I don’t think any of the following factors should have made a difference, but I thought I would include them for reference.

- The custom board was unplugged overnight which may have reset it completely. It is a board in development, but it is in a stable state so I don’t think this should matter.
- Instead of running the `pynq get-notebooks pynq-dpu -p .` command to fetch the notebooks I manually copyed them in the right location through `Samba`, the file sharing service running on the board.

* * *

I would be still interested in knowing what could have caused the errors as I spent way too much time trying to resolve them and it got personal. 😃

Thank you, Mario

---

<div class="post-metadata">

**Author:** ![cathalmccabe](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/cathalmccabe/32/3348_2.png) [@cathalmccabe](https://discuss.pynq.io/u/cathalmccabe)\
**Post date:** [August 25, 2022, 4:03pm UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584/5 "2022-08-25T16:03:31Z")

</div>

Good that you resovled this, and thanks for posting back to report this.

At a guess the bit file may not have been copied properly initially:  
`test_path = '/home/xilinx/pynq/overlays/dpu/dpu.bit'`

You do not get a file not found, but when the file was parsed, the contents were not what the parser expects. Perhaps copying the files again resolved this.

CAthal

---

<div class="post-metadata">

**Author:** ![MarioMihaly](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/mariomihaly/32/3501_2.png) [@MarioMihaly](https://discuss.pynq.io/u/MarioMihaly)\
**Post date:** [August 26, 2022, 11:33am UTC](https://discuss.pynq.io/t/dpu-pynq-custom-zu-board-porting/4584/6 "2022-08-26T11:33:49Z")

</div>

Hi Cathal,

Thank you, that would make sense, although I used the same procedure for copying in both cases (same `bash` script). I got the `RuntimeError` with the default call to `'dpu.bit'` and the `ParseError` to the absolute path (`test_path`) call.

I will try to reproduce the error and come back if I find the source of it, but I don’t think there will be much to find other than a faulty copy operation.

Thank you, Mario
