| Contents | Index |
| On this page… |
|---|
The Simulink® Coder™ product allows you to control how code is generated for any nonvirtual subsystem. The categories of nonvirtual subsystems are:
Conditionally executed subsystems: execution depends upon a control signal or control block. These include triggered subsystems, enabled subsystems, action and iterator subsystems, subsystems that are both triggered and enabled, and function call subsystems. See Creating Conditional Subsystems in the Simulink documentation for more information.
Atomic subsystems: Any virtual subsystem can be declared atomic (and therefore nonvirtual) by using the Treat as atomic unit option in the Block Parameters dialog box.
Note You should declare virtual subsystems as atomic subsystems. This will make simulation and execution behavior for your model consistent. If you generate code for a virtual subsystem, the Simulink Coder software treats the subsystem as atomic and generates the code accordingly. The resulting code can change the execution behavior of your model, for example, by applying algebraic loops, and introduce inconsistencies with the simulation behavior. |
See Systems and Subsystems in the Simulink documentation, and run the sl_subsys_semantics demo for more information on nonvirtual subsystems and atomic subsystems.
You can control the code generated from nonvirtual subsystems as follows:
You can instruct the Simulink Coder code generator to generate separate functions, within separate code files if desired, for selected nonvirtual systems. You can control both the names of the functions and of the code files generated from nonvirtual subsystems.
You can cause multiple instances of a subsystem to generate reusable code, that is, as a single reentrant function, instead of replicating the code for each instance of a subsystem or each time it is called.
You can generate inlined code from selected nonvirtual subsystems within your model. When you inline a nonvirtual subsystem, a separate function call is not generated for the subsystem.
The Simulink Coder software can generate code and build an executable from any subsystem within a model. The code generation and build process uses the code generation and build parameters of the root model.
To generate code and build an executable from a subsystem,
Set up the desired code generation and build parameters in the Configuration Parameters dialog box, just as you would for code generation from a model.
Right-click the subsystem block and select Build Subsystem from the Code Generation submenu of the subsystem block's context menu.
Alternatively, you can select Build Subsystem from the Code Generation submenu of the Tools menu. This menu item is enabled when a subsystem is selected in the current model.
The Build Subsystem window opens. This window displays a list of the subsystem parameters. The upper pane displays the name, class, and storage class of each variable (or data object) that is referenced as a block parameter in the subsystem. When you select a parameter in the upper pane, the lower pane shows all the blocks that reference the parameter and the parent system of each such block.
The StorageClass column contains a popup menu for each row. The menu lets you set the storage class of any parameter or inline the parameter. To inline a parameter, select the Inline option from the menu. To declare a parameter to be tunable, set the storage class to any value other than Inline.

In the previous figure, the parameter K2 is inlined, while the other parameters are tunable and have various storage classes.
See Parameters for more information on tunable and inlined parameters and storage classes.
After selecting tunable parameters, click the Build button. This initiates the code generation and build process.
The build process displays status messages in the MATLAB® Command Window. When the build completes, the generated executable is in your working folder. The name of the generated executable is subsystem.exe (on PC platforms) or subsystem (on The Open Group UNIX® platforms), where subsystem is the name of the source subsystem block.
The generated code is in a build subfolder, named subsystem_target_rtw, where subsystem is the name of the source subsystem block and target is the name of the target configuration.
When you generate code for a subsystem, you can generate an S-function by selecting Tools > Code Generation > Generate S-function, or you can use a right-click subsystem build. See Automate S-Function Generation and Generate S-Function Wrappers for more details.
Simulink Coder Subsystem Build Limitations. The following limitations apply to building subsystems using the Simulink Coder software:
When you right-click build a subsystem that includes an Outport block for which the Data type parameter specifies a bus object, the Simulink Coder build process requires that you set the Signal label mismatch option on the Diagnostics > Connectivity pane of the Configuration Parameters dialog box for the parent model to error. You need to address any errors that occur by setting signal labels.
When a subsystem is in a triggered or function-call subsystem, the right-click build process might fail if the subsystem code is not sample-time independent. To find out whether a subsystem is sample-time independent:
Copy all blocks in the subsystem to an empty model.
In the Configuration Parameters > Solver pane, set:
Type to Fixed-step.
Periodic sample time constraint to Ensure sample time independent.
Click Apply.
Update the model. If the model is sample-time dependent, Simulink generates an error in the process of updating the diagram.
For any nonvirtual subsystem, you can choose the following code generation options from the Function packaging menu in the subsystem Block parameters dialog box:
Auto: This is the default option, and provides the greatest flexibility in most situations. See Auto Option below.
Inline: This option explicitly directs the Simulink Coder code generator to inline the subsystem unconditionally.
Function: This option explicitly directs the Simulink Coder code generator to generate a separate function with no arguments, and (optionally), place the subsystem in a separate file. You can name the generated function and file. As functions created with this option rely on global data, they are not reentrant.
Reusable function: Generates a function with arguments that allows the subsystem's code to be shared by other instances of it in the model. To enable sharing, the Simulink Coder software must be able to determine (by using checksums) that subsystems are identical. The generated function will have arguments for block inputs and outputs (rtB_*), continuous states (rtDW_*), parameters (rtP_*), and so on.
The following sections discuss these options further.
Auto Option. The Auto option is the default. It causes the code generator to inline the subsystem when there is only one instance of it in the model. When multiple instances of a subsystem exist, the Auto option results in a single copy of the function (as a reusable function). Otherwise, the result is as though you selected Inline (except for function call subsystems with multiple callers, which is handled as if you specified Function). Choose Inline to always inline subsystem code, or Function when you specifically want to generate a separate function without arguments for each instance, optionally in a separate file.
Note When you want multiple instances of a subsystem to be represented as one reusable function, you can designate each one of them as Auto or as Reusable function. It is best to use one or the other, as using both creates two reusable functions, one for each designation. The outcomes of these choices differ only when reuse is not possible. |
To use the Auto option,
Select the subsystem block. Then select Subsystem Parameters from the Simulink model editor Edit menu. The Block Parameters dialog box opens.
Alternatively, you can open the Block Parameters dialog box by
Shift-double-clicking the subsystem block
Right-clicking the subsystem block and selecting Subsystem parameters from the menu
If the subsystem is virtual, select Treat as atomic unit. This makes the subsystem nonvirtual, and on the Code Generation tab, the Function packaging option becomes enabled.
If the system is already nonvirtual, the Function packaging option is already enabled.
Go to the Code Generation tab and select Auto from the Function packaging menu, as shown in the figure below.

Click Apply and close the dialog box.
The border of the subsystem thickens, indicating that it is nonvirtual.
Rather than reverting to Inline, the Auto option can optimize code in special situations in which identical subsystems contain other identical subsystems, by both reusing and inlining generated code. Suppose a model, such as the one shown in Reuse of Identical Nested Subsystems with the Auto Option, contains identical subsystems A1 and A2. A1 contains subsystem B1, and A2 contains subsystem B2, which are themselves identical. In such cases, the Auto option causes one function to be generated which is called for both A1 and A2, and this function contains one piece of inlined code to execute B1 and B2, ensuring that the resulting code will run as efficiently as possible.
Reuse of Identical Nested Subsystems with the Auto Option

