Skip to content

feat(vitis/aie): Vitis Unified AIE archetype + helpers + Sphinx docs#388

Open
ruck314 wants to merge 7 commits into
pre-releasefrom
dev/system-vitis-aie
Open

feat(vitis/aie): Vitis Unified AIE archetype + helpers + Sphinx docs#388
ruck314 wants to merge 7 commits into
pre-releasefrom
dev/system-vitis-aie

Conversation

@ruck314
Copy link
Copy Markdown
Contributor

@ruck314 ruck314 commented May 10, 2026

Summary

Adds a reusable Vitis AI Engine (AIE) build flow to ruckus. Downstream firmware projects can now compile, package, and deploy AIE graphs through a single standard Makefile include — eliminating the per-project, locally-vendored AIE makefiles that have been a maintenance burden.

Why it matters

  • Consistency: AIE projects now follow the same convention already in place for Vivado and HLS, so engineers move between flows without relearning.
  • Maintainability: One canonical implementation, owned by ruckus, replaces ad-hoc copies scattered across project repos.
  • Documentation: Full Sphinx how-to + reference shipped alongside the code.

Status

Hardware-validated end-to-end on a VEK280 board against the Simple-VEK280-Example AIE-loopback design. Ready for review.

@ruck314 ruck314 force-pushed the dev/system-vitis-aie branch from 36f00e4 to d7d35d4 Compare May 20, 2026 17:34
@ruck314 ruck314 changed the title feat: add system_vitis_aie.mk + BUILD_TIME ?= override feat: add system_vitis_aie.mk + vitis_aie/ helper dir May 20, 2026
@ruck314 ruck314 changed the title feat: add system_vitis_aie.mk + vitis_aie/ helper dir feat(vitis/aie): Vitis Unified AIE archetype + helpers + Sphinx docs May 20, 2026
Adds an end-to-end Vitis Unified AIE build archetype mirroring the
existing `system_vitis_unified_hls.mk` conventions, so downstream
firmware repos can drop locally-vendored AIE makefiles.

* `system_vitis_unified_aie.mk` — proj/build/x86sim/package/program/
  gui/interactive/test/clean targets driven by the Vitis 2025.1+
  Unified Python API. Self-contained: `make package` writes the
  dynamic PDI to `$(PROJ_DIR)/ip/$(PROJECT)_aie_dynamic.pdi`.
  - Caller contract: exactly one of AIE_PLATFORM (xpfm) or AIE_PART
    (Versal device ID); AIE_SOURCES (whitespace-separated file/dir
    paths, directories imported flat and non-recursive);
    AIE_TOP_LEVEL_FILE basename; AIE_XSA_INPUT (package only) and
    AIE_DTBO/AIE_BOARD_IP (program only) at recipe time.
  - aie_config.cfg location hardcoded at `$(PROJ_DIR)/aie_config.cfg`
    matching the unified HLS hls_config.cfg convention.
  - TOP_DIR defaults to `$(PWD)/../..` for the standard
    firmware/<category>/<name>/Makefile layout.

* vitis/aie/ helpers:
  - create_proj.py — Vitis Python API workspace + AIE component
    creation, idempotent.
  - build.py — hw target by default, --x86sim for the simulator.
  - package.sh — `v++ --package` primary, bootgen fallback when
    USE_BOOTGEN_FALLBACK=1.
  - program.sh — generic Versal/PetaLinux deploy (scp PDI+DTBO,
    reboot, verify fpga_manager state). Refuses *_static.pdi as a
    runtime overlay. Project-specific helpers override via
    AIE_PROGRAM_SCRIPT honoring the -p/-d/-i flag contract.

* Sphinx docs:
  - docs/how-to/vitis_aie.rst — walkthrough, prerequisites, project
    layout, steps, deploy-step customisation, troubleshooting.
  - docs/reference/makefile_reference.rst — Vitis AIE targets table
    and per-variable reference for every AIE_* knob.

* system_vitis_unified_hls.mk: add one-line comment clarifying that
  VIVADO_VERSION feeds BUILD_STRING in system_shared.mk; same shape
  as the comment in the new AIE Makefile fragment.

