使用VS Code搭建C/C++运行环境,建立HLS新工程
搭建VS Code编译环境
安装编译器
- 对于Windows用户,推荐使用MinGW-w64,MinGW(Minimalist GNU for Windows), 是一个适用于微软windows应用程序的极简开发环境。可以选择下载
mingw-w64-install.exe
安装包进行在线安装(在线安装会比较慢),也可下载底部对应系统配置的压缩包(推荐使用),我在此处下载的压缩包为x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z
。 - 以安装包为例,在下载完成后,点击运行,在Version中可选择版本号,若无特殊要求选用最新即可。Architecture选择系统位数,64位系统选择
x86_64
,32位系统选择i686
。Threads设置线程标准可选posix
或win32
。Exception设置异常处理系统,x86_64可选为seh
和sjlj
,i686为dwarf
和sjlj
。Build revision构建版本号,选择最大即可。 - 若是采用直接下载压缩包,则将压缩包解压到合适位置,并将
mingw64/bin
加入环境变量-Path
中即可,添加环境变量的操作不再赘述,可自行搜索。 - 完成以上操作后,可
WIN + R
打开运行界面,输出cmd
打开命令行,输入gcc -v
,若出现类似以下信息则说明编译器安装成功。
安装插件
- 打开VS Code插件界面,安装所需插件,推荐安装的插件有
C/C++
,提供Debug和Format功能;Code Runner
,用于编译运行单文件。其他推荐安装的插件还有Bracket Pair Colorizer 2
,彩虹花括号;One Dark Pro
,VS Code主题 - 接着对于安装的插件进行设置,在用户设置界面,找到以下选项
code-runner.saveFileBeforeRun
,运行之前保存。建议勾选。code-runner.runInTerminal
,在集成终端运行,强烈建议勾选,否则会出现乱码等问题。code-runner.preserveFocus
,焦点回移,在程序运行时焦点回到编辑区。建议不选。 - 完成以上操作,即可愉快的使用VS Code编写调试C/C++代码啦,点击右上角的运行按钮即可编译调试代码。
新建HLS工程
HLS的设计流程

- 添加编写的Source code,使用C、C++、System C进行编写均可
- 添加用于仿真的testbench,添加C文件和输入输出数据,它会自动验证输入的数据与仿真输出的结果是否一致,以验证仿真是否正确
- 添加C的仿真文件,在csim文件夹
- 添加C综合,需要加入Directives,在syn文件夹
- 接着进行C和RTL的联合仿真,RTL的testbench可由C的testbench自动生成,在sim文件夹
- 最后,导出RTL的结果,在impl文件夹
- 每个hls工程可以有多个Solutions,每个Solution可以有自己的Directive,Directive是用于对C综合进行优化操作的,这里推荐将Directives写于directive file中。
- 我们可以通过创建多个Solution,并给予不同的配置参数,以获得多个不同的综合结果,并可以从中挑选我们认为较好的结果进行使用。
HLS工程创建过程
- 打开Vivado HLS软件,点击创建新的工程,设置工程名以及存放路径,点击下一步
- 在
Add/Remove C-based Sources Files
界面,设置顶层函数名。若有已写好的Source Code文件,也可以在该界面添加,点击下一步 - 在
Add/Remove C-based testbench Files
界面,可添加已写好的testbench文件,如没有,则直接点击下一步 - 在
Solution Configuration
界面,可以设置Solution的文件名,并选择对应的FPGA型号,点击Finish,完成工程的创建。 - 在添加代码文件后,可点击界面上面的
C simulation
按钮进行仿真,在仿真结束后会给出仿真结果。 - 如果没有问题,再继续点击
C synthesis
按钮进行C的综合,在综合完成后会自动弹出综合报告,可以查看到相应的资源使用情况。 - 接着再进行
C/RTL Co-simulation
,进行联合仿真,若需要关注仿真结果,可将Verilog/VHDL Simulator Selection
选项选为Vivado Simulation
,Dump Trace
选项选择为Port
,点击OK运行。 - 完成后,可点击
Open Wave Viewer
,查看仿真波形结果。 - 如要进行优化操作,则可创建多个Solutions进行设置比较分析操作
- 最后,可点击顶部菜单栏的
Export RTL
选项,导出相应RTL代码
添加代码文件
- 右键
Sources
,选择New File...
,添加创建代码所需要的.cpp
和.h
文件,点击保存 - 同理,右键
Test Bench
,选择New File...
,添加创建代码所需要的.cpp
文件,点击保存 - 推荐可以将包含的头文件,Source File文件,Testbench仿真文件,放置于同一个文件夹下进行管理。
- 可在HLS软件中直接进行代码编译,也可使用VSCode打开代码文件夹,进行更为方便的代码编写
- 头文件代码如下:
#define N 5//the length if vectot
typedef int data_t;
extern void top(data_t *,data_t c,data_t *);
- 主函数代码如下:
#include "top_file.h"
void top(data_t A[N],data_t c,data_t B[N]){
unsigned int i;
myloop:
for(i = 0 ; i<N ; i++){
B[i] = A[i] +c;
}
}
- testbench代码如下:
#include <iostream>
#include <iomanip>
#include "top_file.h"
using namespace std;
int main(){
data_t A[N] = {-4,-3,0,1,2};
data_t c =5;
data_t B[N] = {0};
data_t RefB[N] = {1,2,5,6,7};
unsigned int i = 0;
unsigned int errcnt = 0;
top(A,c,B);//run top function
cout<< setfill('-')<< setw(30)<<'-'<<'\n';
cout<< setfill(' ')<< setw(10)<<left<<"A";
cout<< setfill(' ')<< setw(10)<<left<<"c";
cout<< setfill(' ')<< setw(10)<<left<<"B"<<'\n';
cout<< setfill('-')<< setw(30)<<'-'<<'\n';
for(i = 0; i< N; i++){
cout<< setfill(' ')<< setw(10)<<left<<A[i];
cout<< setfill(' ')<< setw(10)<<left<<c;
cout<< setfill(' ')<< setw(10)<<left<<B[i];
if(B[i] == RefB[i]){
cout <<'\n';
}
else{
cout<<"("<<RefB[i]<<")"<<'\n';
errcnt++;
}
}
cout<< setfill('-')<<setw(30)<<'-'<<'\n';
if (errcnt>0){
cout<<"Test with "<<errcnt<<" error";
return 1;
}
else{
cout<<"Test Pass";
return 0;
}
}
通过Solution设置优化结果
- 点击
New Solution...
,创建一个新的Solution。 - 在
Option
选项中,勾选Copy directives and constraints from solution
,点击Finish - 切换到可综合C代码的界面,选择右侧的
Dirctive
,右键我们给for循环做的标签myloop
,右键,Insert Directive...
- 在
Directive
选项中选择PIPELINE
,点击OK - 若右侧的Directive是以
%
开头,则表明其存储在单独的directives.tcl
文件中;若以#
开头,则说明其是存储在Source Code
代码中 - 完成
Directives
设置后,我们可再次执行综合 - 完成综合后,我们可选择工具栏中的
Compare Reports
,添加第一个和第二个Solutions,点击OK进行对比,就能看到具体的资源与性能的对比结果。
映射后IO类型
- 通过HLS将C代码转换为RTl代码后,会将接口映射为如下三类IO:
- 模块级别的握手信号IO:ap_clk,ap_rst,ap_start,ap_done,ap_idle,ap_ready
- C代码中的输入IO:A_address0,A_ce0,A_q0,c
- C代码中的输出IO:B_address0,B_ce0,B_we0,B_d0