FPGA 进阶 22:Zynq SoC 入门——PS/PL 划分、启动流程与 Vivado 块设计
本文是
fpga/进阶层第 26 篇。Zynq 枢纽页讲了「ARM + FPGA 异构、软硬件协同」的思想,这篇讲真正上手做第一个 Zynq 工程:PS/PL 怎么分工、三类 AXI 接口(GP/HP/ACP)、怎么用 Vivado 块设计(IP Integrator)图形化搭出系统并自动连 AXI/分配地址、上电启动流程。PL 与 PS 间的大数据搬运(AXI DMA/VDMA)在下一篇 进阶 27。
本文要回答的问题
- PS 和 PL 各负责什么?功能怎么划分?
- GP / HP / ACP 三类 AXI 接口差在哪?控制面和数据面分别走哪个?
- Vivado 块设计怎么搭?Block Automation / Connection Automation 做了什么?
- 地址怎么分配?软件怎么靠 MMIO 访问 PL 寄存器?
- 上电启动顺序(BootROM→FSBL→bitstream→软件/Linux)?
一、PS 与 PL:一颗芯片里的软件 + 硬件
Zynq-7000 分两部分:
- PS(Processing System):双核 ARM Cortex-A9 + DDR3 控制器 + 千兆网/USB/SDIO/UART/I2C/SPI/CAN 等外设,上电就能跑(不依赖 PL),可跑裸机程序或 Linux;
- PL(Programmable Logic):就是传统 FPGA 逻辑(LUT/FF/DSP/BRAM/收发器),做并行高速逻辑。

分工口诀:控制与决策在 PS,数据与流水在 PL。
| 放 PS(软件) | 放 PL(硬件) |
|---|---|
| 控制流、复杂条件分支、状态管理 | 数据流、大规模并行处理 |
| 协议栈、文件系统、网络、UI | 固定周期/严格实时、确定性延迟 |
| 不常变但复杂、易变的策略 | 高吞吐计算(多通道、图像、滤波) |
| 优点:灵活、好调试、改了不用综合 | 优点:快、并行、吞吐高 |
二、GP / HP / ACP:PS 与 PL 的三类 AXI 接口
| 接口 | 主控 | 用途 | 典型场景 |
|---|---|---|---|
| GP(General Purpose,2 主 2 从) | PS 为主 | 通用控制、配置、读写 PL 寄存器 | 软件配置 PL、读写状态/少量数据 |
| HP(High Performance,4 个) | PL 为主 | PL 高带宽直接访问 PS 侧 DDR | 采集流写 DDR、从 DDR 读数据处理(走 DMA/VDMA) |
| ACP(Accelerator Coherency Port,1 个) | PL 为主 | 访问与 CPU cache 一致的内存 | 软件/硬件频繁共享、要 cache 一致性的数据 |
记忆:控制面走 GP(PS 发号施令),数据面走 HP(PL 搬大块数据),要 cache 一致走 ACP。 AXI 协议本身见 AXI4-Stream/Lite 和 AXI4 完整。
三、Vivado 块设计(Block Design / IP Integrator)
Zynq 工程主流用图形化块设计搭,而不是纯写 RTL 连线:
- 建 Block Design,拖入 Zynq Processing System IP(代表 PS);
- Run Block Automation:自动应用开发板预设(DDR 型号、MIO 固定外设——网口/UART/SD 等),勾掉不用的;
- 加 PL IP:自己的 AXI 模块(可用 Tools→Create/Package IP 打包,或 AXI GPIO/Direct DMA 等现成 IP);
- Run Connection Automation:把 PL IP 的 AXI 从口连到 PS 的 GP 主口时,工具自动插入 AXI Interconnect、自动引时钟/复位、自动连;
- Address Editor 自动分配地址:给每个 AXI 从机分一段地址(如
0x43C0_0000起 64K); - Validate Design(检查连线/地址/时钟)→ 生成 HDL wrapper → 综合实现出 bitstream;
- File→Export Hardware(含 bitstream) 到 Vitis/SDK,写软件。
块设计本质是自动生成连线 RTL;好处是 AXI 互联、时钟复位、地址映射这些繁琐易错的活工具全包,和纯 RTL 手写 AXI 从机是两种粒度。
软件怎么访问 PL 寄存器:地址段分配好后,软件把那段地址当 MMIO:
// 裸机(Vitis):对基地址读写就是在访问 PL 里的 AXI-Lite 寄存器
#define MY_REG (*(volatile unsigned int*)0x43C00000)
MY_REG = 0x01; // 写:启动 PL 硬件
int status = MY_REG; // 读:查 PL 状态
// Linux 下则通过 /dev/mem 或驱动 ioremap 同一物理地址访问PL 端 AXI-Lite 从机把地址解码到对应寄存器——这就是「软件控制硬件」的落点。
四、启动流程:PS 先起、再配 PL、再跑软件
Zynq 上电由 PS 主导(PL 自己不会启动):

