2. 开发环境与工具链:Vivado/Vitis环境搭建、驱动编译、硬件平台配置、JTAG与串口调试基础
说实话,很多做算法的人觉得环境搭建是「体力活」。但在我眼里,这是整个上板联调的地基。地基没打好,后面所有调试都是空中楼阁。我自己就吃过这个亏——有一次花了两周查一个莫名其妙的时序问题,最后发现是Vivado版本和驱动不匹配。嗯,从那以后,我再也不敢轻视环境配置了。
2.1 Vivado/Vitis环境搭建——别小看这一步
Vivado和Vitis,说白了就是Xilinx的两把刷子。Vivado负责硬件设计,Vitis负责软件开发。你想想看,一个加速器项目,硬件和软件是绑在一起的,所以这两个工具都得装。
版本选择:我个人习惯用LTS版本,比如2022.2或2023.1。为什么?因为新版本虽然功能多,但坑也多。我在项目中遇到过2023.2版本的一个bug——HLS综合出来的IP核在Vivado里死活连不上AXI总线。后来降级到2023.1就没事了。
安装步骤(以Ubuntu 20.04为例):
- 下载Xilinx Unified Installer,约80GB(嗯,确实很大,建议提前准备硬盘空间)
- 运行安装脚本:
./xsetup - 选择「Vivado + Vitis」组合包,勾选「Device Support」里的对应FPGA型号
- 安装路径建议不要有中文和空格,我一般放在
/tools/Xilinx - 安装完成后,配置环境变量:
# 在 ~/.bashrc 末尾添加
source /tools/Xilinx/Vivado/2022.2/settings64.sh
source /tools/Xilinx/Vitis/2022.2/settings64.sh
export LM_LICENSE_FILE=2100@license_server_ip # 如果有license服务器
配置完记得source ~/.bashrc,然后输入vivado -version验证。如果看到版本号,说明环境搭好了。
2.2 驱动编译——从源码到内核模块
驱动编译这块,很多初学者觉得难。其实核心就三步:下载源码、配置内核、编译安装。我当年第一次编译Xilinx驱动时,卡在「内核头文件不匹配」这个问题上整整一天。后来发现是Ubuntu自动更新了内核版本,但头文件没同步更新。
驱动源码获取:
- Xilinx官方驱动:在Vitis安装目录下的
Vitis/2022.2/data/embeddedsw/XilinxProcessorIPLib/drivers/ - 或者从GitHub克隆:
git clone https://github.com/Xilinx/embeddedsw.git
编译步骤:
# 1. 进入驱动目录
cd /path/to/embeddedsw/XilinxProcessorIPLib/drivers/axidma_v9_4/src
# 2. 检查内核版本
uname -r # 比如输出 5.15.0-86-generic
# 3. 安装对应内核头文件
sudo apt-get install linux-headers-$(uname -r)
# 4. 编译驱动
make
sudo make install
# 5. 加载驱动模块
sudo modprobe axidma
验证驱动是否加载成功:lsmod | grep axidma。如果看到输出,说明驱动已经跑起来了。
2.3 硬件平台配置——Block Design的艺术
硬件平台配置,说白了就是在Vivado里搭积木。你需要把PS(处理系统)和PL(可编程逻辑)通过AXI总线连起来。我刚开始做的时候,总觉得连线很简单,结果有一次把S_AXI和M_AXI接反了,仿真没问题,上板就死机。
典型配置流程:
- 创建Vivado工程,选择对应FPGA型号(比如Zynq-7000系列)
- 添加Zynq Processing System IP核
- 配置PS端:DDR、UART、SD卡等外设
- 添加AXI DMA或AXI Direct Memory Access IP核
- 添加卷积加速器IP核(自己写的或者HLS生成的)
- 自动连线(Run Block Automation)
- 生成顶层HDL文件
- 综合、实现、生成比特流
关键配置项:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| DDR型号 | MT41K256M16RE-125 | 根据板卡实际型号选择 |
| UART波特率 | 115200 | 串口调试常用 |
| AXI数据位宽 | 64位或128位 | 卷积加速器建议128位 |
| 时钟频率 | 100MHz~200MHz | 根据时序收敛情况调整 |
2.4 JTAG与串口调试基础——你的眼睛和耳朵
上板调试,JTAG和串口就是你的眼睛和耳朵。JTAG用来下载比特流和调试硬件,串口用来打印软件日志。两者缺一不可。
JTAG调试:
- 连接方式:USB-JTAG线缆连接PC和板卡
- 在Vivado中打开Hardware Manager,自动识别设备
- 下载比特流:右键设备 -> Program Device
- 调试技巧:使用ILA(集成逻辑分析仪)抓取内部信号
我记得有一次,卷积加速器的输出一直不对。用ILA抓了AXI总线的读写信号,发现是地址对齐出了问题——DMA传输的起始地址不是64字节对齐的。这个问题如果不用ILA,光靠看代码,可能得查好几天。
串口调试:
- 硬件连接:板卡UART口通过USB转串口线连到PC
- PC端工具:minicom(Linux)或Putty(Windows)
- 配置参数:波特率115200,8数据位,1停止位,无校验
- 在PS端代码中添加
xil_printf()打印调试信息
// 串口打印示例
#include "xil_printf.h"
int main() {
xil_printf("Convolution Accelerator Test Start\r\n");
// 初始化DMA
XAxiDma_Config *config = XAxiDma_LookupConfig(0);
XAxiDma_CfgInitialize(&dma, config);
xil_printf("DMA Initialized\r\n");
// 启动卷积计算
start_conv_accelerator();
// 等待完成
while(!is_done());
xil_printf("Convolution Done! Result: 0x%08x\r\n", read_result());
return 0;
}
调试流程总结:
- 先用JTAG下载比特流,确认硬件能正常工作
- 再用串口打印软件初始化信息,确认驱动加载成功
- 最后用ILA抓取关键信号,定位具体问题
这个流程我用了好几年,基本覆盖了90%的上板问题。剩下的10%,嗯,那就得靠经验和运气了。
好了,环境搭建和调试基础就讲到这里。这些内容看起来琐碎,但每一个细节都可能成为你上板联调时的拦路虎。我建议你按照这个流程走一遍,遇到问题不要慌,先检查版本,再检查驱动,最后看硬件配置。大部分问题都能在这三步里找到答案。