目录
基本过程
新建Vivado工程
ZYNQ IP核设置
使用SDK进行软件开发
基于Vivado2017
Vivado工程建立
SDK调试
固化程序
注:Vivado 2019.1 及之前:默认使用 SDK
Vivado 2019.2-2020.1:逐步过渡,支持 SDK 与 Vitis 并存
Vivado 2020.1 及之后:Vitis 成为唯一软件开发工具,SDK 不再更新
Vivado SDK 与 Vitis 是赛灵思(Xilinx,现属 AMD)FPGA 开发中软件开发的演进工具,核心差异在于架构统一性、开发流程和功能扩展
架构设计
平台概念
开发流程差异
操作步骤 | SDK | Vitis |
---|
工程创建 | 自动生成 App + BSP 两个工程 | 仅生成单一应用工程,Platform 需独立创建 |
BSP 配置 | 通过 system.mss 文件 | 通过 platform.spr 文件添加 Domain |
硬件接口启动 | File → Launch SDK | Tools → Launch Vitis IDE |
自定义 IP 支持 | 直接识别 | 需手动修改 Makefile 或导入设置 |
功能扩展
Vitis 新增:
-
Vitis HLS:高阶综合工具(原 Vivado HLS),支持 C/C++ 直接生成 RTL
-
Vitis AI:专用 AI 推理工具链,支持模型量化、DPU 部署(如 YOLOv5)
-
统一加速库:集成优化后的 OpenCL/CUDA 库,提升跨平台兼容性
起始版本:Vitis 2019.2(2019 年 10 月发布),首个稳定版本,取代 SDK 成为官方推荐环境
过渡阶段:
全面替代:Vivado 2020.1 及之后:Vitis 成为唯一软件开发工具,SDK 不再更新
迁移注意事项
工程迁移:
调试兼容性:
自定义 IP:
Vitis软件平台、vitis实例、裸机SOC(SDK)程序移植 - VagueCheung - 博客园
ZYNQ笔记(2):PS端——Hello World ! - 咸鱼IC - 博客园
基本过程
新建Vivado工程
1.打开Vivado,新建一个工程,Next
2.设置工程名称和工程所在目录,Next
3.选择第一项:RTL Project,Next
4.添加资源,可以直接Next
5.添加约束,可以直接Next
6.芯片型号选择xc7z020clg400-2,Next
7.总结页面,Finish
8.进入Vivado工程页面,左边是导航栏,可以直接点击Generate Bitstream,上面的选项也会按顺序被执行。Open Hardware Manager则是硬件管理,用于下载、调试等
9.如果连接好了板卡,那么点击Open Hardware Manager --- Open Target则可以看到板卡信息
ZYNQ IP核设置
1.点击导航栏的 IP INTEGRATOR --- Create Block Design,弹出工程名称和工程位置,填写后点OK
2.点击中间的 + 号添加IP,然后在弹出的小窗口中选择ZYNQ,双击该IP核
3.此时看到ZYNQ的接口界面,有几个引脚,我们只需要最简单的系统,双击ZYNQ进行参数设置
4.进入到ZYNQ内部资源区域,此处可以看到内部有哪些资源可以使用
Zynq Block Design 主页面
PS-PL Configuration PS到PL的相关接口配置信息以及PS部分的一些配置信息
Peripheral I/O Pins 通用外设接口的配置
MIO Configruation 对MIO以及EMIO的分配控制
Clock Configruation PS端时钟资源的配置和管理
DDR Configration DDR控制器的一些参数配置
Interrupts 中断的配置管理
5.点击左侧的PS-PL Configuration, 取消勾选这两项。

6.点击左侧的MIO Configuration,电压设置成LVCMOS 1.8V,用到了SD和UART,因此勾选它们并且设置引脚编号

7.选择Clock Configuration,本实验没有用到FPGA板卡时钟,因此取消勾选。

8.点击左侧DDR Configuration,勾选Enable DDR,点击展开,对DDR进行一些参数设置,之后点击OK


