From d0b2aba28326b8dac38d1b1b11f4031123215fc9 Mon Sep 17 00:00:00 2001 From: josh goldsmith Date: Wed, 29 Jul 2026 12:08:28 +0100 Subject: [PATCH 1/2] fix(xsa_parser): support Versal PDI device images --- pynqutils/build_utils/xsa_parser.py | 60 +++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/pynqutils/build_utils/xsa_parser.py b/pynqutils/build_utils/xsa_parser.py index 406016f..1f4f83c 100644 --- a/pynqutils/build_utils/xsa_parser.py +++ b/pynqutils/build_utils/xsa_parser.py @@ -1,23 +1,14 @@ # Copyright (C) 2022 Xilinx, Inc # SPDX-License-Identifier: BSD-3-Clause -import atexit import json -import logging import os import shutil -import sys import tempfile import zipfile -from distutils.command.build import build as dist_build -from distutils.dir_util import copy_tree, mkpath, remove_tree -from distutils.file_util import copy_file -from typing import Dict, Union -from xml.dom.minidom import Element +from typing import Dict, Optional, Union from xml.etree import ElementTree -import pkg_resources - class XsaParsingCannotFindBlockDesignName(Exception): pass @@ -125,13 +116,21 @@ def __init__(self, path: str) -> None: @property def bitstreamPaths(self) -> tuple: """ - return a tuple of paths to extracted bitstreams defined in sysdef.xml - + Return a tuple of paths to extracted Zynq/ZU+ bitstreams (sysdef File Type=BIT). """ if self.is_pre_synth(): return None return self._Xsa__path([e.attrib["Name"] for e in self.__bitstreamElements()]) + @property + def deviceImagePaths(self) -> tuple: + """ + Return a tuple of paths to extracted Versal PDIs (sysdef File Type=PDI). + """ + if self.is_pre_synth(): + return None + return self._Xsa__path([e.attrib["Name"] for e in self.__deviceImageElements()]) + @property def defaultHwhPaths(self) -> tuple: """ @@ -201,17 +200,36 @@ def referenceBdcJsonPaths(self) -> None: ] return self._Xsa__path(bdc_hwhs) + def _primaryProgrammableImagePath(self) -> Optional[str]: + """ + Return the primary programmable device image path (BIT or PDI), or None. + """ + if self.is_pre_synth(): + return None + if self.bitstreamPaths: + return self.bitstreamPaths[0] + if self.deviceImagePaths: + return self.deviceImagePaths[0] + return None + def createNameMatchingDefaultHwh(self) -> None: """ - A temporary fix to rename the default bd to match the primary bitstream. - TODO: make it so that the whole XsaParser object is passed down into the + Copy the default BD HWH so its basename matches the primary programmable + device image (bitstream or PDI). + + PYNQ expects ``foo.hwh`` alongside ``foo.bit`` or ``foo.pdi`` when loading + an overlay. - Assumes that we have only one bitfile, need to test this with PR projects. + Assumes a single primary image; uses the first BIT or PDI in sysdef order. """ if self.is_pre_synth(): return None - expected_hwh = os.path.splitext(self.bitstreamPaths[0])[0] + ".hwh" + primary = self._primaryProgrammableImagePath() + if primary is None: + return None + + expected_hwh = os.path.splitext(primary)[0] + ".hwh" if expected_hwh not in self.defaultHwhPaths: shutil.copyfile(self.defaultHwhPaths[0], expected_hwh) @@ -278,3 +296,13 @@ def __bitstreamElements(self) -> list: if self.is_pre_synth(): return None return self._Xsa__sysdef.findall("File[@Type='BIT']") + + def __deviceImageElements(self) -> list: + """ + return a list of elements in sysdef representing Versal PDI device images + + sysdef tag=File attributes Type=PDI + """ + if self.is_pre_synth(): + return None + return self._Xsa__sysdef.findall("File[@Type='PDI']") From cd50c6a74d8b80028d646d634efb0de6c10ae33d Mon Sep 17 00:00:00 2001 From: josh goldsmith Date: Wed, 29 Jul 2026 12:08:28 +0100 Subject: [PATCH 2/2] bump version to 0.1.3 --- README.md | 2 +- pynqutils/version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 08513b0..881f49a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![pynq_logo](https://github.com/Xilinx/PYNQ/raw/master/logo.png) -### version 0.1.2 +### version 0.1.3 PYNQ-Utils is a repository containing utilities used in various other repos and projects across the PYNQ ecosystem. The tools are categorized into three sections: * ``/runtime`` for utilities that are used in the PYNQ runtime, such as ```ReprDict``` which is used to pretty print dictionaries in Jupyter. diff --git a/pynqutils/version.txt b/pynqutils/version.txt index d917d3e..b1e80bb 100644 --- a/pynqutils/version.txt +++ b/pynqutils/version.txt @@ -1 +1 @@ -0.1.2 +0.1.3