学fpga(hls之平均值算法编写)
Posted 费晓行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学fpga(hls之平均值算法编写)相关的知识,希望对你有一定的参考价值。
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
一些soc中的fpga,本身除了作为硬件使用之外,还可以作为硬件加速使用。如果是cpu上做的比较慢的一些操作,那么就可以用fpga来加速,这个时候hls就能排上用场了。可以以求平均值作为举例,看看fpga上面是怎么用hls做平均值的计算。
1、一般写法
#include <ap_cint.h>
uint32 _average_int(uint32* array, int num)
uint32 sum = 0;
int i;
for(i = 0; i < num; i++)
sum += array[i];
return sum / num;
uint32 average_int(uint32* array, int num)
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE s_axilite port=num
#pragma HLS INTERFACE m_axi depth=1024 port=array
uint32 result = _average_int(array, num);
return result;
和之前一篇文章有所不同的是,这里的函数return接口是s_axilite,函数返回值也是uint32。此外,除了num还是s_axilite之外,array已经变成了m_axi,毕竟可能需要从ddr读取数据来进行操作。可以看一下编译后的一个中断接口,
2、添加pipeline
#include <ap_cint.h>
uint32 _average_int(uint32* array, int num)
uint32 sum = 0;
int i;
for(i = 0; i < num; i++)
#pragma HLS PIPELINE
sum += array[i];
return sum / num;
uint32 average_int(uint32* array, int num)
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE s_axilite port=num
#pragma HLS INTERFACE m_axi depth=1024 port=array
uint32 result = _average_int(array, num);
return result;
1中的代码虽然能实现功能,但是毕竟不是并行的。一种简单的方法,就是在for循环里面添加pipeline,这样可以提供数据的吞吐量。流水线的加速原理比较简单。就是假设一件事情需要三个步骤,那么在前一件事情开始做第二个步骤的时候,第二件事情没有必要等第一件事情做完,就可以开始第一步骤的操作。
3、进一步添加cache和dataflow
#include <ap_cint.h>
#include <string.h>
uint32 sum;
void _average_int(uint32* array, int num)
sum = 0;
uint32 cache[64];
#pragma HLS STREAM variable=cache depth=64
int i;
int j;
int len;
for(i = 0; i < num; i+= 64)
#pragma HLS LOOP_TRIPCOUNT min=0 max=1024
#pragma HLS DATAFLOW
if((num - i) >= 64)
len = 64;
else
len = num - i;
memcpy(cache, array+i, len);
for(j = 0; i < len; j++)
#pragma HLS PIPELINE
sum += cache[j];
uint32 average_int(uint32* array, int num)
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE s_axilite port=num
#pragma HLS INTERFACE m_axi depth=1024 port=array
_average_int(array, num);
return sum;
和1、2相比较而言,3改动较大。除了添加了全局变量sum之外,还添加了cache和dataflow。添加cache,主要是因为总线资源比较宝贵,可以一次性加载多个数据进行处理,不用每次只加载一个,这样太浪费资源。另外,添加了dataflow之后,memcpy和后面的for循环可以进行数据流操作,进一步提高数据的并行性。
4、优化的步骤和方法
一般来说,hls的优化并不是一蹴而就的。这中间不断的迭代和改进是不可或缺的。通常,第一步是完成基本功能开发,接着完成接口的设定,最后是数据、for循环、流水线的优化。当然,所有这一切还是要上机进行实际环境的验证。资料里面直接给出代码的做法缺少了思考的过程,这方面恰恰是自己需要进行补齐和锻炼的。
以上是关于学fpga(hls之平均值算法编写)的主要内容,如果未能解决你的问题,请参考以下文章