From 796887952d5f7a8283ca23b18119a13c2900f1e1 Mon Sep 17 00:00:00 2001 From: Jeremy Shen Date: Thu, 11 Jun 2026 16:49:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20use=20xsct=20'targets=20-name=20$t'=20?= =?UTF-8?q?=E2=80=94=20universally=20available=20across=202018=E2=80=93202?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'jtag targets' may not exist in all xsct versions (2018.3, etc.). Switch to 'targets -name $t' which works in every Xilinx SDK/Vitis version. Output format: DEVICE:xc7z100, DEVICE:ARM Cortex-A9 MPCore #0 Also broadened _ARM_DAP_RE to match both 'arm_dap' and 'ARM Cortex-A9' patterns for PS detection across different xsct versions. --- src/zynq_checker.py | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/zynq_checker.py b/src/zynq_checker.py index bb9b565..2ba4666 100644 --- a/src/zynq_checker.py +++ b/src/zynq_checker.py @@ -52,18 +52,14 @@ class ZynqCheckResult: error: str = "" # Error message if detection failed -# ── Patterns for parsing xsct "jtag targets" output ────────────────── -# Each line: " 1 xc7z100 (idcode 03736093 irlen 4)" -_JTAG_LINE_RE = re.compile( - r"^\s*(\d+)\s+(\S+)\s+\(idcode\s+([0-9A-Fa-f]+)\s+irlen\s+(\d+)\)", - re.IGNORECASE, -) +# ── Patterns for parsing xsct "targets" output ────────────────────── +# From "targets -name $t": bare device names like "xc7z100", "ARM Cortex-A9 MPCore #0" -# Zynq PL part: "xc7z100", "xc7z010", etc. +# Zynq PL device: "xc7z100", "xc7z010", "xc7z020", etc. _ZYNQ_DEVICE_RE = re.compile(r"^xc\d+z\d+[a-z]?\d+$", re.IGNORECASE) -# ARM DAP (PS side): "arm_dap" -_ARM_DAP_RE = re.compile(r"^arm_dap$", re.IGNORECASE) +# ARM DAP / PS indicators: "arm_dap", "ARM Cortex-A9 MPCore", "Cortex-A9", etc. +_ARM_DAP_RE = re.compile(r"(?:^arm_dap$|ARM\s+Cortex|Cortex-A\d)", re.IGNORECASE) # hw_server default port HW_SERVER_PORT = 3121 @@ -191,16 +187,17 @@ def check_zynq_jtag(config: Config, callback: Callable | None = None) -> ZynqChe def _build_jtag_query_tcl() -> str: """Build TCL script for xsct JTAG device query. - Uses 'jtag targets' (not 'targets') to get raw JTAG chain devices - with IDCODE, irlen — the same info that hw_server exposes. + Uses 'targets -name $id' to enumerate all hardware targets on the + JTAG chain. Compatible with Xilinx 2018.3–2023.2. Returns: - TCL script content as string (semicolon-delimited for -eval mode). + TCL script content (semicolon-delimited for -eval mode). """ return ( "connect; " 'puts "===JTAG_START==="; ' - "jtag targets; " + "set all [targets]; " + 'foreach t $all { puts "DEVICE:[targets -name $t]" }; ' 'puts "===JTAG_END==="; ' "disconnect; " "quit" @@ -208,17 +205,18 @@ def _build_jtag_query_tcl() -> str: def _parse_jtag_chain(output: str) -> list[JtagDevice]: - """Parse xsct 'jtag targets' output into JtagDevice list. + """Parse xsct 'targets -name' output into JtagDevice list. - Expected format (one line per JTAG device): - 1 xc7z100 (idcode 03736093 irlen 4) - 2 arm_dap (idcode 4BA00477 irlen 4) + Expected format (one DEVICE: line per target): + DEVICE:xc7z100 + DEVICE:ARM Cortex-A9 MPCore #0 + DEVICE:ARM Cortex-A9 MPCore #1 Args: output: Combined stdout/stderr from xsct. Returns: - List of JtagDevice objects for all devices on the JTAG chain. + List of JtagDevice objects for all targets on the JTAG chain. """ devices: list[JtagDevice] = [] section = _extract_section(output, "===JTAG_START===", "===JTAG_END===") @@ -229,12 +227,10 @@ def _parse_jtag_chain(output: str) -> list[JtagDevice]: line = line.strip() if not line: continue - match = _JTAG_LINE_RE.match(line) - if match: - _idx = match.group(1) - name = match.group(2) - idcode = match.group(3) - devices.append(_classify_jtag_device(name, idcode)) + if line.startswith("DEVICE:"): + name = line[len("DEVICE:"):].strip() + if name: + devices.append(_classify_jtag_device(name)) return devices