基于AMD EDF 2025.2的KV260自定义PL开发全流程实战

📅 2026/8/20 5:20:56
基于AMD EDF 2025.2的KV260自定义PL开发全流程实战
1. 项目缘起为什么要在KV260上折腾自定义逻辑最近几年边缘计算和嵌入式视觉的火热让Xilinx现在是AMD的一部分的Kria系列SOMSystem-on-Module成了不少开发者的心头好。KV260视觉AI入门套件以其相对亲民的价格和开箱即用的丰富接口HDMI、摄像头、DP等成为了入门边缘AI和硬件加速的一个绝佳平台。官方提供了不少预构建的应用镜像比如智能相机、缺陷检测等直接刷进去就能跑对只想验证算法或快速原型的朋友来说非常友好。但如果你和我一样是个“手痒”的硬件工程师或者FPGA爱好者看着板子上那颗Zynq UltraScale MPSoC心里总会琢磨预构建的镜像固然方便但它底层到底是怎么跑的我能不能把自己设计的那个图像预处理加速器、或者自定义的通信协议IP核放进去和ARM处理器协同工作这个从“用户”到“创造者”的跨越才是玩转KV260乃至整个可编程逻辑世界的精髓所在。然而当你真正打开Vivado准备为KV260创建一个新工程时可能会有点懵。官方的Kria SOM板卡支持包BSP和设计流程与传统的Zynq开发板比如ZCU102有些不同它更强调通过PetaLinux和Vitis统一软件平台进行系统级构建。特别是随着AMD EDFEmbedded Design Flow的演进在2025.2这样的新版本下如何从头开始搭建一个包含自定义PLProgrammable Logic设计的KV260工程并最终生成可以启动的镜像成了一个需要梳理清楚的关键步骤。网上能找到的教程要么是基于老版本的Vivado/Vitis要么是直接使用官方预置的加速应用框架对于“从零开始创建自定义PL设计”这个具体场景步骤分散坑点不少。所以我决定结合最近在AMD EDF v2025.2环境下的实战把这个过程完整地记录下来。这不仅仅是点几下鼠标的教程更是一次对Kria平台设计理念和现代嵌入式开发流程的深度探索。你会发现理解了这套流程你不仅能搞定KV260对于AMD其他的自适应计算平台思路也是相通的。2. 环境准备与工具链选型为什么是Vitis 2025.2工欲善其事必先利其器。在开始设计之前我们必须把“厨房”准备好。对于KV260开发AMD官方推荐的是一套完整的工具链而不是孤立的Vivado。2.1 核心工具Vitis Unified IDE 2025.2首先请放弃单独安装Vivado 2025.2的想法。对于Kria SOM这类平台AMD强力推进的是Vitis统一软件平台。Vitis 2025.2是一个集大成者的IDE它内部已经包含了对应版本的Vivado、Vitis HLS、Vitis Analyzer以及PetaLinux所需的核心组件。这种一体化的设计旨在提供从硬件设计、软件驱动到应用开发的无缝体验。注意直接从AMD官网下载时请选择“Vitis Unified Software Platform 2025.2”的安装包而不是单独的“Vivado Design Suite”。安装过程中确保勾选“Kria SOMs”或“Embedded Development”相关的设备支持包。安装路径尽量避免中文和空格这能避免后续很多潜在的脚本错误。选择2025.2版本不仅因为它是最新稳定版之一带来了性能改进和Bug修复更重要的是它对Kria KV260/K26 SOM的支持最为成熟和完整。早期版本可能在设备树生成、启动流程上存在一些需要手动修补的地方而新版本通常将这些流程集成得更好。2.2 关键组件Kria SOM板卡支持包BSP这是连接你的自定义逻辑与KV260物理板卡的桥梁。BSPBoard Support Package包含了该板卡的硬件描述文件XSA、预配置的硬件平台、以及基础的软件启动组件如FSBL、PMUFW等。如何获取通常有两种方式通过Vitis安装器在线安装在安装Vitis 2025.2时在设备选择页面明确勾选“Kria K26 SOM”或“KV260 Carrier Card”的支持。这是最推荐的方式能确保版本匹配。从AMD官网独立下载前往AMD官网的Kria页面找到对应版本的BSP归档文件通常是一个.bsp或.xsa文件然后通过Vitis的“Import Hardware Platform”功能导入。我强烈推荐第一种方式省心省力。BSP的重要性在于它定义了KV260核心板上的DDR内存接口、时钟网络、MIO/EMIO分配、电源管理等关键硬件资源。你的自定义PL设计必须基于这个已知的、正确的硬件起点来扩展否则很可能无法启动或者无法与PSProcessing System即ARM处理器部分正确通信。2.3 操作系统与依赖Linux是首选虽然Vitis/Vivado也有Windows版本但在嵌入式Linux开发领域Linux宿主机的体验通常更顺畅。原因如下PetaLinux工具链原生基于Linux编译设备树、Linux内核、根文件系统等操作在Linux环境下是天然而高效的。Shell脚本兼容性AMD的很多自动化脚本如生成BOOT.BIN的bootgen、镜像打包脚本都是为bash环境编写的在Windows的WSL或Cygwin下有时会遇到路径或权限的玄学问题。驱动与调试使用JTAG或串口调试时Linux下的驱动配置往往更简单。我个人使用的是Ubuntu 22.04 LTS这是一个经过广泛验证的稳定版本。确保你的系统有足够的磁盘空间建议预留100GB以上因为Vitis全家桶加上编译中间文件体积相当可观。安装完成后别忘了在终端里运行一下Vitis的初始化脚本例如source /opt/Xilinx/Vitis/2025.2/settings64.sh具体路径根据你的安装位置调整。这个操作将必要的工具路径添加到你的环境变量中。3. 创建你的第一个硬件平台从BSP到自定义IP有了趁手的工具我们就可以开始“搭积木”了。第一步是创建一个包含PSARM处理器基础配置和PL你的自定义逻辑接口的硬件平台。3.1 在Vitis中创建硬件平台工程启动Vitis Unified IDE选择一个干净的工作空间目录。点击 “Create Platform Project”。给平台起个名字比如kv260_custom_platform。在“Hardware Specification”步骤选择“Create from a board support package (BSP)”。这是关键在接下来的对话框中你应该能看到“kv260”或“k26”相关的BSP选项。选择它。点击Finish。Vitis会自动基于BSP创建一个硬件平台工程。这个工程本质上是一个包含.xsa硬件描述文件的容器。此时在平台工程的hardware目录下你会找到一个.xsa文件。这个文件是BSP提供的“静态”硬件描述它描述了KV260 SOM上PS部分的默认配置时钟、DDR、外设等。我们的目标是修改并扩展这个配置加入PL部分。3.2 启动Vivado进行硬件定制在Vitis的“Explorer”视图中右键点击你的平台工程选择“Open Hardware Platform in Vivado”。这个操作会启动内嵌的Vivado 2025.2并加载BSP提供的初始Block Design。现在你看到的就是KV260 PS系统的IP集成器IPI视图。这里通常已经配置好了Zynq UltraScale MPSoC IP核连接好了DDR4控制器、时钟、复位以及一些基本的MIO外设。我们的核心任务有两个为PL部分启用时钟和复位在Zynq MPSoC IP的配置中找到“Clock Configuration” - “PL Fabric Clocks”。这里你可以使能一到多个PL时钟例如FCLK0并设置其频率比如100MHz或150MHz。同时在“PS-PL Configuration” - “General”中确保“PL Reset”被使能。这些时钟和复位信号是PL逻辑运行的“水电煤”。创建与PL通信的接口最常用的是AXI接口。例如如果你希望ARM处理器PS能通过内存映射的方式读写PL内的寄存器或存储器就需要添加一个AXI互联AXI InterconnectIP并将其主端口Slave AXI连接到Zynq MPSoC IP的“M_AXI_HPM0_FPD”或类似的AXI主端口上。这样PS端的Linux驱动或裸机程序就能通过访问特定内存地址来操控PL。实操心得对于初学者建议从最简单的“LED控制”或“按钮读取”开始。你可以使用AXI GPIO IP核。在Block Design中添加一个AXI GPIO IP通过AXI Interconnect连接到Zynq MPSoC然后将GPIO的外部引脚gpio_io_o或gpio_io_i引出到顶层端口。在顶层约束文件XDC中将这些端口分配到KV260载板上的实际用户LED或按钮对应的FPGA引脚上。这是一个完整的“PS控制PL外设”的最小闭环能帮你快速验证整个硬件链路。3.3 添加并连接自定义IP核如果你想加入自己设计的逻辑比如一个图像缩放模块你有两种选择使用Vitis HLS或Vivado HLS将C/C代码综合成IP核设计完成后导出为.xoVitis内核或.xciVivado IP文件然后在当前Vivado工程中“Add IP”搜索并添加该IP。直接使用Verilog/VHDL编写RTL模块并打包成IP在Vivado中创建并验证你的RTL模块然后使用“Tools” - “Create and Package IP”向导将其封装成一个可复用的IP核再添加到当前Block Design中。添加自定义IP后你需要将其时钟、复位端口连接到PL的时钟和复位网络。如果需要与PS通信为其添加AXI-Lite或AXI4从接口并连接到AXI Interconnect上。将模块的其他功能信号如图像数据流axis接口引出到顶层或连接到其他IP。完成所有连接后一个常见的错误是地址映射冲突或未分配。你必须运行“Validate Design”F6来检查连接完整性。然后最关键的一步是点击“Address Editor”标签页为所有连接到PS的从设备如你的自定义IP、AXI GPIO等分配唯一的地址空间。Vivado通常可以自动分配但务必检查这些地址是否合理是否与PS端软件驱动预期的地址匹配。3.4 生成硬件输出产品设计验证无误后进行以下操作在“Sources”窗口右键点击你的Block Design例如design_1.bd选择“Generate Output Products”。这个过程会综合你的Block Design生成网表、约束等文件。然后再次右键点击该Block Design选择“Create HDL Wrapper”。让Vivado自动创建顶层的Verilog/VHDL封装文件。最后在左侧Flow Navigator中运行“Generate Bitstream”。这一步会执行综合、实现和比特流生成。对于复杂的PL设计这可能需要一段时间。比特流生成成功后我们还需要导出硬件平台供后续的软件开发使用。 4. 在Vivado菜单栏选择 “File” - “Export” - “Export Hardware”。在对话框中务必勾选“Include bitstream”。选择导出路径通常就放在平台工程目录下点击OK。这将生成一个包含了比特流信息的.xsa文件。至此你的自定义硬件平台就准备好了。这个.xsa文件描述了包含PS基础配置和你的PL设计的完整硬件系统。关闭Vivado回到Vitis IDE你会发现平台工程已经更新。4. 构建支持自定义硬件的软件系统PetaLinux的配置与编译硬件.xsa只是躯壳软件Linux系统才是灵魂。接下来我们需要构建一个能识别并驱动我们PL设计的嵌入式Linux系统。4.1 在Vitis中创建PetaLinux工程Vitis 2025.2已经深度集成了PetaLinux的创建和管理功能。在Vitis中切换到“Platform”视图。右键点击你之前创建的kv260_custom_platform选择“Create PetaLinux Project”或类似选项不同版本菜单名可能略有差异。指定PetaLinux工程的名称和位置。Vitis会自动调用PetaLinux工具并基于你硬件平台.xsa的信息初始化一个PetaLinux工程配置。这个自动初始化的过程非常关键它会根据硬件中的Zynq MPSoC配置生成对应的设备树源文件.dtsi其中包含了CPU、内存、时钟、以及你通过AXI接口连接到PS的所有外设如我们之前添加的AXI GPIO的地址信息。配置Linux内核使能对应的驱动例如xilinx_gpio驱动。4.2 深度定制PetaLinux配置自动生成的配置是基础我们通常需要进一步定制。这需要通过PetaLinux的命令行环境进行。打开终端导航到你的PetaLinux工程目录。运行source 你的PetaLinux安装路径/settings.sh来初始化PetaLinux环境。运行petalinux-config --get-hw-description指向包含.xsa文件的目录的路径。这个命令会启动一个基于ncurses的配置菜单。在这个配置菜单里有几个关键区域需要关注Subsystem AUTO Hardware Settings这里应该已经正确导入了你的硬件信息检查确认。Image Packaging Configuration在这里你可以选择根文件系统的格式如EXT4和存储介质如SD card。对于KV260我们通常将启动镜像放在SD卡上。DTG Settings设备树生成器设置。你可以在这里启用/禁用某些外设的节点生成或者添加自定义的设备树片段.dtsi文件。如果你的自定义IP有特殊的设备树绑定要求就需要在这里引入。u-boot Configuration确保启动参数正确例如console指定为串口通常是ttyPS0bootargs中包含根文件系统所在位置例如root/dev/mmcblk0p2 rw earlyprintk。配置完成后保存退出。4.3 内核驱动与设备树的关联对于标准的AXI外设如AXI GPIO, AXI DMA, AXI UART等PetaLinux的DTG通常能自动生成正确的设备树节点。例如一个AXI GPIO可能会生成如下节点axi_gpio_0: gpioa0000000 { #gpio-cells 2; clock-names s_axi_aclk; clocks zynqmp_clk 71; compatible xlnx,xps-gpio-1.00.a; gpio-controller; reg 0x0 0xa0000000 0x0 0x10000; xlnx,all-inputs 0x0; xlnx,all-outputs 0x1; xlnx,dout-default 0x00000000; xlnx,gpio-width 0x4; xlnx,tri-default 0xffffffff; };这个节点告诉Linux内核在地址0xA0000000处有一个兼容性为“xlnx,xps-gpio-1.00.a”的GPIO控制器宽度为4位全部配置为输出。内核在启动时会根据compatible属性去匹配已编译进内核或作为模块的驱动程序这里是xilinx_gpio驱动并将其加载在/sys/class/gpio下创建相应的控制接口。如果你的自定义IP不是标准AXI IP你需要编写对应的设备树绑定文档描述节点属性。编写或修改Linux内核驱动使其能匹配你的设备树节点。在PetaLinux配置中确保该驱动被编译内置或模块形式。通过“DTG Settings”添加自定义的.dtsi文件在其中描述你的IP节点。这是一个高级话题对于入门项目使用AXI GPIO、AXI DMA这类标准IP是更稳妥的选择。4.4 编译完整系统镜像配置妥当后回到PetaLinux工程目录执行编译命令petalinux-build这个过程会依次编译u-boot、设备树、Linux内核、根文件系统等。根据机器性能可能需要十几分钟到一小时不等。编译成功后在images/linux目录下你会找到所有生成的镜像文件其中最关键的是BOOT.BIN包含FSBL、比特流、PMUFW、u-boot的启动镜像。image.ub包含Linux内核、设备树和初始RAM磁盘rootfs的FITFlattened Image Tree镜像。rootfs.tar.gz根文件系统归档。5. 镜像打包、烧录与上电验证最后一步让我们把成果放到板子上跑起来。5.1 准备SD卡你需要一张至少8GB的SD卡。使用fdisk或图形化工具如GParted将其分为两个分区第一个分区FAT32大小约500MB-1GB用于存放启动文件BOOT.BIN,image.ub。这个分区需要设置为“可启动”标志。第二个分区EXT4占用剩余空间用于存放根文件系统。将编译生成的BOOT.BIN和image.ub复制到SD卡的第一个分区FAT32。将rootfs.tar.gz解压到SD卡的第二个分区EXT4sudo tar -xzf rootfs.tar.gz -C /media/你的用户名/rootfs_partition/注意调整分区挂载点路径。5.2 连接与启动KV260将SD卡插入KV260的卡槽。通过USB转UART串口线连接KV260的UART接口通常是J4到你的电脑。在Linux上使用minicom或screen例如screen /dev/ttyUSB0 115200打开串口终端。给KV260上电。在串口终端中你应该能看到u-boot的启动日志接着是Linux内核的启动信息。如果一切顺利最终会进入Linux登录提示符通常是petalinux用户密码也是petalinux。5.3 验证自定义PL设计登录系统后就可以验证你的PL设计是否被正确识别和驱动了。以我们假设的AXI GPIO控制LED为例检查设备树节点cat /proc/device-tree/axi_gpio_0/compatible应该输出xlnx,xps-gpio-1.00.a。检查sysfs接口ls /sys/class/gpio/你应该能看到gpiochipX目录其中的base文件内容就是该GPIO控制器管理的起始GPIO编号。控制LED假设起始编号是480要控制第一个LED对应GPIO 480echo 480 /sys/class/gpio/export # 导出GPIO echo out /sys/class/gpio/gpio480/direction # 设置为输出 echo 1 /sys/class/gpio/gpio480/value # 点亮LED echo 0 /sys/class/gpio/gpio480/value # 熄灭LED观察KV260载板上的用户LED比如DS24它应该会随着你的命令亮灭。如果LED能被控制那么恭喜你这证明了一个完整的链路你的自定义硬件设计PL中的AXI GPIO - 正确的比特流 - 正确的设备树描述 - 内核驱动加载 - 用户空间通过sysfs控制已经全部打通。这个过程看似步骤繁多但每一步都环环相扣。从BSP硬件平台创建到Vivado中添加和连接IP再到PetaLinux配置编译最后烧录验证构成了在Kria KV260上进行自定义PL开发的完整闭环。理解了这个流程你就掌握了在AMD EDF框架下进行嵌入式系统协同设计的核心方法。在下一部分我们将探讨更复杂的场景例如如何集成DMA进行高速数据搬运或者如何为自定义IP编写更复杂的内核驱动。