2、Vivado HLS开发环境搭建
好,咱们正式开始动手了。这一章我带你搭好环境,把Vivado HLS装起来,再跑通第一个工程——LED闪烁。别小看这个LED,它可是硬件加速的"Hello World"。
我刚开始学HLS的时候,光装软件就折腾了一整天。版本不对、license失效、路径带中文……各种坑踩了个遍。所以这一章我会把那些容易出问题的地方都指出来,你跟着走就行。
2.1 Vivado HLS的安装与配置
先说说版本选择。Vivado HLS现在叫Vitis HLS了,但老版本依然能用。我个人建议:
- 初学者:用Vivado HLS 2019.1或2020.1,稳定,教程多
- 项目开发:用Vitis HLS 2021.2以上,支持C++17,优化更好
安装步骤其实不复杂,但有几个关键点:
- 下载安装包:去Xilinx官网下载,大概20GB左右。嗯,记得留好硬盘空间。
- 安装路径:不要有中文!不要有空格! 我曾经因为路径带了"项目"两个字,编译死活过不去,查了半天才发现是路径问题。
- License配置:申请免费的Vivado HL WebPACK license就够了。把license文件放到安装目录下,然后在Vivado HLS里配置好。
- 环境变量:安装完成后,检查一下系统环境变量里有没有XILINX_VIVADO和PATH。没有的话手动加一下。
vivado_hls -version,如果能显示版本号,说明安装成功了。
2.2 Vivado HLS界面介绍
装好了,咱们打开看看。Vivado HLS的界面其实挺清爽的,主要分这几个区域:
| 区域 | 功能 | 我常用的操作 |
|---|---|---|
| Project Explorer | 工程文件管理 | 右键 -> New Source File |
| Source Editor | 代码编辑区 | 写C/C++代码,加pragma |
| Console | 编译输出信息 | 看错误和警告 |
| Solution Explorer | 解决方案管理 | 切换不同的优化方案 |
| Analysis Perspective | 性能分析视图 | 看时序、资源、吞吐量 |
你想想看,这么多窗口,刚打开肯定有点懵。别急,我告诉你一个规律:左边管文件,右边管分析,中间写代码。记住这个,基本就不会迷路了。
2.3 创建第一个HLS工程(LED闪烁)
好,咱们来真的了。创建一个LED闪烁的HLS工程,步骤很简单:
- 打开Vivado HLS,点击 Create New Project
- 输入工程名:
led_blink,选好路径 - 选择顶层函数:这里我们写一个
led_control函数 - 添加源文件:新建一个
led.cpp - 添加testbench:新建一个
led_tb.cpp - 选择器件:比如
xczu9eg-ffvb1156-2-e(Zynq UltraScale+)
然后咱们写代码。LED闪烁说白了就是让一个GPIO口高低电平交替。在HLS里,我们用AXI GPIO来实现:
// led.cpp
#include <ap_int.h>
#include <hls_stream.h>
#define DELAY_MS 500
void led_control(ap_uint<1> *led_out) {
#pragma HLS INTERFACE ap_none port=led_out
#pragma HLS INTERFACE ap_ctrl_none port=return
static ap_uint<1> led_state = 0;
// 简单的延时计数
for (int i = 0; i < 1000000; i++) {
#pragma HLS PIPELINE II=1
// 空循环,用于产生延时
}
led_state = ~led_state;
*led_out = led_state;
}
等等,你可能会问:为什么用 ap_uint<1> 而不是普通的 int? 嗯,这里有个讲究。HLS综合时,ap_uint<1> 会精确映射到1位寄存器,而 int 是32位,浪费资源。我在项目中吃过这个亏,后来就养成了用精确位宽的习惯。
2.4 工程结构解析(testbench、source、solution)
工程建好了,咱们看看它的结构。Vivado HLS的工程目录是这样的:
led_blink/
├── led.cpp # 源文件(你的硬件代码)
├── led_tb.cpp # 测试文件(验证功能)
├── solution1/ # 解决方案(综合结果)
│ ├── syn/ # 综合报告
│ ├── impl/ # 实现结果
│ └── report/ # 时序/资源报告
└── vivado_hls.log # 编译日志
这里我重点说一下三个核心部分:
- Source(源文件):就是你要综合成硬件的C/C++代码。注意,这里写的代码会被综合成RTL,所以不能有动态内存分配、系统调用、递归这些东西。
- Testbench(测试文件):用来验证你的硬件功能对不对。它不会被综合,所以可以随便写
printf、malloc。我习惯在testbench里加一些边界测试,比如输入最大值、最小值,看看硬件会不会崩。 - Solution(解决方案):同一个工程可以有多个solution,每个solution对应不同的优化策略。比如solution1用流水线,solution2用展开,然后对比哪个性能好。这个功能我经常用,尤其是在做性能调优的时候。
std::vector,结果综合时报错说"不支持动态内存"。后来才明白,testbench虽然不会被综合,但HLS在语法检查阶段会扫描所有文件。所以testbench里也尽量别用STL容器,用数组或者 ap_int 系列更安全。
2.5 知识体系总览
为了让你对整个章节有个直观的认识,我画了一张图:
这张图把咱们这一章的内容串起来了。从安装配置开始,到界面熟悉,再到动手创建工程,最后理解工程结构。每一步都是下一环的基础。
好了,环境搭好了,第一个工程也跑通了。接下来你就可以开始折腾了——改代码、加优化指令、看综合报告。记住,HLS的精髓在于用软件思维写硬件,但心里要时刻想着硬件是怎么实现的。