The focus of this section is high-level discussion of modeling the
convolutional filter using VSC, and not on the lower level details of the implementation
itself. At the top level, the CU is modeled as having a memory interface using three
8-bit pointers (i.e. char*
) to the color values of the
input data and output data, as well as filter coefficients. Some other constant
parameters are also passed to the CU like the bias, image height and image width.
The header file conv_acc_filter.hpp
declares one compute()
wrapper function used for the
host code and software interaction and one or more processing elements (PEs). In this
example there is only one PE named krnl_conv
.
In VSC all accelerators should be written as a class derived from the
VPP_ACC
base class. In the user code, every class
that inherits from the VPP_ACC
class should intend to
be an accelerator that compiles to hardware. Specifically the child class should provide
a function named compute()
that is the software entry
point to the compiled hardware accelerator, as shown in the example below. Every derived
class should have a unique name to represent a unique compute unit function.
#pragma once
#include "common.hpp"
#include "vpp_acc.hpp"
class conv_acc : public VPP_ACC<conv_acc, /*NCU*/3>
{
ACCESS_PATTERN(src,SEQUENTIAL);
ACCESS_PATTERN(coeffs, SEQUENTIAL);
ACCESS_PATTERN(dst, SEQUENTIAL);
// Data copy macros : specifies that size of data to be copied for kernel call in
// case the kernel can process variable size data.
DATA_COPY(src, src[width*height]);
DATA_COPY(coeffs, coeffs[FILTER_V_SIZE*FILTER_H_SIZE]);
DATA_COPY(dst, dst[width*height]);
// Kernel DDR connections
SYS_PORT(coeffs, DDR[0]);
SYS_PORT(src, DDR[0]);
SYS_PORT(dst, DDR[0]);
public:
static void compute(
char *coeffs,
float factor,
short bias,
unsigned short width,
unsigned short height,
unsigned char *src,
unsigned char *dst
);
static void krnl_conv(
char *coeffs,
float factor,
short bias,
unsigned short width,
unsigned short height,
unsigned char *src,
unsigned char *dst
);
};
This header file defines a number of different things including the
top-level interface of the CU. It declares two static functions compute()
and krnl_conv()
. The compute()
function acts as software entry point on the host
side, which is called from the send_while
thread
sending data to the CU (here the conv_acc
class). The
krnl_conv()
function implements all the
functionality of the CU.
The header file also defines some other important items that any kernel model for VSC is required to specify: