硬件设计基础:Block Design 创建、PS 端 IP 核配置与硬件描述文件导出
好,我们正式开始动手。这一章是 Zynq 开发的基石——把硬件搭起来,让 PS 能跑起来。说白了,就是给芯片“通电、定速、连腿”。
很多初学者一上来就写驱动,结果发现外设根本不工作。为什么?因为硬件描述文件(XSA/HDF)就没配对。我刚开始带项目时也吃过这个亏,板子调了三天,最后发现是时钟频率算错了一位。嗯,从那以后,我养成了一个习惯:先花半小时把 Block Design 理清楚,再写一行代码。
3.1 Block Design 是什么?为什么需要它?
Block Design 是 Vivado 里的一种图形化设计方式。你不需要手写 HDL 代码去例化 Zynq 的 PS 端,而是像搭积木一样,把 PS 的 IP 核拖出来,连上需要的接口,配置好参数。
我个人习惯把 Block Design 理解为“芯片的说明书”。它告诉编译器:PS 用哪个时钟、DDR 是什么型号、MIO 哪些引脚被占用了。Vivado 根据这张图,生成最终的硬件描述文件(XSA),供 SDK/Vitis 使用。
3.2 创建 Block Design 的步骤
操作其实不复杂,我带你过一遍关键流程:
- 新建 Vivado 工程:选择对应的 Zynq 芯片型号(比如 XC7Z020)。
- 创建 Block Design:在 Flow Navigator 里点 "Create Block Design",给个名字,比如 "system"。
- 添加 Zynq PS IP:在 Diagram 窗口右键,选 "Add IP",搜索 "Zynq7 Processing System",双击添加。
- 自动连接:Vivado 会弹出 "Run Block Automation",点确定。它会帮你把基础的时钟、复位、DDR 接口连好。
- 手动调整:根据你的板子,修改 DDR 型号、时钟频率、MIO 分配。
这里有个小技巧:每次修改完 Block Design,记得点一下 "Validate Design"(绿色勾)。我遇到过好几次,连错线导致综合报错,查了半天才发现是 Block Design 里有个悬空脚。
3.3 PS 端 IP 核配置:时钟、DDR、MIO/EMIO
双击 Block Design 里的 Zynq PS IP 核,会弹出配置界面。这里我重点讲三个最关键的选项卡。
3.3.1 时钟配置(Clock Configuration)
Zynq 内部有多个时钟域。PS 主频(CPU_CLK)通常跑 666MHz 或 800MHz,DDR 时钟取决于你的内存颗粒。我个人习惯这样配:
| 时钟名称 | 典型频率 | 说明 |
|---|---|---|
| CPU_CLK | 666.667 MHz | PS 主频,决定处理速度 |
| DDR_CLK | 533.333 MHz | DDR3 常用,DDR4 可能更高 |
| IO_PLL | 自动 | 用于 MIO 外设时钟 |
| FCLK_CLK0 | 100 MHz | 可输出给 PL 使用 |
3.3.2 DDR 配置(DDR Configuration)
这个选项卡里,你需要选择 DDR 类型(DDR3、DDR4、LPDDR2 等),以及具体的颗粒型号。Vivado 自带了一个颗粒库,你直接搜型号就行。
如果找不到完全匹配的型号,可以手动填参数:行地址数、列地址数、Bank 数、数据位宽。我建议你优先选官方支持的颗粒,否则时序可能有问题。
3.3.3 MIO/EMIO 配置(MIO Configuration)
MIO 是 PS 端专用的 54 个引脚,每个引脚可以复用为 UART、I2C、SPI、GPIO 等。EMIO 则是把 PS 的外设信号扩展到 PL 端,通过 PL 的引脚输出。
配置时,你只需要勾选需要用到的外设,并分配引脚。比如:
- UART1:勾选,MIO 分配为 48 和 49(常用调试串口)。
- I2C0:勾选,MIO 分配为 10 和 11(接 EEPROM)。
- GPIO:勾选 EMIO,宽度设为 1(通过 PL 引脚控制 LED)。
这里有个容易忽略的点:MIO 的电压等级。Zynq 的 MIO 分为多个 Bank,每个 Bank 可以独立设置电压(1.8V 或 3.3V)。如果你接的外设是 3.3V 的,但 Bank 设成了 1.8V,那通信肯定失败。我刚开始用 Zynq 时就犯过这个错,UART 怎么都打印不出数据,最后发现是 Bank 电压没对上。
3.4 导出硬件描述文件(XSA/HDF)
Block Design 配置完成后,需要导出硬件描述文件,供 SDK/Vitis 使用。在 Vivado 里,操作很简单:
- 先 Generate Output Products:右键 Block Design,选这个选项,Vivado 会生成综合和实现需要的文件。
- 再 Create HDL Wrapper:让 Vivado 自动生成顶层 HDL 文件。
- 最后 Export Hardware:File → Export → Export Hardware。勾选 "Include bitstream"(如果 PL 端有逻辑)。
导出的文件后缀是 .xsa(Vivado 2019.1 之后)或 .hdf(旧版本)。这个文件包含了:
- PS 配置信息(时钟、DDR、MIO)
- 地址映射表
- 中断号分配
- PL 端 bitstream(如果有)
3.5 本章知识体系总览
为了让你更直观地理解整个流程,我画了一张图:
这张图把整个流程串起来了。你跟着走一遍,基本不会漏掉关键步骤。
3.6 常见问题与避坑
最后,我总结几个实际项目中容易踩的坑:
- 时钟频率不对:CPU_CLK 和 DDR_CLK 的比值有约束,不是随便设的。建议用 Vivado 的自动计算功能。
- MIO 冲突:同一个 MIO 引脚不能同时分配给两个外设。配置时留意右下角的冲突提示。
- 忘记导出 XSA:改完 Block Design 后,一定要重新导出。我见过有人改了三遍硬件,SDK 里用的还是第一版 XSA,结果调试了整整两天。
- DDR 颗粒不匹配:如果板子上的 DDR 型号在 Vivado 库里找不到,手动填参数时一定要仔细核对数据手册。
好了,这一章的内容就到这里。硬件基础打牢了,后面写驱动才能顺风顺水。记住:Block Design 配得好,调试烦恼少。