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 without needing to replicate the code or block in the Model Composer
HLS block library to support each type. The xmcImportFunction
command in Model Composer will create generic library
blocks which the user of the block can connect to signals of any data types supported by
the block.
The data type (typename
) template
parameters are resolved at simulation run time, when the code and simulation wrapper are
generated. 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 run time. For example, the following function template specifies the parameter ‘T’ as a customization parameter. Because it is not associated with either input argument, 'x' or 'y', it must be specified by the user when the block is added to the model:
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 to enter the template argument as shown in the following figure.
In the template syntax, the data type template parameters for function or class can be specified with other template parameters. The order of specification is not important. 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 by using 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;
}
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 that are not accepted by that parameter. 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
Specialization is supported for function templates in the xmcImportFunction
command. Model Composer will create
the library block for the generic function template, supporting multiple data types,
but the block will also include any specialized functions to be used when connected
to 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 will call 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);