Function templates for data types are functions that can operate with generic
data types. This lets you create library functions that can be adapted to support
multiple data types. This means you do not need to replicate the code or block in the
Vitis Model Composer HLS block library to
support each type. The xmcImportFunction command in
Model Composer creates generic library blocks which you can connect to signals of any
data types that the block supports.
The data type (typename) template parameters
resolve at simulation runtime, when the tool generates the code and simulation wrapper.
The parameters are replaced during simulation by the actual data types that are
specified by the signals connecting to the library block. The resolved data types can
only be the types that Model Composer supports as discussed in Working with Data Types.
template <typename T>
T max(T x, T y) {
return (x > y) ? x : y;
}
#include <complex>
template <typename T>
void mult_by_two(std::complex< T > x, std::complex< T > *y)
{
*Out = In1 * 2;
}
typename (or class)
parameters are propagated from input signals on the block, or are customization
parameters that must be defined by the user at simulation runtime. For example, the following function template specifies the parameter âTâ as a customization parameter. You must specify this when adding the block to the model, because it is not associated with either input argument, 'x' or 'y':
template <typename T>
T min(int x, int y) {
return (x < y) ? x : y;
}
The Block Parameters dialog box for the generated Library Function block has an edit field. Use this to enter the template argument as shown in the following figure.
In template syntax, you can specify data type template parameters for a function or class along with other template parameters. For example:
template <typename T1, int ROWS, int COLS, int W, int I>
T1 func(T1 x[ROW][COLS], ap_fixed<W, I> &y) {
...
}
SUPPORTED_TYPES/UNSUPPORTED_TYPES Pragma
typename) template
parameter (or class), you can also define the
accepted data types for the variable. Use either the SUPPORTED_TYPES or UNSUPPORTED_TYPES
pragma as part of the function signature. This is shown in the following code
example. #pragma XMC INPORT x
#pragma XMC INPORT y
#pragma XMC SUPPORTED_TYPES T: int8, int16, int32, double, single, half
template <class T>
T max(T x, T y) {
return (x > y) ? x : y;
}
#pragma XMC UNSUPPORTED_TYPES T: boolean
#pragma XMC INPORT x, y
template <typename T>
T min(T x, T y) {
return (x < y) ? x : y;
}
Model Composer supports an extensive list of data types as discussed in Working with Data Types. To specify which of these data
types the template parameter supports, you can either include the list of supported
types, or the unsupported types. The SUPPORTED_TYPES and UNSUPPORTED_TYPES
pragmas are simply two opposite views of the same thing:
-
SUPPORTED_TYPES: Specifies a template parameter name (param), and the list of data types that are accepted by that parameter. This implies the exclusion of all types not listed.#pragma XMC SUPPORTED_TYPES param: type1, type2, ... -
UNSUPPORTED_TYPES: Specifies a template parameter name (param), and the list of data types which that parameter does not accept. This implies the inclusion of all types not listed.#pragma XMC UNSUPPORTED_TYPES param: type1, type2, ...
With the SUPPORTED_TYPES or UNSUPPORTED_TYPES pragma in place, Model Composer will
check the type of input signal connected to the block to ensure that the data type
is supported. Without the use of one of these pragmas, the data type template
parameter will accept any of the data types supported by Model Composer.
Function Template Specialization and Overloading
The xmcImportFunction command supports
specialization for function templates. Model Composer creates the library block for
the generic function template, supporting multiple data types. The block includes
any specialized functions for connecting input signals with matching data types.
Both the generic function, and any specialization functions are compiled into the
block DLL. For example:
template <typename T>
T min(T x, T y) {
return (x < y) ? x : y;
}
template <>
bool min<bool>(bool x, bool y) {
...
}
In this case, Model Composer calls the specialized boolean form of the min function when the block is connected to boolean
signals.
int func(int x);
float func(float x);You can also overload a function template as shown
below:template <typename T>
int func(int x, T y);
template <typename T>
float func(float x, T y);