Defining Customization Parameters - 2022.2 English

Vitis Model Composer User Guide (UG1483)

Document ID
UG1483
Release Date
2023-01-13
Version
2022.2 English

Template parameters can be used to define the port array sizing and data type, and the parameters are defined by the input signals on the block. Additional customization parameters can also be defined, which are not defined by input signals, and thus must be defined by the user using the Block Parameter dialog box sometime before simulation runtime.

There are two methods to define customization parameters for a library function block:

  • Using C/C++ function templates.
  • Assigning the Model Composer (XMC) PARAMETER pragma to a function argument, defining it as not connecting to an input or output of the block, but rather as a customization parameter.

There are pros and cons to both methods, which are discussed below.

Function Templates

The first method, defines a function template that uses template parameters for customization. A template parameter defines a customization parameter in Model Composer if its value is not determined by an input signal, or derived by the function as an output. You can use customization parameters to define the values, data types, or data dimensions of output ports, or for parameters in use in the function body.
Important: The template function signature and function definition must be defined in the C/C++ header file.

The template parameter for the function argument is defined using standard function template syntax, but the template parameter is not assigned to an input argument in the function signature. When the block is instantiated into a model, Model Composer identifies template parameters whose values are not determined by input signals, and lets the user define the values for those customization parameters. Values can be defined for customization parameters in the model any time prior to simulation.

For function templates, the customization parameters can only be integer values to define the size or dimensions of a data type, or can only be scalar variables with definable data types. Model Composer defines a default value of 0 for integer parameters, and 'int32' for data type, or typename parameters.

In the function template example below, the template parameters ‘M’ and 'B' define customization parameters because the parameter values are not inherited from the input signal to the block. In this case, the parameters need to be customized by the user when the block is added to the model, or any time before simulation.
template <int M, int B>
double func1(double x) {
   return x * M + B;
}

Customization parameters are displayed in the Block Parameters dialog box for the imported block as shown for the func1 function below. Double click on a block in the model to open the Block Parameters dialog box, then enter the value for any editable parameters, such as 'M' and 'B' below.

Figure 1. Entering Parameter Values

Optionally, the user can also specify the name of a MATLAB workspace variable in the text field for the customization parameter, and have the value determined by Model Composer through the MATLAB variable. For example, the variable param1 is defined in the MATLAB workspace, and used to define the value for 'M'.

Figure 2. Defining Parameters using Workspace Variables

PARAMETER Pragma

The second method defines function arguments as customization parameters through the use of the Model Composer PARAMETER pragma.

To declare that a function argument is a customization parameter, you must add the PARAMETER pragma with the parameter name, or list of names, before the function signature in the header file. You can specify multiple parameters with one pragma, or have separate pragmas for each, as shown below.
#pragma XMC PARAMETER <name1>, <name2>
#pragma XMC PARAMETER <name3>
function declaration(<name1>, <name2>, <name3>)

When a function argument is declared a customization parameter by pragma, the xmcImportFunction command will not create an input or output port on the block for that argument. It will be defined for use inside the function body only. When the block is added to a model, a customization field is added to the Block Parameter dialog box, and the user of the block can define values for the customization parameters.

Using the PARAMETER pragma on a function argument that is already driven by the input signal will be flagged as an error or a warning. In this case, the signal input propagation through the function will have higher precedence than the customization parameter.

While the function templates method only supports scalar and integer type customization parameters, the PARAMETER pragma supports integer, floating point or fixed point data type for the parameters. The customization parameters also can be scalar, vector or a two-dimensional matrix. In addition, while the function template defines default values of 0 for integer types, and int32 for the data type, the PARAMETER pragma lets you define default value for the parameters. Model Composers defines default values of 0 for all parameters that do not have user-defined defaults.

The example below uses the Model Composer PARAMETER pragma to define the customization parameters 'M' and 'B'.

#pragma XMC PARAMETER M, B
double func2(double x, double M = 1.2, double B = 3) {
return x * M + B;
}

The 'M' and 'B' customization parameters also have default values assigned: M=1.2, B=3. The default values for the customization parameters are assigned to the arguments in the function signature, and are displayed in the Block Parameters dialog box when opened for edit, as shown below.

Figure 3. Customization Parameters with Defaults
Important: If you define default values for the customization parameters of any argument, the C/C++ language requires that all arguments following that one must also have default values assigned, because the function can be called without arguments having default values. Therefore, you should add all customization parameters with default values at the end of the function argument list.

Vector and Matrix Customization Parameters

The PARAMETER pragma method can also be used to specify customization parameters with vector and matrix dimensions, or values. In the following example the coef vector is defined by the pragma as a customization parameter:
#pragma XMC PARAMETER coef
#pragma XMC INPORT din
#pragma XMC OUTPORT dout 
#pragma XMC SUPPORTS_STREAMING
void FIR(ap_fixed<17, 3> din[100], ap_fixed<17, 3> dout[100], 
ap_fixed<16, 2> coef[52]);
The constant array values of the customization parameter are entered in MATLAB expression format.
Note: commas are optional:
  • Vector parameter: [val1, val2, val3, ...]
  • Matrix parameter (row-major order): [val11, val12, val13, ...; val21, val22, val23, ...; ...]

Interface Output Types and Sizes

Customization parameters can also be used to directly set the data types and dimension size for output ports whose values are not determined by inputs to the function. In the function below, the template variables define the word length and fractional length of the ap_fixed data type and the array size.

template <typename T1, int N1, int W2, int I2, int N2>
void func(const T1 in[N1], ap_fixed<W2, I2> out[N2]) {
...
}

The template variables 'W2, 'I2'' and 'N2' define customization parameters because the values must be set by the user rather than determined from the input arguments. However, Model Composer recognizes that the template variables 'T1' and 'N1' are specified on the input port, and so the data type (typename) and the size of the input vector are not customization parameters, but rather get defined by the input signal on the block.

To set the data type for output ports, or arguments used in the body of the function, the typename specified must be one of the Model Composer supported data types, including the signed or unsigned fixed data types.

Table 1. Model Composer Supported Data Types
Supported Typenames
'int8'
'uint8'
'int16'
'uint16'
'int32'
'uint32'
'double'
'single'
'x_half'
'boolean'
'x_sfix<n1>_En<n2>'
'x_ufix<n1>_En<n2>'

In the example function below, while the typename for 'T1' is determined by the input signal, you can set the typename for 'T2' in the Block Parameters dialog box on the mask, when the block is added to a model, or before simulation runtime:

template <typename T1, int N1, typename T2, int N2>
void func(const T1 in[N1], T2 out[N2]) {
...
}