Last week I started a discussion of mux and bus signals. Our mental model of the mux signal is a vector. The Mux and Demux Blocks can do more than just combine and break apart the elements of a vector. This week I want to go a level deeper and talk about the advanced maneuvers using Mux/Demux Blocks.
Mux Blocks as specifications
The first thing I want to show you is how to use the Mux Block to specify additional information about the signal dimensions at its ports. Instead of just putting the number of ports, you can specify the width of each signal line connected to the Mux Block.
This helps if you want to add a little more information to your model and include specifications at the Mux Block ports. When a signal is connected to the Mux Block and it has the wrong width, an error is thrown when the model is compiled.
Error in port widths or dimensions. Invalid dimension has been specified for input port 3 of 'model/System/Mux'.
Source blocks and ports can also supply this type of dimension information. I recommend that you specify dimensions on those source and port elements also, rather than just relying on the Mux Block. Information like dimensions should be included in interface and source blocks. For example, here is where you would add dimension information in the Inport dialog:
The mux is nice to have, but the Demux Block puts this concept to good use for selecting out subsets of your signal. When specifying the number of outputs as a vector of widths, you can pull out blocks of elements from your vector into subvectors.
Here is an example of the Demux Block breaking a vector of 8 elements into new signals of widths 1, 5 and 2.
Going back to our mental model of the mux signal as a vector, I only use this technique if it is logical to represent my signal this way. In this model, peeling off each chunk of signals makes the diagram flow very nicely. This replaces the need to demux all elements of the signal and then mux the subset of the signal into a vector.
Mux and Demux Blocks also work with special signal types
Another use of Mux and Demux Blocks involves the special function call signal type. Before I talk about what mux and demux do, let us review the basics of function calls.
A short introduction to function calls
A function call system is similar to a triggered system except that instead of executing based on the value of a signal they execute immediately when called by the function call initiator. I have seen function call systems used to simulate asynchronous behavior or to schedule the execution of a component independent of other components. Function calls are critical when designing your own scheduler for an embedded system.
Function Call Generators (1 below), Stateflow(2), and S-functions are the most common function call initiators. Model Reference Blocks(3) and Function call subsystems (4) are two examples of functions that can be called.
Function calls and Mux Blocks
When you have a single function call initiator, and a single system to be called, the connection is simply from initiator to the system being called. When you have multiple function call initiators, the Mux block is used to join the function calls together. (Blocks can only have one function call port.)
Function calls and Demux Blocks
When a single initiator needs to call multiple systems, the Demux Block allows you to split the signal. This is a very important semantic role for the Demux Block because function call signals are not allowed to branch like normal signals. Function call signals determine the execution order of the blocks they are connected to. If a function call was to branch, which destination system would be executed first? The Demux Block specifies the order of execution based on the port number that the signal is connected to. Port numbers are always counted from top to bottom, or left to right. Here is an example:
In this example, the function call initiator Task1 will execute Sys1, Sys2 and Sys3 in that order. I don’t know about you, but when I look at that picture I feel an aesthetic desire to uncross the lines going to Sys1 and Sys2. My urge is to reconnect the first and second outport from the Demux in order to uncross the signals, like this:
This would fundamentally change the behavior of the system. The order of execution would then be Sys2, Sys1, and then Sys3. The Demux Block is an important part of function call semantics, and semantics trump aesthetics.
What do you think?
You may have started reading this post with the expectation to learn all about Mux and Demux, but you also got my elevator speech about function calls. Did you know about this use for Mux and Demux? What is new or different in your mental model for these blocks? Leave a comment and tell me about it.
13 CommentsOldest to Newest
firstly, kudos for your blog. Nice to read about mental models, as this is the way I face Simulink.
* is any unification of vectors and buses foreseen? One might consider buses as “hierarchical named grouped vectors”
* I checked on the “bus selection mode”: it is possible to feed one scalar into a demux with bus selection mode=on. According to the documentation it should not be possible. Is this by design or accidentally?
* are there any plans to break compatibility between buses and vecors, as enabled by the bus selection mode?
* I would be interested in more explanation on virtal/nonvirtual buses. Is this in the pipeline for your blog?
A little off-topic: I am also interested into the relation between asynchronous rate transitions (various setups for this), the simulation of it and the code generation for it. Any plans to blog on this?
I’d be interested in more discussion on when it’s a good idea, or a requirement, to specify the dimension and/or sample time of Inports either at the root level or in subsystems. Also, more discussion, with examples, on the use of function call subsystems would be interesting.
@Hans Geerligs – Your questions about bus signals are right on target, and each deserves a good post to help frame the discussion. My next post will be about bus objects and nonvirtual bus signals. Regarding unification of vectors and buses, the changes to bus signals over the past few releases have actually moved away from unifying the concepts. It turns out that there are too many edge cases that really complicate mixing of these concepts. I am planning to post about the Concatenate Block, and I hope to include some of the history behind mux and bus to give some clarification.
Rate transitions are a big topic. I plan blog on this. Thank you for the great suggestions.
@Paul J. – Specifying dimensions is a must for root level inports. The Model Advisor incluses “Check root model Inport block specification” which reports this message:
Your model contains root-level Inport blocks with undefined attributes, such as dimensions, sample time, or data type. If you do not explicitly define these attributes, Simulink will use back-propagation from downstream blocks to assign values to the attributes when updating the model. This can lead to undesired simulation results. To avoid this, fully define the attributes of all of your model’s root-level Inport blocks.
I see specifying root Inport information as being good modeling style. For subsystems, it is optional, but it really depends on how you are treating the subsystem. If the subsystem is a utility from your library and it is designed to handle any width vector input, it makes sense to leave the size inherited (-1). When the subsystem is a functional unit (atomic subsystem) and you can define it’s interface, I think this is the time to include dimensions and even type information. If you are only using subsystems to group blocks, and simplify your model (virtual subsystems), specifying sizes is unnecessary.
Function call subsystems are going to be a future blog topic. Thanks for adding your voice to the community!
i am interested in learning how TeX format can be used in the “documentation” tab of a subsystem. it does not seem to work and i have been told that functionality is not available now, but it sure would be great to add that in.
Thank you for your hints on mux and demux blocks and function calls. Concerning function call subsystems there is one problem I´m struggling with. You can´t use function call subsystems or triggered subsystems for multirate systems. Instead of this you have to use if-action or switch subsystems.
I would be highly obliged, if someone can show me a route to model a typical 2-to-1 Multiplexer, the way we have read & understood it.I want to translate behavior of typical digital 2-to-1 Mux works like this into SIMULINK model.
out = in1;
out = in2;
@Balaji Kalluri – The behavior you are looking for is provided in the MERGE block. Essentially, outputs from conditionally executed blocks can be routed together onto the same signal line. You can see this in the model mergedemo.mdl
always love your small tutorial thanx.
I am struggling to see how I could implement the following, I suspect I might have to use function call or the like but I am simply not sure how and what to do.
let suppose I have a subsystem compose of 2 independant block
the first block implements a simple addition int<-mysum(int, int) and the second block implements sqaring int<-mysquare(int). I want to be able to call the execution of one of this block by given the name of the function to call and arguments using simulink
Thank a lot for any hints
@Pat – I don’t think I understand your question. The conditional execution is possible with function call subsystems or any kind of conditional control in Simulink, but I don’t understand the requirement to call a block given the “name of the function”. Are you doing this from MATLAB code? If that is the case, I think you will be able to use the string handling functions to set a flag or input variable that determines which system executes. Good luck.
Well, Seth, you saved my day and spared me loads of rework! I’ve always complained that one could not have different initiators for a function-call subsystem and it turns out that I was wrong, thank God! Keep up with the good work.
@Jorge – I am glad you found what you needed!
happy to see this post. It is very useful for my project. I have a doubt- in my project for 1 i/p and 1 o/p the i/p dimension is 2 and the o/p is to be 1. How to design this step?
It would helpful to add a few caveats to the multiple function call initiators:
If you have multiple function call generator blocks feeding a mux block then all function call generator blocks need to have the same sample time.
If you have a mux being fed with multiple function calls then it can only be connected to a function-call subsystem but not a model reference with a function call inport block. But you can layer the model reference by placing the model reference block inside the function-call subsystem.