9.回归到ZYNQ主页面,可以看到比之前更简洁了。上面绿色横条处点击Run Block Automation
10.点击OK
12.点击 Source 栏的工程,鼠标右键选择 Generae Output Products
13.弹出一个小窗口,第一项为全局模式,更慢但保险,第二项为OOC模式,更快但有逻辑问题时会编译不通过,我们选第一项,下面线程根据自己电脑配置选择最大的即可。
14.设置让Vivado管理我们的文件,点击Sources,右键选择Create HDL Wrapper,弹出的小页面点击OK
使用SDK进行软件开发
1.本次实验只有 PS 部分的管脚,没有 PL 部分的管脚,而且 PS 部分的管脚都是固定的,所以我们不需要添加管脚约束文件。另外因为没有使用 PL 部分的资源,我们也不需要在 Vivado 下编译和生成 bit 文件了。直接将文件导出到SDK开发目录,点击 File --- Export --- Export Hardware
2.未用到bit流文件,不用勾选 Include bitstream ,直接点 OK
3.启动SDK,点击File Launch SDK,弹出的小窗口直接点OK就行
4.直接点 OK
5.SDK软件开发界面
6.新建一个软件的APP,用于后面的C语言编程。点击File --- New --- Application Project
7.填写项目名称,点击Next
8.选择Hello World,点击Finish
9.此时软件自动开始编译,也可点击 Build Project手动编译,编译完成后出现Hello World 的程序,如果编译出错,可以点击 Clean Project 重新编译。
10.本实验需要用到Uart串口,我们打开我的电脑 --- 设备管理器 --- 端口,检查是否已经连接好串口
11.回到SDK界面,看到界面下方有一个SDK Terminal,点击该选项,并且点击那个+号,设置其自带的串口工具的参数。
12.点击如下选项

13.如果跳出如下界面,点击No

14.点击右上角的按钮可以进行界面切换

15.点击如下图标可以进行FPGA配置,点击Program将程序烧录进板卡,这时跳出小窗口就要选择yes了。



16.当然,也可以点击这个选项进行FPGA配置,这时跳出小窗口就要选择yes了
见ZYNQ笔记(2):PS端——Hello World ! - 咸鱼IC - 博客园
17.页面出现如下的文件目录,表示成功

18.界面上方有几个调试选项:
Resume:运行到断点为止
Step into:进到函数内部
Step over:单步调试
Step return:跳出函数内部
这里选择单步调试即可,可以看到界面下方的SDK Terminal中显示出:Hello World
基于Vivado2017
到 ZYNQ 芯片分为 PL 和 PS,PS 端的 IO 分配相对是固定的,不能任意分配,而且不需要在 Vivado 软件里分配管脚,虽然本实验仅仅使用了 PS,但是还要建立一个Vivado 工程,用来配置 PS 管脚。虽然 PS 端的 ARM 是硬核,但是在 ZYNQ 当中也要将 ARM 硬核添加到工程当中才能使用
Vivado工程建立
创建一个名为“ps_hello”的工程,建立过程不再赘述,参考“PL 的”Hello World”LED 实验”
点击“Create Block Design”,创建一个 Block 设计,也就是图形化设计

“Design name”这里不做修改,保持默认“design_1”,这里可以根据需要修改,不过名字要尽量简短,否则在 Windows 下编译会有问题。

点击“Add IP”快捷图标

搜索“zynq”,在搜索结果列表中双击“ZYNQ7 Processing System”

双击 Block 图中的“processing_system7_0”,配置相关参数

首先出现的界面是 ZYNQ 硬核的架构图,可以很清楚看到它的结构,可以参考 ug585 文档, 里面有对 ZYNQ 的详细介绍。图中绿色部分是可配置模块,可以点击进入相应的编辑界面,当然也可以在左侧的窗口进入编辑。

接下来是 PS-PL Configuration 界面,这个界面主要是进行 PS 与 PL 之间接口的配置,主要是
AXI 接口,这些接口可以扩展 PL 端的 AXI 接口外设,所以 PL 如果要和 PS 进行数据交互,
都要按照 AXI 总线协议进行,xilinx 为我们提供了大量的 AXI 接口的 IP 核。在这里保持默认,
在后面的章节中会对其配置,本章节不与 PL 端进行交互,保持默认

之后进入 PS 端外设的配置阶段,一开始接触 ZYNQ 可能会很疑惑,看到密密麻麻的外设,
无从下手。这里解释一下,ZYNQ 的 PS 端外设很多是复用的,相同的引脚标号可以配置成
不一样的功能,比如下图中的 16-27 可以配置成 Enet0,也可以配置成 SD0、SD1,但只能
配置成一种外设,比如如果配置 Enet0,也就不能再选择 SD0、SD1 了。至于该怎么去选择,是由原理图和 PCB 决定的,可以通过查看原理图或用户手册选择


从原理图中我们可以找到串口连接在 PS 的 MIO48-MIO49 上,所以在“Peripheral I/O Pins”
选项中使能 UART1(MIO48 MIO49),PS 端 MIO 分为两个 Bank,Bank 0 ,也就是原理图中
的 BANK500,电压选择“LVCMOS 3.3V”,Bank 1,也就是原理图中的 BANK501,电压选择
“LVCOMS 1.8 V”。如果不配置 Bank1 电平标准,可能导致串口无法接收
配置 QSPI,QSPI 可以作为 ZYNQ 的启动存储设备,ZYNQ 可以通过读取 QSPI 中存储的启动
文件加载 ARM 和 FPGA,从原理图得知,我们选择 Quad SPI Flash 为 Single SS 4bit IO

配置以太网,在 PS 端设计有以太网接口,根据原理图选择 Ethernet 0 到 MIO16-MIO27

MDIO 为以太网 PHY 寄存器配置接口,选择 MDIO 并配置到 MIO52-MIO53

配置 USB0 到 MIO28-MIO39
除了 QSPI 启动 ZYNQ,还有 SD 卡模式启动 ZYNQ,选择 SD 0,配置到 MIO40-MIO45,选择
Card Detection MIO47,用于检测 SD 卡的插入。
打开 GPIO MIO,PS 便可以控制剩余未分配的 MIO,用作 GPIO
在 GPIO MIO 中选择 MIO46 作为 USB PHY 的复位
至此,外设配置结束。
MIO 配置
修改 Enet0 的电平标准为 HSTL 1.8V,Speed 为 fast,这些参数非常重要,如果不修改,网
络可能不通。其他部分保持默认。
时钟配置
在“Clock Configuration”选项卡中我们可以配置PS时钟输入时钟频率,这里默认是33.333333,
和板子上一致,不用修改,CPU 频率默认 666.666666Mhz,这里也不修改。同时 PS 还可以
给 PL 端提供 4 路时钟,频率可以配置,这里不需要,所以保持默认即可。还有 PS 端外设
的时钟等也可以进行配置,这里保持默认
在“DDR Configuration”选项卡中可以配置 PS 端 ddr 的参数,AX7010 配置 DDR3 型号为
“MT41J128M16 HA-125”, AX7020 配置 DDR3 型号为“MT41J256M16 RE-125”,这里 ddr3
型号并不是板子上的 ddr3 型号,而是参数最接近的型号。Effective DRAM Bus Width”,选择
“32 Bit”
其他部分保持默认,点击 OK。至此 ZYNQ 核的配置结束。
点击“Run Block Automation”,vivado 软件会自动完成一些导出端口的工作

点击“OK”以后我们可以看到 PS 端导出一些管脚,包括 DDR 还有 FIXED_IO,DDR 是 DDR3
的接口信号,FIXED_IO 为 PS 端固定的一些接口,比如输入时钟,PS 端复位信号,MIO 等

连接 FCLK_CLK0 到 M_AXI_GP0_ACLK,按 Ctrl+S 保存设计
知识点:DDR 和 FIXED_IO 是 PS 端引脚,PS_PORB 为 PS 端上电复位信号,不能用于 PL 端复位,
不要将 PL 端的复位绑定到这个引脚号上,切记!!

选择 Block 设计,右键“Create HDL Wrapper...”,创建一个 Verilog 或 VHDL 文件,为 block design
生成 HDL 顶层文件
保持默认选项,点击“OK”
展开设计可以看到 PS 被当成一个普通 IP 来使用
选择 block 设计,右键“Generate Output Products”,此步骤会生成 block 的输出文件,包括
IP,例化模板,RTL 源文件,XDC 约束,第三方综合源文件等等。供后续操作使用。

点击“Generate”
其实并不是说 PS 端的引脚不需要绑定,而是在 IP 生成的输出文件里已经包含了 PS 端引脚
分配的 XDC 文件,在 IP Sources,Block Designsdesign_1Synthesis 中,可以看到处理器
的 XDC 文件,绑定了 PS 端的 IO,因此不需要再新建 XDC 绑定这些引脚
在菜单栏“File -> Export -> Export Hardware...”导出硬件信息,这里就包含了 PS 端的配置信息

在弹出的对话框中点击“OK”,因为实验仅仅是使用了 PS 的串口,不需要 PL 参与,这里就
没有使能“Include bitstream”
此时会多出 xx.sdk 文件夹,并且有个 hdf 文件,这个文件就是这个文件就包含了 Vivado 硬件设
计的信息,供软件开发人员使用

