1. Zynq异构架构与软硬件协同全景
Zynq-7000 系列的本质,是把一颗双核 ARM Cortex-A9 应用处理单元(APU)与一片 Xilinx 7 系列可编程逻辑(PL)集成在同一硅片上,再用一组高带宽、低延迟的片上接口把两者缝合起来。理解这套架构的关键,不是分别记住 PS 和 PL 各自有什么,而是看清"谁在什么时候控制谁、数据从哪里流到哪里、软件与逻辑的边界画在哪里"。本章先建立这张全景图,后续所有 BSP 配置、设备树编写、驱动开发和 PL 加速工作,都落在这张图的某个具体位置上。
一、PS 侧:APU 与它的固定外设
PS(Processing System)是 Zynq 的"硬"部分,出厂即固化,不可重配。核心是双核 Cortex-A9,每核带 32KB 指令/数据 L1 缓存、共享 512KB L2 缓存,主频典型 667MHz(Zynq-7020 常见配置)。两核之外还有 NEON 与浮点单元、256KB 片上 OCM、DDR 控制器、以及一组固定外设:UART、SPI、I2C、SD/SDIO、USB、Gigabit Ethernet、GPIO、定时器等。这些外设的寄存器地址在芯片手册中是固定的,Linux BSP 中的 UART 控制台、以太网 MAC、SD 卡控制器,用的就是它们。
需要特别区分的是 MIO 与 EMIO。MIO(Multiplexed I/O)是 PS 直接引出的 54 个引脚,外设信号通过 MIO 复用矩阵映射到物理引脚,不经过 PL;EMIO(Extended MIO)则是把 PS 外设信号"借道"PL 再引出,共 64 个。当某个外设的引脚需求超过 MIO 可用数量,或需要把信号引到 PL 侧做进一步处理时,就使用 EMIO。这个区别直接影响引脚约束文件和设备树中 pinctrl 的写法。
二、PL 侧:可编程逻辑与它的资源
PL 是"软"的部分,由查找表(LUT)、触发器(FF)、块 RAM(BRAM)、DSP48 切片和可编程互连构成。以 Zynq-7020 为例,约 85K 逻辑单元、140 个 BRAM(36Kb 每块)、220 个 DSP48E1。PL 可以承载纯组合逻辑、状态机、DSP 流水线、甚至软核 MicroBlaze。对 Linux 而言,PL 中的自定义 IP 通常以 AXI 从设备的形式暴露寄存器,被驱动读写;也可以做成 AXI 主设备,主动访问 DDR。
三、PS-PL 接口:协同的物理通道
PS 与 PL 之间不是一根总线,而是多条用途不同的通道,选错通道会直接导致带宽或延迟不达标:
- AXI GP(General Purpose):4 个端口(2 主 2 从),32 位数据宽度,适合寄存器配置、低速控制,典型吞吐几十 MB/s 量级。
- AXI HP(High Performance):4 个从端口,PL 作为主设备访问 DDR/OCM,64 位或 128 位宽度,是 PL 读写大块数据的首选,可接近 DDR 带宽上限。
- AXI ACP(Accelerator Coherency Port):1 个端口,PL 访问可绕过或参与 L2 缓存一致性,适合与 CPU 共享小数据结构。
- 中断与事件:PL 可通过 16 个共享外设中断(SPI)向 PS 发中断,也可用 PL-PS 中断端口;反向 PS 可向 PL 发 4 个中断。
- 时钟与复位:PS 向 PL 提供 4 路 FCLK 和复位信号,PL 逻辑的时序基准通常来自这里。
下面这张图把上述对象、接口方向和典型数据流放在同一张全景中,便于对照理解。
四、启动流程:从 BootROM 到 Linux
Zynq 上电后,PS 的 BootROM 先执行,按 MIO[5:2] 引脚决定的启动模式(QSPI、SD、NAND、JTAG)加载 BootROM Header,再加载 FSBL(First Stage Boot Loader)。FSBL 完成 DDR 初始化、把 bitstream 写入 PL(若需要)、加载第二阶段镜像。典型 Linux 启动链是:BootROM → FSBL → U-Boot(SSBL)→ Linux 内核 → 根文件系统。若使用 PetaLinux 或 Yocto,BOOT.BIN 通常打包 FSBL、bitstream 和 U-Boot,放在 SD 卡 FAT 分区;内核镜像 zImage 与设备树 system.dtb 单独放置,由 U-Boot 加载。
这里有一个协同工程的关键点:bitstream 在启动链中的位置决定了 PL 何时可用。若 bitstream 打包进 BOOT.BIN,PL 在 U-Boot 之前就已配置完成,Linux 启动时 PL 已就绪;若在 Linux 启动后用 FPGA Manager 动态加载,则 PL 配置发生在用户空间,驱动需要处理加载时序与重配置。两种方式对设备树、驱动探测顺序的要求不同。
五、Linux BSP 与 PL 协同工程的边界与交付物
把"软件"和"逻辑"分开看,各自的交付物是清晰的:
| 层面 | 主要交付物 | 关键内容 |
|---|---|---|
| 硬件平台 | XSA / HDF | Vivado 导出的硬件描述,含 PS 配置、PL 逻辑、地址映射 |
| 启动镜像 | BOOT.BIN | FSBL + bitstream + U-Boot,由 bootgen 打包 |
| Linux BSP | zImage、system.dtb、rootfs | 内核配置、设备树、驱动、根文件系统 |
| PL 逻辑 | bitstream、IP 寄存器手册 | 自定义 IP 的寄存器偏移、位定义、中断号 |
| 协同接口 | 设备树节点、驱动、用户态库 | AXI 地址、中断、时钟、DMA 通道的软件映射 |
边界画在哪里,取决于功能放在 PS 还是 PL。一个实用的判断原则:控制密集、分支复杂、需要操作系统服务的任务放 PS;数据密集、时序严格、可流水化的任务放 PL。例如图像预处理中的 Sobel 边缘检测,像素级卷积适合 PL 流水线;而检测结果的坐标解析、与上层应用通信,适合 PS 上的 Linux 进程。两者之间通过 AXI HP 搬像素、通过 AXI GP 传参数、通过中断通知完成。