[HLS1]VSCode搭建C++环境_建立HLS工程

使用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的设计流程

  1. 添加编写的Source code,使用C、C++、System C进行编写均可
  2. 添加用于仿真的testbench,添加C文件和输入输出数据,它会自动验证输入的数据与仿真输出的结果是否一致,以验证仿真是否正确
  3. 添加C的仿真文件,在csim文件夹
  4. 添加C综合,需要加入Directives,在syn文件夹
  5. 接着进行C和RTL的联合仿真,RTL的testbench可由C的testbench自动生成,在sim文件夹
  6. 最后,导出RTL的结果,在impl文件夹
  7. 每个hls工程可以有多个Solutions,每个Solution可以有自己的Directive,Directive是用于对C综合进行优化操作的,这里推荐将Directives写于directive file中。
  8. 我们可以通过创建多个Solution,并给予不同的配置参数,以获得多个不同的综合结果,并可以从中挑选我们认为较好的结果进行使用。

HLS工程创建过程

  1. 打开Vivado HLS软件,点击创建新的工程,设置工程名以及存放路径,点击下一步
  2. Add/Remove C-based Sources Files界面,设置顶层函数名。若有已写好的Source Code文件,也可以在该界面添加,点击下一步
  3. Add/Remove C-based testbench Files界面,可添加已写好的testbench文件,如没有,则直接点击下一步
  4. Solution Configuration界面,可以设置Solution的文件名,并选择对应的FPGA型号,点击Finish,完成工程的创建。
  5. 在添加代码文件后,可点击界面上面的C simulation按钮进行仿真,在仿真结束后会给出仿真结果。
  6. 如果没有问题,再继续点击C synthesis按钮进行C的综合,在综合完成后会自动弹出综合报告,可以查看到相应的资源使用情况。
  7. 接着再进行C/RTL Co-simulation,进行联合仿真,若需要关注仿真结果,可将Verilog/VHDL Simulator Selection选项选为Vivado SimulationDump Trace选项选择为Port,点击OK运行。
  8. 完成后,可点击Open Wave Viewer,查看仿真波形结果。
  9. 如要进行优化操作,则可创建多个Solutions进行设置比较分析操作
  10. 最后,可点击顶部菜单栏的Export RTL选项,导出相应RTL代码

添加代码文件

  1. 右键Sources,选择New File...,添加创建代码所需要的.cpp.h文件,点击保存
  2. 同理,右键Test Bench,选择New File...,添加创建代码所需要的.cpp文件,点击保存
  3. 推荐可以将包含的头文件,Source File文件,Testbench仿真文件,放置于同一个文件夹下进行管理。
  4. 可在HLS软件中直接进行代码编译,也可使用VSCode打开代码文件夹,进行更为方便的代码编写
  5. 头文件代码如下:
#define N 5//the length if vectot
typedef int data_t;
extern void top(data_t *,data_t c,data_t *);
  1. 主函数代码如下:
#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;
    }
}
  1. 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设置优化结果

  1. 点击New Solution...,创建一个新的Solution。
  2. Option选项中,勾选Copy directives and constraints from solution,点击Finish
  3. 切换到可综合C代码的界面,选择右侧的Dirctive,右键我们给for循环做的标签myloop,右键,Insert Directive...
  4. Directive选项中选择PIPELINE,点击OK
  5. 若右侧的Directive是以%开头,则表明其存储在单独的directives.tcl文件中;若以#开头,则说明其是存储在Source Code代码中
  6. 完成Directives设置后,我们可再次执行综合
  7. 完成综合后,我们可选择工具栏中的Compare Reports,添加第一个和第二个Solutions,点击OK进行对比,就能看到具体的资源与性能的对比结果。

映射后IO类型

  • 通过HLS将C代码转换为RTl代码后,会将接口映射为如下三类IO:
  1. 模块级别的握手信号IO:ap_clk,ap_rst,ap_start,ap_done,ap_idle,ap_ready
  2. C代码中的输入IO:A_address0,A_ce0,A_q0,c
  3. C代码中的输出IO:B_address0,B_ce0,B_we0,B_d0