## Use DWork Vectors in S-Functions

### What is a DWork Vector?

DWork vectors are blocks of memory that an S-function asks the Simulink^{®} engine to allocate to each instance of the S-function in a model. If multiple instances of your S-function can occur in a model, your S-function must use DWork vectors instead of global or static memory to store instance-specific values of S-function variables. Otherwise, your S-function runs the risk of one instance overwriting data needed by another instance, causing a simulation to fail or produce incorrect results. The ability to keep track of multiple instances of an S-function is called *reentrancy*.

You can create an S-function that is reentrant by using DWork vectors that the engine manages for each particular instance of the S-function.

DWork vectors have several advantages:

Provide instance-specific storage for block variables

Support floating-point, integer, pointer, and general data types

Eliminate static and global variables

Interact directly with the Simulink engine to perform memory allocation, initialization, and deallocation

Facilitate inlining the S-function during code generation

Provide more control over how data appears in the generated code

**Note**

DWork vectors are the most generalized and versatile type of work vector and the following sections focus on their use. The Simulink product provides additional elementary types of work vectors that support floating-point, integer, pointer, and mode data. You can find a discussion of these work vectors in Elementary Work Vectors.

DWork vectors provide the most flexibility for setting data types, names, etc., of the data in the simulation and during code generation. The following list describes all the properties that you can set on a DWork vector:

Data type

Size

Numeric type, either real or complex

Name

Usage type (see Types of DWork Vectors)

Simulink Coder™ identifier

Simulink Coder storage class

Simulink Coder C type qualifier

See How to Use DWork Vectors for instructions on how to set these properties. The three Simulink Coder properties pertain only to code generation and have no effect during simulation.

### How to Use DWork Vectors in Level-2 MATLAB S-Functions

#### Using DWork Vectors in Level-2 MATLAB S-Functions

The following steps show how to initialize and use DWork vectors in Level-2
MATLAB^{®} S-functions. These steps use the S-function `msfcn_unit_delay.m`

.

In the

`PostPropagationSetup`

method, initialize the number of DWork vectors and the attributes of each vector. For example, the following`PostPropagationSetup`

callback method configures one DWork vector used to store a discrete state.function PostPropagationSetup(block) %% Setup Dwork block.NumDworks = 1; block.Dwork(1).Name = 'x0'; block.Dwork(1).Dimensions = 1; block.Dwork(1).DatatypeID = 0; block.Dwork(1).Complexity = 'Real'; block.Dwork(1).UsedAsDiscState = true;

The reference pages for

`Simulink.BlockCompDworkData`

and the parent class`Simulink.BlockData`

list the properties you can set for Level-2 MATLAB S-function DWork vectors.Initialize the DWork vector values in either the

`Start`

or`InitializeConditions`

methods. Use the`Start`

method for values that are initialized only at the beginning of the simulation. Use the`InitializeConditions`

method for values that need to be reinitialized whenever a disabled subsystem containing the S-function is reenabled.For example, the following

`InitializeConditions`

method initializes the value of the DWork vector configured in the previous step to the value of the first S-function dialog parameter.function InitializeConditions(block) %% Initialize Dwork block.Dwork(1).Data = block.DialogPrm(1).Data;

In the

`Outputs`

,`Update`

, etc. methods, use or update the DWork vector values, as needed. For example, the following`Outputs`

method sets the S-function output equal to the value stored in the DWork vector. The`Update`

method then changes the DWork vector value to the current value of the first S-function input port.%% Outputs callback method function Outputs(block) block.OutputPort(1).Data = block.Dwork(1).Data; %% Update callback method function Update(block) block.Dwork(1).Data = block.InputPort(1).Data;

**Note**

Level-2 MATLAB S-functions do not support MATLAB sparse matrices. Therefore, you cannot assign a sparse matrix to the value of a DWork vector. For example, the following line of code produces an error

block.Dwork(1).Data = speye(10);

where the `speye`

command produces a sparse identity
matrix.

### Level-2 MATLAB S-Function DWork Vector Example

The example S-function `msfcn_varpulse.m`

models a variable width pulse generator. The
S-function uses two DWork vectors. The first DWork vector stores the pulse width
value, which is modified at every major time step in the `Update`

method. The second DWork vector stores the handle of the pulse generator block in
the Simulink model. The value of this DWork vector does not change over the course
of the simulation.

The `PostPropagationSetup`

method, called
`DoPostPropSetup`

in this S-function, sets up the two DWork
vectors.

function DoPostPropSetup(block) % Initialize the Dwork vector block.NumDworks = 2; % Dwork(1) stores the value of the next pulse width block.Dwork(1).Name = 'x1'; block.Dwork(1).Dimensions = 1; block.Dwork(1).DatatypeID = 0; % double block.Dwork(1).Complexity = 'Real'; % real block.Dwork(1).UsedAsDiscState = true; % Dwork(2) stores the handle of the Pulse Geneator block block.Dwork(2).Name = 'BlockHandle'; block.Dwork(2).Dimensions = 1; block.Dwork(2).DatatypeID = 0; % double block.Dwork(2).Complexity = 'Real'; % real block.Dwork(2).UsedAsDiscState = false;

The `Start`

method initializes the DWork vector values.

function Start(block) % Populate the Dwork vector block.Dwork(1).Data = 0; % Obtain the Pulse Generator block handle pulseGen = find_system(gcs,'BlockType','DiscretePulseGenerator'); blockH = get_param(pulseGen{1},'Handle'); block.Dwork(2).Data = blockH;

The `Outputs`

method uses the handle stored in the second DWork
vector to update the pulse width of the Pulse Generator block.

function Outputs(block) % Update the pulse width value set_param(block.Dwork(2).Data, 'PulseWidth', num2str(block.InputPort(1).data));

The `Update`

method then modifies the first DWork vector with the
next value for the pulse width, specified by the input signal to the S-Function
block.

function Update(block) % Store the input value in the Dwork(1) block.Dwork(1).Data = block.InputPort(1).Data; %endfunction

## See Also

Level-2 MATLAB S-Function | S-Function Builder | S-Function | MATLAB Function