Main Content

Simulink Subsystem Semantics

This set of examples shows different types of Simulink® Subsystems and what semantics are used when simulating these subsystems. Each example provides a description of the model and the subtleties governing how the model is executed.

Examples are provided for subsystem types.

  • Virtual and nonvirtual subsystems

  • Function-Call subsystems

  • Triggered subsystems

  • Enabled subsystems

  • Enabled and Triggered subsystems

  • If Action and Switch Case Action subsystems

  • While Iterator subsystems

  • For Each subsystems

  • For Iterator subsystems

Subsystem Semantics Examples

Open the models.

open('SimulinkSubsystemSemantics.prj');
open_system('sl_subsys_semantics');

Virtual and Nonvirtual Subsystems Overview

Simulink software has two classes of subsystems.

  1. Virtual subsystems provide graphical hierarchy in models. Virtual subsystems do not impact model execution. During model execution, the Simulink engine flattens all virtual subsystems.

  2. Nonvirtual subsystems provide execution and graphical hierarchy in models. Nonvirtual subsystems are executed as a single unit, known as atomic execution. All nonvirtual subsystems appear with a bold border in the Simulink canvas.

Virtual and nonvirtual subsystems

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/Virtual and nonvirtual subsystem overview');  

To create a nonvirtual subsystem, right-click the Subsystem block and select Block Parameters (Subsystem). In the Block Parameters dialog box, select Treat as atomic unit and click Apply.

The block parameters dialog box for the Subsystem2 block

The virtual subsystem results in a flat execution list, whereas the nonvirtual subsystem includes execution hierarchy. To display the execution order, in the Simulink Editor, on the Debug tab, select Information Overlays and click Execution order.

Blocks in a virtual and a nonvirtual subsystem display numbers showing the execution order

The Execution Order Block List that appears on the Simulink canvas displays the execution order.

The execution order block list

The Execution Order Block List shows that the nonvirtual subsystem Subsystem2 executed as a single unit.

A nonvirtual subsystem results in an algebraic loop within the execution hierarchy. When you update the diagram, the software issues the warning for the algebraic loop.

set_param(gcs,'SimulationCommand','Update')
Warning: Model 'sl_subsys_overview' contains 1 algebraic loops. 

Function-Call Subsystems

A Function-Call Subsystem block contains a conditionally executed subsystem that runs each time the control port receives a function-call event. Function-call subsystems implement callable functions using Simulink blocks. A Stateflow® Chart (Stateflow), Function-Call Generator block, MATLAB Function block, S-Function block, or Hit Crossing block can provide function-call events.

Function Call Subsystem

For more information, see Function-Call Subsystem.

These examples show valid and invalid uses of function-call subsystems.

close_system('sl_subsys_overview',0)
open_system('s_Function_call_subsystems')

Function-Call Subsystem examples

Nested Function Call

In this model, the Chart is a function-call initiator that executes the function, [d1,d2]=f(). The function f, in turn, executes the function g. After invoking f and g, the Chart uses the values d1 and d2 computed by f and g.

open_system('sl_subsys_fcncall1')

Two function-call subsystems for a nested function-call event

close_system('sl_subsys_fcncall1')

Nested Function Call with Data Sharing

The Chart block executes the function, [d1,d2]=f(), and f in turn executes g. After invoking f, the Chart uses the values d1 and d2 computed by f and g. The functions f and g share data via the signal s(f/Out2 feeds g/In1). Simulink treats the signal s as if the signal were a datastore.

open_system ('sl_subsys_fcncall2')

Two function-call subsystems for nested function-call events with output from one subsystem being fed to another

In general, the inputs to a function-call subsystem must be executed before the function-call initiator (Chart), except when the signal comes from a block executed by a common function-call initiator. In this example, f() is a function-call initiator of g(). However, the Chart is a function-call initiator of f(), which makes the Chart a common function-call initiator of both f() and g().

In that sense, the signal s below can be thought of as a datastore that f() and g() read from and write to in any given order defined by the Chart.

close_system('sl_subsys_fcncall2')

Data Sharing Between Two Function-Call Subsystems with Common Initiator

In this model, d1 and d2 are computed using g() and f(), respectively. The Chart uses d1 and d2 as input and invokes g() and f(). The functions f and g share data via the signal s, in other words, (f/Out1) feeds (g/In1). The model treats the signal s as if the signal is a data store.

