跳转到主要内容

基于AMD VEK385的HDMI 2.1+VCU2参考设计实操

作者:Jack Lin,文章来源:安富利

随着视频系统从4K60逐步向8K、高帧率、高色深以及低延迟方向演进,传统“FPGA+外部视频处理芯片”的架构在系统复杂度、带宽、功耗和软件适配方面都会面临更高挑战。

AMD Versal Gen 2平台在PS、PL、NoC、DDR、GT、高速视频接口以及硬核视频处理单元方面做了更高集成度的设计。本文结合VEK385平台上的 HDMI 2.1+VCU2参考设计,介绍一下Versal Gen 2器件能力、VCU2架构、HDMI视频链路,以及参考设计的编译和运行。

1.Versal Gen 2器件简介

Versal Gen 2 Architecture

Versal Gen 2是AMD面向下一代嵌入式计算和视频处理场景的Adaptive SoC。和第一代Versal相比,Versal Gen 2在几个方面有明显增强:

首先是处理器性能更强。Gen 2 平台提供更高性能的APU和RPU,集成高达8核Arm Coretex A78和10核Arm Coretex R52,算力更强,适合运行更复杂的 Linux 应用、驱动框架和控制任务。

其次是AI Engine能力提升。AI Edge Gen 2 中的新一代AI Engine支持更高能效的AI推理,同时支持MX6、MX9等新数据类型,适合边缘AI、视觉识别和信号处理应用。

第三是视频处理能力更完整。Versal Gen 2 集成了硬核ISP和VCU,其中ISP可以用于图像信号处理,VCU/VCU2可以用于视频编解码。

第四是高速接口和存储能力更强。器件内部集成了高速PS接口,例如PCIe Gen5、10G Ethernet、USB 3.2、DisplayPort、UFS等;同时支持DDR5和LPDDR5X,并通过NoC实现各模块之间的高带宽数据访问。

2.VCU2 简介

VCU2 Architecture

VCU2是Versal Gen 2平台中的硬核视频编解码单元。VCU2支持H.264、H.265编码和解码,并且支持JPEG解码;色彩格式支持4:2:0、4:2:2、4:4:4以及Monochrome;色深支持8bit、10bit和 12bit。单VCU2 Tile支持4Kx2Kp60编码和 4Kx2Kp60解码,并且支持Frame Buffer Compression、多流以及硬化的编码缓存。

和Zynq UltraScale+MPSoC EV系列中的VCU相比,VCU2的变化主要体现在以下几个方面。

可以看到,VCU2的改进并不是单点增强,而是围绕高分辨率、高色深、高带宽和低延迟视频系统做了整体优化。特别是编码缓存硬化、Tile 格式、FBC 以及4:4:4 / 12bit支持,对于高质量视频处理链路非常关键。

VCU2 Software Architecture

从软件架构来看,VCU2并不是裸硬件直接暴露给应用层。典型软件路径可以理解为:GStreamer应用层-> OpenMAX -> VCU2 Control Software -> Kernel Driver -> VCU2 Hardware。

对于应用工程师来说,最常用的是GStreamer。它可以通过Pipeline的方式把视频输入、格式转换、编码、解码和显示串起来。VCU2 Control Software则负责更底层的帧级或Slice级控制,例如生成或解析NAL单元、向固件提交命令、获取每帧状态以及拼接码流等。

因此,在VEK385 HDMI + VCU2参考设计中,我们并不是直接操作VCU2寄存器,而是通过Linux驱动、V4L2、DRM/KMS、GStreamer等软件框架完成整个视频链路的调试。

VEK385 HDMI 2.1+VCU2参考设计简介

VEK385 HDMI 2.1+VCU2参考设计的目标,是在 VEK385 平台上跑通一条完整的视频输入、处理、编解码和输出链路。

HDMI Advanced Subsystem Design

参考设计的基本视频路径可以理解为:HDMI视频源 -> HDMI RX -> VPSS -> Frame Buffer -> DDR -> VCU2 编解码 -> Frame Buffer -> HDMI TX ->显示器。

HDMI RX接收到的视频并不是直接绕回HDMI TX,而是经过VPSS、Frame Buffer、DDR和VCU2编解码链路后,再通过HDMI TX输出。这个路径更接近真实视频应用,例如视频采集、格式转换、编码、解码、显示。

参考设计编译与运行流程

HDMI 2.1+VCU2参考设计整体编译与流程如下图:

参考设计编译与运行总体流程

