第2章:HLS工具链入门:Vitis HLS安装与配置、C/C++综合流程、接口综合与协议、仿真与调试
好,咱们直接进入正题。这一章我打算带大家把HLS的工具链捋一遍。说白了,就是让你知道怎么装、怎么用、怎么调。很多初学者一上来就盯着算法看,结果工具报错卡半天——这种事我见得太多了。
2.1 Vitis HLS安装与配置
先说说安装。Vitis HLS现在集成在Vitis统一平台里,不再单独发布了。我个人习惯用2022.2版本,比较稳定。你下载的时候注意选对操作系统,Linux和Windows我都试过,Linux下综合速度快不少。
安装完成后,有几个环境变量必须配好:
XILINX_VITIS:指向Vitis安装根目录XILINX_VIVADO:指向Vivado安装目录PATH:添加$XILINX_VITIS/bin和$XILINX_VIVADO/bin
配置好之后,在终端敲vitis_hls -version,能看到版本信息就说明装好了。嗯,这一步很简单,但很多人会忘。
2.2 C/C++综合流程
综合流程,我把它拆成三步走:
- 编写C/C++源码——注意风格,后面细说
- 运行C仿真——验证功能正确
- 执行综合——生成RTL
你想想看,这三步其实和软件编译很像。但有个关键区别:HLS综合对代码风格有要求。比如循环要加#pragma HLS PIPELINE,数组要指定存储类型。
我给大家看个最简单的例子:
#include <hls_stream.h>
void add(hls::stream<int> &in1, hls::stream<int> &in2, hls::stream<int> &out) {
#pragma HLS INTERFACE axis port=in1
#pragma HLS INTERFACE axis port=in2
#pragma HLS INTERFACE axis port=out
int a = in1.read();
int b = in2.read();
out.write(a + b);
}
这段代码综合后,会生成一个AXI4-Stream接口的加法器。注意看,我用了hls::stream,这是HLS里处理数据流的推荐方式。
-O3优化选项,能显著提升性能。我在做图像处理加速时,开优化和不优化,吞吐量能差3倍。
2.3 接口综合与协议
接口综合,说白了就是告诉工具:你的函数参数怎么和外部世界连接。HLS支持多种接口协议:
| 接口类型 | 适用场景 | 我踩过的坑 |
|---|---|---|
ap_none |
纯组合逻辑 | 容易产生毛刺,慎用 |
ap_vld |
带有效信号 | 握手逻辑要自己处理 |
ap_fifo |
FIFO接口 | 深度不够会丢数据 |
axis |
AXI4-Stream | 我最常用的,稳定 |
m_axi |
AXI4主接口 | 带宽瓶颈常在这 |
为什么会这样?因为不同的协议对应不同的硬件握手方式。比如axis协议,它自带valid/ready握手,你不需要自己写控制逻辑。而ap_vld只有valid信号,ready要自己实现。
我曾经在一个项目中,把ap_fifo的深度设成了2,结果数据流稍微一波动就丢包。后来改成axis,问题就解决了。所以我的建议是:能用axis就用axis,省心。
2.4 仿真与调试
仿真调试这块,我分成C仿真和RTL协同仿真两个阶段。
C仿真:跑得飞快,适合验证算法逻辑。你写个testbench,给几个测试向量,看看输出对不对。这一步我建议多测边界情况,比如数据全零、全最大值、随机数。
RTL协同仿真:慢,但准。它会调用Vivado的仿真器,生成波形文件。我一般用这个来排查时序问题。
调试时,我最常用的三个命令:
csim:运行C仿真csynth:执行综合cosim:运行RTL协同仿真
嗯,这里要注意:cosim默认只跑1000个时钟周期,如果你的设计需要更长时间,记得加-ldflags "-Wl,--stack,16777216"来增大堆栈。
#pragma HLS RESOURCE,工具默认用了LUTRAM,导致读写冲突。改成BRAM后问题解决。
最后,给大家画个流程图,把整个工具链串起来:
这张图把整个流程串起来了。你从C/C++源码开始,先做C仿真验证功能,然后综合生成RTL。如果综合结果不理想,就回到C仿真那一步优化代码。最后通过RTL协同仿真确认时序,再导出IP。
好了,这一章的内容就到这。工具链这东西,光看没用,你得动手敲一遍。我建议你找个简单的例子,比如矩阵乘法,从头到尾跑一遍流程,遇到问题再回来看这一章。
可可精品资料库