Inline Option. As noted above, you can choose to inline subsystem code when the subsystem is nonvirtual (virtual subsystems are always inlined).
Exceptions to Inlining.There are certain cases in which the Simulink Coder code generator does not inline a nonvirtual subsystem, even though the Inline option is selected. These cases are
If the subsystem is a function-call subsystem that is called by a noninlined S-function, the Inline option is ignored. Noninlined S-functions make such calls by using function pointers; therefore the function-call subsystem must generate a function with all arguments present.
In a feedback loop involving function-call subsystems, the Simulink Coder code generator forces one of the subsystems to be generated as a function instead of inlining it. The product selects the subsystem to be generated as a function based on the order in which the subsystems are sorted internally.
If a subsystem is called from an S-Function block that sets the option SS_OPTION_FORCE_NONINLINED_FCNCALL to TRUE, it is not inlined. This might be the case when user-defined Async Interrupt blocks or Task Sync blocks are required. Such blocks must be generated as functions. The Async Interrupt and Task Sync blocks, located in the VxWorks® block library (vxlib1) shipped with the Simulink Coder product, use the SS_OPTION_FORCE_NONINLINED_FCNCALL option.[1]
To generate inlined subsystem code,
Select the subsystem block. Then select Subsystem Parameters from the Simulink model editor Edit menu. The Block Parameters dialog box opens.
Alternatively, you can open the Block Parameters dialog box by
Shift-double-clicking the subsystem block
Right-clicking the subsystem block and selecting Block parameters from the menu
If the subsystem is virtual, select Treat as atomic unit as shown in the next figure. This makes the subsystem atomic, and on the Code Generation tab, the Function packaging menu becomes enabled.
If the system is already nonvirtual, the Function packaging menu is already enabled.
Go to the Code Generation tab and select Inline from the Function packaging menu as shown in the figure below.

