With this post, I will share some of the methods I have used over the years to make my Simulink models more readable.

## Resize subsystems and reorder ports

Resizing subsystems is a common suggestion to making diagrams more readable.  A step beyond that is to reorder the ports so that the connections between multiple subsystems are more readable.

With this Before/After example, I have done three things

1. Resized the source and destination blocks
2. Changed the port order on the source block
3. Offset the two destination blocks

## MATLAB functions for equations

When I am entering in an equation into Simulink, I ask myself 2 questions

1. Is there a built-in function for this equation (e.g., Integrators, Transfer Functions, table lookups)?  Use the built-in function
2. Is the equation more than 3 operations long?  Use a MATLAB function.

In text form, the Pythagorean theorem is quickly recognized and understood.  When written out as a Simulink equation it takes slightly longer to understand.

Note: I do have a caveat, if the mathematical operations are series of gains, for instance when converting from one unit to another, then keeping the calculations in Simulink is fine.

## Use of  Virtual busses for conditionally executed subsystems

Merging data from conditionally executed subsystems requires the use of the Merge block.  When the subsystems have multiple output ports routing the data quickly becomes cumbersome.  This can be addressed by creating a virtual bus to pack and then unpack the signals.

Note: Using a virtual bus will allow Simulink/Embedded Coder to optimize the memory placement of the signals.  If a structure is desired, then a bus object should be defined and used.

## The rule of 40, 5 and 2

When I create a Simulink subsystem, I aim to have a limited number of active blocks in the subsystem (40).  A limited number of used inputs (5) and a limited number of calculated outputs (2).

1. Active blocks:  Any block that performs an operation.  This count does not include inports, outports, mux, demux, bus…
1. Why: When the total number of blocks goes above 40 the ability to understand what is going on in the subsystem decreases.
2. Used inputs: Bus signals can enter the subsystem, and only one signal off of the bus may be used.  A “used signal” is one that is actively used as part of the subsystems calculations.
1. Why: The number of used inputs is a good metric for how “focused” the subsystem is in addressing a specific issue.
3. The number of outputs: directly relates to the first two metrics, e.g.h, how focused the subsystem is on a specific issue.

Notes: Subsystems that are integration subsystems (see this Model Architecture post) can and should break this rule.)

## Stay out of the deep end, beware of breadth

As a general rule of thumb, I recommend that models have a “depth” of 3.  Navigation up and down the hierarchy quickly can lose a reviewer.  Likewise, for given model, I recommend between 30 and 60 subsystems in total.

This recommendation holds for a single model.  For integration models, each “child” model should be treated as a single unit.

## Final thoughts

These are just a few of the recommendations that I have hit upon in the past 18 years.  I would be curious to hear your thoughts and recommendations.

1. Pierre Nowodzienski says:

Hi Mickael,

What would be your advice regarding the use of From/Goto tags ?
Same question for visualisation blocks (scopes, spectrum analyzer, …).
Do you have best practices for Area and Annotations ?
Thank you,
Pierre

1. Pierre

For Goto/From tags I follow the MAAB style guideline rules
1.) na_0011: Scope of Goto and From Blocks
2.) jc_0171: Maintaining signal flow when using Goto and From blocks

With respect to viewing signals. I try not too put too many scopes into my model, I find this link
useful for deciding what to do with data logging.

With respect to Areas, I haven’t seen a unified best practice emerge yet so I am still thinking about that one.

On annotations, I prefer to use a requirement document to an annotation unless it is a “Work in Progress” note, e.g. something to remind myself what I was doing when I come back to the model.

2. Mark Sahlin says:

Hello Michael,
Many thanks for sharing these very important tidbits of solid modeling practices. I question using Matlab functions for equations, particularly if the function is rather complex. I can see where you are going with your example as it is simple. However, we do not want to go overboard – actually shouldn’t we minimize Matlab function use? What is the impact when transitioning from simulation to embedded code generation? I also believe it is imperative to clearly show intended functionality, and for many instances a Matlab function script can be very complex where others will have a difficult time understanding what’s going on. Just my two cents.

1. Hi Mark,

Long time no talk, thank you for the feedback, in terms of minimizing MATLAB Function use, I’ve gone back and forth on this one over the years with, as the quality of the generated code from MATLAB functions has improved I have been more willing to say “Yes” to them.

My general rules of thumb are
1.) If there is a built-in block that performs the function do not use a MATLAB function. E.g. table look ups, transfer functions, integratals
2.) Don’t create state machines, Stateflow will do that for you.
3.) Stay short: if it is more then 40 lines of code consider breaking it up

Cheers,

This site uses Akismet to reduce spam. Learn how your comment data is processed.