Waiting for a signal (the SCL way)
- Ivaylo Fiziev
- May 5
- 3 min read
Updated: May 9

If your experience is mainly with OLP you are probably quite used to waiting for signals to change in your code. It is a natural thing to do since the code is executed only once. Wait instructions provide a way to pause the execution of the program for a while, until a certain condition is met. If you need to execute some statements periodically you just use a jump or a loop.
Statements are executed one by one (usually one per time interval).
In contrast the SCL script is a cyclic beast. It executes once (start to end) each logic update rate (100ms or so). Statements are again executed one by one but this time all statements are involved. If you have a couple of hundred lines of code in your script, all valid branches in the code will be executed. This is a major difference compared to OLP. This also means that the script should run much faster than the robotic code. e.g. the performance demand is much higher.
Having this in mind, how do you wait inside a SCL script?
Imagine you have an input variable wired to a signal and you want to wait for it in the code with a while loop. Using a while loop makes sense, isn't it? You'd better think again...
In the context of the cyclic evaluation, waiting for an input to change is a mistake. It is a logical error. Inputs will never change while the code runs. They change before the code is run. So if you decide to wait, you will probably end up with an endless loop that causes Process Simulate to hang.
So how do you wait?
You don't. You just check the value of the input with an 'if' statement and react if necessary.
Examples:
In the case of a Boolean input you can simply check its value like this:
VAR_INPUT
clk:BOOL;
END_VAR
BEGIN
IF #clk THEN
; // do something here
END_IF;
This code works but has a problem. The statements inside the 'if' will be executed whenever the input is true. This is probably not the behavior that you want since it does not answer the question of when the input has become true. To address this you have to use a rising edge trigger (R_TRIG). Here is how it looks:
VAR_INPUT
clk:BOOL;
END_VAR
VAR
trigger:R_TRIG;
END_VAR
BEGIN
#trigger(CLK:=#clk);
IF #trigger.Q THEN
; // do something here
END_IF;
Now the behavior is different. The trigger detects the transition from false to true of the input and makes the statements inside the 'if' execute only once on each transition.
How about numeric inputs?
The code is pretty much the same. Only the CLK input for the trigger is different:
VAR_INPUT
in:INT;
END_VAR
VAR
trigger:R_TRIG;
END_VAR
BEGIN
#trigger(CLK:=#in > 100);
IF #trigger.Q THEN
; // do something here
END_IF;
Whenever the value of the input exceeds 100 the trigger will detect it and the statements inside the 'if' will be executed.
The condition (expression) for the trigger is up to you to decide. This makes the script really powerful. If you need the opposite transition (true to false) just replace R_TRIG with F_TRIG (falling edge trigger).
In both cases we do not wait but achieve a similar result due to the cyclic nature of the script. The code however is not blocked in any way. This allows for better performance.
What are loops used for then?
Repetitive statements are often used with arrays or some algorithms (sorting is a typical example) that require multiple iterations. Be careful with the loops! Long loops will ruin the performance of the simulation just because they are executed on a cyclic basis.
I hope this makes it clear.
It is a small change in the mindset when coming from the OLP world. Small but elegant in my opinion.
See you!
Comments