ZYNQ 入门笔记(一):开发流程
概述
ZYNQ 的工程设计大体上可以分为 对硬件逻辑系统的设计 和 对 CPU 软件程序的设计
硬件逻辑系统设计
:搭建一个满足用户需求的硬件环境,通过 Vivado 实现CPU 程序设计
:通过用户程序控制 CPU 工作,使整个系统达到预定的效果,该部分通过 Vitis 实现
两者间的关系及具体设计步骤如下图所示
xsa 文件为硬件资源描述文件,可以通过生成比特流或生成模块设计产生
涉及到 PL 端的设计
:导出 xsa 文件时需要包含比特流,因此通常使用 生成比特流(Bitstream) 的方式产生 xsa 文件纯 PS 端的设计
:导出时不需要比特流,因此两种方式皆可
接下来以按键控制 led 工程为例介绍 ZYNQ 开发的基本流程,本设计实现的功能如下
- 按下 PS 端按键 SW3,PL 端小灯 LED1 亮起,松开则小灯熄灭
- 按下 PL 端按键 SW1,PS 端小灯 LED5 亮起,松开则小灯熄灭
硬件逻辑系统设计
创建 Vivado 工程
双击打开 Vivado,点击 Create Project
填写工程名称并选择保存路径,勾选 Create project subdirectory 则项目保存在 {Project location}/{Project name}
文件夹下,点击 Next
选择 RTL Project,点击 Next
根据实际情况选择芯片,笔者所用开发板型号为 MZ7035FD,芯片型号为 xc7z035ffg676-2,点击 Next
点击 Finish,项目创建完成
创建模块设计
点击 Create Block Design 创建模块设计
在弹出的窗口中修改设计命名(注意不能包含中文及空格),点击 OK 完成创建
可以看到 Design 栏出现了我们刚创建好的 system 模块设计
构建硬件系统
此时我们的设计内没有任何内容,需要点击 + 为设计添加 IP 核
在弹出的搜索栏中输入 zynq,可以看到下方出现了 ZYNQ7 Processing System,双击该 IP 核添加
ZYNQ IP 核的配置通常有两个必需配置的部分:使能外设和配置 DDR 型号。双击 ZYNQ IP 核即可打开配置界面,如下图所示
右侧栏为 ZYNQ 的图形化向导界面,绿色部分为可配置界面,单击即可快速跳转到对应项设置。左侧栏为 ZYNQ IP 核配置的导航窗口,共分为 8 个部分,对应功能如下
ZYNQ Block Design
:图形化向导界面PS-PL Configuration
:PS-PL 接口配置界面,可以对 AXI、HP、DMA 等总线接口进行配置Peripheral I/O Pins
:I/O 外设引脚配置界面,可对 I/O 外设引脚进行 MIO 以及 EMIO 的配置,配置时需要注意 Bank 电平MIO Configuration
:MIO 配置界面,相较于 I/O 外设引脚配置界面功能更为复杂Clock Configuration
:时钟配置界面,用于配置 PS 输入时钟、外设时钟、DDR 时钟和 CPU 时钟等DDR Configuration
:DDR 配置界面,控制 DDR 型号以及细节参数等SMC Timing Calculation
:SMC 时序计算界面,可进行 SMC 时序计算Interrupts
:中断控制界面,可对 PS 与 PL 间的中断进行配置
ZYNQ 中的外设接口由对应控制器控制,使用时需要先进行使能。点击图形化向导界面的 I/O Peripherals 中对应的外设接口便可以跳转到相应的配置界面,点击 GPIO 即可进入相应配置界面
本设计通过 PS 与 PL 侧的按键控制另一侧的 LED 灯,每个按键和 LED 灯都需要一个 GPIO 信号。GPIO 连接到 PS 部分使用的是 MIO 接口,连接到 PL 部分使用的则是 EMIO 接口,因此我们需要使能这两个外设接口。PS 端的引脚是固定的,我们不需要分配;PL 端的按键和 LED 灯都需要一个 EMIO 信号,因此我们将 EMIO 的位宽设置为 2
设置完成后检查电平状态,将 Bank1 的电平设置为 1.8V
使能完成后返回图形化向导界面,可以看到此时在 GPIO 外设后面已经打上 √ 了,代表我们已经使能该接口
接下来开始配置 DDR,DDR 全名为双速率同步动态随机存储器(Double Data Rate Synchronous Dynamic Random Access Memory),也就是我们常说的 内存。基于 PS 端的应用,大部分都需要基于片外存储外设 DDR 上允许。点击图像化界面的 DDR 控制器即可跳转到配置界面
使能 DDR 并选择 DDR 型号,笔者使用的是 MT41K256M16 RE-125
点击 OK,可以看到此时 ZYNQ 的 IP 核如图所示
点击上方的蓝色小字 Run Block Automation 系统就会自动帮我们导出引脚,勾选 All Automation 后点击 OK 即可
导出完成后可以看到软件帮我们导出了 ZYNQ 的两个引脚,但 GPIO_0 还未导出,因此我们需要手动将其导出
点击 GPIO_0 引脚,然后右键点击 Make External 导出引脚
该设计中 ZYNQ IP 核在配置时,有几个端口信号是没有被使用到的
FCLK_RESET0_N
:全局复位信号,低电平有效M_AXI_GP0
:通用 AXI 接口信号,M 代表其作为主机信号M_AXI_GP0_ACLK
:M_AXI_GP0 的输入时钟信号FCLK_CLK0
:PS 输出时钟信号
其中,M_AXI_GP0_ACLK 虽然本设计中并未使用到,但如果不给其一个输入信号,软件便会报错
为了防止出现该现象,我们只需要将 FCLK_CLK0 和 M_AXI_GP0_ACLK 连接即可。连接时只需选中其中一个引脚按住鼠标左键拖动到对应的引脚即可
端口连接完成后使用快捷键 Ctrl+S 保存设计,随后点击上方的 √ 来对设计进行验证
当出现以下弹窗时证明设计无误
生成封装
点击 sources 资源栏我们创建的 system 模块设计,右键选择 Generate Output Products 生成输出
选择 Out Of context per IP,点击 Generate
点击 sources 资源栏我们创建的 system 模块设计,右键选择 Create HDL Wrapper 以创建 HDL 封装
在弹出的窗口中选择让 Vivado 管理封装和自动更新,随后点击 OK 开始创建封装
如果工程资源栏的右上角出现 Updating 的字样表明封装正在创建和更新中,当字样消失且 Sources 栏出现蓝色名为 system_wrapper 的设计文件时,则代表封装已经创建和更新完成
管脚约束
对于涉及 PL 端的设计,在完成封装后我们需要对涉及到的管脚进行分配和约束。点击左侧导航栏的 Open Elaborated Design 进行约束和分配
点击 OK
根据实际情况绑定引脚并设置电平约束,笔者使用的 MZ7035FD 板载接口如下
板载设备 | ZYNQ 接口 |
---|---|
SW1 | H12 |
SW3 | MIO50 |
LED1 | F13 |
LED5 | MIO51 |
使用快捷键 Ctrl+S 保存约束文件,在弹窗中输入约束文件名,点击 OK 即可
生成比特流
完成了管脚约束后即可开始比特流的生成,比特流中包含着对 PL 端的配置信息,其中就包括对 引脚的分配 以及 电平的约束,因此生成比特流需要在进行管脚分配和约束之后。当然如果设计并未使用到 PL 部分资源,可以直接跳过该环节。点击左侧工具栏 Generate Bitstream 开始生成比特流
此时软件会提示 ”没有可用的实现结果,是否先进行综合实现再自动生成比特流“,我们直接点击 Yes 即可
导出硬件
File > Export > Export Hardware
点击 Next
对于纯 PS 端的设计,选择哪一项都可以,而涉及到 PL 端的设计必须选择 Include bitstream,点击 Next
设置 xsa 文件名称及保存路径,点击 Next
点击 Finish 即可
启动 Vitis
硬件导出完成后 Vivado 部分的设计已经完成,接下来打开 Vitis 开始 CPU 软件程序设计。点击 Tools > Launch Vitis IDE
CPU软件程序设计
创建工程
Vitis 将芯片视为一个平台,平台的相关信息通过此前导出的 xsa 文件描述,工程间的关系如下
File > New > Application Project,点击 Next
选择 Create a new platform from hardware (XSA),点击 Browse 选择此前导出的 xsa 文件,或者从列表中选择与开发板相匹配的
等待 xsa 文件加载完成,点击 Next
设置工程名称,点击 Next
点击 Next
选择工程模板,点击 Finish 即完成创建
点击 Finish 即可完成创建
添加应用库
对于某些开发板,厂商可能提供已经编写完善的应用库,若要使用这些应用库就需要将相关文件添加到项目中。以应用库 MZ7035FD_Lib 为例,首先将文件夹复制到项目中
选中项目,右键 Properties
选择 Paths and Symbols,点击右侧 Add 将应用库添加至头文件路径,否则编译时会提示找不到相关文件
点击 Workspace
选择应用库文件夹,点击 OK
点击 OK
点击 Apply and Close
添加用户代码
在项目 src 文件夹下创建文件 main.c
本设计示例代码如下
1 | /* main.c |
1 | /* PS_GPIO.h |
1 | /* PS_GPIO.c |
板级验证与调试
选择工具栏运行按钮,点击 Run Configurations…
双击 Single Application Debug (GDB) 创建配置
选择 Target Setup,取消勾选 Reset entire system,否则烧录后会报错
点击运行按钮即可自动下板运行
点击调试按钮即可下板调试
调试相关按钮(全速运行、暂停、停止、进入函数、跳过语句)
程序固化
项目调试通过后,将代码固化至 Flash 或 SD 卡以在启动时自动加载程序,下面介绍 Zynq 固件打包、下载流程
打包
点击工具栏 Build 图标,勾选 Release 模式,程序将自动在 Release 模式下编译一次
点击工具栏 Xilinx > Create Boot Image > Zynq and Zynq Ultrascale
选择芯片架构(Zynq 或 Zynq UltraScale + MPSoC)、BIF 文件路径和固件路径,BOOT.bin 文件即在 Output path 下
固件 BOOT.bin 一般由 bootloader
、elf
和 bitstream
三部分打包而成(不涉及 PL 端的应用没有 bitstream)
bootloader
:负责初始化 PS 端外设、加载 PL 端数据流、加载 PS 端用户程序等elf
:用户程序bitstream
:PL 端数据流
首先添加 bootloader 文件,点击 Boot image partitions 中的 Add
选择 FSBL 文件(通常在 {platform_project}/zynqmp_fsbl 路径下),设置 Partition type 和 Destination Device 和 Destination CPU,点击 OK 添加完成
接下来添加用户程序 elf 文件(通常在 {application_project}/Debug 或 {application_project}/Release 路径下),推荐打包 Release 模式下的固件,可以获得更好的性能
最后添加 PL 端比特流
点击 Create Image 即可生成固件
BOOT.bin 即为生成的固件
下载
下载至 SD 卡
将启动模式设置为 SD 卡启动,一般通过拨码开关调整,如 ZCU106 板卡在该模式下需要将 SW6 设置为 1110
需要注意的是,Zynq Ultrascale+ 系列支持 SD0 (2.0)、SD1 (2.0) 和 SD1 LS (3.0) 三种 SD 卡启动模式 [UG1085]
SD0 (2.0) 和 SD1 (2.0) 兼容 SD2.0 电平标准(3.3V),对应 Ultrascale 的两个 SD 控制器,使用时根据 SD 卡槽硬件连接关系选择。SD1 LS (3.0) 兼容 SD3.0 电平标准 (1.8V),若 SD 卡槽为 3.3V 电平则该模式下无法启动
将 BOOT.bin 文件拷贝至 SD 卡 根目录 下(SD 卡需要格式化为 FAT32 格式),重新上电即可自动加载程序
Vitis 联合 VSC 编程
Vitis 在编写代码时需要通过快捷键 Alt+?
启用代码提示,使用体验非常差。为此下面介绍如何使用 VS Code 编写代码,效果如下
首先在 VS Code 中打开 Vitis 项目文件夹,鼠标放置在报错部分 > 快速修复 > 编辑 “includePath” 设置
更改编译器为 gcc
此时报错信息消失,按住 Ctrl 并用鼠标点击变量、函数名等已可以查看其定义、跳转函数,开始用 VS Code 愉快地编程吧!
Vivado 联合 Modelsim 仿真
Modelsim 在仿真速度和使用体验上均要优于 Vivado 自带的仿真器,因此接下来将介绍如何在 Vivado 中调用 Modelsim 进行仿真
编译 Vivado 仿真库
Modelsim 安装完成后并不包含 Xilinx 相关的器件库,因此需要先编译后才能使用。打开 Vivado,Tools > Compile Simulation Libraries
设置 Simulator 为 Modelsim Simulator,选择编译库存放路径和 modelsim.exe 所在文件夹,勾选 Compile Xilinx IP,点击 Compile
等待编译完成
设置仿真工具和库路径
Vivado 新建工程的默认仿真工具是 Vsim,使用 Modelsim 需要修改设置,点击 Tools > Settings
侧边栏选中 Simulation,设置 Target Simulator 为 Modelsim Simulator,点击 Yes
设置 Xilinx 编译库路径,点击 OK
点击侧边栏 Run Simulation > Run Behavioral Simulation
等待 Modelsim 仿真结果,大功告成!
参考文献
[1] 小梅哥. 基于C编程的Zynq裸机程序设计与应用教程