主机端完成参考设计源码获取、Vivado硬件编译、EDF配置与bitbake镜像生成;同时基于SDT / PDI 制作hdmi_overlay.zip;板端启动Linux后,再通过dfx-mgr-client加载overlay,并使用media-ctl、modetest和GStreamer验证HDMI+VCU2链路。

准备参考设计源码

参考设计工程可以从Xilinx GitHub获取。Windows 环境可以直接下载ZIP包,Linux环境可以使用git clone。

git clone https://github.com/Xilinx/versal2-vek385-advss.git

下载完成解压缩后,进入hdmi参考设计文件夹,可见如下图的文件结构。

HDMI参考设计目录中包含hw、scripts、xdc、sw 和Makefile等目录或文件。其中hw用于Vivado硬件工程,scripts中包含主要Tcl脚本,xdc用于约束,sw用于EDF软件编译。

Vivado编译硬件设计

进入HDMI硬件工程目录,加载Vivado 2025.2环境变量后执行编译。

cd /home/vek385/vek385/workspace/hdmi/versal2-vek385-advss-2025.2/hdmi/hw
 source /opt/xilinx/2025.2/Vivado/settings64.sh
 make all

这一步会完成Vivado工程创建、综合、实现、比特流 / PDI相关生成,并生成后续EDF需要解析的硬件描述文件。

编译完成后,会在hw/runs/hdmi路径下生成hdmi.xsa文件。实操中需要重点确认Vivado版本和参考设计分支匹配,例如使用2025.2分支时建议配套Vivado 2025.2环境,以免版本不匹配造成的错误。

EDF编译Linux镜像

Vivado编译完成后,进入软件目录并加载EDF Yocto编译环境。

cd /home/vek385/vek385/workspace/hdmi/versal2-vek385-advss-2025.2/hdmi/sw
source /opt/yocto/edf_v25.11/edf-init-build-env

随后修改build/conf/local.conf,加入下载目录、sstate缓存、并行编译参数以及HDMI 2.1驱动模块。

DL_DIR = "/opt/yocto/downloads"
SSTATE_DIR = "/opt/yocto/sstate-cache"
PARALLEL_MAKE = "-j 32"
BB_NUMBER_THREADS = "32"
IMAGE_INSTALL:append = "kernel-module-hdmi21"
BB_NO_NETWORK = "1"

其中IMAGE_INSTALL:append="kernel-module-hdmi21"很关键,否则系统启动后可能缺少HDMI 2.1相关驱动模块。

接着使用gen-machineconf根据Vivado输出的 SDT / 硬件描述生成machine配置和设备树。

MACHINE=versal-2ve-2vm-vek385-revb-sdt-seg gen-machineconf parse-sdt \
--template /opt/yocto/edf_v25.11/sources/meta-amd-adaptive-socs/meta-amd-adaptive-socs-bsp/conf/machineyaml/versal-2ve-2vm-vek385-revb-sdt-seg.yaml \
--hw-description /home/vek385/vek385/workspace/hdmi/hw/hdmi_sdt \
--machine-name versal-2ve-2vm-vek385-revb-sdt-seg

这里的--hw-description路径需要根据前面Vivado / sdtgen实际输出目录调整。然后编译OSPI启动镜像和EDF Linux文件系统镜像。

MACHINE=versal-2ve-2vm-vek385-revb-sdt-seg bitbake edf-ospi
MACHINE=amd-cortexa78-mali-common bitbake edf-linux-disk-image

编译完成后,通常会得到edf-ospi-*.bin、BOOT-*.bin 和 edf-linux-disk-image-*.wic.xz等关键文件。其中 .wic.xz 可以用于烧录SD卡,BOOT.bin 或OSPI boot镜像用于启动。

烧录SD卡

SD卡镜像可以使用balenaEtcher等工具烧录。选择生成的.wic或.wic.xz镜像,写入16GB / 32GB Micro-SD卡即可。

烧录完成后,将SD卡插入VEK385。启动方式根据实际调试策略选择:如果使用OSPI默认镜像启动,需要确认板卡启动模式拨码设置;

制作二段加载文件

Versal Gen 2参考设计采用二段加载方式。系统先通过第一段PDI启动PS、DDR和基础NoC,Linux 启动后再加载PLD PDI和设备树overlay。

制作二段加载文件时,需要准备三个核心文件:pl.dtbo、XXX_pld.pdi和shell.json。其中 pl.dtbo来自修改后的pl.dtsi编译结果,XXX_pld.pdi来自Vivado / sdtgen输出目录,shell.json用于描述shell类型和slot信息。