open_system ('sl_subsys_fcncall3')

Two function-call subsystems that use the same function-call event source

In general, the inputs to a function-call subsystem must be executed before the function-call initiator (Chart), except when the signal comes from a block executed by a common function-call initiator. In this example, the Chart is a common function-call initiator of both f() and g(). Therefore, the signal s can be thought of as a data store.

close_system('sl_subsys_fcncall3')

Enabled Subsystem Containing Function-Call Initiator with Data Sharing

This enabled subsystem contains a Stateflow chart that invokes the functions f() and g(). The enabled subsystem in the model sl_subsys_fcncall4 is a common function-call initiator of both f() and g(), so the software treats the signal s as a datastore.

open_system ('sl_subsys_fcncall4')

Two function-call subsystems that use function-call events from the same enabled subsystem

close_system('sl_subsys_fcncall4')

Function-Call Subsystem with Merge Blocks

This model contains a chart that executes two function-calls. The model uses Merge blocks to map multiple signals onto a single memory location. The signals f/d1_out and g/d1_out are merged into a single memory location and fed back to the Chart as d1. The signals f/k_out and g/k_out are merged into a single memory location and fed back to f/k_in. Merging signals into a single memory location and feeding them back to the Chart allows the Chart to make complex decisions about how to compute values.

open_system ('sl_subsys_fcncall5')

Function-call subsystems with Merge block

close_system('sl_subsys_fcncall5')

Multiple Initiators of Function-Call Subsystem

This function-call subsystem is called by two different function-call initiators, Chart1 and Chart2. The data connection between Chart1/out1 and Chart2/d1 guarantees that Chart1 executes before Chart2. You must be careful when creating function-call subsystems with multiple callers.

For example, if you remove the data connection between Chart1 and Chart2, then you need to add priorities to Chart1 and Chart2 to specify the relative execution order of these blocks. Failure to do so results in ambiguous execution order.

However, the software does not give an error for this condition because the condition may be valid for specific cases. As an example, if you remove all states from f() and you delete the line connecting Chart1/out1 to Chart2/d1, then the order in which Chart1 and Chart2 execute does not matter.

open_system ('sl_subsys_fcncall6')

Function-call events from two different sources are set up to execute one function-call subsystem

close_system('sl_subsys_fcncall6')

Enabled Subsystem Containing Function-Call Subsystems That Specify Reset Behavior

This enabled subsystem contains two function-call subsystems. The left function-call subsystem is configured to hold the value of its states when it is enabled and to hold the value of its output when it is disabled. The right function-call subsystem is configured to reset the value of its states when it is enabled, and to reset the value of its output when it is disabled.

open_system ('sl_subsys_fcncall7')

Function-call subsystems are inside enabled subsystem

close_system('sl_subsys_fcncall7')

Function-Call Subsystems Specify Periodic Execution

This Stateflow chart schedules the execution order of function-call subsystems in the model. However, the function-call subsystems are executed exactly once every time step. The function calls do not specify conditional execution but rather control the relative order of execution of the subsystems. This setting can be useful when data is transferred between the subsystems using datastores to ensure the proper sequence for reading from and writing to the datastores. Since the function-call subsystems are intended to be executed unconditionally, you should specify that they have a periodic sample time using the Sample time parameter of the Trigger blocks in the subsystems. As a consequence, during simulation, the Simulink engine verifies that the periodic function-call subsystems are executed exactly once per time step.

In addition, when code is generated, elapsed time inside the function-call subsystems is represented by a literal value (the specified, constant sample time) instead of being maintained and computed from timers, as is standard for a function-call subsystem. Therefore, the generated code is significantly more efficient.

To view the sample time of subsystems, in the Simulink Editor, on the Debug tab, select Information Overlays and click Colors.

open_system ('sl_subsys_fcncall8')

Sample time is displayed for function-call subsystems executed periodically

The sample time color of the function-call subsystems is red rather than cyan, indicating a periodic rather than triggered sample time. If the function-call connections are interchanged, the result is delayed one time step due to the modified interaction between the Data Store Read and Data Store Write blocks in the subsystems.

close_system('sl_subsys_fcncall8')

Function-Call Initiator Issues Active and Inactive Events

