Where is the algebraic loop coming from?

38 views (last 30 days)
Sergei
Sergei on 29 Sep 2025 at 15:38
Commented: Sergei about 24 hours ago
Dear all,
I faced an issue with algebraic loop in simulink (see the model attached).
When I update the model it says "Algebraic loop error", even though there seem to be no algebraic loop at all.
The issue is resolved if I combine these two subsystems into a one.
Could you please explain where the algebraic loop is coming from?
Thank you!

Accepted Answer

Walter Roberson
Walter Roberson on 29 Sep 2025 at 16:49
The ready_out of toRAM_interface is an output. You send that to ready_in of the FIFO. Meanwhile, the FIFO has lines that are inputs to the toRAM_interface.
Everything that is connected has to be true at the same time unless separated by a zero order hold or memory block or rate transformation (including a 1/z block with a very short time constant. (I might be overlooking some other cases.) So your connected series means that the ready_out from the toRAM_interface has to be true at the same time as the outputs of the FIFO and the output lines of the FIFO. Even if we suppose that the read_out line is the trigger for the FIFO to send information, no time is being alotted for the *_out lines to settle or for the ready_out line to change state in response to the *_in being received. That is an algebraic loop.
Your system either needs a delay on the ready_out line, or else delays on the *_out lines that are input to the toRAM_interface
  3 Comments
Walter Roberson
Walter Roberson 29 minutes ago
Suppose we are at the state where toRAM_interface has just set ready_out to be true, thereby triggering the FIFO to send samples. We will simplify the discussion by focusing on the beginning of the ready_out pulse, ignoring any time before that. We will also simplify by assuming that FIFO reacts to the ready_out pulse immediately, making data for the *_out lines immediately available.
Now at some point, the toRAM_interface needs to signal that it is busy (because it is reading the *_out signals and processing them.) When that happens, toRAM_interface will set ready_out to false.
Here is the thing: it takes time for ready_out to flip to false.
Consider the contrary: if it did not take any time for ready_out to become false, then it would become false simultaneously with it becoming true to signal that toRMA_interface is ready. But no signal can be simultaneously true and false, and Simulink cannot process the possibility of a signal being simultaneously true and false.
The Simulink interface between FIFO and toRAM_interface needs to be configured so Simulink knows that there is time between ready_out becoming true and ready_out becoming false. Even if the time is only 50 nanoseconds, there needs to be a delay line or a zero-order hold or a memory block or a transfer function (I might have overlooked options) on the line so that Simulink is not trying to figure out how to handle the situation of ready_out being simultaneously true and false.
Sergei
Sergei 5 minutes ago
Edited: Sergei 5 minutes ago
Thank you for your update!
Your further explanation is based on that it takes time for ready_out to flip false, am I correct? I did not quite understand what that means.
So am I correct that RAM would try to set ready_out to 1, FIFO would try to set valid to 1, this might cause RAM to set ready_out to 0 -> inconsistency?
This would mean that the output ready_out depends on the current input *_in, is that really so?
Also, why then would placing the two parts in one subsystem resolves the problem? (check my previous comment for model)
Thank you again

Sign in to comment.

More Answers (1)

Sam Chak
Sam Chak on 1 Oct 2025 at 8:31
Moved: Sam Chak on 1 Oct 2025 at 8:33
Unmasking the 'FIFO' and 'toRAM_interface' blocks allows you to observe the signal dependence and identify the algebraic loop issue. The StreamFIFO block requires a feedback signal (ready_signal) that appears to originate from the Bus Object registered in both the toRAMctrl and fromRAMctrl ports. By default, Simulink's data type propagation for input and output ports uses the "Inherit: Auto" setting.
If you merely want to test the functions of the three SoC blocks, you can temporarily replace the toRAMctrl and fromRAMctrl ports with the Terminator and Ground blocks, respectively.
[data signal, valid_signal, ~] = StreamFIFO(data_in, valid_in, ready_signal)
toRAMctrl = SoCBusCreator(0, 0, valid_signal)
[ready_signal, ~, ~] = SoCBusSelector(fromRAMctrl)
Unmasked SoC subsystem
Workaround
  3 Comments
Sam Chak
Sam Chak 4 minutes ago
In the actual scenario, this SoC subsystem is probably connected to a much larger system via the RAM Controller for signal processing tasks, through multiple Simulink blocks that may be static (where signals are transmitted instantaneously) or dynamic (where a delay occurs as data travels from a sending point to a receiving point on a network).
If the blocks on the RAM side of the system are all static, a circular dependency will arise. Conversely, if the RAM side of the system includes some dynamic blocks with properly specified initial conditions, a circular loop will still exist, but it will not depend algebraically.
Note: If you cannot view the "Workaround" block diagram, click the attached image in this post.
Sergei
Sergei about 1 hour ago
Thank you for your explanations, clear!
I can see the picture now.
Actually that is what I did in the first model I attached "algebraic_loop.slx", placed terminators and ground.
I still do not understand the nature of this algebraic loop as ready_out, as how I have seen in my simulations, does not depend on the current RAM input, so there is already some kind of delay.
However, not to stick to the problem for too long I just placed a delay block and it is working fine.
Thank you!

Sign in to comment.

Categories

Find more on Schedule Model Components in Help Center and File Exchange

Products


Release

R2025a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!