16. Model Semantics#
A number of different tools interpret how Simulink / Stateflow models execute. These include Reactis, the MathWorks Simulation environment, and various autocode tools. In this chapter we discuss issues related to the semantics of Simulink / Stateflow models. In particular we focus on how model execution affects coverage tracking.
16.1. Conditional Input Branch Execution#
A number of factors influence whether or not a Simulink block executes during a given simulation step. These include whether or not the block (or a subsystem containing the block) has a sample time and whether or not the block resides in a conditionally executed subsystem. Conditional input branch execution is an optimization supported by Simulink that offers an additional way to determine when blocks execute by disabling them in some cases. Beginning with V2007, Reactis also supports this feature.
To understand how conditional input branch execution works, consider the simple model shown in Figure 16.1. When input c
is greater than or equal to zero, the Switch
block outputs RelOp1
and ignores RelOp2
. Conversely, when c
is less than zero, the Switch block outputs RelOp2
and ignores RelOp1
. The basic idea behind conditional input branch execution is to not execute blocks whose output is ignored.
This optimization does not change the outputs computed by the model, but it will speed up execution since some blocks are not executed. In the case of Reactis, the optimization has an important impact on coverage tracking: the coverage targets associated with a block are not covered during any simulation step in which the block is ignored due to conditional input branch execution. For example, in Figure 16.1, neither the true nor false branch of RelOp2
are covered when c
is greater than or equal to zero.
In addition to switch blocks, conditional input branch execution also occurs when Multiport Switch blocks or non-virtual subsystems are executed. The non-control inports of Multiport Switches and the inports of non-virtual subsystems each serve as the root of an ignorable branch just as each non-control inport of a switch block does. We call these inports ignorable inports.
In Figure 16.1, each ignorable branch consists of a single block wired to an ignorable inport; however, in general, an entire group of blocks might be ignored. The set of blocks included in an ignorable branch is computed as follows. A block B is included in an ignorable branch IB if it meets each of the following conditions:
To understand how conditional input branch execution works, consider the simple model shown in Figure 16.1. When input c is greater than or equal to zero, the Switch block outputs RelOp1 and ignores RelOp2. Conversely, when c is less than zero, the Switch block outputs RelOp2 and ignores RelOp1. The basic idea behind conditional input branch execution is to not execute blocks whose output is ignored.
This optimization does not change the outputs computed by the model, but it will speed up execution since some blocks are not executed. In the case of Reactis, the optimization has an important impact on coverage tracking: the coverage targets associated with a block are not covered during any simulation step in which the block is ignored due to conditional input branch execution. For example, in Figure 16.1, neither the true nor false branch of RelOp2 are covered when c is greater than or equal to zero.
In addition to switch blocks, conditional input branch execution also occurs when Multiport Switch blocks or non-virtual subsystems are executed. The non-control inports of Multiport Switches and the inports of non-virtual subsystems each serve as the root of an ignorable branch just as each non-control inport of a switch block does. We call these inports ignorable inports.
In Figure 16.1, each ignorable branch consists of a single block wired to an ignorable inport; however, in general, an entire group of blocks might be ignored. The set of blocks included in an ignorable branch is computed as follows. A block B is included in an ignorable branch IB if it meets each of the following conditions:
To understand how conditional input branch execution works, consider the simple model shown in Figure 16.1. When input c is greater than or equal to zero, the Switch block outputs RelOp1 and ignores RelOp2. Conversely, when c is less than zero, the Switch block outputs RelOp2 and ignores RelOp1. The basic idea behind conditional input branch execution is to not execute blocks whose output is ignored.
This optimization does not change the outputs computed by the model, but it will speed up execution since some blocks are not executed. In the case of Reactis, the optimization has an important impact on coverage tracking: the coverage targets associated with a block are not covered during any simulation step in which the block is ignored due to conditional input branch execution. For example, in Figure 16.1, neither the true nor false branch of RelOp2 are covered when c is greater than or equal to zero.
In addition to switch blocks, conditional input branch execution also occurs when Multiport Switch blocks or non-virtual subsystems are executed. The non-control inports of Multiport Switches and the inports of non-virtual subsystems each serve as the root of an ignorable branch just as each non-control inport of a switch block does. We call these inports ignorable inports.
In Figure 16.1, each ignorable branch consists of a single block wired to an ignorable inport; however, in general, an entire group of blocks might be ignored. The set of blocks included in an ignorable branch is computed as follows. A block B is included in an ignorable branch IB if it meets each of the following conditions:
B is a direct-feedthrough block. Such blocks do not maintain a state, instead their output values can be computed as a function only of their inputs. Examples of direct-feedthrough blocks include Gain, Sum, Logical Operator, and Relational Operator blocks. The following blocks are not direct-feedthrough blocks: Unit Delay, Discrete Integrator, Discrete State Space, Hit Crossing, Memory, Relay, Integer Delay, and S-Function (if there are ports that are not direct-feed-through).
B’s outports only feed into either:
the ignorable port at the root of IB; or
the inports of blocks in IB.
B has the same underlying execution schedule as the block containing the ignorable inport at the root of IB. Two blocks have the same underlying execution schedule if:
both are triggered by same trigger; and
both are enabled by same enable port; and
both have the same sample time (possibly inherited).
In Simulink, a model is configured to use conditional branch execution in two ways.
For switch and Multiport Switch blocks, the Simulation Parameters dialog is used (see Figure 16.2). The following steps are required:
Load your model in Simulink.
Select Simulation > Configuration Parameters… menu item.
Click the Optimization tab.
Check the box for Conditional input branch execution (item 1 in Figure 16.2).
Non-virtual subsystems are configured on a subsystem-by-subsystem basis, by performing the following steps:
Load your model in Simulink.
Right-click on a non-virtual subsystem and select Subsystem parameters…
Check the box for Propagate execution context across subsystem boundary.
Conditional input branch execution in Reactis is controlled independently for each model. The steps required to change the setting are as follows:
In the main Reactis window, select Edit > General….
The Reactis info file editor will appear with the General… tab selected. This tab contains a parameter Conditional input branch execution, which can be set to
On
,Off
, orInherited from model settings
.