Simulink® can add a hidden signal buffer before the Outport block in a conditional subsystem or before an Outport block at the top-level of a model. This buffer ensures consistent initialization of the Outport block signal.
In a few cases, adding a signal buffer with a conditional output signal or partial write signal can cause a different simulation result. The parameter Ensure outport is virtual is an option on an Outport block to remove the buffer. Select this option when you are concerned with conditional or partial write signals.
Consider the following model. To open model, see ex_conditional_write
.
The Merge block combines its inputs into a single signal whose value at any time is equal to the most recently computed output of its driving blocks.
For the case with most models, clear the Ensure outport is virtual
check box on the Outport block connected to Enabled Subsystem
C
.
The Outport block follows non-virtual semantics. A hidden buffer is inserted if needed before the Outport block.
The buffer provides consistent initialization of the Outport block signal.
Time 0: A
runs, C
does not run, but because the
buffer is in A
, it runs and copies the initial value of zero to the
Outport block. B does not run. The merge signal is zero from the output
from A
.
Time 0.5: A does not run. B runs and outputs a sine wave. The merge signal is the sine
wave from B
.
Time 1. A
runs, C does not run, but the buffer again runs and copies
over the initial value of zero to the Outport block. B does not run. The
merge signal is again the initial value of A
, not the last value from
B
.
Simulating the model with a fixed-step, produces the following result.
For the case where you are concerned with conditional and partial writes, select (check) the Ensure outport is virtual check box for the Outport block connected to Enabled Subsystem C.
The Outport block follows virtual semantics.
A hidden buffer is not inserted before the Outport block of the Subsystem.
If Simulink determines a buffer is needed, an error is displayed.
Time 0: A
runs, C does not run. B does not run. Merge signal is the
initial value of the signal.
Time 0.5 sec: A does not run. B runs and outputs a sine wave. The merge signal is the value of the sine wave from B.
Time 1: A
runs, C does not run. B does not run. The merge signal is
the most recently computed output which was the sine wave from B.
A typical modeling pattern is where you want to initialize a vector signal and then periodically update partial elements of the signal based upon certain conditions or inputs. One way of modeling this pattern is to use a Merge block whose inputs are from two Function-Call Subsystem blocks. One subsystem is the initialize task while the other subsystem is a periodic write task.
The model below demonstrates this pattern. The
Initialize_Process_Subsystem is called once at the beginning of a
simulation to initialize a vector signal. The Run_Process_Subsystem is called
to partially write to elements of the vector. However, the output from the
Assignment block needs a path where hidden buffers do not make copies of
the vector. Selecting the Ensure outport is virtual check box on the
Outport block removes a hidden buffer. If Simulink determines the buffer is needed an error is displayed. To open model, see
ex_partial_write_single_merge
.
The Initialize_Process_SubSystem
Initializes each element of a 2 element vector with a value of
7
.
Outputs the vector [7 7]
.
The Run_Process_Subsystem
Inputs an index value of 1, but because the Index mode
parameter for the Selector blocks is set to
Zero-based
, they select the 2nd elements from the input
vectors.
Adds the output scalar values from the Selector blocks for a result
of 4
.
Because the Assignment block Index mode
parameter is set to Zero-based
and the input index Idx1 is
1
, the output signal needs to be a vector with length 2. After
setting the Output size parameter to 2
, the
Assignment block is able to write to the 2nd element.
Selecting the Ensure outport is virtual check box removes the hidden buffer.
Code generated from this model includes two functions. Init_Proc
and
Run_Proc
.
/* Model step function */ void Init_Proc(void) { int32_T s3_iter; /* Initialize signal vector elements with 7.0 */ for (s3_iter = 0; s3_iter < 2; s3_iter++) { PartialWriteSingleMerge_DW.Assignment[s3_iter] = 7.0; } for (s3_iter = 0; s3_iter < 2; s3_iter++) { PartialWriteSingleMerge_Y.Out4[s3_iter] = PartialWriteSingleMerge_DW.Assignment[s3_iter]; } } /* Model step function */ void Run_Proc(void) { /* Write to element 1 of the output signal vector */ PartialWriteSingleMerge_Y.Out4[1] = 4.0; }