2. Vivado工程搭建:创建Block Design、配置MIO/EMIO、导出硬件描述文件(XSA)

好,咱们正式开始动手。这一章是Zynq开发的基础操作,说白了就是给PS端画一张“硬件地图”。你后面写的所有驱动代码,都得在这张地图上跑。我见过不少新手,上来就写代码,结果外设死活不工作,回头一查——MIO管脚配错了。嗯,咱们别走这个弯路。

2.1 创建Block Design——搭积木的第一步

打开Vivado,新建工程。选芯片型号的时候,我建议你直接搜你板子上的具体型号,比如XC7Z020-1CLG484C。别偷懒选个通用型号,有些封装差异会导致后面布线失败。

工程建好后,左侧Flow Navigator里点Create Block Design。名字我一般用默认的design_1,省事。

我的习惯:每次新建BD之前,先确认一下工程目录没有中文路径。Vivado对中文支持不太好,我曾经因为这个折腾了一下午,最后发现是路径里有“项目”两个字。

在Diagram窗口空白处右键,选Add IP,搜索Zynq,双击添加Zynq7 Processing System。这时候你会看到一个灰色的方块,上面标着ZYNQ7 PS——这就是咱们的处理器系统。

2.2 配置MIO——把管脚分配清楚

双击那个灰色方块,弹出配置界面。这里才是重头戏。左侧导航栏选MIO Configuration,你会看到一张表格,列出了所有MIO管脚(0~53)。

每个MIO管脚可以复用多种功能。比如MIO 14,你可以把它配成UART1的TX,也可以配成SPI0的SCLK。怎么选?看你的板级原理图。

MIO编号 默认功能 常用复用功能 我踩过的坑
MIO 14~15 GPIO UART1 (TX/RX) 忘记勾选UART,串口死活没输出
MIO 16~19 GPIO SPI0 (SCLK/MOSI/MISO/SS) SPI时钟极性配反,通信全是乱码
MIO 40~43 GPIO SD0 (CLK/CMD/DAT0~DAT3) SD卡初始化失败,原来是电压等级没选1.8V
MIO 50~53 GPIO ENET0 (TXD0~TXD3) 千兆以太网跑不通,发现MIO 53被误配成GPIO

配置的时候,我建议你遵循一个原则:先看原理图,再动手配。把板子上每个外设对应的MIO编号列个清单,然后一项一项在Vivado里勾选。别凭记忆配,我吃过这个亏。

注意:MIO管脚一旦被某个外设占用,其他外设就不能再用。比如你配了UART1用MIO 14/15,那这两个管脚就不能再当GPIO用。Vivado会帮你检查冲突,但不会帮你自动解决——它只会报错。

2.3 EMIO配置——扩展你的管脚

MIO只有54个,有时候不够用。这时候就要用EMIO了。EMIO本质上是把PS的管脚通过PL(可编程逻辑)扩展出去,数量可以到64个。

在配置界面的MIO Configuration里,找到EMIO那一栏。勾选GPIO EMIO,然后设置宽度。比如你要用8个EMIO管脚,就填8。

配置完成后,BD里会出现一组新的管脚——GPIO_0,展开后能看到GPIO_0_tri_io[7:0]。这些管脚需要你手动连到PL侧的顶层端口上。

关键区别:

  • MIO:直接连到PS,延迟低,不需要PL参与。适合高速外设(如千兆以太网、SD卡)。
  • EMIO:经过PL再出去,延迟稍大,但数量灵活。适合低速控制信号(如LED、按键、复位)。

我个人习惯把EMIO用在那些“丢了也不心疼”的信号上。比如板子上的几个LED指示灯,用EMIO控制就行。但如果是SD卡的时钟线,我坚决走MIO——少一层PL绕线,时序更可靠。

2.4 自动连接与验证

配置完MIO和EMIO后,回到Diagram窗口。点击上方工具栏的Run Block Automation,Vivado会自动帮你连好时钟、复位、DDR接口等基础信号。

然后点Run Connection Automation,它会扫描所有未连接的接口,弹出一个对话框。我建议你全选,然后点OK。Vivado会帮你把AXI总线、中断线这些乱七八糟的连线都搞定。

连线完成后,右键点击BD空白处,选Validate Design。Vivado会检查有没有漏连的线、有没有冲突的地址。如果有错误,它会告诉你具体位置。我一般会等到Validation Successful再往下走。

一个小技巧:验证通过后,按Ctrl+S保存BD。然后右键点击BD文件,选Generate Output Products。这一步会生成所有IP的例化模板和综合文件,后面综合的时候能省不少时间。

2.5 导出硬件描述文件(XSA)

BD建好了,验证通过了,接下来要把它变成SDK能认的东西。这个文件就是XSA(Xilinx Support Archive)。

操作很简单:在Vivado的菜单栏选File → Export → Export Hardware。弹出来的对话框里,记得勾选Include bitstream——如果你用了PL侧的IP(比如EMIO),就必须把bitstream一起打包进去。

然后点Next,选择输出路径。我习惯放在工程根目录下的export文件夹里,文件名用system_wrapper.xsa。

导出完成后,你会得到一个.xsa文件。这个文件包含了:

  • PS的配置信息(MIO/EMIO分配、时钟频率、DDR参数)
  • PL侧的bitstream(如果有)
  • 中断路由表
  • 地址映射关系

后面在Vitis(或者老版本的SDK)里新建工程时,就要用这个XSA文件作为硬件平台。没有它,你的驱动代码连寄存器地址都找不到。

我曾经犯过的错:有一次我改了BD里的MIO配置,但忘了重新导出XSA。结果在Vitis里编译通过,下载到板子上就是跑不起来。查了两天,最后发现XSA还是旧版本的。从那以后,我每次改BD都会重新导出XSA,并且把文件名加上日期后缀,比如system_wrapper_20250315.xsa。

2.6 本章知识结构图

下面这张图帮你理清整个流程。从创建BD开始,到配置MIO/EMIO,再到验证和导出XSA,每一步都有对应的输出产物。

Vivado工程搭建流程 Vivado工程搭建核心流程 创建Block Design 添加Zynq PS IP 配置MIO / EMIO 根据原理图分配管脚功能 Run Automation Export Hardware → XSA 关键输出产物 • design_1.bd (Block Design) • system_wrapper.v (顶层HDL) • system_wrapper.xsa (硬件描述) 常见错误 • MIO管脚冲突 • 忘记勾选Include bitstream 我的建议 • 每次改BD重新导出XSA • XSA文件名加日期后缀

嗯,这一章的内容就这些。BD建好了,XSA导出了,接下来就可以在Vitis里写驱动代码了。不过在那之前,我建议你先花10分钟把板子上的外设原理图对照着BD再检查一遍——管脚配对了,后面调试能省一半时间。