Real-Time Workshop    

Categories of Output Expressions

When you implement a C-MEX S-function, you can specify whether the code corresponding to a block's output is to be generated as an expression. If the block generates an expression, you must specify that the expression is constant, trivial, or generic.

A constant output expression is a direct access to one of the block's parameters. For example, the output of a Constant block is defined as a constant expression, because the output expression is simply a direct access to the block's Value parameter.

A trivial output expression is an expression that may be repeated, without any performance penalty, when the output port has multiple output destinations. For example, the output of a Unit Delay block is defined as a trivial expression, because the output expression is simply a direct access to the block's state. Since the output expression involves no computations, it may be repeated more than once without degrading the performance of the generated code.

A generic output expression is an expression that should be assumed to have a performance penalty if repeated. As such, a generic output expression is not suitable for repeating when the output port has multiple output destinations. For instance, the output of a Sum block is a generic rather than a trivial expression because, it is costly to recompute a Sum block output expression as an input to multiple blocks.

Examples of Trivial and Generic Output Expressions

Consider the block diagram of Figure 9-3. The Delay block has multiple destinations, yet its output is designated as a trivial output expression, so that it can be used more than once without degrading the efficiency of the code.

Figure 9-3: Diagram With Delay Block Routed to Multiple Destinations

The following code excerpt shows code generated from the Unit Delay block in this block diagram. Note that the three root outputs are directly assigned from the state of the Unit Delay block, which is stored in a field of the global data structure rtDWork. Since the assignment is direct, involving no expressions, there is no performance penalty associated with using the trivial expression for multiple destinations.

On the other hand, consider the Sum blocks in Figure 9-4.

Figure 9-4: Diagram With Sum Block Routed to Multiple Destinations

The upper Sum block in Figure 9-4 generates the signal labelled non_triv. Computation of this output signal involves two multiplications and an addition. If the Sum block's output were permitted to generate an expression even when the block had multiple destinations, the block's operations would be duplicated in the generated code. In the case illustrated, the generated expressions would proliferate to four multiplications and two additions. This would degrade the efficiency of the program. Accordingly the output of the Sum block is not allowed to be an expression since it has multiple destinations

The code generated for the block diagram of Figure 9-4 illustrates how code is generated for Sum blocks with single and multiple destinations.

The Simulink engine does not permit the output of the upper Sum block to be an expression, since the signal non_triv is routed to two output destinations. Instead, the result of the multiplication and addition operations is stored in a temporary variable (rtb_non_triv) that is referenced twice in the statements that follow, as seen in the code excerpt below.

In contrast, the lower Sum block, which has only a single output destination (Out2), does generate an expression.

Specifying the Category of an Output Expression

The S-Function API provides macros that let you declare whether an output of a block should be an expression, and if so, to specify the category of the expression. Table 9-1 specifies when to declare a block output to be a constant, trivial, or generic output expression.

Table 9-1: Types of Output Expressions
Category of Expression
When to Use

Constant

Use only if block output is a direct memory access to a block parameter

Trivial

Use only if block output is an expression that may appear multiple times in the code without reducing efficiency (for example, a direct memory access to a field of the DWork vector, or a literal)

Generic

Use if output is an expression, but not constant or trivial

You must declare outputs as expressions in the mdlSetWorkWidths function, using macros defined in the S-Function API. The macros have the following arguments:

The following macros are available for setting an output to be a constant, trivial, or generic expression:

The following macros are available for querying the status set by any prior calls to the macros above:

Note that the set of generic expressions is a superset of the set of trivial expressions, and the set of trivial expressions is a superset of the set of constant expressions.

Therefore, when you query an output that has been set to be a constant expression with ssGetOutputPortTrivialOutputExprInRTW, it will return True. A constant expression is considered a trivial expression, because it is a direct memory access that may be repeated without degrading the efficiency of the generated code.

Similarly, an output that has been configured to be a constant or trivial expression will return true when queried for its status as a generic expression.


  Supporting Expression Folding in S-Functions Acceptance or Denial of Requests for Input Expressions