Hardware Application Development

Hardware Application Development

This is a getting started guide providing walk through style examples using the AMD Embedded Development Framework (EDF) covering initial board setup and running a pre-built disk image, hardware and software applications development using the pre-built image, and full custom hardware & software builds and image creation.

Table of Contents

Hardware Application Development

image-20250328-112619.png

Custom RTL or hardware design is a key part of the value of Adaptive SOC and FPGA devices.

This section shows to generate PL images (payloads) that are compatible with a base design such as the EDF pre-built disk images and OSPI boot images utilizing Segmented Configuration. See also https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/3250586143

These flows enable different payloads (PL or other) to be deployed to a board and then loaded or re-loaded from Linux at run time, speeding up development (by testing on a running system) and enabling dynamic payload management on deployed systems with Linux / U-boot as the system manager (for example version management, fallback, recovery).

 

This example is based on and compatible with the Embedded Common Platform CED design which is the Vivado design used to create the EDF BSP’s, the EDF pre-built OSPI firmware and EDF Linux Disk images.

PL design / payload content:

The PL IP example application has the below IPs:

  • AXI BRAM

  • AXI GPIO

    • GPIO0: x4 User LEDs 

    • GPIO1: x2 User push buttons

    • GPIO2: x4 User DIP switches

  • AXI TIMER

The block design is shown below, and can be viewed in Vivado after generation.

 

The steps to generate this compatible design are similar to the steps used when generating the base design, and use the XPR and XSA from the base design as inputs.

Block design image (VEK385):

Maintaining and checking compatibility of a generated PL firmware application (child design) with the base/parent Vivado project

Compatibility is enabled and verified through the Segmented Configuration workflows in Vivado, using some files created when the base / parent project was compiled.

NOC solution file (.ncr) from base project

The child project must include the golden NOC solution file from the base / parent project, this allows Vivado to implement a compatible NOC solution in the child project. The NOC solution file or NCR file (,ncr) is generated during compilation of the base / parent project and should be stored.

The NCR file for the embedded common platform CEDs used in EDF BSP hardware designs is stored as part of the CED, and can be found in the Vivado installation

NCR importing (example shown for VEK385)

set_property NOC_SOLUTION_FILE [file normalize <vivado installation>/data/xhub/ced/XilinxCEDStore/ced/Xilinx/IPI/Versal_gen2_platform/vek385_golden_ncr/vek385_*.ncr] [get_runs impl_1]

Post compile UID checks

The PDI Unique ID from the child design and PDI Unique ID from the base project / parent design (OSPI boot pdi) should be checked before loading the application.

Issue the below command on the cloned repo to check whether the PL PDI matches with boot.pdi which is part of the OSPI boot image.

PL Design Unique ID

$ make checkpdi PDI_UNIQUE_ID:0xe2261acc GOLDEN_UNIQUE_ID:0xe2261acc UNIQUE ID MATCHED The above check only compares the vivado base ced boot.pdi UNIQUE ID with child design boot.pdi UNIQUE ID. Read the unique id of boot.pdi which is packed as part boot.bin/ospi.bin using the attached script. If above PDI_UNIQUE_ID and below boot.bin/ospi.bin UNIQUE ID should match then only you can use boot.bin/ospi with child design firmware

 

For boot.bin $ ./get_uniqueid.sh <downloaded artifacts>/versal-2ve-2vm-vek385-sdt-seg_xilinx-bootbin/boot.bin boot.bin Specified Boot.bin Reading BIN file from offset: 0x0 *** Unique ID of BANK offset 0x0 is 0xe2261acc For ospi.bin $ ./get_uniqueid.sh <downloaded artifacts>/versal-2ve-2vm-vek385-sdt-seg_edf-ospi/edf-ospi-versal-2ve-2vm-vek385-sdt-seg.bin Reading BIN file from offset: 0x1580000 *** Unique ID of BANK offset 0x1580000 is 0xe2261acc Reading BIN file from offset: 0x87C0000 *** Unique ID of BANK offset 0x87C0000 is 0xe2261acc

DCP file check with pr_verify

We have segmented based parent and child designs. During design generation, the NoC routing will be captured in dcp files. We need to ensure that the routing should be same across parent and child design.

We need to run pr_verify using dcp files as in the example below using the sample Tcl file

cat pr_verify.tcl

pr_verify -initial <path to dcp from parent design/vek385_base.runs/impl_1/versal_gen2_platform_wrapper_routed.dcp> -additional <path to child design dcp/vek385_bram_gpio_timer.runs/impl_1/versal_gen2_platform_wrapper_routed.dcp >

The above pr_verify.tcl should be run in Vivado batch mode as shown below 

<vivado installation>/settings.sh vivado  % vivado -mode batch -s pr_verify.tcl

 

Building a compatible PL design payload and creating a Firmware Bundle (Device Tree Overlay)

Refer to Hardware Design Repo Overview for cloning the hardware design repo and for setting up the AMD tools.

This example can be built using the following make commands which build the design artifacts for the BRAM/GPIO/TIMER example design, which is compatible with EDF pre-built disk image and base design for the board. (VEK385 is shown, update paths for your evaluation board). The makefile uses Tcl (main.tcl and gen_sdt.tcl) scripts as a part of make steps to build the design and generate the output files

$ git clone https://github.com/Xilinx/amd-yocto-hw-platforms.git -b xlnx_rel_v2025.2 #example for the v2025.2 version. Use latest available which matches EDF version $ cd amd-yocto-hw-platforms/eval_board_examples/vek385_bram_gpio_timer $ make all JOBS=8(default JOBs will be 1 to speed up setting it to 8) $ make gen_overlay

The generated directories will be created

  • Vivado project directory hw_project - The folder contains the XPR project file which can be used to open and edit the project in Vivado

  • SDT directory hw_project_sdt - The SDT directory is needed to generate the firmware bundle 

  • Firmware directory <designname>-fw (VEK385 example vek385_bram_gpio_timer-fw)  - The firmware directory contains the pld PDI, the matching device tree overlay binary (dtbo), and a metadata json file

The generated firmware directory will include:

  • shell.json - This metadata file is consumed by dfx-mgr

  • pl.dtbo - The device tree overlay binary describes the devices in the incremental hardware design. It is used by Linux to load the corresponding device drivers

  • <design name>_pld.pdi (VEK385 example - vek385_bram_gpio_timer_pld.pdi) - The pld PDI is the incremental PL payload that gets loaded from Linux on top of the boot PDI

Example output (from VEK385 design)-

$ tree -L 1 vek385_bram_gpio_timer-fw/ vek385_bram_gpio_timer-fw/ ├── pl.dtbo ├── pl.dtsi ├── shell.json ├── system-top.dts.pp └── vek385_bram_gpio_timer_pld.pdi

 

Custom Designs- Manual Flows for building the compatible PL design payload and creating a Firmware Bundle (Device Tree Overlay)

All steps contained in the Makefile be done manually through the Vivado GUI and command line utilities.

Create the Compatible PL design in the GUI.

  1. Open the parent / base Vivado project in the Vivado GUI

    1. Follow the steps in https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/3258188188 then open the design in the Vivado GUI

  2. Create a new PL payload by modifying or extending the default PL payload - Add or modify IP blocks in the block design add custom logic etc.

The PS and NOC settings should not be edited, this may break compatibility with the pre-built boot.pdi and / or the pre-built EDF images which are based on the EDF specifications.

  • If PS settings are edited this moves into a full-custom flow, requiring re-generation of the EDF Linux image and update of the boot.pdi

  1. Save the updated design

  2. Ensure the NCR file has been added to the project. See https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/3258090078/Hardware+Application+Development#NOC-solution-file-(.ncr)-from-base-project )

  3. Generate output products and the XSA.

  4. Validate the compatibility of the project by following relevant sections. See - https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/3258090078/Hardware+Application+Development#Post-compile-UID-checks and https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/3258090078/Hardware+Application+Development#DCP-file-check-with-pr_verify

Create the SDTgen design artifacts (hand off information)

Note: make sdt can be used build the SDTgen design artifacts from the XSA.

$ source <path to Vivado Install>/Vivado/settings64.sh $ sdtgen sdtgen% set_dt_param -debug enable sdtgen% set_dt_param -zocl enable sdtgen% set_dt_param -dir ./hw_project_sdt sdtgen% set_dt_param -xsa ./<xsa_name>.xsa sdtgen% set_dt_param -board_dts versal2-vek385-revA sdtgen% generate_sdt

Create the firmware bundle to enable dfx-mgr-client to manage multiple PL Payloads and configure the PL from Linux

  • Firmware bundle - a directory containing device tree overlay (.dtbo), PL payload (.pdi) and .json file (dfx-mgr-client configuration file)

Note: make gen_overlay can be used build the firmware bundle from the SDTGen artifacts

  1. Create a directory to contain the files in the firmware bundle, and copy in the source *_pld.pdi file

$ mkdir -p <project name>-fw $ cp ./hw_project_sdt/<project name>_pld.pdi <project name>-fw
  1. Create a shell.json file in the firmware bundle directory (<project name>-fw) with the following content :

{ "shell_type" : "XRT_FLAT", "num_slots": "1" }
  1. Use Lopper to create the Linux Device Tree from the System Device Tree

$ source <path to Vivado Install>/Vivado/settings64.sh $ lopper --enhanced -O <project name>-fw -f ./hw_project_sdt/system-top.dts -- xlnx_overlay_dt cortexa78_0 full
  1. Use Device Tree Compiler to create the device tree overlay (.dtbo)

$ source <path to Vivado Install>/Vivado/settings64.sh $ dtc -I dts -O dtb -o <project name>-fw/pl.dtbo <project name>-fw/pl.dtsi

You now have a firmware bundle (directory) that can be transferred to the running system for use.

Deploying the PL firmware application onto target

The firmware files can be copied to the /lib/firmware/xilinx directory on the running system for immediate use - using SCP, TFTP or a similar network tool, or via direct copy to the SDCARD. See GitHub - Xilinx/dfx-mgr for more information on dfx-manager.

Optionally the firmware bundle could be packaged and included as part of the Yocto image build by writing a Yocto recipe - https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/3258090263/Application+Deployment+using+Yocto+Recipes+AMD+Versal+device+portfolio#Firmware-Bundle

Listing and loading the firmware package (vek385 example):

versal2-common:/home/edf# scp -r <user>@<host/ ip address>:<path to firmware directory>/versal2-vek385-pl-bram-gpio-timer-fw /lib/firmware/xilinx/. # sudo dfx-mgr-client -listPackage Accelerator Accel_type Base Pid Base_type #slots(RPU+PL+AIE) slot->handle vek385-pl-bram-gpio-fw XRT_FLAT vek385-pl-bram-gpio-fw id_ok XRT_FLAT (0+0+0) -1 versal2-vek385-pl-bram-gpio-timer-fw XRT_FLATversal2-vek385-pl-bram-gpio-timer-fw id_ok XRT_FLAT (0+0+0) -1 versal2-common:/home/edf# sudo dfx-mgr-client -load versal2-vek385-pl-bram-gpio-timer-fw versal2-vek385-pl-bram-gpio-timer-fw: Loaded with slot_handle 0 versal2-common:/home/edf# sudo dfx-mgr-client -listPackage Accelerator Accel_type Base Pid Base_type #slots(RPU+PL+AIE) slot->handle vek385-pl-bram-gpio-fw XRT_FLAT vek385-pl-bram-gpio-fw id_ok XRT_FLAT (0+0+0) -1 versal2-vek385-pl-bram-gpio-timer-fw XRT_FLATversal2-vek385-pl-bram-gpio-timer-fw id_ok XRT_FLAT (0+0+0) 0->0,

Running the pl axi _timer example after deploying pl firmware

$ START_TIME=$SECONDS $ sleep 60 $ echo $((SECONDS - START_TIME)) - should give approximately 60

Related Links

 

Trademarks

Yocto Project and all related marks and logos are trademarks of The Linux Foundation. This website is not, in any way, endorsed by the Yocto Project or The Linux Foundation.

Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.

© 2025 Advanced Micro Devices, Inc. Privacy Policy