VEK280 Programmable Logic Video Decoder Unit Demo
This page describes an AMD EDF demo for the VEK280 evaluation board. The demo uses dynamically loaded programmable logic firmware together with a containerized VDU application flow on top of the EDF Linux BSP.
Overview
The demo combines two pieces that ship through the
meta-amd-edf-demos Yocto layer:
A container application that bundles the VDU components and applications (
vdu-ctrlsw,vdu-firmware,libvdu-omxil, andkernel-module-vdu). The container also includesdfx-mgr-clientsupport so that it can drive PL firmware that the host loads dynamically.A PL firmware recipe that packages the VDU PL design for the VEK280. The recipe uses the
dfx_user_dtsmechanism so thatdfx-mgrcan discover and load the firmware at runtime through the AMD Dynamic Function eXchange (DFX) manager.
Together, these pieces show how EDF can run a containerized validation application on top of a dynamically loaded PL design on the VEK280.
The recipes referenced by this page (vek280-pl-vdu-fw
and container-app-vek280-vdu) live in the
meta-amd-edf-demos layer; see References
for the upstream recipe URLs.
Demo Components
The following table summarizes the two recipes that make up the demo and the role each one plays.
Recipe |
Type |
Purpose |
|---|---|---|
|
PL firmware |
Packages the VDU PL design for VEK280 and
installs it under |
|
Container application |
Builds a container image that bundles
|
Programmable Logic Firmware Recipe
The PL firmware recipe vek280-pl-vdu-fw provides the
VEK280 VDU PL design as a loadable firmware package.
The recipe inherits dfx_user_dts, which:
compiles the recipe-supplied
pl.dtsiinto an overlay.dtbo;installs the bitstream and the overlay under
/lib/firmware/xilinx/<package-name>/; andregisters the package with
dfx-mgrso thatdfx-mgr-client -listPackageenumerates it on the target.
The recipe is compatible with the VEK280 EDF target machine.
The firmware package contains the required PL artifacts for
dynamically loading the VDU design through the AMD dfx-mgr.
For background on the dfx_user_dts flow and how it fits into
the EDF segmented build, refer to:
Container Application Recipe
The container application recipe
container-app-vek280-vdu builds a container image
on top of the base container image flow. The container rootfs includes:
vdu-ctrlsw– standalone command-line executable for enc.vdu-firmware– firmware package loaded onto the VDU hard block.kernel-module-vdu– contains the source code of al5r drivers.libvdu-omxil– contains the AllegroDVT OpenMax Integration Layer (OMXIL) implementation.dfx-mgr-client– so the container can list and load PL firmware packages that the host’sdfx-mgrexposes.
For the general container application packaging pattern, refer to the Application Deployment page.
Building the Demo
BitBake builds the container application from a Yocto build environment. The
environment must include the meta-amd-edf-demos layer and
target the VEK280 machine. The firmware is included through CONTAINER_APP.
Clone meta-amd-edf-demos layer:
$ cd ../sources $ git clone https://github.com/AMD-AECG-SSW-PUBLIC/meta-amd-edf-demos.git
Add meta-amd-edf-demos layer
$ cd build/ $ bitbake-layers add-layer ../sources/meta-amd-edf-demos/
Build the container application:
$ MACHINE=amd-cortexa72-common bitbake container-app-vek280-vdu
The generated container rootfs tarball is available under:
${TMPDIR}/deploy/images/amd-cortexa72-common/....
Alternatively, copy the generated container rootfs tarball
to the running target.
Manually Adding Reserved Memory Nodes
To manually add the reserved memory nodes:
Remove the existing CMA reserved nodes, CMA reserved symbols, and phandles from the DTS.
Obtain
cortexa72-linux.dtbfrom the soc-prebuilt-firmware repository and convert it to DTS:$ dtc -I dtb -O dts -o cortexa72-linux.dts cortexa72-linux.dtb
Remove the following nodes from cortexa72-linux.dts:
cma_reserved@50000000000 { phandle = <0x18e>; label = "cma_reserved_50000000000"; compatible = "shared-dma-pool"; reusable; linux,cma-default; reg = <0x500 0x00 0x00 0xc0000000>; }; cma_reserved@60000000000 { phandle = <0x18f>; label = "cma_reserved_60000000000"; compatible = "shared-dma-pool"; reusable; linux,cma-default; reg = <0x600 0x00 0x00 0xc0000000>; };
cma_reserved_50000000000 = "/reserved-memory/cma_reserved@50000000000"; cma_reserved_60000000000 = "/reserved-memory/cma_reserved@60000000000";
From APU_Linux node remove the cma_reserved phandle address.
reserved-memory = <0x18e 0x18f 0x190 0x191 0x192 0x193>;
Add the VDU reserved memory nodes in the cortexa72-linux.dts.
mem_reg_0: myddr1@50000000000 { compatible = "shared-dma-pool"; no-map; reg = <0x500 0x00 0x00 0x80000000>; phandle = <0x555>; }; mem_reg_1: myddr2@50080000000 { compatible = "shared-dma-pool"; no-map; reg = <0x500 0x80000000 0x00 0x80000000>; phandle = <0x556>; }; mem_reg_2: myddr3@60000000000 { compatible = "shared-dma-pool"; no-map; reg = <0x600 0x00 0x00 0x80000000>; phandle = <0x557>; }; mem_reg_3: myddr4@60080000000 { compatible = "shared-dma-pool"; no-map; reg = <0x600 0x80000000 0x00 0x80000000>; phandle = <0x558>; };
Convert the dts back to dtb and regenerate
boot.bin. Use the updatedboot.binwith the WIC image.$ dtc -@ -I dts -O dtb -o cortexa72-linux.dtb cortexa72-linux.dts
Source the Vivado settings script from your local installation, replacing
2026.1with the version directory of your Vivado installation:$ source /opt/Xilinx/Vivado/2026.1/settings64.sh $ bootgen -arch versal -image bootgen.bif -w -o bg.bin
Copy
bg.bininto the bootable partition of the EDF WIC image and boot the board with the updated image.$ wic cp bg.bin <edf-image>.rootfs.wic:1
Running the Demo on the Target
The following steps assume the VEK280 has booted an EDF image
with dfx-mgr and a container runtime (for example docker
or podman) installed. The steps also assume that the
preceding container image is present on the target.
Extract and Import the Container Image
List the available PL firmware packages:
$ sudo dfx-mgr-client -listPackage
Extract the generated rootfs tarball:
$ bunzip2 container-app-vek280-vdu-amd-cortexa72-common-rootfs-<date>.tar.bz2
Import the container image into Docker:
$ sudo docker import \ container-app-vek280-vdu-amd-cortexa72-common-rootfs-<date>.tar
List the available container images:
$ sudo docker images
Create Docker Volume and Run the Application from the Container Image
Create Firmware directory
$ sudo mkdir -p /lib/firmware/xilinx/vek280-pl-vdu-fw
Create a Docker volume that bind-mounts the firmware directory.
$ sudo docker volume create --name producer_consumer \ --driver local --opt type=none --opt o=bind \ --opt device=/lib/firmware/xilinx/vek280-pl-vdu-fw
Verify the created volume:
$ sudo docker volume ls
Run the container with the firmware volume and dfx-mgr socket mounted.
$ sudo docker run -it \ --privileged \ -v /dev:/dev \ -v producer_consumer:/lib/firmware/xilinx/vek280-pl-vdu-fw \ -v /var/run/dfx-mgrd.socket:/var/run/dfx-mgrd.socket \ <image-id> bash
Note
If you need the reserved memory nodes, update the
mem_regreferences in the AL5D nodes inside the device tree overlay before running the container. See Manually Adding Reserved Memory Nodes for the complete procedure.Exit the container bash terminal:
$ exit
Change to the firmware directory on the host:
$ cd /lib/firmware/xilinx/vek280-pl-vdu-fw
Convert the device tree overlay blob to source:
$ dtc -I dtb -O dts -o temp.dtso vek280-pl-vdu-fw.dtbo
Update memory-region references in the AL5D nodes inside temp.dtso to match the new reserved memory nodes from cortexa72-linux.dts. For each AL5D node, set the
memory-regionproperty to the phandle of the corresponding reserved memory node:al5d0: al5d@a4020000 { al,devicename = "allegroDecodeIP0"; reg = <0x0 0xa4020000 0x0 0x100000>; interrupt-names = "vdu_host_interrupt0"; xlnx,vdu = <&vdu_vdu_0>; compatible = "al,al5d"; interrupt-parent = <&gic>; interrupts = <0x0 0x54 0x4>; memory-region = <0x555>; }; al5d1: al5d@a4120000 { al,devicename = "allegroDecodeIP1"; reg = <0x0 0xa4120000 0x0 0x100000>; interrupt-names = "vdu_host_interrupt1"; xlnx,vdu = <&vdu_vdu_0>; compatible = "al,al5d"; interrupt-parent = <&gic>; interrupts = <0x0 0x55 0x4>; memory-region = <0x556>; }; al5d2: al5d@a4220000 { al,devicename = "allegroDecodeIP2"; reg = <0x0 0xa4220000 0x0 0x100000>; interrupt-names = "vdu_host_interrupt2"; xlnx,vdu = <&vdu_vdu_0>; compatible = "al,al5d"; interrupt-parent = <&gic>; interrupts = <0x0 0x56 0x4>; memory-region = <0x557>; }; al5d3: al5d@a4320000 { al,devicename = "allegroDecodeIP3"; reg = <0x0 0xa4320000 0x0 0x100000>; interrupt-names = "vdu_host_interrupt3"; xlnx,vdu = <&vdu_vdu_0>; compatible = "al,al5d"; interrupt-parent = <&gic>; interrupts = <0x0 0x57 0x4>; memory-region = <0x558>; };
Convert the updated source back to dtbo:
$ dtc -I dts -O dtb -o vek280-pl-vdu-fw.dtbo temp.dtso
Remove the temporary dts file:
$ rm -rf temp.dtso
Run the docker container again (as in the previous step) and continue with the following steps.
From inside the container, load the VDU firmware package:
$ dfx-mgr-client -loadByName vek280-pl-vdu-fw
Verify that the firmware package is loaded successfully by re-running
dfx-mgr-client -listPackage.Run the VDU application from inside the container.
$ ctrlsw_decoder -avc -i AIR_1080p30_nv12.avc --noyuv
The container communicates with the host dfx-mgr daemon through the mounted socket and dynamically loads the VDU programmable logic design at runtime.
Unloading the Programmable Logic Firmware
When the demo finishes, unload the firmware from the host:
$ sudo dfx-mgr-client -unloadByName vek280-pl-vdu-fw