对于SDSOC这个工具的使用来说,最重要的一步骤就是硬件加速,对应着在项目界面(project explore)中添加要加速的硬件函数(Haradware Funcion),引出了下面的问题
回答:
需要注意三点:
①不使用bool类型的数组
②不对顶层硬件函数的接口使用hls::stream
③不对顶层硬件函数进行接口优化,但可以指定生成接口
//创建AXI接口
#pragma SDS data zero_copy(): Use to generate a shared memory interface
//创建FIFO接口
#pragma SDS data access_pattern(argument:SEQUENTIAL)
查看例程<mmultadd.h>:
带<#pragma SDS>类指令在头文件中出现,目的是以声明的形式创建函数传输端口;
带<#pragma HLS>类指令在函数体内出现,目的是向计算密集函数内添加基于HLS工具的硬件加速语句。
- 头文件中,声明了函数<mmult()>和函数<madd()>的数据传输端口形式为FIFO,FIFO可以理解为顺序读取。
- 如果不使用#pragma SDS指令来制定端口的话,则会使用默认端口形式RAM,RAM可以理解为随机读取。
- 随机读取对于某些特定的处理任务产生影响,因此请指定适合处理任务的数据传输端口
#ifndef _MMULTADD_H_
#define _MMULTADD_H_
#define N 32
/**
* Design principles to achieve best performance
*
* 1. Declare secquential access to stream data into accelerators via a hardware FIFO
* interface. Otherwise, the default RAM interface requires all data to arrive
* before starting HLS accelerator
*/
#pragma SDS data access_pattern(A:SEQUENTIAL, B:SEQUENTIAL, C:SEQUENTIAL)
void mmult (float A[N*N], float B[N*N], float C[N*N]);
#pragma SDS data access_pattern(A:SEQUENTIAL, B:SEQUENTIAL, C:SEQUENTIAL)
void madd(float A[N*N], float B[N*N], float C[N*N]);
#endif /* _MMULTADD_H_ */
查看<mmult.cpp>,其中带<#>的语句就是向计算密集函数内添加基于HLS工具的硬件加速语句:
`#include <stdio.h>
#include <stdlib.h>
#include "mmultadd.h"
/**
*
* Design principles to achieve II = 1
* 1. Stream data into local RAM for inputs (multiple access required)
* 2. Partition local RAMs into N/2 sub-arrays for fully parallel access (dual-port read)
* 3. Pipeline the dot-product loop, to fully unroll it
* 4. Separate multiply-accumulate in inner loop to force two FP operators
*
*/
void mmult (float A[N*N], float B[N*N], float C[N*N])
{
float Abuf[N][N], Bbuf[N][N];
#pragma HLS array_partition variable=Abuf block factor=16 dim=2
#pragma HLS array_partition variable=Bbuf block factor=16 dim=1
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
#pragma HLS PIPELINE
Abuf[i][j] = A[i * N + j];
Bbuf[i][j] = B[i * N + j];
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
#pragma HLS PIPELINE
float result = 0;
for (int k = 0; k < N; k++) {
float term = Abuf[i][k] * Bbuf[k][j];
result += term;
}
C[i * N + j] = result;
}
}
}