When you generate code from your model, the Simulink Coder code generator writes inline code within model.c or model.cpp (or in its parent system's source file) to perform subsystem computations. You can identify this code by system/block identification tags, such as the following.
/* Atomic SubSystem Block: <Root>/AtomicSubsys1 */
Function Option. Choosing the Function or Reusable function option lets you direct the Simulink Coder code generator to generate a separate function and optionally a separate file for the subsystem. When you select the Function option, two additional options are enabled:
The Function name options menu lets you control the naming of the generated function.
The File name options menu lets you control the naming of the generated file (if a separate file is generated and you select the User specified option).
The figure below shows the Block Parameters dialog box with the Function option selected, with File name options set to User specified, and with a name specified for the generated file.
Subsystem Function Code Generation Option with User-Specified File Name

This menu offers the following choices, but the resulting identifiers are also affected by which General code appearance options are in effect for the model:
Auto: By default, the Simulink Coder code generator assigns a unique function name using the default naming convention: model_subsystem(), where subsystem is the name of the subsystem (or that of an identical one when code is being reused).
Use subsystem name: the Simulink Coder code generator uses the subsystem name as the function name.
User specified: When this option is selected, the Function name field is enabled. Enter any legal C or C++ function name (which must be unique).
This menu offers the following choices:
Use subsystem name: the Simulink Coder software generates a separate file, using the subsystem (or library block) name as the file name.
Note When File name options is set to Use subsystem name, the subsystem file name is mangled if the model contains Model blocks, or if a model reference target is being generated for the model. In these situations, the file name for the subsystem consists of the subsystem name prefixed by the model name. |
Use function name: the Simulink Coder software generates a separate file, using the function name (as specified by Function name options) as the file name.
User specified: When this option is selected, the File name (no extension) text entry field is enabled. The Simulink Coder software generates a separate file, using the name you enter as the file name. Enter any file name, but do not include the .c or .cpp (or any other) extension. This file name need not be unique.
Auto: The Simulink Coder software does not generate a separate file for the subsystem. Code generated from the subsystem is generated within the code module generated from the subsystem's parent system. If the subsystem's parent is the model itself, code generated from the subsystem is generated within model.c or model.cpp.
To generate both a separate subsystem function and a separate file,
Select the subsystem block. Then select Subsystem Parameters from the Simulink model editor Edit menu, to open the Block Parameters dialog box.
Alternatively, you can open the Block Parameters dialog box by
Shift-double-clicking the subsystem block
Right-clicking the subsystem block and selecting Subsystem parameters from the menu.
If the subsystem is virtual, select Treat as atomic unit. On the Code Generation tab, the Function packaging menu becomes enabled.
If the system is already nonvirtual, the Function packaging menu is already enabled.
Go to the Code Generation tab and select Function from the Function packaging menu as shown in Subsystem Function Code Generation Option with User-Specified File Name.
Set the function name, using the Function name options parameter, as described in Function Name Options Menu.
Set the file name, using any File name options parameter value other than Auto (values are described in File Name Options Menu).
Subsystem Function Code Generation Option with User-Specified File Name shows the use of the User Specified file name option.
Code generated from nonvirtual subsystems, when written to separate files, is not completely independent of the generating model. For example, subsystem code may reference global data structures of the model. Each subsystem code file contains include directives and comments explaining the dependencies. The Simulink Coder software checks for cyclic file dependencies and warns about them at build time. For descriptions of how generated code is packaged, see Generated Source Files and File Dependencies.
This section describes model referencing considerations that apply specifically to code generation by the Simulink Coder. This section assumes that you understand referenced models and related terminology and requirements, as described in Referencing a Model.
When generating code for a referenced model hierarchy, the code generator produces a stand-alone executable for the top model, and a library module called a model reference target for each referenced model. When the code executes, the top executable invokes the model reference targets to compute the referenced model outputs. Model reference targets are sometimes called Simulink Coder targets.
Be careful not to confuse a model reference target (Simulink Coder target) with any of these other types of targets:
Hardware target — A platform for which the Simulink Coder software generates code
System target — A file that tells the Simulink Coder software how to generate code for particular purpose
Rapid Simulation target (RSim) — A system target file supplied with the Simulink Coder product
Simulation target — A MEX-file that implements a referenced model that executes with Simulink Accelerator™ software
The code generator places the code for the top model of a hierarchy in the current working folder, and the code for submodels in a folder named slprj within the current working folder. Subfolders in slprj provide separate places for different types of files. See Project Folder Structure for Model Reference Targets for details.
By default, the product uses incremental code generation. When generating code, it compares structural checksums of referenced model files with the generated code files to determine whether you should regenerate model reference targets. To control when rebuilds occur, use the Configuration Parameters > Model Referencing > Rebuild. For details, see Rebuild.
In addition to incremental code generation, the Simulink Coder software uses incremental loading. The code for a referenced model is not loaded into memory until the code for its parent model executes and needs the outputs of the referenced model. The product then loads the referenced model target and executes. Once loaded, the target remains in memory until it is no longer used.
Most code generation considerations are the same whether or not a model includes any referenced models: the Simulink Coder code generator handles the details automatically insofar as possible. This chapter describes topics that you may need to consider when generating code for a model reference hierarchy.
Custom targets must declare themselves to be model reference compliant if they need to support Model blocks. See Support Model Referencing for details.
About Generating Code for Referenced Models. To generated code for referenced models, you
Create a subsystem in an existing model.
Convert the subsystem to a referenced model (Model block).
Call the referenced model from the top model.
Generate code for the top model and referenced model.
Explore the generated code and the project folder.
You can accomplish some of these tasks automatically with a function called Simulink.Subsystem.convertToModelReference.
Create and Configure the Subsystem. In the first part of this example, you define a subsystem for the vdp demo model, set configuration parameters for the model, and use the Simulink.Subsystem.convertToModelReference function to convert it into two new models — the top model (vdptop) and a referenced model vdpmultRM containing a subsystem you created (vdpmult).
In the MATLAB Command Window, create a new working folder wherever you want to work and cd into it:
mkdir mrexample cd mrexample
Open the vdp demo model by typing:
vdp
Drag a box around the three blocks on the left to select them, as shown below:

Choose Create Subsystem from the model's Edit menu.
A subsystem block replaces the selected blocks.
If the new subsystem block is not where you want it, move it to a preferred location.
Rename the block vdpmult.
Right-click the vdpmult block and select Subsystem Parameters.
The Function Block Parameters dialog box appears.
In the Function Block Parameters dialog box, select Treat as atomic unit, then click OK.
The border of the vdpmult subsystem thickens to indicate that it is now atomic. An atomic subsystem executes as a unit relative to the parent model: subsystem block execution does not interleave with parent block execution. This property makes it possible to extract subsystems for use as stand-alone models and as functions in generated code.
The block diagram should now appear as follows:

You must set several properties before you can extract a subsystem for use as a referenced model. To set the properties,
Open Model Explorer by selecting Model Explorer from the model's View menu.
In the Model Hierarchy pane, click the symbol preceding the model name to reveal its components.
Click Configuration (Active) in the left pane.
In the right pane, under Solver Options change the Type to Fixed-step, then click Apply. You must use fixed-step solvers when generating code, although referenced models can use different solvers than top models.
In the center pane, select Optimization. In the right pane, select the Signals and Parameters tab, and under Simulation and code generation, select Inline parameters. Click Apply.
In the center pane, select Diagnostics. In the right pane:
Select the Data Validity tab. In the Signals area, set Signal resolution to Explicit only.
Select the Connectivity tab. In the Buses area, set Mux blocks used to create bus signals to error.
Click Apply.
The model now has the properties that model referencing requires.
In the center pane, click Model Referencing. In the right pane, set Rebuild to If any changes in known dependencies detected. Click Apply. This setting prevents unnecessary code regeneration.
In the vdp model window, choose File > Save as. Save the model as vdptop in your working folder. Leave the model open.
Convert a Model to Use Model Referencing. In this portion of the example, you use the conversion function Simulink.SubSystem.convertToModelReference to extract the subsystem vdpmult from vdptop and convert vdpmult into a referenced model named vdpmultRM. To see the complete syntax of the conversion function, type at the MATLAB prompt:
help Simulink.SubSystem.convertToModelReference
For additional information, type:
doc Simulink.SubSystem.convertToModelReference
If you want to see a demo of Simulink.SubSystem.convertToModelReference before using it yourself, type:
sldemo_mdlref_conversion
Simulink also provides a menu command, Convert to Model Block, that you can use to convert a subsystem to a referenced model. The command calls Simulink.SubSystem.convertToModelReference with default arguments. See Converting a Subsystem to a Referenced Model in the Simulink documentation.
Extracting the Subsystem to a Referenced Model.To use Simulink.SubSystem.convertToModelReference to extract vdpmult and convert it to a referenced model, type:
Simulink.SubSystem.convertToModelReference...
('vdptop/vdpmult', 'vdpmultRM',...
'ReplaceSubsystem', true, 'BuildTarget', 'Sim')This command:
Extracts the subsystem vdpmult from vdptop.
Converts the extracted subsystem to a separate model named vdpmultRM and saves the model to the working folder.
In vdptop, replaces the extracted subsystem with a Model block that references vdpmultRM.
Creates a simulation target for vdptop and vdpmultRM.
The converter prints a number of progress messages and terminates with
ans =
1The parent model vdptop now looks like this:

Note the changes in the appearance of the block vdpmult. These changes indicate that it is now a Model block rather than a subsystem. As a Model block, it has no contents of its own: the previous contents now exist in the referenced model vdpmultRM, whose name appears at the top of the Model block. Widen the Model block to expose the complete name of the referenced model.
If the parent model vdptop had been closed at the time of conversion, the converter would have opened it. Extracting a subsystem to a referenced model does not automatically create or change a saved copy of the parent model. To preserve the changes to the parent model, save vdptop.
Right-click the Model block vdpmultRM and choose Open Model 'vdpmultRM' to open the referenced model. The model looks like this:

The files in your working folder now consist of the following (not in this order).
| File | Description |
|---|---|
vdptop.mdl | Top model that contains a Model block where the vdpmult subsystem was |
vdpmultRM.mdl | Referenced model created for the vdpmult subsystem |
vdpmultRM_msf.mexw32 | Static library file (Microsoft® Windows® platforms only). The last three characters of the suffix are system-dependent and may differ. This file executes when the vdptop model calls the Model block vdpmult. When called, vdpmult in turn calls the referenced model vdpmultRM. |
/slprj | Project folder for generated model reference code |
Code for model reference simulation targets is placed in the slprj/sim subfolder. Generated code for GRT, ERT, and other Simulink Coder targets is placed in slprj subfolders named for those targets. You will inspect some model reference code later in this example. For more information on project folders, see Working with Project Folders.
Running the Converted Model.Open the Scope block in vdptop if it is not visible. In the vdptop window, click the Start tool or choose Start from the Simulation menu. The model calls the vdpmultRM_msf simulation target to simulate. The output looks like this:

Generate Model Reference Code for a GRT Target. The function Simulink.SubSystem.convertToModelReference created the model and the simulation target files for the referenced model vdpmultRM. In this part of the example, you generate code for that model and the vdptop model, and run the executable you create:
If the model vdptop is not open, open it. Make sure it is the active window.
Open Model Explorer by selecting Model Explorer from the model's View menu.
In the Model Hierarchy pane, click the symbol preceding the vdptop model to reveal its components.
Click Configuration (Active) in the left pane.
In the Save to workspace section of the right pane, check Time and Output and clear Data stores. Click Apply. The pane shows the following information:

These settings instruct the model vdptop (and later its executable) to log time and output data to MAT-files for each time step.
Generate GRT code (the default) and an executable for the top model and the referenced model by selecting Code Generation in the center pane and then clicking the Build button.
The Simulink Coder build process generates and compiles code. The current folder now contains a new file and a new folder:
| File | Description |
|---|---|
vdptop.exe | The executable created by the Simulink Coder build process |
vdptop_grt_rtw/ | The Simulink Coder build folder, containing generated code for the top model |
The Simulink Coder build process also generated GRT code for the referenced model, and placed it in the slprj folder.
To view a model's generated code in Model Explorer, the model must be open. To use the Model Explorer to inspect the newly created build folder, vdptop_grt_rtw:
Open Model Explorer by selecting Model Explorer from the model's View menu.
In the Model Hierarchy pane, click the symbol preceding the model name to reveal its components.
Click the symbol preceding Code for vdptop to reveal its components.
Directly under Code for vdptop, click This Model.
A list of generated code files for vdptop appears in the Contents pane:
rtmodel.h vdptop.c vdptop.h vdptop.mk vdptop_private.h vdptop_types.h
You can browse code in any of these files by selecting a file of interest in the Contents pane.
To open a file in a text editor, click a filename, and then click the hyperlink that appears in the gray area at the top of the Document pane. The figure below illustrates viewing code for vdptop.c, in a text editor. Your code may differ.

Working with Project Folders. When you view generated code in Model Explorer, the files listed in the Contents pane can exist either in a build folder or a project folder. Model reference project folders (always rooted under slprj), like build folders, are created in your current working folder, and this implies certain constraints on when and where model reference targets are built, and how they are accessed.
The models referenced by Model blocks can be stored anywhere. A given top model can include models stored on different file systems or in different folders. The same is not true for the simulation targets derived from these models; under most circumstances, all models referenced by a given top model must be set up to simulate and generate model reference target code in a single project folder. The top and referenced models can exist anywhere on your path, but the project folder is assumed to exist in your current folder.
This means that, if you reference the same model from several top models, each stored in a different folder, you must either
Always work in the same folder and be sure that the models are on your path
Allow separate project folders, simulation targets, and Simulink Coder targets to be generated in each folder in which you work
The files in such multiple project folders are generally quite redundant. Therefore, to minimize code regeneration for referenced models, choose a specific working folder and remain in it for all sessions.
As model reference code generated for Simulink Coder targets as well as for simulation targets is placed in project folders, the same considerations as above apply even if you are generating target applications only. That is, code for all models referenced from a given model ends up being generated in the same project folder, even if it is generated for different targets and at different times.
Code for models referenced by using Model blocks is generated in project folders within the current working folder. The top-level project folder is always named /slprj. The next level within slprj contains parallel build area subfolders.
The following table lists principal project folders and files. In the paths listed, model is the name of the model being used as a referenced model, and target is the system target file acronym (for example, grt, ert , rsim, and so on).
| Folders and Files | Description |
|---|---|
| slprj/sim/model/ | Simulation target files for referenced models |
| slprj/sim/model/tmwinternal | MAT-files used during code generation |
| slprj/target/model/referenced_model_includes | Header files from models referenced by this model |
| slprj/target/model | Model reference target files |
| slprj/target/model/tmwinternal | MAT-files used during code generation |
| slprj/sl_proj.tmw | Marker file |
| slprj/target/_sharedutils | Utility functions for model reference targets, shared across models |
| slprj/sim/_sharedutils | Utility functions for simulation targets, shared across models |
If you are building code for more than one referenced model within the same working folder, model reference files for all such models are added to the existing slprj folder.
Minimize occurrences of algebraic loops by selecting the Minimize algebraic loop occurrences parameter on the Model Reference pane. The setting of this option affects only generation of code from the model. See Consider Platform Options for Development and Deployment in the Simulink Coder documentation for information on how this option affects code generation. For more information, see Model Blocks and Direct Feedthrough.
Use the Integer rounding mode parameter on your model's blocks to simulate the rounding behavior of the C compiler that you intend to use to compile code generated from the model. This setting appears on the Signal Attributes pane of the parameter dialog boxes of blocks that can perform signed integer arithmetic, such as the Product and n-D Lookup Table blocks.
For most blocks, the value of Integer rounding mode completely defines rounding behavior. For blocks that support fixed-point data and the Simplest rounding mode, the value of Signed integer division rounds to also affects rounding. For details, see Rounding in the Simulink Fixed Point User's Guide.
When models contain Model blocks, all models that they reference must be configured to use identical hardware settings. For information on the Model Referencing pane options, see Referencing a Model in the Simulink documentation.
By default, the Simulink engine rebuilds simulation targets before the Simulink Coder software generates model reference targets. You can change the rebuild criteria or specify that the engine always or never rebuilds targets. See Rebuild for details.
The Simulink Coder software generates a model reference target directly from the Simulink model. The product automatically generates or regenerates model reference targets.
You can command the Simulink and Simulink Coder products to generate a simulation target for an Accelerator mode referenced model, and a model reference target for any referenced model, by executing the slbuild command with arguments in the MATLAB Command Window.
The Simulink Coder software generates only one model reference target for all instances of a referenced model. See Reusable Code and Referenced Models for details.
Reduce Change Checking Time. You can reduce the time that the Simulink and Simulink Coder products spend checking whether any or all simulation targets and model reference targets need to be rebuilt by setting configuration parameter values as follows:
In the top model, consider setting Configuration Parameters > Model Referencing > Rebuild to If any changes in known dependencies detected. (See Rebuild.)
In all referenced models throughout the hierarchy, set Configuration Parameters > Diagnostics > Data Validity > Signal resolution to Explicit only. (See Signal resolution.)
These parameter values exist in a referenced model's configuration set, not in the individual Model block, so setting either value for any instance of a referenced model sets it for all instances of that model.
A model reference hierarchy must satisfy various Simulink Coder requirements, as described in this section. In addition to these requirements, a model referencing hierarchy to be processed by the Simulink Coder software must satisfy:
The Simulink requirements listed in:
The Simulink limitations listed in Limitations on All Model Referencing
The Simulink Coder limitations listed in Simulink Coder Model Referencing Limitations
Configuration Parameter Requirements. A referenced model uses a configuration set in the same way that any other model does, as described in Manage a Configuration Set. By default, every model in a hierarchy has its own configuration set, which it uses in the same way that it would if the model executed independently.
Because each model can have its own configuration set, configuration parameter values can be different in different models. Furthermore, some parameter values are intrinsically incompatible with model referencing. The response of the Simulink Coder software to an inconsistent or unusable configuration parameter depends on the parameter:
Where an inconsistency has no significance, or a trivial resolution exists that carries no risk, the product ignores or resolves the inconsistency without posting a warning.
Where a nontrivial and possibly acceptable solution exists, the product resolves the conflict silently; resolves it with a warning; or generates an error. See Model configuration mismatch for details.
Where no acceptable resolution is possible, the product generates an error. You must then change some or all parameter values to eliminate the problem.
When a model reference hierarchy contains many submodels that have incompatible parameter values, or a changed parameter value must propagate to many submodels, manually eliminating all configuration parameter incompatibilities can be tedious. You can control or eliminate such overhead by using configuration references to assign an externally-stored configuration set to multiple models. See Manage a Configuration Reference for details.
The following tables list configuration parameters that can cause problems if set in certain ways, or if set differently in a referenced model than in a parent model. Where possible, the Simulink Coder software resolves violations of these requirements automatically, but most cases require changes to the parameters in some or all models.
Configuration Requirements for Model Referencing with All System Targets
| Dialog Box Pane | Option | Requirement | |
|---|---|---|---|
| Solver | Start time | Some system targets require the start time of all models to be zero. | |
Hardware Implementation | Emulation hardware options | All values must be the same for top and referenced models. | |
Code Generation | System target file | Must be the same for top and referenced models. | |
| Language | Must be the same for top and referenced models. | ||
Generate code only | Must be the same for top and referenced models. | ||
Symbols | Maximum identifier length | Cannot be longer for a referenced model than for its parent model. | |
Interface | Code replacement library | Must be the same for top and referenced models. | |
Data exchange > Interface | C API | The C API check boxes for signals, parameters, and states must be the same for top and referenced models. | |
| ASAP2 | Can be on or off in a top model, but must be off in a referenced model. If it is not, the Simulink Coder software temporarily sets it to off during code generation. | ||
Configuration Requirements for Model Referencing with ERT System Targets
| Dialog Box Pane | Option | Requirement | |
|---|---|---|---|
Code Generation | Ignore custom storage classes | Must be the same for top and referenced models. | |
Symbols | Global
variables Global types Subsystem methods Local temporary variables Constant macros | $R token must appear. | |
Signal naming | Must be the same for top and referenced models. | ||
| M-function | If specified, must be the same for top and referenced models. | ||
Parameter naming | Must be the same for top and referenced models. | ||
#define naming | Must be the same for top and referenced models. | ||
Interface | Support floating-point numbers | Must be the same for both top and referenced models | |
Support non-finite numbers | If off for top model, must be off for referenced models. | ||
Support complex numbers | If off for top model, must be off for referenced models. | ||
Suppress error status in real-time model | If on for top model, must be on for referenced models. | ||
Templates | Target operating system | Must be the same for top and referenced models. | |
Data Placement | Module Naming | Must be the same for top and referenced models. | |
| Module Name (if specified) | If set, must be the same for top and referenced models. | ||
Signal display level | Must be the same for top and referenced models. | ||
Parameter tune level | Must be the same for top and referenced models. | ||
Naming Requirements. Within a model that uses model referencing, there can be no collisions between the names of the constituent models. When you generate code from a model that uses model referencing, the Maximum identifier length parameter must be large enough to accommodate the root model name and the name mangling string. A code generation error occurs if Maximum identifier length is not large enough.
When a name conflict occurs between a symbol within the scope of a higher-level model and a symbol within the scope of a referenced model, the symbol from the referenced model is preserved. Name mangling is performed on the symbol from the higher-level model.
The Embedded Coder™ product provides a Symbol format field that lets you control the formatting of generated symbols in much greater detail. When generating code with an ERT target from a model that uses model referencing:
The $R token must be included in the Identifier format control parameter specifications (in addition to the $M token).
The Maximum identifier length must be large enough to accommodate full expansions of the $R and $M tokens.
See Code Generation Pane: Symbols and for more information.
Custom Target Requirements. A custom target must meet various requirements in order to support model referencing. See Support Model Referencing for details.
Models containing Model blocks can use signals of storage class Auto without restriction. However, when you declare signals to be global, you must be aware of how the signal data will be handled.
A global signal is a signal with a storage class other than Auto:
ExportedGlobal
ImportedExtern
ImportedExternPointer
Custom
The above are distinct from SimulinkGlobal signals, which are treated as test points with Auto storage class.
Global signals are declared, defined, and used as follows:
An extern declaration is generated by all models that use any given global signal.
As a result, if a signal crosses a Model block boundary, the top model and the referenced model both generate extern declarations for the signal.
For any exported signal, the top mode is responsible for defining (allocating memory for) the signal, whether or not the top model itself uses the signal.
All global signals used by a referenced model are accessed directly (as global memory). They are not passed as arguments to the functions that are generated for the referenced models.
Custom storage classes also follow the above rules. However, certain custom storage classes are not currently supported for use with model reference. See Custom Storage Class Limitations for details.
Storage Classes for Parameters Used with Model Blocks. All storage classes are supported for both simulation and code generation, and all except Auto are tunable. The supported storage classes thus include
SimulinkGlobal
ExportedGlobal
ImportedExtern
ImportedExternPointer
Custom
Note the following restrictions on parameters in referenced models:
Tunable parameters are not supported for noninlined S-functions.
Tunable parameters set using the Model Parameter Configuration dialog box are ignored.
Note the following considerations concerning how global tunable parameters are declared, defined, and used in code generated for targets:
A global tunable parameter is a parameter in the base workspace with a storage class other than Auto.
An extern declaration is generated by all models that use any given parameter.
If a parameter is exported, the top model is responsible for defining (allocating memory for) the parameter (whether it uses the parameter or not).
All global parameters are accessed directly (as global memory). They are not passed as arguments to any of the functions that are generated for any of the referenced models.
Symbols for SimulinkGlobal parameters in referenced models are generated using unstructured variables (rtP_xxx) instead of being written into the model_P structure. This is so that each referenced model can be compiled independently.
Certain custom storage classes for parameters are not currently supported for model reference. See Custom Storage Class Limitations for details.
Parameters used as Model block arguments must be defined in the referenced model's workspace. See Parameterizing Model References in the Simulink documentation for specific details.
Effects of Signal Name Mismatches. Within a parent model, the name and storage class for a signal entering or leaving a Model block might not match those of the signal attached to the root inport or outport within that referenced model. Because referenced models are compiled independently without regard to any parent model, they cannot adapt to all possible variations in how parent models label and store signals.
The Simulink Coder software accepts all cases where input and output signals in a referenced model have Auto storage class. When such signals are test pointed or are global, as described above, certain restrictions apply. The following table describes how mismatches in signal labels and storage classes between parent and referenced models are handled:
Relationships of Signals and Storage Classes Between Parent and Referenced Models
Referenced Model | Parent Model | Signal Passing Method | Signal Mismatch Checking |
|---|---|---|---|
Auto | Any | Function argument | None |
SimulinkGlobal or resolved to Signal Object | Any | Function argument | Label Mismatch Diagnostic (none / warning / error) |
Global | Auto or SimulinkGlobal | Global variable | Label Mismatch Diagnostic (none / warning / error) |
Global | Global | Global variable | Labels and storage classes must be identical (else error) |
To summarize, the following signal resolution rules apply to code generation:
If the storage class of a root input or output signal in a referenced model is Auto (or is SimulinkGlobal), the signal is passed as a function argument.
When such a signal is SimulinkGlobal or resolves to a Simulink.Signal object, the Signal Mismatch diagnostic is applied.
If a root input or output signal in a referenced model is global, it is communicated by using direct memory access (global variable). In addition,
If the corresponding signal in the parent model is also global, the names and storage classes must match exactly.
If the corresponding signal in the parent model is not global, the Signal Mismatch diagnostic is applied.
You can set the Signal Mismatch diagnostic to error, warning, or none in the Configuration Parameters > Diagnostics > Connectivity dialog.
See Inheriting Sample Times in the Simulink documentation for information about Model block sample time inheritance. In generated code, you can control inheriting sample time by using ssSetModelReferenceSampleTimeInheritanceRule in different ways:
An S-function that precludes inheritance: If the sample time is used in the S-function's run-time algorithm, then the S-function precludes a model from inheriting a sample time. For example, consider the following mdlOutputs code:
static void mdlOutputs(SimStruct *S, int_T tid)
{
const real_T *u = (const real_T*)
ssGetInputPortSignal(S,0);
real_T *y = ssGetOutputPortSignal(S,0);
y[0] = ssGetSampleTime(S,tid) * u[0];
}
This mdlOutputs code uses the sample time in its algorithm, and the S-function therefore should specify
ssSetModelReferenceSampleTimeInheritanceRule (S, DISALLOW_SAMPLE_TIME_INHERITANCE);
An S-function that does not preclude Inheritance: If the sample time is only used for determining whether the S-function has a sample hit, then it does not preclude the model from inheriting a sample time. For example, consider the mdlOutputs code from the S-function demo sfun_multirate.c:
static void mdlOutputs(SimStruct *S, int_T tid)
{
InputRealPtrsType enablePtrs;
int *enabled = ssGetIWork(S);
if (ssGetInputPortSampleTime
(S,ENABLE_IPORT)==CONTINUOUS_SAMPLE_TIME &&
ssGetInputPortOffsetTime(S,ENABLE_IPORT)==0.0) {
if (ssIsMajorTimeStep(S) &&
ssIsContinuousTask(S,tid)) {
enablePtrs =
ssGetInputPortRealSignalPtrs(S,ENABLE_IPORT);
*enabled = (*enablePtrs[0] > 0.0);
}
} else {
int enableTid =
ssGetInputPortSampleTimeIndex(S,ENABLE_IPORT);
if (ssIsSampleHit(S, enableTid, tid)) {
enablePtrs =
ssGetInputPortRealSignalPtrs(S,ENABLE_IPORT);
*enabled = (*enablePtrs[0] > 0.0);
}
}
if (*enabled) {
InputRealPtrsType uPtrs =
ssGetInputPortRealSignalPtrs(S,SIGNAL_IPORT);
real_T signal = *uPtrs[0];
int i;
for (i = 0; i < NOUTPUTS; i++) {
if (ssIsSampleHit(S,
ssGetOutputPortSampleTimeIndex(S,i), tid)) {
real_T *y = ssGetOutputPortRealSignal(S,i);
*y = signal;
}
}
}
} /* end mdlOutputs */
The above code uses the sample times of the block, but only for determining whether there is a hit. Therefore, this S-function should set
ssSetModelReferenceSampleTimeInheritanceRule (S, USE_DEFAULT_FOR_DISCRETE_INHERITANCE);
You can control the library file suffix, including the file type extension, that the Simulink Coder code generator uses to name generated model reference libraries by specifying the string for the suffix with the model configuration parameter TargetLibSuffix. The string must include a period (.). If you do not set this parameter,
| On a... | The Simulink Coder Software Names the Libraries... |
|---|---|
| MicrosoftWindows system | model_rtwlib.lib |
| The Open Group UNIX system | model_rtwlib.a |
The following Simulink Coder limitations apply to model referencing. In addition to these limitations, a model reference hierarchy used for code generation must satisfy:
The Simulink requirements listed in:
The Simulink limitations listed in Model Referencing Limitations.
The Simulink Coder requirements applicable to the code generation target, as listed in Configuration Parameter Requirements.
The Simulink Coder code generator ignores custom code settings in the Configuration Parameter dialog box and custom code blocks when generating code for a referenced model.
Some restrictions exist on grouped custom storage classes in referenced models. See Custom Storage Class Limitations for details.
Referenced models do not support custom storage classes if the parent model has inline parameters off.
This release does not include Stateflow® target custom code in simulation targets generated for referenced models.
Data type replacement is not supported for simulation target code generation for referenced models.
Simulation targets do not include Stateflow target custom code.
To Workspace blocks, Scope blocks, and all types of runtime display, such as the display of port values and signal values, are ignored when the Simulink Coder software generates code for a referenced model. The resulting code is the same as if the constructs did not exist.
Code generated for referenced models cannot log data to MAT-files. If data logging is enabled for a referenced model, the Simulink Coder software disables the option before code generation and re-enables it afterwards.
If you log states for a model that contains referenced models, the ordering of the states in the output is determined by block sorted order, and might not match between simulation output and generated code MAT-file logging output.
State Initialization Limitation. When a top model uses the Load from workspace > Initial state option to specify initial conditions, the Simulink Coder software does not initialize the states of any referenced models.
Reusability Limitations. If a referenced model used for code generation has any of the following properties, the model must specify Configuration Parameters > Model Referencing > Total number of instances allowed per top model as One, and no other instances of the model can exist in the hierarchy. If the parameter is not set as required, or more than one instance of the model exists in the hierarchy, an error occurs. The properties are:
The model references another model which has been set to single instance
The model contains a state or signal with non-auto storage class
The model uses any of the following Stateflow constructs:
Machine-parented data
Machine-parented events
Stateflow graphical functions
The model contains a subsystem that is marked as function
The model contains an S-function that is:
Inlined but has not set the option SS_OPTION_WORKS_WITH_CODE_REUSE
Not inlined
The model contains a function-call subsystem that:
Has been forced by the Simulink engine to be a function
Is called by a wide signal
If a referenced model contains an S-function that should be inlined using a Target Language Compiler file, the S-function must use the ssSetOptions macro to set the SS_OPTION_USE_TLC_WITH_ACCELERATOR option in its mdlInitializeSizes method. The simulation target will not inline the S-function unless this flag is set.
A referenced model cannot use noninlined S-functions generated by the Simulink Coder software.
The Simulink Coder S-function target does not support model referencing.
For additional information, in the Simulink documentation, see Using S-Functions with Model Referencing.
Simulink tools that require access to a model's internal data or configuration (including the Model Coverage tool, the Simulink Report Generator™ product, the Simulink debugger, and the Simulink profiler) have no effect on code generated by the Simulink Coder software for a referenced model, or on the execution of that code. Specifications made and actions taken by such tools are ignored and effectively do not exist.
If a subsystem contains Model blocks, you cannot build a subsystem module by right-clicking the subsystem (or by using Tools > Code Generation > Build subsystem) unless the model is configured to use an ERT target .
If you generate code for an atomic subsystem as a reusable function, inputs or outputs that connect the subsystem to a referenced model can affect code reuse, as described in Reusable Code and Referenced Models.
Simulink Coder grt_malloc targets do not support model reference.
The Simulink Coder S-function target does not support model referencing.
Errors or unexpected behavior can occur if a Model block is part of a cycle, the Model block is a direct feedthrough block, and an algebraic loop results. See Model Blocks and Direct Feedthrough for details.
The External mode option is not supported. If it is enabled, it is ignored during code generation.
The difference between functions and reusable functions is that the latter have data passed to them as arguments (enabling them to be reentrant), while the former communicate by using global data. Choosing the Reusable function option directs the Simulink Coder code generator to generate a single function (optionally in a separate file) for the subsystem, and to call that code for each identical subsystem in the model, if possible.
Note The Reusable function option yields code that is called from multiple sites (hence reused) only when the Auto option would also do so. The difference between these options' behavior is that when reuse is not possible, selecting Auto yields inlined code (or if circumstances prohibit inlining, creates a function without arguments), while choosing Reusable function yields a separate function (with arguments) that is called from only one site. |
For a summary of code reuse limitations, see Code Reuse Limitations.
Models that employ model referencing might require special treatment when generating and using reusable code. The following sections identify general restrictions and discuss how reusable functions with inputs or outputs connected to a referenced model's root Inport or Outport blocks can affect code reuse.
General Considerations. You can generate code for subsystems that contain referenced models using the same procedures and options described in Subsystems. However, the following restrictions apply to such builds:
A top model that uses single-tasking mode and that has a submodel that uses multi-tasking mode executes for blocks with the different rates that are not connected. However, you get an error if the blocks with different rates are connected by Rate Transition block (inserted either manually or by Simulink).
ERT S-functions do not support subsystems that contain a continuous sample time.
The Simulink Coder S-function target is not supported.
The Tunable parameters table (set by using the Model Parameter Configuration dialog box) is ignored; to make parameters tunable, you must define them as Simulink parameter objects in the base workspace.
All other parameters are inlined into the generated code and S-function.
Note You can generate subsystem code using any target configuration available in the System Target File Browser. However, if the S-function target is selected, Build Subsystem behaves identically to Generate S-function. (See Automate S-Function Generation.) |
Code Reuse and Model Blocks with Root Inport or Outport Blocks. Reusable functions with inputs or outputs connected to a referenced model's root Inport or Outport block can affect code reuse. This means that code for certain atomic subsystems cannot be reused in a model reference context the same way it is reused in a standalone model.
For example, suppose you create the following subsystem and make the following changes to the subsystem's block parameters:
Select Treat as an atomic unit
Go to the Code Generation tab and set Function packaging to Reusable function

Suppose you then create the following model, which includes three instances of the preceding subsystem.

With the Inline parameters option enabled in this stand-alone model, the Simulink Coder code generator can optimize the code by generating a single copy of the function for the reused subsystem, as shown below.
void reuse_subsys1_Subsystem1(
real_T rtu_0,
rtB_reuse_subsys1_Subsystem1 *localB)
{
/* Gain: '<S1>/Gain' */
localB->Gain_k = rtu_0 * 3.0;
}
When generated as code for a Model block (into an slprj project folder), the subsystems have three different function signatures:
/* Output and update for atomic system: '<Root>/Subsystem1' */
void reuse_subsys1_Subsystem1(const real_T *rtu_0,
rtB_reuse_subsys1_Subsystem1
*localB)
{
/* Gain: '<S1>/Gain' */
localB->Gain_w = (*rtu_0) * 3.0;
}
/* Output and update for atomic system: '<Root>/Subsystem2' */
void reuse_subsys1_Subsystem2(real_T rtu_In1,
rtB_reuse_subsys1_Subsystem2
*localB)
{
/* Gain: '<S2>/Gain' */
localB->Gain_y = rtu_In1 * 3.0;
}
/* Output and update for atomic system: '<Root>/Subsystem3' */
void reuse_subsys1_Subsystem3(real_T rtu_In1, real_T *rty_0)
{
/* Gain: '<S3>/Gain' */
(*rty_0) = rtu_In1 * 3.0;
}
One way to make all the function signatures the same for code reuse, is to insert Signal Conversion blocks. Place one between the Inport and Subsystem1 and another between Subsystem3 and the Outport of the referenced model.

The result is a single reusable function:
void reuse_subsys2_Subsystem1(real_T rtu_In1,
rtB_reuse_subsys2_Subsystem1 *localB)
{
/* Gain: '<S1>/Gain' */
localB->Gain_g = rtu_In1 * 3.0;
}
You can achieve the same result (reusable code) with only one Signal Conversion block. You can omit the Signal Conversion block connected to the Inport block if you select the Pass fixed-size scalar root inputs by value check box at the bottom of the Model Referencing pane of the Configuration Parameters dialog box. When you do this, you still need to insert a Signal Conversion block before the Outport block.
You can generate reusable code from a Stateflow chart, or from a subsystem containing a chart, except in the following cases:
The Stateflow chart contains exported graphical functions.
The Stateflow model contains machine parented events.
Regarding S-Function blocks, there are several requirements that need to be met in order for subsystems containing them to be reused. See Write S-Functions That Support Code Reuse for the list of requirements.
When you select the Reusable function option, two additional options are enabled, Function name options and File name options. See Function Option for descriptions of these options and fields. If you use these fields to enter a function name and/or a file name, you must specify exactly the same function name and file name for each instance of identical subsystems for the Simulink Coder software to be able to reuse the subsystem code.
Subsystem Reusable Function Code Generation Option

To request that the Simulink Coder software generate reusable subsystem code,
Select the subsystem block. Then select Subsystem Parameters from the Simulink model editor Edit menu. The Block Parameters dialog box opens.
Alternatively, you can open the Block Parameters dialog box by:
Shift-double-clicking the subsystem block
Right-clicking the subsystem block and selecting Subsystem parameters from the menu.
If the subsystem is virtual, select Treat as atomic unit. On the Code Generation tab, the Function packaging menu becomes enabled.
If the system is already nonvirtual, the Function packaging menu is already enabled.
Go to the Code Generation tab and select Reusable function from the Function packaging menu as shown in Subsystem Reusable Function Code Generation Option.
If you want to give the function a specific name, set the function name, using the Function name options parameter, as described in Function Name Options Menu.
If you do not choose Auto for the Function name options parameter, and want code to be reused, you must assign exactly the same function name to all other subsystem blocks that you want to share this code.
If you want to direct the generated code to a specific file, set the file name using any File name options parameter value other than Auto (options are described in File Name Options Menu).
In order for code to be reused, you must repeat this step for all other subsystem blocks that you want to share this code, using the same file name.
The Simulink Coder software uses a checksum to determine whether subsystems are identical. You cannot reuse subsystem code if:
Multiple ports of a subsystem share the same source.
A port used by multiple instances of a subsystem has different sample times, data types, complexity, frame status, or dimensions across the instances.
The output of a subsystem is marked as a global signal.
Subsystems contain identical blocks with different names or parameter settings.
The output of a subsystem is connected to a Merge block, and the output of the Merge block is a custom storage class that is implemented in the C code as memory that is nonaddressable (for example, BitField).
The input of a subsystem is nonscalar and has a custom storage class that is implemented in the C code as memory that is nonaddressable.
A masked subsystem has a parameter that is nonscalar and has a custom storage class that is implemented in the C code as memory that is nonaddressable.
Some of these situations can arise even when you copy and paste subsystems within or between models or you construct them manually such that they are identical. If you select Reusable function and the Simulink Coder software determines that code for a subsystem cannot be reused, it generates a separate function that is not reused. The code generation report can show that the separate function is reusable, even if it is used by only one subsystem. If you prefer that subsystem code be inlined in such circumstances rather than deployed as functions, you choose Auto for the Function packaging option.
Use of the following blocks in a subsystem can also prevent its code from being reused:
Scope blocks (with data logging enabled)
S-Function blocks that fail to meet certain criteria (see Write S-Functions That Support Code Reuse)
To File blocks (with data logging enabled)
To Workspace blocks (with data logging enabled)
Due to the limitations noted in Code Reuse Limitations, the Simulink Coder software might not reuse generated code as you expect. To determine why code generated for a subsystem is not reused,
Review the Subsystems section of the HTML code generation report
If you cannot determine why based on the report, compare subsystem checksum data
Review the Subsystems Section of the HTML Code Generation Report. If you determine that the Simulink Coder code generator does not generate code for a subsystem as reusable code and you specified the subsystem as reusable, examine the Subsystems section of the HTML code generation report (see Generate an HTML Code Generation Report). The Subsystems section contains
A table that summarizes how nonvirtual subsystems were converted to generated code
Diagnostic information that explains why the contents of some subsystems were not generated as reusable code
In addition to diagnosing exceptions, the Subsections section also indicates the mapping of each noninlined subsystem in the model to functions or reused functions in the generated code. For an example, open and build the rtwdemo_atomic demo model.
Compare Subsystem Checksum Data. If the HTML code generation report indicates that no code reuse exceptions occurred and code for a subsystem you expect to be reused is not reused, you can determine why by accessing and comparing subsystem checksum data. The Simulink Coder software determines whether subsystems are identical by comparing subsystem checksums, as noted in Code Reuse Limitations.
Consider the demo model, rtwdemo_ssreuse.

SS1 and SS2 are instances of the same subsystem, and in both instances the subsystem parameter Function packaging is set to Reusable function.
The following example demonstrates how to use the method Simulink.SubSystem.getChecksum to get the checksum for a subsystem and compare the results to determine why code is not reused.
Open the model rtwdemo_ssreuse and save a copy of the demo in a folder where you have write access.
Select subsystem SS1 in the model window and in the command window enter
SS1 = gcb;
Select subsystem SS2 in the model window and in the command window enter
SS2 = gcb;
Use the method Simulink.SubSystem.getChecksum to get the checksum for each subsystem. This method returns two output values: the checksum value and details on the input used to compute the checksum.
[chksum1, chksum1_details] = ... Simulink.SubSystem.getChecksum(SS1); [chksum2, chksum2_details] = ... Simulink.SubSystem.getChecksum(SS2);
Compare the two checksum values. They should be equal based on the subsystem configurations.
isequal(chksum1, chksum2)
ans =
1To see how you can use Simulink.SubSystem.getChecksum to determine why the checksums of two subsystems differ, change the data type mode of the output port of SS1 so that it differs from that of SS2.
Look under the mask of SS1 by right-clicking the subsystem and selecting Look Under Mask in the context menu. A block diagram of the subsystem appears.
Double-click the Lookup Table block to open the Block Parameters dialog box.
Click Signal Attributes.
Select int8 for Output data type and click OK.
Get the checksum for SS1 again and compare the checksums for the two subsystems again. This time, the checksums should not be equal.
[chksum1, chksum1_details] = ...
Simulink.SubSystem.getChecksum(SS1);
isequal(chksum1, chksum2)
ans =
0After you determine that the checksums are different, find out why. The Simulink engine uses information, such as signal data types, some block parameter values, and block connectivity information, to compute the checksums. To determine why checksums are different, you compare the data used to compute the checksum values. You can get this information from the second value returned by Simulink.SubSystem.getChecksum, which is a structure array with four fields.
Look at the structure chksum1_details.
chksum1_details
chksum1_details =
ContentsChecksum: [1x1 struct]
InterfaceChecksum: [1x1 struct]
ContentsChecksumItems: [221x1 struct]
InterfaceChecksumItems: [91x1 struct]ContentsChecksum and InterfaceChecksum are component checksums of the subsystem checksum. The remaining two fields ContentsChecksumItems and InterfaceChecksumItems contain the checksum details.
Determine whether a difference exists in the subsystem contents, interface, or both. For example:
isequal(chksum1_details.ContentsChecksum.Value,...
chksum2_details.ContentsChecksum.Value)
ans =
0
isequal(chksum1_details.InterfaceChecksum.Value,...
chksum2_details.InterfaceChecksum.Value)
ans =
0In this case, differences exist in both the contents and interface.
Write a script like the following to find the differences.
idxForCDiffs=[];
for idx = 1:length(chksum1_details.ContentsChecksumItems)
if (~strcmp(chksum1_details.ContentsChecksumItems(idx).Identifier, ...
chksum2_details.ContentsChecksumItems(idx).Identifier))
disp(['Identifiers different for contents item ', num2str(idx)]);
idxForCDiffs=[idxForCDiffs, idx];
end
if (ischar(chksum1_details.ContentsChecksumItems(idx).Value))
if (~strcmp(chksum1_details.ContentsChecksumItems(idx).Value, ...
chksum2_details.ContentsChecksumItems(idx).Value))
disp(['String values different for contents item ', num2str(idx)]);
idxForCDiffs=[idxForCDiffs, idx];
end
end
if (isnumeric(chksum1_details.ContentsChecksumItems(idx).Value))
if (chksum1_details.ContentsChecksumItems(idx).Value ~= ...
chksum2_details.ContentsChecksumItems(idx).Value)
disp(['Numeric values different for contents item ', num2str(idx)]);
idxForCDiffs=[idxForCDiffs, idx];
end
end
end
idxForIDiffs=[];
for idx = 1:length(chksum1_details.InterfaceChecksumItems)
if (~strcmp(chksum1_details.InterfaceChecksumItems(idx).Identifier, ...
chksum2_details.InterfaceChecksumItems(idx).Identifier))
disp(['Identifiers different for interface item ', num2str(idx)]);
idxForIDiffs=[idxForIDiffs, idx];
end
if (ischar(chksum1_details.InterfaceChecksumItems(idx).Value))
if (~strcmp(chksum1_details.InterfaceChecksumItems(idx).Value, ...
chksum2_details.InterfaceChecksumItems(idx).Value))
disp(['String values different for interface item ', num2str(idx)]);
idxForIDiffs=[idxForIDiffs, idx];
end
end
if (isnumeric(chksum1_details.InterfaceChecksumItems(idx).Value))
if (chksum1_details.InterfaceChecksumItems(idx).Value ~= ...
chksum2_details.InterfaceChecksumItems(idx).Value)
disp(['Numeric values different for interface item ', num2str(idx)]);
idxForIDiffs=[idxForIDiffs, idx];
end
end
endRun the script. The following example assumes you named the script check_details.
check_details String values different for contents item 64 String values different for contents item 75 String values different for contents item 81 String values different for interface item 46
The results indicate that differences exist for index items 64, 75, and 81 in the subsystem contents and for item 46 in the subsystem interfaces.
Use the returned index values to get the handle , identifier, and value details for each difference found.
chksum1_details.ContentsChecksumItems(64)
ans =
Handle: 'my_ssreuse/SS1/Lookup Table Output1'
Identifier: 'CompiledPortAliasedThruDataType'
Value: 'int8'
chksum2_details.ContentsChecksumItems(64)
ans =
Handle: 'my_ssreuse/SS2/Lookup Table Output1'
Identifier: 'CompiledPortAliasedThruDataType'
Value: 'double'
chksum1_details.ContentsChecksumItems(75)
ans =
Handle: 'my_ssreuse/SS1/Lookup Table'
Identifier: 'RunTimeParameter{'OutputValues'}.DataType'
Value: 'int8'
chksum2_details.ContentsChecksumItems(75)
ans =
Handle: 'my_ssreuse/SS2/Lookup Table'
Identifier: 'RunTimeParameter{'OutputValues'}.DataType'
Value: 'double'
chksum1_details.ContentsChecksumItems(81)
ans =
Handle: 'my_ssreuse/SS1/Lookup Table'
Identifier: 'OutDataTypeMode'
Value: 'int8'
chksum2_details.ContentsChecksumItems(81)
ans =
Handle: 'my_ssreuse/SS2/Lookup Table'
Identifier: 'OutDataTypeMode'
Value: 'Same as input'
chksum1_details.InterfaceChecksumItems(46)
ans =
Handle: 'my_ssreuse/SS1'
Identifier: 'CanonicalParameter(1).DataType'
Value: 'int8'
chksum2_details.InterfaceChecksumItems(46)
ans =
Handle: 'my_ssreuse/SS2'
Identifier: 'CanonicalParameter(1).DataType'
Value: 'double'As expected, the details identify the Lookup Table block and data type parameters as areas on which to focus for debugging a subsystem reuse issue.
Fix the problem by changing the output data type mode for the subsystems such that they match.
If you want to combine several models (or several instances of the same model) into a single executable, the Simulink Coder product offers several options.
The most powerful solution is to use Model blocks. Each instance of a Model block represents another model, called a referenced model. For code generation, the referenced model effectively replaces the Model block that references it. For details, see Referencing a Model and Referenced Models.
When developing embedded systems using the Embedded Coder product, you can interface the code for several models to a common harness program by directly calling the entry points to each model. However, the Embedded Coder target has certain restrictions that might not apply to your application. For more information, see the Embedded Coder documentation.
The GRT malloc target is a another possible solution. Use it in situations where you want to:
Selectively control calls to more than one model
Use dynamic memory allocation
Include models that employ continuous states
Log data to multiple files
Run one of the models in external mode
To summarize by target, your options are as follows:
| Target | Support for Combining Multiple Models? |
|---|---|
Generic Real-Time Target (grt.tlc) | Yes (using Model blocks) |
Generic Real-Time Target with dynamic memory allocation (grt_malloc.tlc) | Yes |
Embedded Coder (ert.tlc) | Yes |
S-function Target (rtwsfcn.tlc) | No |
This section discusses how to use the GRT malloc target to combine models into a single program.
Building a multiple-model executable is fairly straightforward:
Generate and compile code from each of the models that are to be combined.
Combine the makefiles for each of the models into one makefile for creating the final multimodel executable.
Create a combined simulation engine by modifying grt_malloc_main.c to initialize and call the models.
Run the combination makefile to link the object files from the models and the main program into an executable.
Share Data Across Models. Use unidirectional signal connections between models. This affects the order in which models are called. For example, if an output signal from modelA is used as input to modelB, modelA's output computation should be called first.
Timing Issues. You must generate all the models you are combining with the same solver mode (either all single-tasking or all multitasking.) In addition, if the models employ continuous states, the same solver should be used for all models.
Because each model has its own model-specific definition of the rtModel data structure, you must use an alternative mechanism to control model execution, as follows:
The file rtw/c/src/rtmcmacros.h provides an rtModel API clue that can be used to call the rt_OneStep procedure.
The rtmcmacros.h header file defines the rtModelCommon data structure, which has the minimum common elements in the rtModel structure required to step a model forward one time step.
The rtmcsetCommon macro populates an object of type rtModelCommon by copying the respective similar elements in the model's rtModel object. Your main routine must create one rtModelCommon structure for each model being called by the main routine.
The main routine will subsequently invoke rt_OneStep with a pointer to the rtModelCommon structure instead of a pointer to the rtModel structure.
If the base rates for the models are not the same, the main program (such as grt_malloc_main) must set up the timer interrupt to occur at the greatest common divisor rate of the models. The main program is responsible for calling each of the models at a time interval.
Data Logging and External Mode Support. A multiple-model program can log data to separate MAT-files for each model.
Only one of the models in a multiple-model program can use external mode.
[1] VxWorks is a registered trademark of Wind River® Systems, Inc.
![]() | Configure a Model for Code Generation | Scheduling | ![]() |

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.
| © 1984-2012- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |