Function Templates for Data Types - 2025.2 English - UG1483

Vitis Model Composer User Guide (UG1483)

Document ID
UG1483
Release Date
2025-11-20
Version
2025.2 English

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.

To import a block that accepts multiple data types, you use a function template. For example:
template <typename T>
T max(T x, T y) {
   return (x > y) ? x : y;
}
Or, in the case of a function with complex function arguments. For example:
#include <complex>
template <typename T>
void mult_by_two(std::complex< T > x, std::complex< T > *y)
{
   *Out = In1 * 2;
}
Model Composer determines the type during simulation. The 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.
Important: The data type for a function or class cannot be propagated from an output.

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.

Figure 1. Library Function Block Parameters

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) {
...
}
Important: In the example above, the 'T1' template parameter specifies both the function return and the data type of the input 'x'. In this case, because it uses a single template parameter, both arguments resolve to the same data type. That type propagates from the input signal to the block.

SUPPORTED_TYPES/UNSUPPORTED_TYPES Pragma

When defining a data type (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.

Model Composer supports overloading of a function with the same number of input/output arguments. For example, the following defines two forms of the function:
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);
Tip: Model Composer does not support overloading functions with different numbers of input/output arguments or different argument dimensions, and must be defined as separate functions.