This Stateflow chart specifies that the event activate is bound to the state ON. When the state ON transitions to being active, the function-call subsystem Integrate, initiated by that event, is enabled. In addition, when the state transitions to inactive, the function-call subsystem initiated by that event is disabled. If the function-call subsystem is configured to reset states on being enabled or outputs on being disabled, such actions will occur. In this example, the subsystem resets its states and outputs upon being enabled and disabled, respectively.

open_system ('sl_subsys_fcncall9')

Function-call subsystem using active and inactive function-call events, respectively

close_system('sl_subsys_fcncall9')

Interpreting Outputs of Function-Call Subsystems

1) The return value of the function call is the direct connection from the output of a function-call subsystem to its function-call initiator. For example, the Stateflow chart Chart1 below is a function-call initiator that executes the function d1=f1(). After invoking f1, the chart uses the return-value d1 computed by f1 within the same time-step.

2) In the second example, the execution of the Unit Delay block is not triggered by Chart2. Therefore, during the execution of Chart2, the signal d2 maintains its value from the previous time step at which the Unit Delay was invoked.

open_system ('sl_subsys_fcncall10')

Observe function-call subsystem output by delaying and feeding the function-call subsystem output into the stateflow chart that initiates the function-call event

close_system('sl_subsys_fcncall10')

Branching of Function-Call Signals

This Stateflow chart initiates a periodic function-call signal with a period of 1 during the time interval when its input signal u is 1. For every function-call invocation, the subsystems execute in the order f followed by h followed by g. This execution order is a result of the order specified on the function-call split blocks, where the port annotated with a dot executes first.

Exporting this model to releases earlier than R2015b results in an error because the signal b is treated as a data dependency violation.

open_system ('sl_subsys_fcncall11')

Function-call subsystems respond to branched function-call signals

This Stateflow Chart initiates a periodic function-call signal with a period of 1 during the time interval when its input signal u is 1.

For each function-call invocation, the subsystem f1 executes before the subsystem g1. This execution order is a result of the order specified on the function-call split block, where the port annotated with a dot executes first.

Exporting this model to releases earlier than R2015b results in an error because the signal b is treated as a data dependency violation when the Latch input for feedback signals of function-call subsystem outputs parameter on the Inport block of subsystem f1 is cleared.

Function-call subsystems for branched function-call signals

close_system('sl_subsys_fcncall11')

Illegal Function-Call Subsystems

This list identifies illegal function-call subsystems listed. The fixes are explained in the corresponding model subsystem.

open_system('s_Function_call_subsystems')
  1. Ambiguous execution order error

  2. Data dependency violation involving block driven by the function-call initiator

  3. Data dependency violation involving block between two function-call subsystems

  4. Ambiguous execution order error due to feedback of modified function-call output

  5. Ambiguous execution order error due to feedback of modified function-call output between two subsystems

  6. Data dependency violation involving a merge block and a Stateflow chart

  7. Data dependency violation involving atomic subsystem and gain block

  8. Function-call subsystem cycle data dependency violation

  9. Indirect data dependency violation

  10. Nested data dependency violation

  11. Function-call subsystems incorrectly specify periodic execution

  12. Function-call subsystems inputs computed within called context

  13. Data dependency violation involving branched function-call signal and block connecting function-call subsystems

close_system('s_Function_call_subsystems',0)

If Action and Switch Case Action Subsystems

If action subsystems execute at each time step when a logical condition is true. Switch case action subsystems execute when a signal has one of a specified set of values.

If Action Subsystem

Switch Case Action Subsystem

For more information, see If Action Subsystem and Switch Case Action Subsystem.

These examples show how to use If Action and Switch Case Action subsystems.

open_system('sl_subsys_semantics')
open_system('sl_subsys_semantics/If Action and Switch Case Action subsystems')

If and Switch Case Action Subsystems examples

close_system('sl_subsys_semantics/If Action and Switch Case Action subsystems')

Triggered Subsystems

Triggered subsystems enable you to implement software triggering, hardware triggering or a combination of the two. You can add the Triggered Subsystem block from the Simulink Library Browser. Alternatively, you can create this subsystem by placing the Trigger block inside a Subsystem block.

Triggered Subsystems

For more information, see Triggered Subsystem.

These examples show how to use triggered subsystems.

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/Triggered subsystems')

Triggered Subsystem examples

Software triggering is defined in this code:

if (trigger_signal_edge_detected) {

out(t) = f(in(t));

}

Hardware triggering is defined in this code:

