Sinelabore Homepage

Generating C++ code from SysML v2 textual models#

SysML logo

SysML® v2 is a newer version of SysML that is more flexible and powerful. An important aspect is that it now allows to write textual models. This lowers the entry barrier to the model based system development a lot because no special tools are needed to write the models. E.g. a Visual Studio Code plugin is available to write SysML v2 models. The Sinelabore Code Generator supports code generation from SysML v2 models. In opposite to the current Sinelabore capabilites, the code generation also supports the generation of structural code and not just the generation of state machine code.

This means that also code for parts, interactions between parts and so forth is generated. This can be used to quickly generate mockups and simulations of an intended system.

To generate C++ code from a SysML model call the code generator with the command line flag -p Sysml2Text.

Visual Studio Code with SysML plugin

A fully functional example is available on our GitHub site.

Introduction#

The present version only supports a small subset of the powerful SysML v2 feature set. Over time more features might be added. Main goal of this first version of the SysML v2 backend is to support a relevant set of features to generate code for state machines and the interaction of statemachines between parts.

To execute the generated code a small header only runtime environment is provided. It contains some base classes and implements inter-part communication via ports and timeout handling. So just the minimum to execute a model.

In case a part contains a state machine the code generator also generates additional files for the state machine. This code follows the structure that is already used by the cppx backend.

  • Parts: Parts are the main building blocks of a system. They can contain other parts, attributes, a state machine, actions, enums, connections and ports. Parts are realized as C++ classes in the generated code. If a part contains other parts you are responsible to create them in the init method. Create a subclass of the part class and override the init method. Then call the base class init method. Example: part def P1{part p2:P3;}
  • Attributes Parts can have attributes. Attributes can have a base type and a default value. Attributes can contain other attributes. Attributes are translated to C++ member variables. Depending on the type of the attribute it is realized as a basic data type or a class. Example: attribute a:bool;
  • Enums: Basic enums with their enum values can be defined. Enums are directly translated to C++ enums in the generated code. Example: enum def Color{RED; GREEN; BLUE;}
  • Ports: Ports are the way to communication points between parts. The framework has some helper classes to realize ports. A port marked as in has a receive method, a port marked as out has a send method in the generated C++ code. Example: port def p {attribute x : Integer;}
  • Connections: Connections are the way to connect ports of parts in order to share data. Connections are realized as queues in the generated code. Only ports of the same type can be connected. One part must be marked as in, one as out. If you need bidirectional communication you can add two other ports in opposite direction. All attributes in a port share the same direction. Example: connect p1.sendPort to p2.recvPort;
  • State Machines: A part can have a state machine. State machines are not as expressive as in UML so far, but still powerful. With the help of a TimerManager class in the framework, timed transitions can be realized. Example: {state def sm { ... }}

In the sub-pages that describe the supported features of the code generator text references are made to: OMG Systems Modeling Language™ (SysML®), Version 2.0 Part 1: Language Specification. OMG Document Number: formal/2026-03-02 Date: March 2026, Standard document URL: https://www.omg.org/spec/SysML/2.0/

The following listing shows an example for a small traffic light control system model. It consists of three parts with some attributes and actions. The TrafficManagementCenter part represents a central control system that can control TrafficLightController parts connected via ports.

In this simple model the TrafficManagementCenter just enables a traffic light controllers to operate by sending a start event. The TrafficLightController then changes state from OutOfService to Operational and performs expected traffic light operations. In a real system this simulation is for sure much more complex. But the example is rich enough to show the available possibilities. The TrafficLightSystem part weaves together the TrafficManagementCenter and the TrafficLightController parts.

private import ScalarValues::*;

package TrafficLight {


    // definition of events to control motor
    enum def TRAFFICLIGHTCONTROLLERSM_EVENT_T {
        //@TrafficLightController
        evOperational;
        evError;
    }

    //@TrafficManagementCenter
    enum def TRAFFICMANAGEMENTCENTERSM_EVENT_T {
    }

    port def ControlPortData {
        attribute msg : TRAFFICLIGHTCONTROLLERSM_EVENT_T;
        attribute test:Integer;
    }

    part def Test{}

    // traffic management center
    part def TrafficManagementCenter{
        out port sendPort : ControlPortData;
        part test1 : Test;

        state def tmcStateMachine {
            entry; then PreOperational;

            state PreOperational;
            accept after 2[SI::second] do send new ControlPortData(TRAFFICLIGHTCONTROLLERSM_EVENT_T::evOperational,5) via sendPort then Operational;

            state Operational {

            }

        }
    }

    part def TrafficLightController{

        in port recvPort : ~ControlPortData;
        part test1 : Test;

        action def setRedLED{}
        action def resetRedLED{}
        action def setYellowLED{}
        action def resetYellowLED{}
        action def setGreenLED{}
        action def resetGreenLED{}
        action def setRedAndYellowLED{}
        action def resetRedAndYellowLED{}

        state def tlcStateMachine {
            ...
        }
    }
    // Main system composition
    part def TrafficLightSystem {
        doc /*
        * Main system that contains the parts
        */
        part tmc : TrafficManagementCenter;
        part tlc : TrafficLightController;

        // Connect the parts
        connect tmc.sendPort to tlc.recvPort;
    }
}

The SysML code generation is work in progress#

SysML v2 is a very rich model language. There are many features that are not yet supported by the code generator. The following list is not exhaustive but list some of the not supported features. Take a look at the code on GitHub to see what is used in the code generator and therefore supported.

  • Regions in state machines
  • Inner transitions
  • Attributes can’t be qualified by additional keywords like ordered or unique
  • Attributes can’t have multiplicity
  • Referencing, Subsetting, …
  • Additions features in enums beside basic definition
  • Other inter part communication features than ports and connections as shown above
  • The complete model must reside in a single file. It is not supported to split the model into multiple files.
  • SysML imports are ignored and no code is generated for them. But it still useful just to satisfy SysML v2 editors and get rid of error messages.
  • Many other features not shown in the example code.