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 run time.
- 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 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.
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.
param1
is defined in the
MATLAB workspace, and used to define the value for 'M'.PARAMETER Pragma
The second method defines function arguments as customization parameters
through the use of the Model Composer PARAMETER
pragma.
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.
Vector and Matrix Customization Parameters
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]);
- 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.
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 run time:
template <typename T1, int N1, typename T2, int N2>
void func(const T1 in[N1], T2 out[N2]) {
...
}