SDK调试
点击 Vivado 菜单“File -> Launch SDK”,启动 SDK
启动SDK后我们会看到一个文件夹,有一个名为"system.hdf”文件,这个文件就包含了Vivado
硬件设计的信息,可以给软件开发使用,也可以看到 PS 端外设的寄存器列表
在 SDK 的菜单“New -> Application Project”,建立一个 APP 工程
Project name”填写“hello”,其他默认,点击“Next
模板选择“Hello World”,点击“Finish”

)可以看到 SDK 创建了一个“hello”目录,还有一个“hello_bsp”的目录,在“hello_bsp”
目录中可以找到很多有用的信息,软件开发人员比较清楚,BSP也就是Board Support Package
板级支持包的意思,里面包含了开发所需要的驱动文件,用于应用程序开发
双击“system.mss”,还可以看到有些 PS 外设还提供了例程,这是用来了解学习这些外设的
第一手资料。驱动文档说明可以在 Documentation 中找到。通过 Import Examples 引入官方
例子,加快学习
连接 JTAG 线到开发板、UART 的 USB 线到 PC
使用 PuTTY 软件做为串口终端调试工具,PuTTY 是一个免安装的小软件
选择 Serial,Serial line 填写 COM3,Speed 填写 115200,COM3 串口号根据设备管理器里显
示的填写,点击“Open”
在上电之前最好将开发板的启动模式设置到 JTAG 模式
给开发板上电,准备运行程序,开发板出厂时带有程序,这里可以把运行模式选择 JTAG 模
式,然后重新上电。选择“hello”,右键,可以看到很多选项,本实验要用到这里的“Run as”,
就是把程序运行起来,“Run as”里又有很对选项,选择第一个“Launch on Hardware(System
Debuger)”,使用系统调试,直接运行程序
这个时候观察 PuTTY 软件,可能有输出显示,也可能没有输出
为了保证系统的可靠调试,需要添加一个配置,右键“Run As -> Run Configuration...”
选择“Reset entire system”复位整个系统,如果系统中还有 PL 设计,还必须选择“Program
FPGA”,再次点击“Run”
这次就可以看到熟悉“Hello World”显示出来了
除了“Run As”,还可以“Debug As”,这样可以设置断点,单步运行

进入 Debug 模式

和其他 C 语言开发 IDE 一样,可以逐步运行、设置断点等

右上角可以切换 IDE 模式
固化程序
普通的 FPGA 一般是可以从 flash 启动,或者被动加载,ZYNQ 的启动是由 ARM 主导的,包
括 FPGA 程序的加载,ZYNQ 启动一般为最少两个步骤,在 UG585 中也有介绍:
Stage 0 :在上电复位或者热复位之后,处理器首先执行 BootRom 里的代码,这一步是最初始启
动设置。BootRom 存放了一段用户不可更改的代码,当然是在非 JTAG 模式下才执行,代码里包
含了最基本的 NAND,NOR,Quad-SPI,SD 和 PCAP 的驱动。另外一个很重要的作用就是把 stage 1 的代码搬运到 OCM 中,就是 FSBL 代码(First Stage Boot Loader),空间限制为 192KB
Stage 1: 接下来进入最重要的一步,当 BootRom 搬运 FSBL 到 OCM 后,处理开始执行 FSBL 代码, FSBL 主要有以下几个作用:
- 初始化 PS 端配置,这些配置也就是在 Vivado 工程中对 ZYNQ 核的配置。包括初始化 DDR, MIO,SLCR 寄存器。主要是执行 ps7_init.c 和 ps7_init.h,ps7_init.tcl 的执行效果跟 ps7_init.c是一样的。
- 如果有 PL 端程序,加载 PL 端 bitstream
- 加载 second stage bootloader 或者 bare-metal 应用程序到 DDR 存储器
- 交接给 second stage bootloader 或 bare-metal 应用程序
Stage 2: Second stage bootloader 是可选项,一般是在跑系统的情况下使用,比如 linux 系统的
u-boot,在这里不再介绍,后面会使用 petalinux 工具制作 linux 系统。
生成 FSBL
FSBL 是一个二级引导程序,完成 MIO 的分配、时钟、PLL、DDR 控制器初始化、SD、QSPI
控制器初始化,通过启动模式查找 bitstream 配置 FPGA,然后搜索用户程序加载到 DDR,最后
交接给应用程序执行。详情请参考 ug821 文档
新建一个名为 fsbl 的 APP,特别注意硬件平台选择最新的那个
模板选择 Zynq FSBL
添加调试宏定义 FSBL_DEBUG_INFO,可以在启动输出 FSBL 的一些状态信息,有利于调试,
但是会导致启动时间变长
修改后保存,SDK 默认会自动编译,生成 fsbl.elf 文件
可以看一下 fsbl 里包含了很多外设的文件,包括 ps7_init.c,nand,nor,qspi,sd 等,在 fsbl
的 main.c 中,第一个运行的函数就是 ps7_init,至于后面的工作,大家可以再仔细读读代码。当然这个 fsbl 模板也是可以修改的,至于怎么修改根据自己的需求来做
创建 BOOT 文件
选择 APP 工程,右键选择 Create Boot Image
弹出的窗口中可以看到生成的 BIF 文件路径,BIF 文件是生成 BOOT 文件的配置文件,还有
生成的 BOOT.bin 文件路径,BOOT.bin 文件是我们需要的启动文件,可以放到 SD 卡启动,
也可以烧写到 QSPI Flash
在 Boot image partitions 列表中有要合成的文件,第一个文件一定是 bootloader 文件,就是
上面生成的 fsbl.elf 文件,第二个文件是 FPGA 配置文件 bitstream,在本实验中由于没有 FPGA
的 bitstream,不需要添加,第三个是应用程序,在本实验中为 hello.elf,由于没有 bitstream,
在本实验中只添加 bootloader 和应用程序。点击 Create Image 生成
在生成的目录下可以找到 BOOT.bin 文件
SD 卡启动测试
格式化 SD 卡,只能格式化为 FAT32 格式,其他格式无法启动
放入 BOOT.bin 文件,放在根目录
SD 卡插入开发板的 SD 卡插槽
启动模式调整为 SD 卡启动
打开 putty 软件,上电启动,即可看到打印信息,红色框为 FSBL 启动信息,黄色箭头部分
为执行的应用程序 helloworld
QSPI 启动测试
在 SDK 菜单 Xilinx -> Program Flash

