第一章:Vitis HLS 初探
1.1 什么是HLS?
HLS,全称是High-Level Synthesis,中文叫高层次综合。说白了,就是让你用C/C++代码去写FPGA逻辑。
我刚开始接触FPGA时,用的都是Verilog。写个简单的图像缩放,光状态机就折腾了两天。后来项目赶进度,被迫用上了HLS。说实话,第一次跑通的时候,我自己都有点不敢相信——C代码写的算法,居然真的能综合成硬件电路。
HLS的工作原理其实不复杂:
- 你写C/C++代码,描述算法行为
- HLS工具分析你的代码,推断出数据流和控制逻辑
- 然后自动生成对应的RTL代码(Verilog/VHDL)
- 最后综合成FPGA的比特流
嗯,这里要注意:HLS不是万能的。它擅长的是数据流密集型的算法,比如图像处理、信号处理。控制逻辑太复杂的场景,还是老老实实用Verilog吧。
核心观点:HLS的本质是「用C描述硬件行为」,而不是「把C编译成硬件」。这两者有本质区别。
1.2 为什么用HLS做图像加速?
图像处理算法有个特点:数据量大,计算模式固定。比如卷积、滤波、色彩空间转换,这些算法用C写起来很顺手,但用Verilog写就特别痛苦。
我做过一个项目,需要在FPGA上实现一个实时去雾算法。算法本身是里的,用C验证好了。如果用Verilog重写,光调试就要花两周。但用HLS,我只花了两天就把C代码改成了可综合的风格,然后直接跑通了。
你想想看,图像加速的核心瓶颈是什么?是数据搬运。FPGA的优势在于流水线和并行计算。HLS正好能帮你把C代码中的循环自动展开、流水线化,充分利用FPGA的并行能力。
具体来说,HLS做图像加速有这几个好处:
- 开发效率高:C代码直接转硬件,省去手写RTL的时间
- 验证方便:C仿真比RTL仿真快几个数量级
- 优化灵活:通过pragma指令控制流水线、展开、数组分割
- 复用性强:OpenCV库可以直接用,省去自己写图像处理基础函数
个人经验:我建议初学者先从简单的图像处理算法入手,比如灰度转换、高斯滤波。这些算法结构清晰,容易理解HLS的优化思路。
1.3 开发环境搭建
工欲善其事,必先利其器。搭建开发环境是第一步,也是容易踩坑的一步。
需要的软件:
- Vivado HLS / Vitis HLS(推荐2020.1以上版本)
- Vivado(用于后续的完整工程)
- Xilinx Runtime (XRT)(如果要用加速卡)
- 一个趁手的文本编辑器(VS Code或Sublime都行)
安装步骤:
- 从Xilinx官网下载Vitis统一安装包
- 安装时选择Vitis HLS组件
- 设置环境变量:
source /opt/Xilinx/Vitis/2020.1/settings64.sh - 验证安装:在终端输入
vitis_hls -version
避坑指南:我曾经在Ubuntu 18.04上安装Vitis 2019.2,结果死活跑不起来。后来发现是libncurses5库版本不对。建议直接用Ubuntu 20.04 + Vitis 2020.1,兼容性最好。
1.4 第一个Hello World工程
好了,环境搭好了,我们来写第一个HLS工程。别紧张,就是最简单的加法器。
步骤1:创建工程
打开Vitis HLS,点击Create New Project。工程名就叫hello_hls,选择好保存路径。顶层函数名填add。
步骤2:编写源代码
创建一个add.cpp文件,内容如下:
// add.cpp
#include <ap_int.h>
int add(int a, int b) {
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE s_axilite port=a
#pragma HLS INTERFACE s_axilite port=b
return a + b;
}
步骤3:编写测试文件
创建一个add_tb.cpp文件:
// add_tb.cpp
#include <iostream>
#include "add.h"
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;
}
}
步骤4:运行C仿真
在Vitis HLS界面中,点击Project -> Run C Simulation。如果看到"Test passed!",恭喜你,第一个HLS工程跑通了。
步骤5:综合与查看结果
点击Solution -> Run C Synthesis。综合完成后,你会看到资源使用报告和时序报告。对于这个简单的加法器,资源消耗几乎可以忽略不计。
关键点:HLS的仿真和综合是分离的。先仿真验证功能正确,再综合生成硬件。这个流程和传统软件开发很像,但背后是完全不同的逻辑。
1.5 本章知识体系
为了让你更直观地理解本章的内容结构,我画了一张图:
1.6 本章小结
这一章我们走了一遍HLS的入门流程。从概念到实践,从环境搭建到第一个工程跑通。说实话,HLS的学习曲线比Verilog平缓得多,但要想用好它,还是需要理解硬件思维。
我记得第一次用HLS做图像处理时,犯了一个低级错误:在循环里用了动态内存分配。综合时报了一堆错误,我还以为是工具的问题。后来才明白,硬件里哪来的堆和栈?
嗯,这些坑以后都会慢慢遇到。但别担心,跟着这个课程走,你会少走很多弯路。
课后练习:试着修改Hello World工程,实现一个4输入的加法器。然后观察资源使用报告的变化。你会发现,多几个加法器,资源几乎不增加——这就是FPGA并行计算的优势。