- FSBL 由 Vitis 按硬件导出(.xsa/.hdf)生成;开发阶段用 JTAG 一键下载 FSBL + bitstream + elf,脱机量产用 SD/QSPI 启动(把 FSBL、bitstream、应用/boot 镜像打包放进去);
- 改了 PL 逻辑要重新出 bitstream 并重新导出硬件给 Vitis,否则软件地址/配置对不上;
- PL 没配好(bitstream 没加载)时访问 PL 寄存器无效,软件要等 PL 配置完成。
常见坑对照
| 坑 | 后果 | 正确做法 |
|---|---|---|
| 大数据搬运也走 GP 口 | 带宽不够、卡顿 | 大块数据走 HP 口 + DMA,GP 只管控制 |
| Address Editor 漏分配/地址冲突 | 软件读写 PL 无效 | Validate 检查,确认每个从机有唯一地址段 |
| 改了 PL 没重新导出硬件 | 软件地址/外设对不上 | 重新 Export Hardware 再建 Vitis 平台 |
| PL 未配置就访问寄存器 | 读到全 0/全 F、无响应 | 等 bitstream 加载完成再访问 |
| 把复杂控制流硬塞进 PL | 状态机臃肿、难改 | 控制决策放 PS,数据流水放 PL |
| 块设计不 Validate 就生成 | 时钟/复位/连线隐患 | 先 Validate Design 清零报错 |
| 裸机/Linux 地址直接照抄 demo | 访问错地址挂死 | 按本设计 Address Editor 的实际基地址 |
相关与延伸
前置/配套:Zynq 异构枢纽页(架构与协同思想)、AXI4-Stream/Lite、AXI4 完整与互联(GP/HP 口上跑的协议)。 PS↔PL 大数据搬运(HP 口 + AXI DMA/VDMA、裸机/Linux 数据通路)见下一篇 进阶 27 Zynq 数据交互;块设计 IP Integrator 深入见 #28、嵌入式软件见 #29;专家线有 Zynq PS/PL 深水区、UltraScale+/Versal。
一句话总结
Zynq = PS(ARM 双核 + DDR + 网口等,上电就跑、可上 Linux)+ PL(FPGA 逻辑)紧耦合在一颗芯片,分工口诀「控制与决策在 PS、数据与流水在 PL」。两者靠三类 AXI 口互联:GP(PS 主控,配寄存器/控制面)、HP(PL 主控,高带宽直连 DDR 搬大数据/数据面)、ACP(cache 一致共享)。上手流程:Vivado 建 Block Design 拖 Zynq PS → Run Block Automation 配 DDR/MIO → 加 PL IP → Run Connection Automation 自动插 AXI Interconnect、连时钟复位 → Address Editor 分配地址段 → Validate → 出 bitstream → Export Hardware 到 Vitis 写软件;软件把分配到的地址当 MMIO 读写即可控制 PL 寄存器。启动由 PS 主导:BootROM→FSBL(初始化 PS)→写 bitstream 配 PL→裸机 elf 或 U-Boot→Linux,开发用 JTAG、量产用 SD/QSPI;改了 PL 务必重新导出硬件、配好 PL 再访问。