HLS-使用C/C++开发FPGA的IP Core-上

目前,绝大部分的FPGA的IP或者功能都是使用硬件描述语言进行开发的。在目前的人工智能时代,许多的复杂算法、高深的算法,使用硬件描述语言已经无法进行快速的迭代了。因此,利用成熟的语言,进行算法的开发,并利用一些工具或者手段,将其转换为硬件描述语言的IP Core,便成为了一种选择。其中,使用高级设计语言(C/C++)进行FPGA的开发,就称之为高层次综合设计,简称HLS。
本文的目的,在于简单描述如何使用C/C++进行FPGA的IP Core的开发,主要分为2部分:
1.工具和环境以及初级入门
2.高阶应用以及优化
其中,第二部分将另开篇章进行描述。
本文选择的是Intel的工具集,进行开发。

一、环境以及工具集
Intel HLS需要Quartus和C/C++编译器,目前支持开源的GCC编译器,以及Windows平台的Visual Studio(<=2015)。不过目前已经下载不到Visual Studio 2015,以及Windows平台配置的繁琐,本文选择使用Linux平台,以及GCC编译器作为HLS的开发环境。
主要的环境以及工具集版本如下:
平台:Centos 7.x
编译器:GCC >= 4.85
Quartus: 18.1 lite (本文安装于/opt/intelFPGA_lite/18.1)
Modelsim: For Intel FPGA 10.5b (Free版本,本文安装于/opt/intelFPGA_lite/18.1/modelsim_ase/)

二、基本使用
HLS的基本使用与标准的C一模一样,不同的仅仅是编译方式上,以及头文件上。
在这里插入图片描述
如果是按照C语言的编译方式,则只需要通过GCC即可。我们简单的将上述的代码修改一下,加入HLS的头文件,并选择使用HLS的编译器进行编译。
在这里插入图片描述
编译之前,需要指定ModelSim的路径:功能仿真需要使用ModelSim,并且需要其提供的一系列库文件。
在这里插入图片描述
编译的指令是将GCC替换为i++,除此之外就是添加一个新的参数—component即可。
在这里插入图片描述
编译之后的结果,如下:
在这里插入图片描述
生成的test文件同样可以直接运行,只是,生成的只有在CPU端能够运行的文件,并没有生成FPGA端的代码。而我们真正需要的,是在FPGA端的代码。
因此,需要添加新的参数进行编译。
可用的编译指令如下:
在这里插入图片描述
注意,在这里,我们新加了一个参数,-march=CycloneV,表示,在编译时,按照CycloneV的器件(FPGA芯片)的资源和电路结构进行编译。
而当前版本的Quartus(i++)支持哪些版本的FPGA芯片(器件),则可以根据i++ —help查看。
在这里插入图片描述
将对应的名称去除空格,进行替换即可。
编译之后的结果如下:
在这里插入图片描述
其中,test.prj文件夹当中的文件,就是我们所需要的FPGA端的代码。
在这里插入图片描述
components为生成的模块代码(即accelerate函数所对应的硬件描述语言代码)。
quartus为硬件工程。
report为编译结果报告,包括了性能描述报告。性能报告非常重要,在后期的优化当中,优化的主要依据就是借助编译报告完成的verification则是生成的测试文件。

剩下的,就是使用Quartus软件,对生成的硬件描述语言代码进行编译,生成FPGA可以使用的文件。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
到此,基本的HLS开发就算完成了。但是还是有不少的地方可以进行改进。

三、改进
虽然在编译的时候,我们可以使用—component参数指定需要编译生成的模块,但是,如果模块太多,则会导致比较麻烦,因此,我们可以采用另外的方式进行。
在这里插入图片描述
如上代码,只需要在函数前面,加上关键字component,编译的时候,就可以取消—component参数。
上述代码的编译指令修改如下:
在这里插入图片描述
得到的结果和之前的一样。

如果不想手动打开quartus进行生成的硬件代码的编译工作,可以在参数当中添加—quartus-compile参数,当硬件代码生成之后,自动进行工程的编译。
在这里插入图片描述
如果需要查看更加详细的编译信息,还可以加上参数-v,如下:
在这里插入图片描述
根据我们的修修补补,基本上,最后生成的文件如下:
在这里插入图片描述

四、限制
从上面的结果看,我们就已经完成了使用C/C++等高级语言开发FPGA模块的工作,不过,需要澄清的是,我们完成的仅仅是一个模块,并不是整个FPGA工程,因此,这些生成好的代码需要由硬件工程师嵌入到对应的硬件工程当中进行使用;另外,虽然高级语言进行IP Core的开发确实效率比较高,但是,也存在一些限制。
1.main函数不能添加component关键字,即main函数不能被编译为FPGA的一个模块。
2.标记为component的函数当中,不能使用内存分配函数,包括open,malloc,calloc,free等等。
3.component函数当中不能使用多线程,文件读写等一切关于涉及到系统调用的函数。

作者:张家龙,海云捷迅资深架构师,原文链接:https://www.fpga-china.com/11762.html
其他文章推荐:
1.串口的FPGA实现
2.FPGA 在深度神经网络当中的应用(一)

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HLS(High-Level Synthesis)是一种将高级语言(如C/C++)转换为硬件描述语言(如Verilog和VHDL)的技术,以方便进行FPGA设计。在HLS中实现F.conv2d(二维卷积运算)的方法如下: 1. 定义输入和输出数据类型:首先需要定义输入和输出数据类型。假设输入数据为3通道的图像,每个通道有16位的像素值,输出数据也是16位。则可以使用以下代码定义数据类型: ```c++ typedef short data_t; typedef struct { data_t data[3][H][W]; } input_t; typedef struct { data_t data[H][W]; } output_t; ``` 其中,H和W分别表示图像的高度和宽度。 2. 实现卷积核:卷积核是一个3维数组,用于对输入图像进行卷积运算。可以使用以下代码定义卷积核: ```c++ typedef struct { data_t data[K][K][C][F]; } weight_t; ``` 其中,K表示卷积核的大小,C表示输入图像的通道数,F表示输出图像的通道数。 3. 编写卷积函数:卷积函数的输入包括输入图像、卷积核和偏置项(可选),输出为卷积后的图像。可以使用以下代码实现卷积函数: ```c++ void conv2d(input_t input, weight_t weight, data_t bias, output_t output) { for (int i = 0; i < H-K+1; i++) { for (int j = 0; j < W-K+1; j++) { for (int f = 0; f < F; f++) { data_t sum = 0; for (int c = 0; c < C; c++) { for (int ii = 0; ii < K; ii++) { for (int jj = 0; jj < K; jj++) { sum += input.data[c][i+ii][j+jj] * weight.data[ii][jj][c][f]; } } } sum += bias; output.data[i][j][f] = sum; } } } } ``` 该函数使用4层循环,分别遍历输出图像的每个像素、每个通道和卷积核的每个参数。 4. 使用HLS编译器生成硬件描述语言:使用HLS编译器将C/C++代码转换为硬件描述语言(如Verilog或VHDL),并在FPGA上实现卷积运算。 以上是使用HLS实现F.conv2d的一般流程,具体实现可能因不同的HLS工具和FPGA平台而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值