Ultra96开发板深度解析:Zynq MPSoC架构、PS/PL设计与嵌入式AI实践
如果你刚拿到一块 Ultra96 开发板第一反应多半是这玩意儿和以前玩的纯 FPGA 板子长得不太一样。正面没有成排的拨码开关和 LED反而是 DC 电源口、USB、千兆网口、DisplayPort 排成一排底下压着一个树莓派风格的 40-pin 连接器第一眼看上去更像一台紧凑的单板电脑。这种设计背后藏着一个很明确的定位Ultra96 不是让你拿来点灯的纯逻辑评估板而是一块面向边缘计算、AI 推理和嵌入式计算视觉的 Zynq UltraScale MPSoC 平台。本篇作为 Understanding the Ultra96 Board 的第一部分我不打算堆数据手册而是从怎么理解这块板子的角度出发带你拆清楚它的定位、核心架构、板载资源、首次上电流程和开发工具链的配合逻辑。这块板子适合谁说实话它的目标用户比普通 FPGA 开发板更聚焦。如果你是想验证 FPGA 逻辑、做纯 Verilog/VHDL 电路设计预算有限的实验室通常更喜欢便宜的 Artix 板子但如果你想在一颗芯片上同时跑 Linux 系统、做实时控制、挂硬件加速器或者对软件无线电、机器视觉、工业检测这类场景感兴趣Ultra96 就正好落在那个生态位上。它不算便宜但作为 ZU3EG 平台的入门选择它把 PSProcessing System和 PLProgrammable Logic两边最核心的能力都摆在了台面上让你用一块板子摸清整个 MPSoC 开发链条。1. MPSoC 异构定位树莓派、传统 FPGA 和 Ultra96 的核心差异1.1 为什么嵌入式开发会走到异构这一步先聊个基础问题跑 Linux 的应用处理器和 FPGA为什么会出现在同一颗芯片里树莓派这类单板电脑能轻松跑视频解码、Python 脚本、神经网络推理框架但它的问题在于并行处理能力很弱。CPU 再多核也是几核到十几核的规模做图像滤波、FFT、协议解析这类吞吐密集的任务数据一上来 CPU 就陷入频繁的中断和缓存搬运延迟和功耗都不好看。传统 FPGA 恰恰相反它用查找表 LUT、触发器 FF 和 DSP Slice 搭出真正的并行硬件流水线几个时钟周期就能处理一整行图像数据。但纯 FPGA 的短板也明显跑个 Linux 要自己折腾软核或者外接 ARM网络协议栈、文件系统、设备驱动这些生态几乎为零调试一个外设驱动能耗费大量时间。于是 Zynq UltraScale MPSoC 这种异构 SoC 成了自然答案一颗芯片上集成多核 ARM 处理器、实时处理器、GPU再加上一块完整的可编程逻辑阵列。处理器负责流程控制、操作系统和复杂算法可编程逻辑负责数据搬运、协议处理和高吞吐计算两者通过高带宽 AXI 总线互联既有树莓派的生态又有 FPGA 的灵活。1.2 Ultra96 在 96Boards 生态里的位置Ultra96 是 Avnet 推出的开发板遵循 96Boards CEConsumer Edition硬件标准。这个标准的直观意义是板子尺寸、接口布局、电源输入都有一套明确规范第三方厂商可以按这个标准做扩展模块社区里的一些外设也能通过 40-pin 接口通用。但更要理解的是它在 Zynq UltraScale 家族中的定位。Ultra96 用的是 ZU3EG 这个型号在 UltraScale 系列里偏向入门级。相比 ZU7EV、ZU19EG 这些大芯片ZU3EG 的逻辑资源不算夸张但关键在于它的封装和供电设计被压缩到了一块 85mm x 54mm 的板卡上功耗控制在 15W 以内典型场景更低这使它成为少数能放进便携设备里做原型验证的 MPSoC 平台。从个人学习和产品预研的角度看Ultra96 的价值在于麻雀虽小五脏俱全PS 侧的完整应用处理能力、PL 侧的可编程逻辑、丰富的板载外设三条技能线都能在这块板子上训练。很多做工业视觉检测的朋友最初就是从 Ultra96 起步先把算法在 PL 里加速跑通再迁移到更大的 ZU 系列芯片上做量产这个路线非常现实。1.3 什么样的项目适合选 Ultra96结合我接触过的实际案例适合用 Ultra96 的场景通常有这几个特征需要 Linux 系统做网络通信、文件管理或 UI 交互同时又有实时或高吞吐的数据通路要处理数据量大到 CPU 顶不住但又不想等多代产品才完善的独立 FPGA 方案摄像头、传感器、SD 卡、网口这类接口要多路接入单芯片集成比处理器主板 FPGA 板连接更省空间需要相对低的功耗不能上大功率风扇和笨重散热器反向来说如果只是做纯算法仿真、纯 FPGA 逻辑练习或者完全不碰 Linux 只想用 Verilog 写状态机Ultra96 可能不是最高性价比的选择。理解这个边界比你记住任何引脚定义都重要。2. ZU3EG 处理器体系PS 与 PL 双域架构逐层拆解2.1 PS 侧的三国分工A53、R5F 与 GPUZU3EG 的 PS 部分集成了三套计算单元理解它们的分工是理解整块板子的钥匙。第一套是四核 ARM Cortex-A5364 位架构最高主频 1.5GHz 左右。这套处理器干的就是我们通常理解的运行 Linux 应用这个活跑 Python 脚本、启动 Web 服务、处理网络协议栈、做 AI 框架的预处理和后处理。它和大头电脑上的 CPU 没有本质区别只是功耗更低、引脚都封装在芯片内部。第二套是双核 ARM Cortex-R5F这是很多人刚接触 Ultra96 时最容易被忽略的部分。R5F 是实时处理器它不跑 Linux而是运行裸机代码或轻量级 RTOS专门应对必须在一个确定的时钟周期内响应的任务比如电机控制环路、电源管理协议、传感器同步采样。A53 可能因为 Linux 调度延迟、缓存未命中而慢几微秒但 R5F 的响应时间是确定性的。这就是为什么工控场景里R5F 常被用来做安全岛或实时前端。第三套是 Mali-400 GPU负责图形渲染和简单的 GPGPU 任务。在 Ultra96 上它主要服务于显示输出和 GUI 场景比如通过 DisplayPort 输出一个 Qt 界面。别指望它做大规模并行计算——那部分是 PL 的活。三套处理器的组合反映了一个系统设计原则用一个芯片的不同核心去匹配任务的不同特性而不是用一颗通用 CPU 硬扛所有负载。2.2 PL 可编程逻辑资源154K 逻辑单元到底能做什么ZU3EG 的 PL 部分数据手册给出的资源包括约 154K 逻辑单元、141K CLB 触发器、360 个 DSP Slice以及 432 块 Block RAM约 15.5Mb 总容量。单看数字可能没概念我直接举例用 PL 实现一个基于 Vivado HLS 的卷积加速器或者在 PL 里搭一个千兆以太网的硬件协议栈或者做多通道 ADC 数据的实时滤波与图像预处理——这个量级的资源都够用。但如果你想在 PL 里做视频编解码或者超大模型的 Transformer 加速ZU3EG 就会显得局促那就该往 ZU7EV 以上走了。PL 和 PS 的通信靠的是片内的 AXI 总线。具体到 Ultra96PS 和 PL 之间有多个 AXI 接口数据位宽和协议版本各不相同。简单的理解是PS 侧的 ARM 通过 AXI 总线去读写 PL 里的寄存器或 BRAM就像访问外部外设一样PL 里的加速器也可以通过 AXI 总线去访问 DDR 内存把自己算完的数据直接写进内存不需要在 PS 和 PL 之间搬来搬去。高效的数据流设计核心就是设计好这条 AXI 通路的吞吐和延迟这也是很多 MPSoC 开发者的核心技能。2.3 存储体系DDR4、eMMC、SD 卡的分工与合作Ultra96 的板上存储包含三块DDR4 内存、eMMC 闪存和 microSD 卡槽。DDR4 是系统主内存v1 板卡是 2GBv2 升级到了 4GB数据总线 64 位默认运行速率在 2400MT/s 左右。PS 和 PL 共享这块 DDR4PS 上跑的 Linux 用它做系统内存PL 里的加速器通过 AXI HP 接口也访问它。这个共享设计是 MPSoC 高性能的关键也是和传统 DSPFPGA 双芯片方案拉开差距的地方。eMMC8GB承担的是板载存储的职责相当于电脑里的 SSD可以存放多个系统镜像、数据日志和算法模型。microSD 卡槽则是最灵活的启动和存储方式做原型开发时用 SD 卡装不同版本的 Linux 镜像可以随便换不用覆盖 eMMC。存储方面我建议你直接形成三条经验第一日常开发优先用 SD 卡启动出问题可以快速换镜像第二产品化或者要跑长期稳定性测试时把最终镜像固化到 eMMC第三DDR4 容量虽然 4GB 在嵌入式里算大但也要注意 PS 和 PL 之间的内存带宽是共享的PL 里的大规模读写会抢占系统内存带宽设计时要有全局观念。3. 板载资源与接口盘点哪些引脚能干活哪些走的是系统总线3.1 板载外设全览直接看板子正面你会发现 Ultra96 的接口其实非常精简这种精简也是 MPSoC 平台的特点很多资源被集成到了 PS 内部不需要外部芯片去扩展。接口/连接器型号与速率典型用途12V DC 电源12V/3A 推荐整板供电micro-USBUART/JTAGFTDI 桥接串口终端、JTAG 调试USB 3.0 Type-A5GbpsU 盘、键盘鼠标、USB 摄像头等外设USB 3.0 Type-C支持 Device 模式用于烧写镜像、RNDIS 网络共享千兆以太网10/100/1000 Mbps网络启动、SSH、NFS 文件共享DisplayPort4K30 输出接显示器跑 GUI 程序microSD 卡槽SD 卡启动存储镜像、独立启动介质40-pin 低功耗连接器1.8V 电平兼容树莓派 HAT 物理接口PMOD 接口1.8V 电平接 PMOD 外设模块MIPI CSI 摄像头接口v2MIPI CSI-2摄像头输入机器视觉应用注意表格里我特意标注了 1.8V 电平。这是 Ultra96 新手最容易踩的坑后面避坑章节我会展开讲。3.2 40-pin 接口和 PMOD扩展能力的边界Ultra96 的 40-pin 低功耗连接器在物理上兼容许多树莓派 HAT但电气定义有本质区别。它提供的 IO 电平是 1.8V而不是树莓派常见的 3.3V。这意味着你随手把一个 3.3V 的树莓派传感器模块插上去很可能烧坏接口或者让板子工作异常。要接 3.3V/5V 模块必须经过电平转换电路。这个接口上除了一组可配置 GPIO 外还提供了 I2C、UART、SPI 等常见总线信号设计逻辑和树莓派差别不大。PMOD 接口则是标准 FPGA 世界里常见的外设扩展接口Ultra96 上提供的是 1.8V 电平的 PMOD通常用于接一些低速 SPI、UART 模块或者干脆让你用杜邦线引出自定义信号。实际做原型时40-pin 的 GPIO 和 PMOD 可以用来观察内部信号、调试逻辑非常方便。但记住它们的数据带宽远低于内部 AXI 通路千万不要指望通过 IO 引脚做高速数据搬运。3.3 千兆网口、DisplayPort 和摄像头接口的定位在 Ultra96 上千兆以太网不只是用来联网的它是嵌入式开发里最高效的调试通道。通过 NFS 挂载根文件系统、通过 SSH 快速拷贝文件、用 GDB 远程调试——比老式串口方式舒服得多。很多工程团队甚至把 Ultra96 放在局域网的固定 IP 下开发机直接用 VS Code 的 Remote-SSH 插件远程改代码、编译工作流和云端服务器开发一模一样。DisplayPort 接口则承担了 人机交互 的职责。你可以用一块普通的 DP 显示器让 Ultra96 跑一个带图形界面的 Linux 系统或者用 Qt/GTK 做工业上位机界面原型。对学习 MPSoC 开发来说能看到画面很多抽象概念会具体很多。MIPI CSI 摄像头接口是 Ultra96 v2 新增的亮点。过去要让 FPGA 接摄像头得靠 USB 摄像头或者外部转接延迟和带宽都不理想。有了原生 CSI 口后cmos 传感器可以直接连到 PL 端的 MIPI IP图像数据可以不经 CPU 直达加速器这也是当前机器视觉应用最喜欢的架构。4. 第一次上电从 microSD 镜像到串口登录的完整链路4.1 上电前需要准备的东西不少朋友拿到板子第一件事就是插电看灯。先别急Ultra96 不像树莓派它没有预装系统出厂板载存储里可能只带了硬件测试程序或者干脆是空的。第一次上电前我建议你准备好一张 16GB 以上的 microSD 卡一个读卡器一根 micro-USB 线一根 USB 转 type-C 线用于 USB Device 模式一个 12V/3A 的 DC 电源适配器以及一台已经装好串口终端软件比如 Windows 的 PuTTY、Mac/Linux 的 minicom 或 screen的电脑。4.2 将预编译 Linux 镜像写入 SD 卡从 Ultra96 官网或者 Avnet 的资源中心下载官方预编译的 PetaLinux 镜像一般是一个 .img 或者 .wic 文件然后用 BalenaEtcher 或者 dd 工具把镜像写入 SD 卡。Windows 下我推荐 BalenaEtcher它在烧录时会校验写入数据能避免低概率的镜像损坏Linux 下直接用 dd 也很快sudo dd ifultra96v2.img of/dev/sdX bs4M statusprogress sync写完后将 SD 卡插入板卡底部的 microSD 卡槽注意方向金属触点朝板子内侧再把板子用 micro-USB 线连接到电脑的 USB 口。这个 micro-USB 口集成了 UART 转 USB 和 JTAG 功能连接成功后电脑上会出现一个新的串口设备Windows 是 COM 口Linux 是 /dev/ttyUSB0 或 /dev/ttyACM0。串口参数固定为 115200 波特率、8 数据位、1 停止位、无校验、无流控。4.3 观察启动过程从 BootROM 到 Linux 登录接通电源后打开串口终端你会看到一条完整的 MPSoC 启动链路。概括起来就是BootROM芯片内部固化代码→ FSBLFirst Stage Boot Loader→ ATF U-Boot → Linux 内核 → 根文件系统。BootROM 负责读外部启动介质的第一段代码FSBL 初始化 DDR 和部分外设然后加载 U-Boot 引导 Linux。如果你使用的是官方预编译镜像启动日志会一路滚动到 Linux 登录提示符默认账号通常是root密码为root或ultra96具体以镜像文档说明为准。看到 rootultra96:~# 这样的提示符就意味着板子已经真正跑起来了。这条启动链路理解起来很简单但它解释了为什么 MPSoC 开发会经常讨论 BOOT.BIN、image.ub、U-Boot 这些概念它们分别对应启动链路中的不同阶段。后续你要定制系统、修改设备树、固化内核改的都是这条链路上的某个环节。4.4 网络配置与第一次 SSH 远程登录串口登录只是起点。用于正式开发强烈建议配置网络用 SSH 远程操作。Ultra96 的千兆网口默认启用了 DHCP把网线插到路由器或者交换机上在串口终端里用ip addr查一下 eth0 获取到的 IP然后在电脑上执行ssh root192.168.x.x如果你手里只有一根网线连到电脑没有路由器可以手动给 Ultra96 配置一个静态 IP比如 192.168.1.100电脑网卡设为 192.168.1.50再直连。开发机上能 SSH 上去之后我通常第一件事是挂载 NFS把板子的根文件系统或者数据目录挂到开发机共享目录上这样在开发机编译好的文件马上能在板子上运行效率提升非常明显。5. 开发工具链选型Vivado、Vitis、PetaLinux 到底怎么配合5.1 Vivado 负责 PL 侧硬件设计Vivado 是 xilinx 官方的 FPGA 设计套件在 Ultra96 开发里它用来创建 PL 侧的硬件设计。当你需要往 PL 里添加自定义加速器、MIPI 控制器、某个协议 IP 时就打开 Vivado做 Block Design 或者 RTL 设计然后综合、布局布线最终生成比特流 bit 文件。但 MPSoC 开发里Vivado 生成的不仅是 bit 文件还包含一个 XSA 文件Xilinx Shell Archive。这个 XSA 把硬件描述、引脚约束、PS 配置等信息打包在一起供 Vitis 使用。换句话说Vivado 做的事是设计硬件电路Vitis 做的事是在硬件上写软件。5.2 Vitis 负责 PS 侧软件开发Vitis 是 Xilinx 统一后的开发环境基于 Eclipse负责 PS 侧的软件开发。它能做的事分三种级别第一裸机应用开发不跑 OS直接在 A53 或 R5F 上跑 C 程序适合实时控制类任务第二Linux 应用开发编译在 Linux 用户空间运行的程序链接各种库第三加速器开发你通过 Vitis 的 HLS 流程把 C/C 函数综合成 PL 硬件模块再生成驱动和可执行文件。Vitis 和 Vivado 的版本必须匹配2019.2 的 Vivado 配 2019.2 的 Vitis这是最基础的常识但真有不少人因为版本不一致浪费了一整天。安装时我也建议只装一个主版本别多版本混用环境变量和许可证容易冲突。5.3 PetaLinux 负责定制嵌入式 LinuxPetaLinux 是 Xilinx 提供的嵌入式 Linux 构建工具基于 Yocto 项目用来生成 U-Boot、Linux 内核、设备树和根文件系统。什么时候必须用 PetaLinux当你需要给 Ultra96 的 Linux 添加一个硬件外设驱动、修改内核配置、集成自定义 rootfs 时就要进入 PetaLinux 的流程。初次使用 PetaLinux坦白说从零构建一次要花几个小时而且对网速和磁盘空间要求不低。好消息是厂家提供的预编译镜像已经包含了基础内核和常见驱动很多入门阶段不需要碰 PetaLinux。我的建议是入门先直接用官方镜像学会 Linux 环境、串口、网络、GPIO 操作等你真正需要改内核时再引入 PetaLinux不要一上来就陷入构建工具的泥潭。5.4 一条最推荐的学习路径从实测经验看如果你想最快速地掌握 Ultra96我建议的学习顺序是烧官方镜像用串口和 SSH 玩转 Linux 基础用 sysfs 或 libgpiod 操作板上的 GPIO建立CPU 控制引脚的概念打开 Vivado做一个最小的 Block Design把 PL 里一个 LED 灯逻辑跑起来生成 XSA用 Vitis 写一个简单的裸机程序读写 PL 里的寄存器理解 PS 如何控制 PL再回到 Linux 环境通过设备树把 PL 的 IP 注册成内核驱动用 Linux 应用去控制它。这条路径把 PS、PL、工具链、系统启动这几个关键环节都串了一遍而且每一步的复杂度都在可控范围。等你走完这套流程再去看复杂的加速器设计、多处理器协同视角会完全不同。6. 新手最容易踩的坑与调板实战经验6.1 引脚电平 1.8V那些被烧掉的传感器模块这是 Ultra96 新手翻车率最高的问题。板上的 40-pin 连接器和 PMOD 接口的 IO 电平是 1.8V很多从树莓派转过来的朋友直接插上 3.3V 传感器模块结果模块工作异常运气差的还会烧掉板子上的引脚或者损坏模块本身。网上买扩展模块时一定要确认清楚模块是否支持 1.8V 电平或者自己配一块双向电平转换板。有些 I2C 模块和 SPI 模块在 1.8V 下也能工作但很多老的传感器芯片只支持 3.3V这种情况必须转电平没有商量余地。我自己的教训是第一块 Ultra96 买了不到一个月就烧坏了一个 40-pin 接口的引脚后来专门接了逻辑分析仪才发现是电平不匹配导致的。6.2 串口连接不上和乱码问题串口连不上的原因通常有几个驱动没装好FTDI 芯片需要驱动、串口号选错、波特率不对。Ultra96 的串口参数是 115200 8N1但你电脑上可能同时识别出多个串口要确认选的是 FTDI 对应的那个。Linux 下可以用lsusb查看设备Windows 下可以在设备管理器里看端口号。还有一种情况是串口终端能打开但收到一堆乱码这多半是波特率设置错误。有些镜像默认波特率可能不是 115200如果你是用自定义 PetaLinux 构建的系统建议统一设成 115200省事。另外上电时不要先开串口终端再插电顺序反过来有时会丢启动日志尽量先连好串口再上电。6.3 电源不足导致各种灵异问题Ultra96 的官方推荐电源是 12V/3A。低于这个规格比如用一个 12V/1A 的山寨适配器板子在低负载时看起来正常一旦你插上 USB 外设、跑起算法、PL 里逻辑密集调用电压跌落就会导致随机重启、USB 设备无法识别、DDR 报错。排查问题之前先确认电源是不是达标这是最重要的前提。还有一次我遇到板子莫名其妙进不了系统折腾了半天最后发现是电源插头接触不良。建议买电源时选择线材较粗、接头严丝合缝的工业级适配器多花十几块钱能省下大把排查时间。6.4 用 JTAG 调试时版本匹配问题Vivado 的硬件管理器里可以通过 micro-USB 口的 JTAG 通道连接板子上 ZU3EG 的调试链。这一步在下载比特流、调试裸机程序时很有用。但要注意Vivado/Vitis 的版本和你板卡上 JTAG 固件版本需要匹配否则可能识别不到器件。遇到这种情况先升级 Vivado 或者更新板卡的 JTAG 固件再排查硬件连接。另外JTAG 调试时如果板子在 Linux 运行中被复位可能导致 DDR 里的数据状态混乱需要重新上电或者重启系统才能恢复。我的习惯是调试 FPGA 逻辑或裸机程序时先断开 Linux 系统的自动启动避免两边抢资源调试 Linux 应用时就不用挂 JTAG用 SSH GDB 远程调试更舒服。6.5 资源规划逻辑资源看着够实际布线就吃紧ZU3EG 的 154K 逻辑单元对很多算法加速够了但综合布局布线后实际可用资源会打折扣。尤其当你加了多个 AXI 外设、多个时钟域、大量 Debug 核ILA之后布线拥塞会导致时序收敛困难。我的经验是设计目标资源占用不要超过 70%留出余量给布线、时钟和调试逻辑。如果占满资源时序收敛会变得极其痛苦性能反而上不去。在 PL 里加 ILA 观察信号时也要克制ILA 会占用不少 BRAM 和逻辑资源采样深度太大会拖慢布局布线。真正排查问题时先缩小采样窗口、只抓关键信号确认大方向正确后再细化。6.6 设备树和 FPGA ManagerLinux 下加载 PL 的一个隐藏机制在 Linux 环境里加载 PL 的比特流除了用 JTAG更工程化的方式是使用 FPGA Manager。你可以在 Linux 用户空间通过configfs或者设备树里配置 FPGA Manager 节点把编译好的 bit 文件加载到 PL然后通过设备树匹配驱动。这套流程的核心在于理解设备树里 PL 的 IP 节点描述比如 compatible 属性、reg 地址它决定了 Linux 内核能否正确识别和操作 PL 里的硬件。很多新手在 Vitis 里生成了硬件平台也写出了应用但一放到 Linux 下就跑不通问题往往出在设备树没跟上。所以纯裸机验证用 Vitis 开发简单但产品化最终都要往 Linux 设备树方案上走越早理解这套机制后面越省力。在跑调 Ultra96 的这段时间里我越来越体会到这块板子的价值不在于某一项指标有多强而在于它把 MPSoC 开发最关键的全链路塞进了一块小巧的板卡里。从电源管理到启动引导从 Linux 应用到 PL 加速器从串口调试到远程开发每一个环节都能在上面获得真实的工程体验。这篇作为 Understanding the Ultra96 Board 的第一部分重点关注的是架构认知和上手流程先把地基打好后面再聊具体的 PS-PL 数据通路设计、HLS 加速器开发、以及基于 PetaLinux 的系统定制时才能真正得心应手。