Hardware-validated against Simple-VEK280-Example AIE-loopback:
byte-identical *_aie_dynamic.pdi, end-to-end make build / package /
program cycle with /sys/class/fpga_manager/fpga0/state == operating
post-deploy.
@ruck314 ruck314 force-pushed the dev/system-vitis-aie branch from 3f5bc02 to 6a1d3fa Compare May 20, 2026 22:55
@ruck314 ruck314 requested a review from scompa18 May 20, 2026 23:07
@ruck314 ruck314 marked this pull request as ready for review May 20, 2026 23:07
ruck314 added 6 commits May 24, 2026 06:01
The parse-time `ifndef AIE_XSA_INPUT` guard fired on every make
invocation, breaking `make clean`, `make gui`, and other targets that
don't need the XSA. Move the check inside the `package` recipe,
mirroring the AIE_DTBO pattern used by `program`.
Vitis 2025.2 auto-attaches a default `aiecompiler.cfg` at AIE component
creation; AIE components reject a second cfg file ("Multiple cfg files
are not allowed"), so add_cfg_file() failed for the SLAC convention of
$(PROJ_DIR)/aie_config.cfg.

Query report() for any existing cfg files and remove them before adding
ours. Idempotent: pre-2025.2 behavior (no auto-cfg) is unaffected since
the loop iterates over an empty list.
…lude paths

Two related changes for the AMD-canonical kernels-subdir layout (graph.h
referencing `adf::source(loop) = "kernels/loopback.cc"`):

1. AIE_SOURCES gains an optional `:dest_subdir` suffix per entry. Without
   it, files import flat at the component root (existing behavior). With
   it, files import into <component>/<dest_subdir>/.
   e.g. AIE_SOURCES = $(CURDIR)/aie $(CURDIR)/aie/kernels:kernels

2. create_proj.py now synthesizes PROJ_DIR/aie_config.generated.cfg
   combining auto-derived `include=` directives (one per unique
   dest_subdir, plus the component root) with the user's aie_config.cfg
   contents. The generated cfg is what gets attached to the component;
   without these include directives, the aiecompiler can't resolve
   `adf::source("subdir/file.cc")` paths after Vitis 2025.2's default
   cfg gets stripped.

Backward compatible: AIE_SOURCES entries without `:dest_subdir` keep the
flat-import behavior, and projects without subdirs still get a working
generated cfg (just `include=../..` plus user content).
AMD policy: v++ --package only accepts accelerated/PFM-style platforms.
SLAC's standard Versal SoC firmware XSAs (axi-soc-versal-core) are
non-accelerated, so v++ --package always errors with [v++ 60-1606]
"is a non-accelerated platform". The bootgen escape hatch
(USE_BOOTGEN_FALLBACK=1) already existed for this case, but required
the caller to know about it.

Detect that specific rejection in the v++ log and transparently retry
via bootgen. Other v++ failures still surface as hard errors with the
USE_BOOTGEN_FALLBACK=1 hint. USE_BOOTGEN_FALLBACK=1 still skips v++
entirely as before.
…clean

Two cleanups so AIE archetype projects don't accumulate Vitis/Bootgen
clutter in the project root:

- create_proj.py: write the synthesized aie_config.generated.cfg under
  OUT_DIR (build/) instead of PROJ_DIR. It's a regenerable build
  artifact, not user-managed, so it belongs alongside the workspace.
  Reference path drops to `../aie_config.generated.cfg` (relative to
  the component dir).

- package.sh: cd into AIE_PKG_DIR before invoking v++/bootgen so their
  CWD-anchored strays (_x/, v++.package_summary, v++_package.log,
  xcd.log, .Xil/) land in build/aie_package/ instead of PROJ_DIR. Also
  pass --temp_dir/--log_dir/--report_dir explicitly so v++ never
  re-anchors them outside AIE_PKG_DIR even when run from elsewhere.

Net effect: PROJ_DIR keeps only the source tree (Makefile, aie/,
aie_config.cfg) plus build/ and ip/. All Vitis/Bootgen working
artifacts disappear into build/.
The previous commit started running v++/bootgen from AIE_PKG_DIR to
localize stray outputs, but that broke callers passing AIE_XSA_INPUT as
a relative path (e.g. ../../targets/<name>/images/<name>.xsa from the
AIE project dir). v++ resolves --platform against its own cwd, so a
relative AIE_XSA_INPUT failed with "platform is not found or is not
valid" — and that error doesn't match the non-accelerated-platform
auto-fallback regex, so the build hard-failed instead of falling back.

realpath the input once at script entry, before the cd. Absolute paths
pass through unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant