-
Notifications
You must be signed in to change notification settings - Fork 5
Syntax
Note that this page refers to the new textual SCCharts syntax (SCTX). See Converting Legacy Models (sct) on how to convert legacy files.
For a detailed description of the basic concept and semantics of SCCharts please consult Sections 3.1 & 3.2 in the dissertation of Christian Motika.
Here you can see an SCCharts graphical notation overview.
Each SCChart starts with the keyword scchart followed by an ID. An ID can be any alpha-numerical combination, but must start with an alphabetical character or an underscore (a single underscore is prohibited). However, underscores are used to identify auto-generated constructs, so the modeler should not use them as prefix.
One of the basic constructs of SCCharts is a simple state. A simple state does not have any inner behavior and can be connected via transitions to other states.
scchart Simple {
initial state A
auto go to B
state B
delayed go to C
final state C
}
To tell the program where to start, a state can be marked as initial. Exactly one state (per concurrent region, see concurrency) must be marked as initial.
Transitions connect states. There are different kinds of Transitions, but we will restrict ourselves to the two basic types for now. (See below for more complex transitions.)
They can be guarded by a trigger that determines when this transition is enabled and they can have one or more effects that are executed whenever this transition becomes active.
The exact syntax is as follows:
[immediate] [if condition] [do effect [; effect]*] (go | abort | join) to targetstate
A delayed transition cannot trigger in the instance the parent state is entered. If a state is entered, they become *active *in the next tick. You can see this in the Simple example. Just write go to.
scchart Transitions {
input bool A, B
output int X, Y
initial state A
immediate if A do X++ go to B
state B
if A && B do X++; Y = X * 2 go to A
}
Immediate transitions are checked as soon as their parent state is entered. Hence, the state can be entered and left within the same tick. Use the keyword immediate to create an immediate transition
scchart Simple {
initial state A
go to B
state B
go to C
state C
immediate go to A
}
A state can also be marked as final. A final state marks the end of a thread. If a final state is reached on root level, the program terminates.
Each scope (for now just the SCChart) can have a list of declarations. The SCChart code on the right gives an example. A declaration starts with the type, followed by a list of variable identifier. Each variables can be initialized with a specific value.
scchart Variables {
input bool second
output bool beep
int i, j, k
int arr[10]
bool alarm = false
const bool ON = 1
extern "rObj" rail
initial state A
go to B
state B
}
The following native types are supported: bool, int, float, string, host, and signal (see below)
Additionally, you can mark a declaration as extern and give it a string that will be used in the serialization of the final code, e.g., the name of a host type. You can then add variables as before.
Please note that most code generators will translate the semantical type float into a high-precision floating point host type (e.g. double in java).
If you add brackets to a variable and specify cardinalities, you declare an array.
Declarations can be marked as constant, meaning that each occurrence is then replaced by the initialization because the variable is not allowed to be changed.
You can assign a whole vector to an array at once.
scchart tuples {
output int arr[5] = {1, 2, 3, 4, 5}
initial state init {
entry do arr = {6, 7, 8, 9, 10}
}
}
To assign only certain values of an array, you can also use the ignore value placeholder. Consult the expression manual for further information.
scchart tuples {
const int A = 1
output int arr[3][2] = {{A,0}, {2,0}, {3,0}}
initial state init
do arr = {{arr[0] + 1, _}, _, {arr[2] + 1, _}} go to init
}
This would, for example, result in c code assignments as shown below.
void logic(TickData* d) {
d->_g0 = d->_GO;
if (d->_g0) {
d->arr[0][0] = 1;
d->arr[0][1] = 0;
d->arr[1][0] = 2;
d->arr[1][1] = 0;
d->arr[2][0] = 3;
d->arr[2][1] = 0;
}
d->_g2 = d->_pg1;
if (d->_g2) {
d->arr[0][0] = d->arr[0] + 1;
d->arr[2][0] = d->arr[2] + 1;
}
d->_g1 = d->_g0 || d->_g2;
}
Signals, as known from languages such as Esterel, are set to absent at the beginning of the tick. They can then be set to present during the current tick. Pure signals just know their activity state, whereas valued signals - in addition to their state also carry a value, which is persistent across ticks. If valued signals are emitted multiple times in the same tick, they require a combine function to merge the emitted values.
scchart Singals {
signal x
signal int y = 0 combine +
region {
initial state A
do x; y(3) go to B
final state B
}
region {
initial state A
if x do y(4) go to B
final state B
}
}
You can simply use JavaDoc-style comments to comment you SCChart. The comments will appear in the synthesized diagram as comment boxes. You can toggle these boxes in your sidebar.
Additionally, for documentation reason, you can annotate different elements to give them a user-defined style. E.g. colorize a state or comment box for visual effect. Please use a double @@ inside comments (to allow java doc etc). Use html-like color codes for different colors. Please read more on annotations in the section below.
/**
* Getting there!
*/
scchart Root {
/** Test */
input bool second
output bool speaker
/**
* Main region!
*/
region main:
/**
* The initial state
* This is entered as soon as the program starts.
*/
@foreground f0f024
@background ffffcc
@backgroundTarget fff9ba
initial state Superstate {
initial state R1
}
/** Transition */
/** Transition 2 */
join to S
/**
* The final state!
* @@foreground f00
* @@background a00
*/
final state S
}
Superstates model hierarchy. Each nested superstate creates a new scope. The syntax is easy: just start a new scope via curly brackets after your initial state declaration.
A superstate can be exited by any transition preemption type. However, especially the termination (or join) is of interest as it is taken as soon as the superstate finishes (meaning a final state is reached.)
Regions model concurrency. They follow the initialize-update-read protocol if scheduling between different regions becomes necessary.
A termination transition is taken if all regions of the superstate have reached a final state.
scchart superstates {
input bool F
initial state init {
initial state init
if F go to done
final state done
}
join to done
final state done
}
scchart concurrencies {
input bool E, F
initial state EF {
region handleF {
initial state init
if F go to done
final state done
}
region handleE {
initial state init
if E go to done
final state done
}
}
join to done
final state done
}
You can automatically duplicate regions and access a region counter variable.
scchart IIIRO {
input int I
input bool R
output bool O
initial state IIO {
entry do O = false
initial state II {
region main for i : 1 to 3 {
initial state IWait
if I == i go to IDone
final state IDone
}
}
do O = true join to Done
state Done
}
if R go to IIO
}
This is also possible for a complete array.
scchart IIIRO {
input int I
input bool R
output bool O
input bool ACTIVE[10]
initial state IIO {
entry do O = false
initial state II {
region for i : ACTIVE {
initial state IWait
if ACTIVE[i] go to IDone
final state IDone
}
}
do O = true join to Done
state Done
}
if Rgo to IIO
}
Complex Final states are final states that comprise inner behavior. Besides being a superstate, also actions and outgoing transitions count. Basically, any not simple final state without outgoing transitions is a complex final state.
Action in SCCharts are defined at the beginning of a state after the declarations.
scchart Actions {
input bool trigger
output int effect
initial state A
go to B
state B {
entry do effect = 0
entry if trigger do effect++
during if trigger do effect++
immediate during if trigger do effect++
exit if trigger do effect *= 10
initial state B1
if trigger go to B2
state B2
}
}
An entry action is executed immediately when its state is entered. If the optional trigger is specified the effect(s) will only be executed if the trigger condition is true.
A during action is executed in each tick its state is active except when the state is entered. If an immediate during is used the action is also executed in the tick the state is entered. If the optional trigger is specified the effect(s) will only be executed if the trigger condition is true.
An entry action is executed when its state is left. Exit actions are considered inner behavior and are consequently suppressed if the state is strongly aborted. If the optional trigger is specified the effect(s) will only be executed if the trigger condition is true.
Transitions and actions in the diagram can be replaced by user defined labels.
Displaying these label can be controlled by the 'User Labels' synthesis option.
scchart UserLabels {
output int O
initial state A {
entry do O = 1 label "Initialize O"
during do O++ label "Increment O"
exit do O = 0 label "Reset O"
} do print("Hello World") go to B label "Say Hello"
final state B
}
Suspend suppresses the inner behavior of a state, if is trigger is evaluated to true. If the immediate modifier is present the suspension can already be enabled in the tick the state is entered, otherwise the trigger is only checked in subsequent ticks. The weak modifier allows instantaneous inner behavior of a suspended state but the reached state is not memorized.
Weak suspend is not fully supported in 1.0 and may not be transformed or visualized (during simulation) correctly.
scchart Suspension {
input bool S1, S2, S3, S4
output int O = 0
suspend if S1
immediate suspend if S2
weak suspend if S3
immediate weak suspend if S3
initial state A
do O++ go to A
}
In Core SCCharts only simple transitions that originate from simple states and terminations for superstates are legit. However, there are more complex transition types if taking Extended SCCharts into account.
SCCharts knows two types of preemption: weak and strong aborts.
Semantically, a weak abort allows the behavior of the aborting superstate in the current tick to proceed before preemption, whereas strong aborts terminate the superstate immediately. In the diagram, strong aborts are depicted with a red circle decorator.
In a count delay transition, the transition trigger has to become true multiple times before firing.
If a superstate is entered via a shallow history transition, the superstate continues its execution in the state that was active when the superstate was left. The last active state is re-entered that means entry actions will be executed again. If this state is a superstate too, shallow history will not restore the last active state in deeper hierarchy levels.
With deep history transitions, the execution also recognizes deeper nesting levels, when re-entering the superstate.
If a deferred transition is taken, it preempts all immediate behavior in the target state, this includes entry actions.
History and deferred transitions are not fully supported in 1.0 and may result in unexpected behavior when combined. They may not be visualized correctly during simulation.
scchart Aborts {
input bool I, S, W, Imm
output int F = 0
initial state A {
initial state A0
immediate if I && Imm go to A1
if I go to A2
final state A1
final state A2
}
immediate if S && Imm do F = 1 abort to F1
if S do F = 2 abort to F2
immediate if W && Imm do F = 3 go to F3
if W do F = 5 go to F4
do F = 5 join to F5
final state F1
final state F2
final state F3
final state F4
final state F5
}
scchart ComplexTransitions {
input bool CD, SH, DH, D
output int F, F2
initial state A {
initial state Init
immediate do F = 0 go to Count
state Count {
during do F++
initial state Init
immediate do F2 = 0 go to Count2
state Count2 {
during do F2++
}
}
}
if 3 CD go to Wait
state Wait
if SH go to A shallow history
if DH go to A history
if D go to A deferred
go to A
}
We will use the beep.sctx as example for referenced SCCharts.
scchart Beep {
input bool second
output bool beep = false
initial state A
if second do beep = true go to B
state B
if second do beep = false go to A
}
If you want to use another SCChart inside your model, you must first include it with an import statement. For example, if you want to include beep into the comment example "root" from above, you can add import "beep" and include a state that references beep.
import "beep"
/**
* Getting there!
*/
scchart Root {
/** Test */
input bool second
output bool speaker
/**
* Main region!
*/
region main:
/**
* The initial state
* This is entered as soon as the program starts.
* @@foreground f0f024
* @@background ffffcc
* @@backgroundTarget fff9ba
*/
initial state R is Beep(second to second, speaker to beep)
/** Transition */
/** Transition 2 */
join to S
/**
* The final state!
* @@foreground f0f0240
* @@background ffc
*/
final state S
}
The keyword is indicates that R is a reference. When you are referencing, you have to bind the interface of the referenced SCChart model to variables of the actual on. You must do this in the parentheses after the referenced state. In the example second is bound to second, and the local speaker boolean is bound to the beep from beep's interface. You can read more about variable bindings in the next paragraph. Also, the content assist will help you with your bindings and inform you about missing bindings.
Example warnings from the content assist:
There are three different kinds of bindings: explicit bindings, order bindings, and implicit bindings. In the example we used explicit bindings, which are the safest way of bindings.
initial state R is Beep(second to second, speaker to beep)
They state explicitly which local variable gets bound to which remote. The content assist will help you with errors.
If you know the order of the variables (and/or listen to the content assist), you can also use order bindings and simply state the list of local variables.
initial state R is Beep(second, speaker)
They will be bound to the interface in the order of declaration in the remote SCChart. However, be aware of the fact that the bindings will change, when the declarations of the referenced SCChart change.
In the example, the names of the local and referenced second variables are identical. Hence, you can also omit the binding completely.
initial state R is Beep(speaker to beep)
SCCharts will then bind the variable implicitly. However, we also consider this kind of binding unsafe and the editor will warn you about any implicit bindings. They can be handy though when dealing with large interfaces.
As any state, referenced states are allowed to own transitions. However, if you are using terminations, you must make sure that the referenced SCChart terminates. Otherwise, the transition will never trigger. The content assist will help you with this issue.
Legacy
You do not need to activate the Xtext nature as in previous versions of SCCharts. In fact, we recommend to deactivate the Xtext nature for SCCharts projects.
KIELER is an open source software project by the RTSYS Group at Kiel University, licensed under the Eclipse Public License or Eclipse Public License 2.0 | KIELER Mailing List
- Basic Syntax
- Annotations and Pragmas
- Dataflow
- Hostcode
- Timed Automata
- Object Orientation
- LEGO Mindstorms
- Developer Eclipse Setup with Oomph
- Semantics Release Process
- Build KIELER without Eclipse
- Automated Tests and Benchmarks
- Simulation Visualization (KViz)
- Legacy .sct Models
- Simulation Visualization (KViz)
- KiCo Tutorial