一、Vitis概述与环境搭建:Vitis统一软件平台介绍、安装Vitis、配置环境变量、创建第一个HLS工程
各位同学,咱们今天聊聊Vitis。说实话,我第一次接触Vitis的时候,心里是有点懵的。为什么呢?因为Xilinx把以前那一堆工具——SDK、SDAccel、Vivado HLS——全塞进了一个平台里。说白了,Vitis就是Xilinx的“全家桶”。
但你别被它吓到。我用了几年下来,发现Vitis其实挺顺手的。它最大的好处是:你不用再在好几个工具之间来回切换了。写C/C++、做HLS综合、跑仿真、调驱动,全在一个界面里搞定。
核心概念:Vitis统一软件平台 = Vivado(硬件设计)+ Vitis HLS(高层次综合)+ Vitis IDE(软件开发)+ 各种库(加速库、AI库等)。
1.1 Vitis统一软件平台到底是个啥?
你想想看,以前做FPGA开发,硬件工程师用Vivado画原理图、写Verilog,软件工程师用SDK写C代码。两边各干各的,联调的时候经常出问题。Vitis把这两拨人拉到一起了。
我个人习惯把Vitis理解成“一座桥”。桥的一头是C/C++这样的高级语言,另一头是FPGA硬件。你写个C函数,Vitis帮你把它变成硬件电路。嗯,听起来很神奇对吧?
我在项目中遇到过这样一个场景:客户要求把一段图像处理算法加速。如果用Verilog写,至少得两周。但用Vitis HLS,我三天就把C代码转成了RTL,仿真通过后直接上板。这就是Vitis的价值。
1.2 安装Vitis——别踩这些坑
安装Vitis其实不复杂,但有几个地方我得提醒你。我曾经因为安装路径带中文,折腾了一下午。所以,记住下面几条:
- 安装包大小:Vitis完整安装包大概在50GB左右。别惊讶,它包含了Vivado、Vitis HLS、各种器件库。我建议你预留至少100GB的磁盘空间。
- 操作系统:Ubuntu 18.04/20.04 或 CentOS 7.x 是主流选择。Windows也能装,但我在Windows上遇到过一些奇怪的路径问题,所以个人更推荐Linux。
- 安装步骤:
- 从Xilinx官网下载Vitis统一安装程序(建议用2022.2或更新版本)。
- 运行安装脚本:
./xsetup - 选择“Vitis”组件,它会自动勾选Vivado和Vitis HLS。
- 选择器件支持——如果你只做Zynq系列,勾选Zynq-7000和Zynq UltraScale+就够了。
- 等待安装完成(大概1-2小时,取决于你的网速和硬盘速度)。
警告:安装路径不要有空格和中文!我曾经因为把Vitis装在了“Program Files (x86)”下,结果HLS工程一直报路径错误。血的教训。
1.3 配置环境变量——这一步不能省
装完Vitis,你以为就能直接用了?别急。你得先告诉系统“Vitis在哪”。
我记得第一次装完Vitis,兴冲冲地打开终端输入vitis,结果系统告诉我“命令未找到”。当时我还以为是安装出问题了,后来才发现是环境变量没配。
配置方法很简单,在~/.bashrc文件末尾加上一行:
source /opt/Xilinx/Vitis/2022.2/settings64.sh
然后执行:
source ~/.bashrc
验证一下:
which vitis
# 应该输出:/opt/Xilinx/Vitis/2022.2/bin/vitis
如果你用的是C shell(csh或tcsh),那就用settings64.csh。这个细节我当年就栽过跟头——公司服务器用的是csh,我按bash的方法配,结果折腾了半天。
小技巧:如果你同时装了多个版本的Vitis,可以在.bashrc里写个别名,比如:alias vitis2022='source /opt/Xilinx/Vitis/2022.2/settings64.sh && vitis'。这样切换版本就方便了。
1.4 创建第一个HLS工程——手把手带你走一遍
好了,环境搭好了,咱们来创建第一个HLS工程。别紧张,其实就是写个C函数,然后让Vitis把它变成硬件。
我选一个最简单的例子:两个数相加。你可能会说:“这也太简单了吧?” 嗯,但这是理解HLS流程最好的起点。
步骤1:启动Vitis HLS
在终端输入vitis_hls,或者从Vitis IDE里打开HLS工具。我个人习惯直接用命令行,因为后面做自动化脚本方便。
步骤2:创建新工程
点击 Create New Project,输入工程名(比如add_hls),选择保存路径。注意,路径同样不要有中文。
步骤3:添加源文件
创建一个C源文件add.cpp,内容如下:
// add.cpp
#include "add.h"
int add(int a, int b) {
#pragma HLS INTERFACE ap_ctrl_none port=return
return a + b;
}
对应的头文件add.h:
// add.h
#ifndef ADD_H
#define ADD_H
int add(int a, int b);
#endif
这里我加了一个#pragma HLS INTERFACE指令。它的作用是告诉Vitis:这个函数的返回值不需要握手信号。说白了,就是让这个加法器变成一个纯组合逻辑电路。
步骤4:编写测试平台(Testbench)
创建add_tb.cpp:
// add_tb.cpp
#include "add.h"
#include <iostream>
int main() {
int result = add(3, 5);
if (result == 8) {
std::cout << "Test passed!" << std::endl;
return 0;
} else {
std::cout << "Test failed!" << std::endl;
return 1;
}
}
步骤5:运行C仿真
在Vitis HLS界面中,点击 Project → Run C Simulation。你会看到控制台输出“Test passed!”。这说明你的C代码逻辑是对的。
步骤6:综合(Synthesis)
点击 Solution → Run C Synthesis → Active Solution。Vitis会开始把C代码转成RTL。这个过程可能需要几分钟。综合完成后,你会看到一个报告,里面包含了资源使用情况(LUT、FF、DSP等)和时序信息。
关键指标解读:对于这个加法器,综合报告里应该显示:0个BRAM、0个DSP、几个LUT和FF。为什么没有DSP?因为加法器用LUT就能实现,不需要DSP硬核。这个细节在项目中很重要——别把DSP浪费在简单的加减法上。
步骤7:查看生成的RTL
综合完成后,在 Solution → impl → verilog 目录下,你会看到add.v文件。打开看看,是不是跟你手写的Verilog差不多?
1.5 本章知识体系总览
下面这张图是我用SVG画的,帮你理清Vitis环境搭建和HLS工程创建的整个流程。你可以把它当成一张“地图”,以后迷路了就回来看看。
1.6 避坑指南——我踩过的那些雷
最后,分享几个我实际项目中遇到的坑,你遇到了可以少走弯路:
- 综合时间过长:我曾经综合一个图像处理模块,等了两个小时还没结束。后来发现是循环边界设成了变量,导致Vitis无法展开循环。解决办法:把循环边界改成常量,或者用
#pragma HLS UNROLL指令。 - C仿真通过但综合后功能不对:这种情况多半是因为C代码里有不可综合的语法,比如
malloc、printf、递归调用。Vitis HLS只支持可综合的C子集,写代码时要注意。 - 接口协议不匹配:在项目中,我经常遇到HLS生成的IP和Vivado里的AXI总线连不上。原因往往是
#pragma HLS INTERFACE没写对。建议初学者先用ap_ctrl_none和ap_none,等熟悉了再尝试AXI协议。
好了,这一章的内容就到这。你跟着我走完一遍,应该已经能搭建好Vitis环境,并且跑通第一个HLS工程了。下一章咱们会深入讲HLS的数据类型和接口协议,到时候见。
课后练习:试着把上面的加法器改成4输入加法器,然后综合看看资源增加了多少。这是理解HLS综合开销的好方法。