Hardware Platform 选择最新的,Image FIle 文件选择要烧写的 BOOT.bin,FSBL file 选择芯驿
电子定制的特别版本 fsbl.elf,只有用这个 fsbl 才能烧写。选择 Verify after flash,在烧写完
成后校验 flash
点击 Program 等待烧写完成
设置启动模式为 QSPI,再次启动,可以在 putty 里看到与 SD 同样的启动效果
Vivado 下烧写 QSPI
在 HARDWARE MANGER 下选择器件,右键 Add Configuration Memory Device
选择尝试 Winbond,类型选择 qspi,宽度选择 x4-single,这时候出现 w25q128,选择红框
型号,开发板使用 w25q256,但是不影响烧录
右键选择编程文件
选择要烧写的文件和 fsbl 文件,就可以烧写了,如果烧写时不是 JTAG 启动模式,软件会给
出一个警告,所以建议烧写 QSPI 的时候设置到 JTAG 启动模式
使用批处理文件快速烧写 QSPI
新建一个 program_qspi.txt 文本文件,扩展名改为 bat,内容填写如下,其中 set
XIL_CSE_ZYNQ_DISPLAY_UBOOT_MESSAGES=1 设置显示烧写过程中的 uboot 打印信息,
C:\Xilinx\SDK\2017.4\bin\program_flash 为我们工具路径,按照安装路径适当修改,-f 为要
烧写的文件,-fsbl 为要烧写使用的 fsbl 文件(芯驿电子特定文件),-blank_check -verify 为
校验选项
把要烧录的 BOOT.bin、fsbl、bat 文件放在一起
插上 JTAG 线后上电,双击 bat 文件即可烧写 flash
常见问题




本章从 FPGA 工程师和软件工程师两者角度出发,介绍了 ZYNQ 开发的经典流程,FPGA 工
程师的主要工作是搭建好硬件平台,提供硬件描述文件 hdf 给软件工程师,软件工程师在此基
础上开发应用程序。本章是一个简单的例子介绍了 FPGA 和软件工程师协同工作,后续还会牵
涉到 PS 与 PL 之间的联合调试,较为复杂,也是 ZYNQ 开发的核心部分。
同时也介绍了 FSBL,启动文件的制作,SD 卡启动方式,QSPI 下载及启动方式,Vivado 下载
BOOT.BIN 方式,本章没有 FPGA 加载文件,后面的应用中会再介绍添加 FPGA 加载文件制作
BOOT.BIN。