3. Vivado与Vitis工具链工程搭建

在AMD FPGA工业控制与实时信号处理项目中,工具链工程搭建是后续所有开发工作的物理载体。Vivado负责硬件逻辑的综合、实现与比特流生成,Vitis负责在已导出的硬件平台上构建软件应用。两者通过XSA(Xilinx Support Archive)文件衔接,形成"硬件平台—软件应用"的完整工程体系。本节以一个典型的工业控制场景为例:在Zynq-7000或Zynq UltraScale+ MPSoC上实现一路PWM输出与一路ADC采样控制,讲解从工程创建到比特流下载的全过程,并给出可落地的版本管理策略。

一、工程创建:目录结构与器件选型

Vivado工程创建的第一步不是点"New Project",而是先规划磁盘目录。推荐采用"工程根目录 + 源码分离"的结构,避免综合产物与设计源码混在一起:

industrial_ctrl/
├── rtl/                 # 设计源码(.v/.sv)
│   ├── pwm_gen.v
│   └── adc_ctrl.v
├── constrs/             # 约束文件(.xdc)
│   └── top.xdc
├── sim/                 # 仿真文件
├── ip/                  # IP核配置(.xci)
├── scripts/             # Tcl脚本
│   ├── create_project.tcl
│   └── build.tcl
└── vivado_prj/          # Vivado工程目录(可删除重建)

这种结构的关键价值在于:vivado_prj/目录可以随时删除并由Tcl脚本重建,而rtl/、constrs/、ip/才是真正需要纳入版本管理的资产。创建工程时,器件选型必须与实际硬件一致。例如目标板卡为XC7Z020-2CLG400I,则在Tcl中写为:

create_project industrial_ctrl ./vivado_prj -part xc7z020clg400-2
set_property board_part digilentinc.com:zybo-z7-20:part0:1.1 [current_project]

若器件型号或速度等级选错,后续综合可能通过,但实现阶段会出现时序无法收敛或引脚不匹配的问题,且排查成本极高。因此工程创建后应立即核对report_property [current_project]中的PART属性。

二、约束文件:XDC的三类核心约束

XDC(Xilinx Design Constraints)文件是连接逻辑设计与物理器件的桥梁。工业控制项目中,XDC至少应包含三类约束:

  • 引脚约束:将顶层端口映射到FPGA实际引脚,并指定I/O电平标准。例如PWM输出接LED或驱动芯片,ADC接口接PMOD或FMC连接器。
  • 时钟约束:定义输入时钟周期,供时序引擎计算建立/保持余量。例如create_clock -period 20.000 -name sys_clk [get_ports sys_clk]表示50MHz时钟。
  • 时序例外:对跨时钟域路径、异步复位、伪路径进行声明,避免工具过度优化或误报违例。

以下是一个面向工业控制板的XDC片段示例:

# 时钟约束:50MHz输入
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]

# 引脚约束
set_property PACKAGE_PIN H16 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property PACKAGE_PIN P15 [get_ports pwm_out]
set_property IOSTANDARD LVCMOS33 [get_ports pwm_out]

# 异步复位伪路径
set_false_path -from [get_ports rst_n]

# 跨时钟域:ADC数据从adc_clk到sys_clk
set_clock_groups -asynchronous -group [get_clocks adc_clk] -group [get_clocks sys_clk]

约束文件应随RTL源码一同纳入Git管理。每次修改引脚或时钟后,必须重新运行综合与实现,并通过report_timing_summary确认WNS(最差负裕量)≥0。若WNS为负,说明设计未满足时序,比特流即使生成也不可靠。

三、综合、实现与比特流生成

Vivado的构建流程分为综合(Synthesis)与实现(Implementation)两个阶段。综合将RTL转换为门级网表,实现则完成布局布线并生成时序报告。工业控制项目建议使用Tcl脚本驱动全流程,便于复现和CI集成:

