From 6bbfe540e74305d455a73da4959042c07e716cdb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Feb 2025 11:26:28 +0100 Subject: [PATCH] add 2 helper scripts --- .gitignore | 1 + scripts/xsct-init.tcl | 77 ++++++++++++++++++++++++ scripts/zynq7000-ps-pl-init.py | 103 +++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 scripts/xsct-init.tcl create mode 100755 scripts/zynq7000-ps-pl-init.py diff --git a/.gitignore b/.gitignore index 7f153fc..91b46fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /app.map +/xsct-output.log diff --git a/scripts/xsct-init.tcl b/scripts/xsct-init.tcl new file mode 100644 index 0000000..cda4d5e --- /dev/null +++ b/scripts/xsct-init.tcl @@ -0,0 +1,77 @@ +if {[info exists env(IP_ADDRESS_HW_SERVER)]} { + set ip $env(IP_ADDRESS_HW_SERVER) +} else { + set ip "localhost" +} +puts "Hardware server IP address: $ip" +connect -url tcp:$ip:3121 + +set devices [targets] + +set apu_line [string trim [targets -nocase -filter {name =~ "APU"}]] +set arm_core_0_line [string trim [targets -nocase -filter {name =~ "ARM Cortex-A9 MPCore #0"}]] +set fpga_line [string trim [targets -nocase -filter {name =~ "xc7z020"}]] + +set apu_device_num [string index $apu_line 0] +set arm_core_0_num [string index $arm_core_0_line 0] +set fpga_device_num [string index $fpga_line 0] + +puts "Select ps target with number: $apu_device_num" + +# Select the target +target $apu_device_num + +# Resetting the target involved problems when an image is stored on the flash. +# It has turned out that it is not essential to reset the system before loading +# the software components into the device. +puts "Reset target" +# Reset the target +rst + +if {![file exists $env(BITSTREAM)]} { + error "The bitstream file '$env(BITSTREAM)' does not exist" + exit 0 +} + +if {![file exists $env(PS_INIT_SCRIPT)]} { + puts "The ps init tcl script '$env(PS_INIT_SCRIPT)' does not exist" + exit 0 +} + +# Check if BITSTREAM is set and the file exists before programming FPGA +if {[info exists env(BITSTREAM)] && [file exists $env(BITSTREAM)]} { + puts "Set FPGA target with number: $fpga_device_num" + target $fpga_device_num + + # Without this delay, the FPGA programming will fail + after 1500 + + puts "Program bitstream $env(BITSTREAM)" + # Program FPGA + fpga -f $env(BITSTREAM) +} else { + puts "Skipping bitstream programming (BITSTREAM is not set or file does not exist)" +} + +puts "Set ps target with device number: $arm_core_0_num" +targets $arm_core_0_num + +puts "Initialize processing system" +# Init processing system +source $env(PS_INIT_SCRIPT) + +ps7_init +ps7_post_config + +if {![file exists $env(APP)]} { + puts "The app '$env(APP)' does not exist" + exit 0 +} + +puts "Set arm core 0 target with number: $arm_core_0_num" +target $arm_core_0_num + +puts "Download app $env(APP) to target" +dow $env(APP) + +puts "Successful" diff --git a/scripts/zynq7000-ps-pl-init.py b/scripts/zynq7000-ps-pl-init.py new file mode 100755 index 0000000..726601d --- /dev/null +++ b/scripts/zynq7000-ps-pl-init.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +import argparse +import os +import subprocess +import sys +from pathlib import Path + +# Define the default values +TCL_SCRIPT_NAME = "xsct-init.tcl" +SCRIPTS_DIR = "scripts" +DEFAULT_IP_ADDRESS_HW_SERVER = "localhost" + + +def main(): + parser = argparse.ArgumentParser( + description="Script to launch xsct, initialize and prepare the processing system for debugging " + "and load an a bare-metal application to the board" + ) + parser.add_argument( + "-t", + "--tools", + # Required only if env var is not set + required=not bool(os.getenv("VIVADO_TOOLS")), + # Use env var if set + default=os.getenv("VIVADO_TOOLS"), + help="The path to the tool to use. Must point to a valid Vivado tools installation which" + "also provides xsct, for example a Vitis installation. The directory where the path " + " points to should contain a shell script named settings64.sh", + ) + parser.add_argument( + "--itcl", + dest="init_tcl", + required=True, + help="Path to the ps7 initialization TCL file to prepare the processing system.", + ) + parser.add_argument( + "-a", "--app", required=True, dest="app", help="Path to the app to program" + ) + parser.add_argument( + "-i", + "--ip", + default=DEFAULT_IP_ADDRESS_HW_SERVER, + help="The IP address of the hardware server (default: localhost)", + ) + parser.add_argument( + "-b", + "--bit", + dest="bit", + help="Optional path to the bitstream which will also be programed to the device.", + ) + + args = parser.parse_args() + + settings_script = os.path.join(args.tools, "settings64.sh") + + if not os.path.isfile(settings_script): + print(f"Invalid tool path {args.tools}, did not find settings file.") + sys.exit(1) + + # Source the settings script and check for xsdb availability + command = f"source {settings_script} && command -v xsct" + result = subprocess.run( + command, + shell=True, + capture_output=True, + executable="/bin/bash", + ) + + if result.returncode != 0: + print("Error: 'xsct' could not be found after sourcing settings64.sh.") + sys.exit(1) + + if not os.path.isfile(args.app): + print(f"The app '{args.app}' does not exist") + sys.exit(1) + + # Export environment variables + os.environ["APP"] = args.app + os.environ["IP_ADDRESS_HW_SERVER"] = args.ip + if args.bit: + os.environ["BITSTREAM"] = args.bit + os.environ["PS_INIT_SCRIPT"] = args.init_tcl + + xsct_script = Path(TCL_SCRIPT_NAME) + + if not xsct_script.exists(): + xsct_script = Path(os.path.join(SCRIPTS_DIR, TCL_SCRIPT_NAME)) + if not xsct_script.exists(): + print(f"Could not find the xsct initialization script {TCL_SCRIPT_NAME}") + sys.exit(1) + + # Launch xsct with the initialization script + + command = f"bash -c 'source {settings_script} && xsct {xsct_script} | tee xsct-output.log'" + subprocess.run( + command, + shell=True, + check=True, + ) + + +if __name__ == "__main__": + main()