以下只是一个简单的2D卷积的示例:
头文件

#include<ap_int.h>
#include<iostream>
#include<hls_video.h>
#define MAX_LEN 100
#define K 3
using namespace std;

typedef ap_int<16> data_t;

void conv2d(data_t in[MAX_LEN*MAX_LEN],data_t weight[K][K],data_t out[MAX_LEN*MAX_LEN],int fsize,int pad);


源文件

#include"conv2d.h"

void conv2d(data_t in[MAX_LEN*MAX_LEN],data_t weight[K][K],data_t out[MAX_LEN*MAX_LEN],int fsize,int pad){
#pragma HLS array_partition variable=weight complete dim=0
	hls::LineBuffer<K,MAX_LEN,data_t> LineBuffer;
	hls::Window<3,3,data_t> WindowBuffer;

    data_t tmp;
    int n=0;
    int addr=0;
    int start=2*(fsize+2*pad)+2;           //2=K-1,window is valid when n>=start
    //
	for(int r=0;r<fsize+2*pad;r++)
    	for(int c=0;c<fsize+2*pad;c++){
#pragma HLS PIPELINE II=1
#pragma HLS dependence variable=LineBuffer false
#pragma HLS dependence variable=WindowBuffer false
            //deal with linebuffer
    		LineBuffer.shift_pixels_up(c);
            if(r>=pad&&r<fsize+pad&&c>=pad&&c<fsize+pad)
            	tmp=in[(r-pad)*fsize+(c-pad)];
            else
            	tmp=(data_t)0;
            LineBuffer.insert_bottom_row(tmp,c);
            //deal with window
            WindowBuffer.shift_pixels_left();
            data_t new_col[K]={LineBuffer.getval(0,c),LineBuffer.getval(1,c),LineBuffer.getval(2,c)};
            WindowBuffer.insert_left(new_col);
            //calc
            if(n>=start&&(n-start)%(fsize+2*pad)<fsize){
            	data_t sum=0;
            	for(int i=0;i<K;i++)
            		for(int j=0;j<K;j++)
            		{
            			sum+=weight[i][j]*WindowBuffer.getval(i,j);
            		}
            	out[addr]=sum;
            	addr++;
            }
            n++;
    	}
}



测试文件

#include"conv2d.h"


void conv(data_t in[MAX_LEN*MAX_LEN],data_t weight[K][K],data_t out[MAX_LEN*MAX_LEN],int fsize,int pad){
    int fsize_o=fsize+2*pad-K+1;
    for(int r=0;r<fsize_o;r++)
    	for(int c=0;c<fsize_o;c++){
    		data_t tmp=0;
    		for(int i=0;i<K;i++)
    			for(int j=0;j<K;j++)
    				if(r+i-pad>=0&&r+i-pad<fsize&&c+j-pad>=0&&c+j-pad<fsize)
    					tmp+=weight[i][j]*in[(r+i-pad)*fsize+(c+j-pad)];
    		out[r*fsize_o+c]=tmp;
    	}
}

int main(){
	data_t in[MAX_LEN*MAX_LEN];
	data_t out[MAX_LEN*MAX_LEN];
	data_t out_ref[MAX_LEN*MAX_LEN];
	data_t weight[K][K];
	int pad=1;
	int fsize=32;
	//initialize
	for(int i=0;i<K;i++)
		for(int j=0;j<K;j++)
			weight[i][j]=i*K+j;
    for(int i=0;i<fsize;i++)
    	for(int j=0;j<fsize;j++)
    		in[i*fsize+j]=i*fsize+j;
    //calculate
    conv(in,weight,out_ref,fsize,pad);
    conv2d(in,weight,out,fsize,pad);

    int err=0;
    for(int i=0;i<fsize*fsize;i++){
    	if(out_ref[i]!=out[i])
    		err++;
    	cout<<out_ref[i]<<","<<out[i]<<endl;
    }
    cout<<"error count is "<<err<<endl;
    return 0;
}

参考链接

更多推荐