(一)HLS第一个入门工程(简单加法器)
目标:实现一个“输入两个整数、输出其和”的加法器模块,完整走通HLS开发的核心流程(工程创建→代码编写→C仿真→HLS综合→查看RTL结果),理解每一步的目的。
步骤1:创建HLS工程(Vitis HLS 2022.1,Windows为例)
- 启动Vitis HLS 2022.1,等待主界面加载完成;
- 点击菜单栏
File → New → Project,弹出工程创建向导:- 第一步:填写工程名(比如
adder_hls),选择工程保存路径(无中文/空格,比如D:\HLS_Projects\adder_hls),点击Next; - 第二步:填写“Top Function Name”(顶层函数名,HLS只会综合这个函数,填
adder),点击Next; - 第三步:添加源文件(暂时跳过,先创建空工程),点击
Next; - 第四步:添加测试文件(暂时跳过),点击
Next; - 第五步:选择目标FPGA器件(新手选
xc7z020clg484-1,Zynq 7020,入门最常用),点击Finish;
- 第一步:填写工程名(比如
- 此时你会看到工程界面:左侧
Project Explorer里有adder_hls工程,默认生成Solution1(综合解决方案)。
步骤 2:新建头文件adder.h
右键工程里的Source文件夹 → New → File;
文件名填adder.h,点击Finish;
输入以下代码:
// adder.h:头文件,存放数据类型和函数声明
#ifndef ADDER_H // 防止头文件被重复包含(关键!)
#define ADDER_H
// HLS基础头文件
#include "hls_stream.h"
#include "ap_int.h"
// 定义8位有符号整数类型(对应FPGA的8位寄存器)
typedef ap_int<8> data_t;
/**
* @brief HLS顶层函数:8位整数加法器(仅声明,不实现)
* @param a 输入1
* @param b 输入2
* @param c 输出
*/
void adder(data_t a, data_t b, data_t &c);
#endif // ADDER_H
步骤3:编写顶层函数(加法器的C++代码)
顶层函数是HLS综合的“入口”,必须是void类型,参数用指针/引用(硬件端口),不能用return(硬件没有“返回值”,只有输入输出端口)。
- 右键工程里的
Source文件夹 →New → File; - 文件名填
adder.cpp,点击Finish; - 在代码编辑区输入以下代码(带详细注释):
// adder.cpp:加法器顶层函数
// 头文件:HLS需要的基础头文件
#include "hls_stream.h"
#include "ap_int.h"
// 定义数据类型:ap_int<8>表示8位宽的整数(对应FPGA的8位寄存器)
typedef ap_int<8> data_t;
/**
* @brief HLS顶层函数:8位整数加法器
* @param a 输入1(硬件输入端口)
* @param b 输入2(硬件输入端口)
* @param c 输出(硬件输出端口)
*/
void adder(data_t a, data_t b, data_t &c) {
// 加法逻辑:和RTL不同,只需要写功能,不用关心硬件连线
c = a + b;
}
- 保存文件(
Ctrl+S),检查无语法错误(Editor会实时标红错误)。
步骤4:编写Testbench(测试文件,验证算法逻辑)
Testbench是C++测试代码,用来模拟FPGA的输入输出,验证adder函数的逻辑是否正确(相当于软件里的“单元测试”)。
- 右键工程里的
Test Bench文件夹 →New → File; - 文件名填
adder_tb.cpp,点击Finish; - 输入以下测试代码:
// adder_tb.cpp:加法器测试文件
#include "adder.h" // 包含顶层函数
#include <iostream> // 用于打印测试结果
using namespace std;
int main() {
// 定义测试变量
data_t a, b, c;
// 测试用例:覆盖正数、负数、边界值
int test_cases[5][3] = {
{1, 2, 3}, // 1+2=3
{10, -5, 5}, // 10+(-5)=5
{127, 1, -128},// 8位有符号数边界:127+1=-128(溢出,符合硬件特性)
{0, 0, 0}, // 0+0=0
{-10, -20, -30}// -10+(-20)=-30
};
// 遍历测试用例
for(int i=0; i<5; i++) {
a = test_cases[i][0];
b = test_cases[i][1];
// 调用加法器函数
adder(a, b, c);
// 打印结果,验证是否正确
cout << "Test Case " << i+1 << ": " << (int)a << " + " << (int)b << " = " << (int)c;
if(c == test_cases[i][2]) {
cout << " [PASS]" << endl;
} else {
cout << " [FAIL] Expected: " << test_cases[i][2] << endl;
}
}
return 0;
}
步骤5:运行C仿真(验证算法逻辑)
C仿真的目的是:先确认C++代码的算法逻辑100%正确,再进行硬件综合(避免硬件综合后才发现算法错)。
- 点击菜单栏
Project → Run C Simulation; - 弹出配置窗口:
Test Bench选adder_tb.cpp;Simulation Mode选Functional(功能仿真,只验证逻辑,不关心时序);- 点击
Run;
- 等待仿真完成(Console窗口会输出日志),最终看到测试结果:
Test Case 1: 1 + 2 = 3 [PASS]
Test Case 2: 10 + -5 = 5 [PASS]
Test Case 3: 127 + 1 = -128 [PASS]
Test Case 4: 0 + 0 = 0 [PASS]
Test Case 5: -10 + -20 = -30 [PASS]
所有用例PASS,说明算法逻辑正确。
步骤5:运行HLS综合(生成RTL代码)
这是HLS的核心步骤:把C++的加法器逻辑,转换成Verilog/VHDL(RTL)代码。
- 点击菜单栏
Project → Run C Synthesis; - 弹出配置窗口:保持默认(Top Function选
adder),点击Run; - 等待综合完成(约1-2分钟,Console会输出进度),完成后会显示“C Synthesis completed successfully”;
- 此时HLS会自动生成:
- Verilog/VHDL代码(在
Solution1/impl/verilog文件夹里,能看到adder.v); - 综合报告(
Solution1/syn/report/adder_csynth.rpt):包含资源占用、时序性能等。
- Verilog/VHDL代码(在
步骤6:查看生成的RTL代码和综合报告(关键)
- 查看RTL代码:双击
Solution1/impl/verilog/adder.v,能看到HLS生成的Verilog代码,核心部分如下(不用全懂,重点看端口和加法逻辑):
module adder(
input [7:0] a, // 8位输入a(对应C++的data_t a)
input [7:0] b, // 8位输入b
output [7:0] c // 8位输出c
);
assign c = a + b; // 加法逻辑,和C++代码一一对应
endmodule
- 查看综合报告:双击
adder_csynth.rpt,重点看:Resource Estimates(资源占用):加法器只用到少量LUT,几乎无FF/DSP;Latency Estimates(延迟):加法器的硬件延迟是1个时钟周期(符合预期)。
总结
- HLS开发的核心流程:创建工程→写顶层函数(算法逻辑)→写Testbench→C仿真(验逻辑)→HLS综合(生成RTL)→查综合报告;
- 顶层函数是HLS综合的入口,参数要用指针/引用(对应硬件端口),数据类型推荐用
ap_int<N>(自定义位宽,适配FPGA); - C仿真先验证算法正确性,再做硬件综合,是HLS开发的最佳实践。

浙公网安备 33010602011771号