1. Zynq平台概述:从架构到环境搭建

做嵌入式这么多年,Zynq是我见过最「有意思」的芯片之一。它把ARM处理器和FPGA逻辑放在同一个die上,说白了就是让软件工程师和硬件工程师能真正坐在一起干活。我第一次接触Zynq是在一个工业视觉项目上,客户既要跑Linux做网络协议栈,又要做实时图像预处理——传统方案得用ARM+FPGA两块板子,Zynq一片搞定。

1.1 Zynq-7000系列架构:PS与PL的「双核」世界

Zynq-7000系列的核心架构,可以拆成两大部分:PS(Processing System)和PL(Programmable Logic)。PS是硬核的ARM Cortex-A9双核处理器,PL就是那片可编程的FPGA逻辑。两者通过内部高速总线互联,延迟比板级连接低一个数量级。

关键认知:Zynq不是「FPGA带了个ARM」,而是「ARM SoC集成了FPGA」。PS是老大,系统上电后PS先启动,PL可以看作是PS的一个外设。

我习惯把PS比作「大脑」,PL比作「可定制的肌肉」。大脑负责决策(操作系统、网络、文件系统),肌肉负责高速重复劳动(图像滤波、FFT、数据包处理)。

PS内部结构速览

组件 说明 我的经验
ARM Cortex-A9双核 主频最高1GHz,带NEON SIMD引擎 跑Linux完全够用,别指望它做实时控制
L1/L2 Cache 32KB I/D + 512KB共享L2 注意Cache一致性,PL访问DDR时要小心
DDR控制器 支持DDR3/DDR3L,最大1GB 我踩过坑:PL和PS同时访问DDR,带宽分配要提前规划
静态存储器接口 NAND、NOR、QSPI 启动方式从这里选,QSPI最常用
I/O外设 USB、UART、I2C、SPI、CAN、GigE 这些是硬核,不占PL资源

PL部分核心资源

  • 逻辑单元(LC):从Artix-7到Kintex-7级别,28K~444K
  • DSP48E1 Slice:每个可做25×18乘法累加,适合数字信号处理
  • Block RAM:36Kb每块,可配置为双端口RAM/FIFO
  • 高速收发器(GTP/GTX):最高12.5Gbps,做SerDes接口

选型建议:如果算法以乘加为主(如CNN卷积),多关注DSP数量;如果以数据缓存为主(如视频帧缓冲),多关注BRAM容量。我做过一个雷达信号处理项目,DSP用光了,BRAM还剩一半——选型时失算了。

1.2 PS与PL协同工作原理:内部总线与接口

PS和PL怎么通信?靠的是内部总线。Zynq提供了多种接口,每种接口的带宽、延迟、用途都不一样。选错了接口,性能可能差一个数量级。

主要通信接口一览

接口名称 带宽 延迟 典型用途
AXI_HP(高性能端口) 4个口,每个32位/64位,最高600MB/s 低 PL直接访问DDR,大数据搬移
AXI_GP(通用端口) 2个主+2个从,32位,约150MB/s 中 控制寄存器、小数据量通信
AXI_ACP(加速一致性端口) 1个,64位,约600MB/s 低 PL访问CPU Cache,保持一致性
EMIO(扩展MIO) GPIO级别 高 PL控制PS的I/O引脚

为什么会这样设计?你想想看,如果PL只是偶尔读几个寄存器,用AXI_GP就够了。但如果PL要做视频帧的实时处理,每秒几十MB的数据量,那就必须走AXI_HP直通DDR。我见过有人用AXI_GP传视频数据,结果帧率上不去,查了半天才发现是接口带宽瓶颈。

避坑指南:AXI_ACP虽然能保持Cache一致性,但使用起来有坑。我曾经在ACP端口上做DMA传输,没处理好Cache Line对齐,导致数据错位。建议:除非你非常熟悉ARM的Cache模型,否则优先用AXI_HP + 手动Cache刷新。

启动流程:PS先跑,PL后配

Zynq的启动顺序是固定的:

  1. PS从Boot ROM加载第一阶段引导程序(FSBL)
  2. FSBL初始化PS基本外设(DDR、时钟、MIO)
  3. FSBL加载PL的比特流(Bitstream),配置FPGA逻辑
  4. 加载U-Boot或裸机程序,最终启动Linux

这个流程意味着:PL的配置是在PS控制下完成的。你可以选择在Linux启动前配置PL(早期配置),也可以在Linux启动后动态配置(部分重配置)。我一般用早期配置,简单可靠。

1.3 开发环境搭建:Vivado + Vitis + Petalinux

搭建开发环境是入门的第一道坎。很多新手在这里卡住,其实没那么复杂。我按自己的习惯,把搭建过程分成三步。

第一步:Vivado —— 硬件设计工具