需要在pl.dtsi中增加或修改HDMI相关节点,添加 ref40m fixed-clock、添加xv_fmc connector节点、修改hdmi_ss_axi_iic节点、修改 hdmi_gt_controller节点的clock-names和 clocks 引用,以及修改HDMI RX Subsystem的 max-bits-per-component属性。

然后使用dtc编译设备树overlay,完成编译后会在路径下生成pl.dtbo设备树文件。

dtc -I dts -O dtb -@ -o pl.dtbo pl.dtsi

创建overlay目录并放入pl.dtbo、第二段PDI和 shell.json。

mkdir hdmi_overlay
cp pl.dtbo hdmi_overlay/
cp XXX_pld.pdi hdmi_overlay/

shell.json的内容示例如下。

{
  "shell_type" : "XRT_FLAT",
  "num_slots" : "1"
}

最后压缩得到hdmi_overlay.zip。

zip -r hdmi_overlay.zip hdmi_overlay/

启动HDMI+VCU2功能

Linux启动后,将hdmi_overlay.zip放到板端指定位置,然后执行二段加载。

dfx-mgr-client -load hdmi_overlay

加载成功后,Linux系统中应该能够识别HDMI、Video、DRM/KMS、VCU2等相关设备节点。首先可以通过media-ctl查看视频输入拓扑。

media-ctl -p

然后配置VPSS输入输出格式。下面命令来自参考设计资料,实际使用时需要根据media-ctl -p打印出来的entity名称、分辨率和格式进行调整。

media-ctl -d /dev/media0 -V '"b0000000.v_proc_ss":0 [fmt:RBG888_1X24/3840x2160 field:none]'
media-ctl -d /dev/media0 -V '"b0000000.v_proc_ss":1 [fmt:VYYUYY8_1X24/3840x2160 field:none]'

接着使用modetest查看DRM/KMS输出设备,并设置HDMI TX输出模式,例如4K60。

modetest -D axi:drm-pl-disp-drvhdmi_ss_hdmi_tx_ss_v_hdmi_txss1

modetest -D axi:drm-pl-disp-drvhdmi_ss_hdmi_tx_ss_v_hdmi_txss1 \
-s 39@35:3840x2160-60@BG24

最后可以通过GStreamer完成HDMI输入、VCU2编码、VCU2解码和HDMI输出。

gst-launch-1.0 \
 v4l2src device=/dev/video0 io-mode=4 ! \
 video/x-raw, width=3840, height=2160, format=NV12, framerate=60/1 ! \
 omxh265enc qp-mode=auto gop-mode=basic gop-length=60 b-frames=0 \
 target-bitrate=60000 control-rate=constant prefetch-buffer=true low-bandwidth=false ! \
 video/x-h265, profile=main, alignment=au ! queue ! \
 omxh265dec internal-entropy-buffers=5 low-latency=0 ! queue max-size-bytes=0 ! \
 fpsdisplaysink name=fpssink text-overlay=false fps-update-interval=1000 \
 video-sink="kmssink driver-name=xlnx plane-id=33 show-preroll-frame=false" -v

这条命令的作用可以简单理解为:V4L2采集HDMI 输入 -> 指定原始视频格式 -> H.265 编码 -> H.265 解码 -> KMS显示输出。也就是用 GStreamer 把输入、编码、解码和显示串成一条完整的视频处理 Pipeline。

小结

VEK385 HDMI 2.1 + VCU2参考设计的价值,在于它不是一个单独的HDMI Demo,也不是一个单独的 VCU2 Demo,而是一套完整的视频系统参考链路。

从硬件上看,它覆盖了HDMI RX、GT、VPSS、Frame Buffer、NoC、DDR、VCU2 和 HDMI TX。从软件上看,它覆盖了EDF Linux、设备树 overlay、DFX二段加载、V4L2、DRM/KMS和 GStreamer。

从工程实操角度看,跑通这个设计后,开发者可以掌握Versal Gen 2视频系统的几个核心方法:如何完成HDMI 2.1输入输出链路搭建,如何通过NoC和 DDR组织视频帧数据,如何使用VCU2完成硬件编解码,如何通过Linux多媒体框架调试视频 Pipeline,以及如何使用二段加载方式加载PL功能和设备树overlay。

对于后续做视频采集、视频转码、边缘视频处理、高清显示、工业视觉或者低延迟视频传输系统的工程师来说,这个参考设计是一个非常有价值的起点。