Building a Shared Library

To build a shared library, sdscc requires at least one accelerator. This example provides three entry points into two hardware accelerators: a matrix multiplier and a matrix adder. You can find these files in the samples/libmatrix/build directory.

  • mmult_accel.cpp – Accelerator code for the matrix multiplier
  • mmult_accel.h – Header file for the matrix multiplier
  • madd_accel.cpp – Accelerator code for the matrix adder
  • madd_accel.h – Header file for the matrix adder
  • matrix.cpp – Code that calls the accelerators and determines the data motion network
  • matrix.h – Header file for the library

The matrix.cpp file contains functions that define the accelerator interfaces as well as how the hardware functions communicate with the platform (i.e., the data motion networks between platform and accelerators). The function madd calls a single matrix adder accelerator, and the function mmult calls a single matrix multiplier accelerator. Another function mmultadd is implemented using two hardware functions, with the output of the matrix multiplier connected directly to the input of the matrix adder.

/* matrix.cpp */
#include "madd_accel.h"
#include "mmult_accel.h"
    
void madd(float in_A[MSIZE*MSIZE], float in_B[MSIZE*MSIZE], float out_C[MSIZE*MSIZE])                                             
{
  madd_accel(in_A, in_B, out_C);
}
    
void mmult(float in_A[MSIZE*MSIZE], float in_B[MSIZE*MSIZE], float out_C[MSIZE*MSIZE])                                            
{
  mmult_accel(in_A, in_B, out_C);
}
    
void mmultadd(float in_A[MSIZE*MSIZE], float in_B[MSIZE*MSIZE], float in_C[MSIZE*MSIZE], 
float out_D[MSIZE*MSIZE])
{
  float tmp[MSIZE * MSIZE];
    
  mmult_accel(in_A, in_B, tmp);
  madd_accel(tmp, in_C, out_D);
}

The matrix.h file defines the function interfaces to the shared library, and will be included in the application source code.

/* matrix.h */
#ifndef MATRIX_H_
#define MATRIX_H_
   
#define MSIZE 16
    
void madd(float in_A[MSIZE*MSIZE], float in_B[MSIZE*MSIZE], float out_C[MSIZE*MSIZE]);
  
void mmult(float in_A[MSIZE*MSIZE], float in_B[MSIZE*MSIZE], float out_C[MSIZE*MSIZE]);
    
void mmultadd(float in_A[MSIZE*MSIZE], float in_B[MSIZE*MSIZE], float in_C[MSIZE*MSIZE], 
float out_D[MSIZE*MSIZE]);
    
#endif /* MATRIX_H_ */

The Makefile shows how the project is built by specifying that the functions mmult_accel, madd, and mmult_add must be implemented in programmable logic.

SDSFLAGS = \
    -sds-pf ${PLATFORM} \
    -sds-hw mmult_accel mmult_accel.cpp -sds-end \
    -sds-hw madd_accel madd_accel.cpp -sds-end

As is the case for normal shared libraries, object files are generated with position independent code (-fpic option).

sds++ ${SDSFLAGS} -c -fpic –o mmult_accel.o mmult_accel.cpp
    sds++ ${SDSFLAGS} -c -fpic –o madd_accel.o madd_accel.cpp
    sds++ ${SDSFLAGS} -c -fpic –o matrix.o matrix.cpp

To link the objects files we also follow the standard method and use the –shared switch.

sds++ ${SDSFLAGS} -shared -o libmatrix.so mmult_accel.o madd_accel.o matrix.o

After building the project, these files will be generated

  • libmatrix.so – Shared library suitable for linking using GCC and for runtime use
  • sd_card – Directory containing an SD card image for booting the board

Delivering a Library

The following structure allows compiling and linking into applications using GCC in standard ways.

<path_to_library>/include/matrix.h
<path_to_library>/lib/libmatrix.so
<path_to_library>/sd_card
Note: The sd_card folder is to be copied into an SD card and used to boot the board. This image includes a copy of the libmatrix.so file that is used at runtime.