Vivado负责PL端的开发:写RTL代码、综合、实现、生成比特流。也负责PS端的配置:DDR参数、时钟、外设使能。

  • 版本选择:我建议用最新的稳定版,目前2023.x系列比较成熟
  • 安装要点:勾选「Zynq-7000」器件库,其他按需选
  • 许可证:WebPACK版免费,够用;如果要用Kintex-7以上器件,需要付费许可

小技巧:Vivado安装包很大(~30GB),下载时选「Combined Installer」一次性搞定。我习惯把Vivado、Vitis、Petalinux装在同一台Ubuntu 20.04机器上,省得来回切换。

第二步:Vitis —— 软件/嵌入式开发工具

Vitis是Xilinx的统一软件平台,替代了老的SDK。它负责:

  • 编写PS端的裸机程序或Linux应用
  • 编译、调试、下载
  • 管理硬件平台(Hardware Platform)

Vitis的安装通常和Vivado一起完成。安装后需要配置一下XSA文件路径——XSA是Vivado导出的硬件描述文件,包含PS配置、地址映射、外设信息。

第三步:Petalinux —— Linux系统定制工具

Petalinux是Xilinx提供的嵌入式Linux构建系统,基于Yocto。它帮你生成:

  • U-Boot引导程序
  • Linux内核(含设备树)
  • 根文件系统
  • PL驱动模块

安装Petalinux前,需要确保系统满足依赖:

# Ubuntu 20.04 安装依赖
sudo apt-get install -y gawk wget git diffstat unzip texinfo \
  gcc build-essential chrpath socat cpio python3 python3-pip \
  python3-pexpect xz-utils debianutils iputils-ping python3-git \
  python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 \
  xterm python3-distutils python3-setuptools

# 设置Petalinux环境
source /opt/Xilinx/Petalinux/2023.1/settings.sh

注意:Petalinux对Ubuntu版本有严格限制。2023.1版本只支持Ubuntu 20.04和22.04。我曾经在Ubuntu 18.04上硬装,编译到一半报错,浪费了半天。老老实实按官方文档来。

1.4 知识结构总览:一张图看懂Zynq开发

下面这张SVG图,概括了Zynq开发的核心流程和工具链关系。我每次带新人,都会先让他们看这张图。

Zynq开发流程与工具链总览 Zynq开发流程与工具链总览 Vivado 硬件设计 RTL开发 / IP集成 / 约束 Vitis 软件开发 裸机 / Linux应用 / 调试 Petalinux 系统定制 内核 / 设备树 / 文件系统 XSA 硬件描述 输出产物 比特流(.bit) + 硬件平台(.xsa) + 引导镜像(BOOT.bin) + 内核镜像(image.ub) Zynq-7000 目标平台 PS (ARM Cortex-A9) + PL (FPGA Logic) AXI总线互联 · DDR共享 · 外设集成 💡 开发流程要点 1. 先做Vivado硬件设计,导出XSA → 2. Vitis基于XSA开发软件 → 3. Petalinux定制Linux系统 4. 三者产物合并为BOOT.bin,烧录到QSPI或SD卡启动

1.5 环境验证:跑通第一个Hello World

环境搭好后,我习惯先跑一个最简单的「Hello World」来验证。这里说的不是printf,而是让PS通过AXI_GP控制PL上的一个LED。

步骤很简单:

  1. Vivado中创建一个Block Design,添加Zynq PS核和AXI GPIO IP
  2. 连接AXI总线,分配地址(默认0x41200000)
  3. 生成比特流,导出XSA
  4. Vitis中创建裸机工程,写代码:
#include "xparameters.h"
#include "xgpio.h"

XGpio gpio;

int main() {
    // 初始化GPIO设备
    XGpio_Initialize(&gpio, XPAR_AXI_GPIO_0_DEVICE_ID);
    
    // 设置方向:输出
    XGpio_SetDataDirection(&gpio, 1, 0x00);
    
    // 循环闪烁
    while(1) {
        XGpio_DiscreteWrite(&gpio, 1, 0x01);  // LED亮
        sleep(1);
        XGpio_DiscreteWrite(&gpio, 1, 0x00);  // LED灭
        sleep(1);
    }
    return 0;
}

下载到板子上,看到LED闪烁,说明整个工具链通了。嗯,这一步虽然简单,但能帮你排除90%的环境问题。

我的习惯:每次新项目开始前,我都会用这个「LED闪烁」工程验证开发板、下载器、工具链是否正常。别嫌它简单,它能帮你省下后面排查「到底是代码问题还是环境问题」的时间。

1.6 本章小结

Zynq平台的核心就三件事:PS管控制、PL管加速、AXI管通信。开发环境搭建也不复杂,Vivado做硬件、Vitis做软件、Petalinux做系统,三者通过XSA文件串联。记住启动顺序:PS先跑,再配PL,最后进Linux。