if (trigger_signal_edge_detected) {

out(t) = f(in(t-h)); // h == last step size

}

Each input port of a triggered subsystem configures whether or not the input should be latched. A latched input provides the hardware triggering semantics for that input port. The software marks a latched input port with the symbol <L>.

close_system('sl_subsys_semantics/Triggered subsystems')

Enabled Subsystems

Enabled subsystems let you create conditionally executed subsystems that are only executed when the enabling signal is greater than zero. Enabled subsystems give you control over the initial value of the output signals and whether or not to reset states each time the subsystem is enabled.

You can add the Enabled Subsystem block from the Simulink Library Browser. Alternatively, you can create this subsystem by placing the Enable block inside a Subsystem block.

Enabled Subsystem

For more information, see Enabled Subsystem.

The following examples show how to use enabled subsystems.

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/Enabled subsystems')      

Enabled Subsystem examples

close_system('sl_subsys_semantics/Enabled subsystems')

Enabled and Triggered Subsystem

These subsystems below illustrate the option for states and outport resetting. The enabled and triggered subsystem executes when both the enable and trigger conditions occur.

You can add the Enabled and Triggered Subsystem block from the Simulink Library Browser. Alternatively, you can create this subsystem by placing both the Enable block and the Trigger block inside a Subsystem block.

For more information, see Enabled and Triggered Subsystem.

This example shows how to use enabled and triggered subsystems.

open_system('sl_subsys_semantics')
open_system('sl_subsys_enabtrig1.slx')  

Enabled and Triggered Subsystems

close_system('sl_subsys_enabtrig1.slx')        

Resettable Subsystems

Resettable subsystems let you reset the states of blocks within the subsystem based on the reset signal. You can add the Resettable Subsystem block from the Simulink Library Browser.

Resettable Subsystem

For more information, see Resettable Subsystem.

These examples show how to use resettable subsystems.

open_system('sl_subsys_semantics')
open_system('sl_subsys_semantics/Resettable subsystems')

Resettable Subsystem examples

close_system('sl_subsys_semantics/Resettable subsystems')

For Each Subsystem

The for each subsystem repeats execution during a simulation time step on each element or subarray of an input signal or mask parameter array. You can add the For Each Subsystem block from the Simulink Library Browser. Alternatively, you can create this block by placing a For Each block inside a Subsystem block. A for each subsystem repeats the algorithm on individual elements or subarrays of an input signal. A for each subsystem keeps block states separate for each element or subarray that the subsystem processes.

For Each Subsystem

For more information, see For Each Subsystem.

These examples show how to use for each subsystems.

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/For Each subsystems')

For Each Subsystem examples

close_system('sl_subsys_semantics/For Each subsystems')

While Iterator Subsystem

The while iterator subsystem repeats execution during a simulation time step while a logical condition is true. You can add the While Iterator Subsystem block from the Simulink Library Browser. Alternatively, you can create this subsystem by placing a While Iterator block inside a Subsystem block. A while iterator subsystem runs multiple iterations on each model time step. The number of iterations is controlled by the while iterator condition.

The while iterator subsystem is similar to a function-call subsystem in that it can run for any number of iterations on a given time step.

The while iterator subsystem differs from a function-call subsystem in that it contains no separate initiator, such as a Stateflow Chart. In addition, the while iterator subsystem has access to the current iteration number optionally produced by the While Iterator block.

While Iterator Subsystem

For more information, see While Iterator Subsystem.

These examples show how to use while iterator subsystems.

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/While Iterator subsystems')

While Iterator Subsystem example

close_system('sl_subsys_semantics/While Iterator subsystems')

For Iterator Subsystem

The for iterator subsystem repeats execution during a simulation time step for a specified number of iterations. You can add the For Iterator Subsystem block from the Simulink Library Browser. Alternatively, you can create this subsystem by placing a For Iterator block inside a Subsystem block. A for iterator subsystem runs a fixed number of iterations on each model time step. The number of iterations can be an external input to the for subsystem or specified internally on the For Iterator block.

A for iterator subsystem is very similar to a while iterator subsystem with the restriction that the number of iterations on any given time step is fixed.

For Iterator Subsystem

For more information, see For Iterator Subsystem.

These following examples show how to use for iterator subsystems.

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/For Iterator subsystems')   

For Iterator Subsystem Example

close_system('sl_subsys_semantics/For Iterator subsystems')

See Also

Related Topics