# build.tcl
open_project ./vivado_prj/industrial_ctrl.xpr
reset_run synth_1
launch_runs synth_1 -jobs 8
wait_on_run synth_1
launch_runs impl_1 -to_step write_bitstream -jobs 8
wait_on_run impl_1
write_bitstream -force ./vivado_prj/industrial_ctrl.bit

综合完成后应检查report_utilization,确认LUT、FF、BRAM、DSP的占用率。以XC7Z020为例,若LUT占用超过70%,后续增加功能可能无法布局。实现完成后必须查看report_timing_summary,重点关注WNS、TNS(总负裕量)和WHS(最差保持裕量)。只有三者均满足要求,比特流才具备下载价值。

Vivado → Vitis 工程链路与版本管理节点 Vivado 硬件侧 ① 工程创建 器件选型 / 目录规划 ② XDC 约束 引脚 / 时钟 / 时序例外 ③ 综合 Synthesis RTL → 门级网表 ④ 实现 Implementation 布局布线 / 时序收敛 ⑤ 生成比特流 .bit + .xsa XSA 硬件平台描述 导出 Vitis 软件侧 ⑥ 创建 Platform Project 导入 XSA / 配置 BSP ⑦ 创建 Application Project C/C++ 应用 / 链接脚本 ⑧ 编译与调试 生成 .elf / JTAG 调试 ⑨ 下载与运行 比特流 + ELF 联合下载 ⑩ 固化到 Flash BOOT.bin / 上电自启动 导入 Git 版本管理:rtl/ · constrs/ · ip/ · scripts/ · vitis_src/ 纳入仓库;vivado_prj/ · .bit · .elf 通过 .gitignore 排除

四、Vitis工程创建与软硬件协同

比特流生成后,通过File → Export → Export Hardware导出XSA文件,勾选"Include bitstream"。随后启动Vitis,创建Platform Project并导入该XSA。Vitis会自动解析硬件信息,生成BSP(Board Support Package),其中包含外设驱动、地址映射和中断控制器配置。

在Platform基础上创建Application Project,选择"Hello World"或空模板。对于工业控制应用,通常需要操作GPIO、PWM和ADC。以下是一个基于Zynq的PWM寄存器写操作示例:

#include "xil_io.h"
#define PWM_BASEADDR 0x43C00000
#define PWM_PERIOD   0x00000000
#define PWM_DUTY     0x00000004

int main(void) {
    // 设置PWM周期为1000个时钟周期
    Xil_Out32(PWM_BASEADDR + PWM_PERIOD, 1000);
    // 设置占空比为300,即30%
    Xil_Out32(PWM_BASEADDR + PWM_DUTY, 300);
    return 0;
}

编译生成.elf文件后,通过JTAG将比特流与ELF联合下载。在Vitis中右键Application Project → Run As → Launch Hardware,工具会自动完成FPGA配置和CPU程序加载。若需上电自启动,则需将比特流、FSBL和ELF打包为BOOT.bin,写入QSPI Flash或SD卡。

五、版本管理策略

FPGA工程的版本管理不能简单地把整个工程目录塞进Git。推荐做法是:将rtl/、constrs/、ip/、scripts/和Vitis源码目录纳入版本控制;将vivado_prj/、.bit、.elf、.xsa等生成物通过.gitignore排除。每次提交应附带Tcl脚本,使任何人在任意机器上执行vivado -mode batch -source create_project.tcl即可重建工程。

对于团队协作,建议在Git中为每次比特流发布打Tag,例如v1.0-pwm-adc,并在Release中附带对应的XSA和BOOT.bin。这样软件工程师可以基于确定的硬件版本开发,避免"硬件改了但软件不知道"的经典问题。
常见陷阱:修改XDC后未重新综合就直接生成比特流,导致引脚约束未生效;或在Vitis中修改了硬件地址却未更新XSA,导致软件访问错误地址。每次硬件变更后,必须重新导出XSA并刷新Vitis Platform。

整个流程的核心判断节点有三个:综合后看资源占用是否合理,实现后看时序是否收敛,下载后看功能是否与预期一致。三者依次通过,才算完成一次可靠的工程构建。