8.1 The .blk file: blocks in depth
A .blk file represents one architectural block. One block per file is the most consequential structural decision in Sylang's architectural file types. Every block gets its own addressable file, and your directory layout becomes a literal map of the block decomposition. The per-block validator and renderer also get a unit of meaningful engineering scope to work on, with nothing tangled in.
Why one block per file
This convention breaks from SysML practice, where a single XMI file holds many blocks (and many other model elements) and loses meaningful addressability as a result. Sylang's convention has three practical benefits.
- Directory layout reflects decomposition. The project's
/PowerStage/directory containsEpbController.blk; the/Sensors/directory containsClampForceSensor.blkandMotorPositionSensor.blk. Anyone browsing the file system sees the architectural decomposition at once. In the SysML approach, directory layout has no relation to the model's content. - Git-level addressability. A pull request that changes one block touches one file. Reviewers see that block's changes in isolation, not tangled up with other blocks. Blame, log, and bisect all work cleanly against a single block's history. If you've ever tried to review a model change buried in one giant XMI diff, you'll feel the difference right away.
- Variant gating at file granularity. A block that exists only in some variants gates on when ref config at its hdef, and the whole file goes inactive in non-matching variants. Variant-aware coverage analysis then works at file granularity, which is conceptually simpler than gating inside a multi-block file.
The cost is file count. A program with 200 blocks has 200 .blk files, which is a real scaling concern in tools that struggle with many files (some IDEs, some build systems). In practice, the modern toolchain (git, ripgrep, VS Code-class editors, Sylang Studio) handles thousands of files without trouble, so the count is rarely the binding constraint.
File structure
A .blk file is more tightly constrained than other Sylang file types. The hdef block <Name> may contain only one kind of def: def characteristic, for AIAG-VDA product characteristics. Operations, signals, datatypes, and parameters belong in .ifc files, not in .blk. The constraint keeps the architectural unit (the block) separate from the interface definition (the operations and signals that flow between blocks).
use configset EpbConfig
use featureset EpbFeatures
use functionset EpbFunctions
use interfaceset EpbInterfaces
hdef block EpbController
name "Electric Parking Brake Controller (ECU)"
description "Real-time controller for the dual-motor EPB..."
owner "EPB Hardware Engineering"
level component
blocktype component
safetylevel ASIL-D
status approved
// Interface usage
needs ref signal RawSwitchInput, ShifterPosition, VehicleSpeed
provides ref signal MotorPwmCommand, EngageComplete
// Hierarchy and allocation
decomposesto ref block ClampForceMonitorUnit, MotorDriverUnit
implements ref function EngageController, ReleaseController
enables ref feature CoreEpb
// AIAG-VDA product characteristics
def characteristic EcuCanLatency
name "ECU CAN response latency"
chartype critical
unit "ms"
nominalvalue 5
upperlimit 10
...The header-level properties fall into four groups.
- Identity: name, description, designrationale, owner, tags.
- Classification: level (system through component to part); blocktype (object / objectelement / buildingblock / component / part); safetylevel; status.
- Mechanical and material properties: modelfile, mass, volume, centerofmass, materialname, density, youngsmodulus, poissonratio, yieldstrength, ultimatestrength. Use these for blocks that represent physical parts where mechanical analysis matters.
- Effort estimation: analysiseffort, deveffort, testeffort.
Note that blocktype is one of object, objectelement, buildingblock, component, part. It is not hardware, software, or hybrid, as some older Sylang documentation shows. The validator rejects those older values. The new vocabulary aligns with the SysML 2 block-type taxonomy, which fits modern systems-engineering practice better.
Relationship vocabulary
Six relationship keywords do most of the work in a .blk file.
- needs ref operation|signal|port: inputs the block consumes from other blocks through the interface set.
- provides ref operation|signal: outputs the block produces for other blocks.
- decomposesto / decomposedfrom ref block: the block hierarchy. They are bilateral inverses.
- implements ref function: the block realizes these functions. In
.blkfiles, implements can only target function. Elsewhere the more general implements can also target requirement, but here it is narrowed. - enables ref feature: the block helps realize these features. It is less common than the function side. You'll mostly see it on blocks with a strong feature-marketing identity, such as a Cleanroom-Certified Joint Assembly block in a cobot.
- derivedfrom / implementedby ref requirement: ASPICE bilateral traceability for the requirement-to-block link. It is common in projects assessed under ASPICE Level 3.
A handful of other relationships round out the vocabulary.
- allocatedto: used in some specialized blocks, typically physical-part blocks allocated to a parent assembly.
- requires ref parameter: declares that the block consumes parameters defined in the interface set.
- meets ref characteristic|safetygoal: states that the block satisfies an external characteristic or safety goal.
- verifiedby ref testcase: links block-level characteristics to their verification.
- when ref config: gates the entire block on a variant configuration.
AIAG-VDA characteristics inside blocks
The only def subtype allowed inside a .blk is def characteristic. In the AIAG-VDA FMEA sense, a characteristic is a measurable property of the block whose value is controlled during manufacture and verified during inspection. Take the EPB controller's EcuCanLatency characteristic. It says the ECU's CAN response latency must stay within 1 to 10 milliseconds, with a nominal of 5 ms, and manufacturing must verify each unit's latency against that.
Each def characteristic carries:
- Identity: name, description, owner.
- Classification: chartype, one of special, critical, significant (the AIAG-VDA characteristic types). chartype critical characteristics typically need 100% inspection; significant needs sample-based inspection; special needs both inspection and process-capability evidence.
- Quantification: unit, nominalvalue, upperlimit, lowerlimit, tolerance.
- Manufacturing control: controlmethod, measuringequipment, samplingplan, inspectionfrequency, documentreference.
- Traceability: derivedfrom ref requirement, verifiedby ref testcase, meets ref safetygoal.
Putting characteristics inside the block is a deliberate engineering choice. The block is the architectural unit; its characteristics are the manufacturing-quality contract for that unit. The same engineer typically owns both, so keeping them in one file simplifies the workflow. Characteristic data feeds the AIAG-VDA FMEA (Chapter 13) and the manufacturing control plan, a downstream artifact that Sylang doesn't model in its present scope.
What's next
Subchapter 8.2 covers the .ifc (interface set) file type: operations, signals, datatypes, parameters. It also covers the operation-versus-signal distinction, the most consequential modeling decision in the architectural file types. Subchapter 8.3 covers .smd (state machines), and Subchapter 8.4 covers .ucd (use cases) and .seq (sequence diagrams). Together, they give you the complete architectural vocabulary.
Exercises
8.2 The .ifc file: operations, signals, datatypes, parameters
An .ifc file specifies the interfaces that flow between blocks: operations, signals, datatypes, parameters. The most consequential decision you'll make in an .ifc file is whether to model an interaction as an operation or a signal. That distinction mirrors the AUTOSAR Classic RTE split between client-server (operations) and sender-receiver (signals). It also directly shapes the runtime behavior of the implementing software, so this subchapter gives it particular attention.
File structure
An .ifc file starts with use configset (typically) and use functionset (so function references resolve), followed by hdef interfaceset <Name> and its header properties. The body holds four def subtypes: def operation, def signal, def datatype, def parameter. They can appear in any order. By convention, operations come first, then signals, datatypes, and parameters.
use configset EpbConfig
use functionset EpbFunctions
hdef interfaceset EpbInterfaces
name "EPB Control Interfaces"
owner "EPB Software Engineering"
safetylevel ASIL-D
allocatedto ref block EpbController
def operation GetVehicleSpeed
name "Get vehicle speed (CAN broadcast)"
safetylevel ASIL-D
requires ref datatype Speed_kph
def signal MotorPwmCommand
name "Motor PWM command"
safetylevel ASIL-D
requires ref datatype PwmDutyCycle
def datatype Speed_kph
name "Vehicle speed in km/h"
def parameter EngageTimeoutMs
name "Engage timeout"
value 1500
unit "ms\The header property allocatedto ref block names the block that owns this interface set. Typically there is one .ifc per block: the block's external interface contract. Large blocks may have several .ifc files for different interface domains (control, diagnostics, calibration).
Operation vs signal: the canonical decision
Both def operation and def signal model communication between blocks. Choosing between them is the most consequential interface decision, because the choice constrains how the implementing software behaves at runtime.
- operation: a request / response (client / server) interaction. The caller invokes the operation, the implementer executes it, and control returns to the caller, optionally with a return value. Software typically realizes operations as function calls (in a single process) or as RPC calls (across process boundaries). In AUTOSAR Classic, operations correspond to
RTE_Call_<Op>communication, with explicit client and server runnables. - signal: a broadcast / subscribe (sender / receiver) interaction. The producer writes the signal; the value persists in shared storage until overwritten; consumers read it at their own cadence. Software typically realizes signals as shared variables (in a single process) or as bus messages (across process or bus boundaries). In AUTOSAR Classic, signals correspond to
RTE_Read_/Write_<Sig>communication.
Four operational characteristics should drive the choice.
- Synchrony. An operation is synchronous: the caller waits for the response. A signal is asynchronous: the producer writes and moves on, and the consumer reads at its own pace. Inter-ECU communication that must complete in bounded time suits operation semantics; inter-ECU communication that tolerates eventual consistency suits signal semantics.
- Cardinality. An operation typically has one server (the implementer) and many possible clients. A signal typically has one producer and many possible consumers, though multi-producer signals are also common where the implementation supports them. Cardinality is partly modeling discipline (one-to-one is typical for operations) and partly a runtime constraint: multi-producer signals need conflict-resolution semantics that not every runtime provides.
- Liveness. An operation has natural liveness: each call is a discrete event. A signal has continuous liveness: the value is always available, even if stale. Diagnostic queries, calibration writes, and state-machine triggers suit operation semantics; continuously changing telemetry (vehicle speed, joint position, glucose level) suits signal semantics.
- Failure mode. When an operation fails (server unreachable, timeout), the client sees it. When a signal fails (stale value, sensor drift), only whoever monitors the signal's freshness sees it; a consumer that just reads the latest value won't notice. That is why safety-critical designs often add explicit freshness or cross-check signals to catch signal failures.
Here are some common patterns. The EPB anchor's .ifc uses the conventional choice in each case, and so do the cobot, autopilot, and infusion pump anchors.
- GetVehicleSpeed (a query that returns a value) is naturally an operation.
- MotorPwmCommand (a continuously updated control output) is naturally a signal.
- ClampForceFault (an event-like flag) is naturally a signal.
- SetMotorPwm (a command from the controller to a downstream driver) is naturally an operation.
def datatype: payload specification
def datatype names a payload type that operations and signals carry. Datatypes have no required properties; a minimal one is just def datatype Speed_kph. By convention, though, you write a name (display name) and a description covering precision, range, units, and any encoding details a downstream developer needs.
Operations and signals reference datatypes through requires ref datatype <Name>. The validator checks that every datatype referenced from an operation or signal exists in the interface set; a missing one produces SYLANG_UNRESOLVED_REFERENCE. A common workflow is to write the operation or signal first, see the validator's complaint, and then add the missing datatype.
Reuse datatypes wherever you can. Speed_kph is the payload of both GetVehicleSpeed (an operation) and VehicleSpeed (a signal), and both reference the same datatype instead of duplicating it. That keeps the model coherent: change the datatype's precision once, and every interface using it picks up the change.
def parameter: tunable values
def parameter declares a tunable numeric value that the system's behavior depends on. Unlike datatypes, parameters carry a specific value (value 1500) and unit (unit "ms"). They typically represent thresholds, gains, time constants, and similar calibration-controllable quantities.
Blocks, functions, requirements, and tests reference parameters through requires ref parameter <Name>. The value is visible at the reference site, so a requirement that says "the EPB shall complete engagement within EngageTimeoutMs" makes it explicit and trackable. Calibration changes show up in version-control history at the parameter's definition. A reverse lookup of requires ref parameter gives you bilateral traceability to every consumer.
What's next
Subchapters 8.3 (state machines) and 8.4 (use cases and sequence diagrams) cover the behavioral file types that complement the structural ones from 8.1 and 8.2. Together, they give you the complete architectural vocabulary.
Exercises
8.3 The .smd file: state machines
A state machine specifies a block's operational lifecycle: the discrete modes it moves between, the conditions that trigger each transition, and the functions invoked along the way. The .smd file type encodes state machines in the conventional Mealy-style form, where transitions carry actions. It also supports hierarchical decomposition, so states can contain sub-states.
This subchapter covers the file's structure, and how to decide when a block's behavior belongs in a state machine rather than a sequence diagram or a use case (Subchapter 8.4).
File structure
An .smd file declares one state machine, owned by one block. The hdef often carries allocatedto ref block <Name> and sometimes implements ref requirement <Name>. The body contains two def subtypes: def state and def transition.
use functionset EpbFunctions
use block EpbController
hdef statemachine EpbStateMachine
name "EPB Operational State Machine"
owner "EPB Software Engineering"
safetylevel ASIL-D
allocatedto ref block EpbController
def state Released
name "Released"
initialstate true
def state Engaging
name "Engaging"
def state Engaged
name "Engaged"
def state Fault
name "Fault"
def state SafeStop
name "Safe Stop"
endstate true
def transition EngageRequested
from ref state Released
to ref state Engaging
condition "EngageRequest = 1 AND VehicleSpeed < 10 km/h"
call ref function EngageControllerdef state clauses carry very few properties. There's name (display), initialstate true on the single entry state, and endstate true on terminal states like the EPB's SafeStop. Optionally, a state carries implements ref requirement when its behavior directly satisfies a requirement.
def transition clauses are the substance of the state machine. Each one carries from ref state <Source>, to ref state <Target>, a condition, and an optional call ref function <Function> naming the function the transition invokes as it fires. The condition is a string describing the trigger predicate. The language treats it as opaque prose, not as a formal expression to evaluate.
When to use a state machine
Not every block benefits from a state machine, and the decision rule is practical. Model a block as a state machine when, and only when, three things hold. It has discrete operational modes; those modes change on identifiable trigger conditions; and its behavior differs materially from one mode to the next.
- Yes, model: The EPB's engage / release / hold / fault / safe-stop lifecycle. The autopilot's engaged / disengaged / armed-mode-pending / mode-active lifecycle. The infusion pump's idle / priming / delivering / paused / alarm lifecycle. The cobot's manual / programming / running / safe-stop lifecycle.
- No, don't model: A continuous-time controller (a PID loop), whose behavior is best described by transfer functions, not states. A purely combinational logic block (a multiplexer, a coordinate transform), whose output depends only on its inputs, with no internal state. A block whose state model would have hundreds of states with one transition per pair: that model would be unintelligible, and you need a different abstraction.
Some blocks show state-machine behavior in some aspects and continuous-control behavior in others. The convention is to put only the state-machine aspect in .smd, and to describe the continuous-control aspect in the requirement set and the block's description. The state machine captures the discrete mode changes; the continuous behavior is implementation that the state machine commands.
State machine vs sequence diagram
State machines (.smd) and sequence diagrams (.seq) both model behavior, but at different levels. A state machine shows one block's internal lifecycle: the modes it passes through over time. A sequence diagram shows interactions across several blocks: the messages two or more participants exchange over time. They complement each other, and many subsystems benefit from both.
The EPB anchor uses a state machine for the controller's operational lifecycle (the engage / release transitions). It uses a sequence diagram for the over-current detection scenario: the messages exchanged between EpbController, VehicleControlUnit, and GateDriver during a fault response. Together, the two give you a complete picture; either one alone would leave gaps.
What's next
Subchapter 8.4 covers the remaining two file types. .ucd (use case diagrams) models the actor-system interactions at the system boundary. .seq (sequence diagrams) models the message flow between blocks within a scenario.
Exercises
8.4 The .ucd and .seq files: use cases and sequence diagrams
Two file types complete the architectural behavioral set: .ucd (use case diagram) and .seq (sequence diagram). Both model interactions, but at different scopes. Use cases model the boundary between actors and the system; sequence diagrams model the message flow across several blocks within a scenario. This subchapter covers both compactly, then helps you choose among the three behavioral file types (state machine, use case, sequence diagram) for a given concern.
The .ucd file: use cases
A .ucd file models the system's actor-facing behavior at a level that suits stakeholder communication: product management, regulatory affairs, marketing, customer-facing documentation. Its audience is usually outside engineering. Its job is to show who interacts with the system and what they accomplish, not to specify the internal architecture.
A .ucd file declares two def subtypes: def actor for the external entities that interact with the system, and def usecase for the discrete user-facing interactions. Actors carry an actortype property: primary for the principal users, secondary for supporting external entities. Use cases carry from and to references and a connection property naming the relationship type (associated for actor-to-use-case, includes for use-case-to-use-case inclusion).
use functionset EpbFunctions
hdef usecaseset EpbUseCases
name "EPB Use Cases"
def actor Driver
name "Driver"
actortype primary
def actor ServiceTechnician
name "Service Technician"
actortype primary
def actor VehicleControlUnit
name "Vehicle Control Unit (VCU)"
actortype secondary
def usecase RequestEngagement
name "Driver requests EPB engagement"
from ref actor Driver
to ref function EngageController
connection associatedUse cases tend to be stakeholder-facing artifacts, produced fairly late in the systems-engineering cycle. Teams focused on internal architecture (.blk, .ifc) sometimes skip them entirely and absorb the boundary concerns into the requirements set. Programs with significant non-engineering review (product organizations, regulatory affairs, safety auditors) benefit from explicit use cases as a communication artifact.
The .seq file: sequence diagrams
A .seq file models the message flow across several blocks (or functions) over time during a specific scenario. Where a state machine shows one block's internal lifecycle, a sequence diagram shows the interactions among several. It is essential for understanding cross-block fault scenarios, complex coordination sequences, and protocol-level interactions where message order matters.
A .seq file declares three def subtypes. def block defines the participants, def sequence defines the individual message arrows, and def fragment adds optional grouping constructs (alt, else, parallel, loop) that structure the diagram.
use block EpbController, VehicleControlUnit
use operation SetMotorPwm
use signal MotorPwmCommand, OvercurrentFlag
hdef sequenceset OvercurrentResponse
name "Over-current Detection → Safe Stop"
safetylevel ASIL-D
def sequence S1_TorqueIn
from ref block VehicleControlUnit
to ref block EpbController
flow ref signal TorqueRequest
def sequence S2_PwmOut
from ref block EpbController
to ref block MotorDriver
flow ref signal MotorPwmCommand
def fragment OvercurrentBranch
name "Fault branch"
fragmenttype alt
condition "ClampForceFault = 1"
def sequence S3_FaultUp
from ref block EpbController
to ref block VehicleControlUnit
flow ref signal ClampForceFaultEach def sequence carries from ref block|function and to ref block|function: the source and destination lanes. It also carries either flow ref operation|signal (the message payload) or call ref function (when the arrow is a function invocation rather than a signal flow). Fragments carry fragmenttype alt|else|parallel|loop and a condition, a string describing the predicate or repetition count.
Choosing among state machines, use cases, and sequence diagrams
The three behavioral file types serve different purposes, and they often coexist in the same project. Here's how to choose:
- State machine (.smd): for one block's internal lifecycle. The focus is the discrete modes the block moves between. Write one
.smdfor each block with non-trivial state-machine behavior; a block may have at most one. - Sequence diagram (.seq): for cross-block message flow in a specific scenario. The focus is the order of messages across several participants. Write one
.seqper scenario you want to model explicitly. A project typically has several to dozens of.seqfiles, each covering one important scenario. - Use case (.ucd): for the external actor-system boundary. The focus is who interacts with the system from outside and what they accomplish. Write one
.ucdper stakeholder-facing system; its audience is typically non-engineering.
The four anchors mix them differently.
- EPB: a
.smd(the controller's operational lifecycle) and a.seq(the over-current scenario), but no.ucd. Its stakeholder-facing description lives in the product line metadata and the requirement rationale. - Cobot: a
.smd(the cobot's operational modes) and a.ucd(operator-cobot interactions). - Autopilot: mainly
.smd(engaged-mode transitions) and.seq(autoland scenario phases). - Infusion pump: all three, with
.smdfor delivery states,.seqfor the bolus-delivery scenario, and.ucdfor patient-clinician-pump interactions.
Closing Chapter 8
That completes the architectural file set. You've covered blocks (8.1), interfaces (8.2), state machines (8.3), and use cases and sequence diagrams (this subchapter). The chapter's worked anchor, the EPB's EpbController.blk, EpbInterfaces.ifc, and EpbStateMachine.smd files in the companion repository, shows the conventions at production scale. If you're learning the architectural vocabulary, start there.
Chapter 9 turns to requirements: the .req file type, which consumes the architecture and the function model and produces the bilateral traceability the safety standards require. It is anchored on the insulin pump, whose requirements set is the most safety-rich of the four anchors.
Exercises
Key takeaways
You’ve got this chapter if you remember:
- One block per file turns your directory tree into a map of the architecture and makes each block's history reviewable on its own.
- A
.blkmay contain only def characteristic; operations, signals, datatypes, and parameters live in.ifcfiles. - Choose operation or signal by synchrony, cardinality, liveness, and failure mode: request/response is an operation, broadcast/subscribe is a signal.
- Use
.smdfor one block's lifecycle,.seqfor cross-block messages in a scenario, and.ucdfor the external actor-system boundary.
Check yourself
Answer in your head first, then reveal.
1Why does
blocktype hardwarefail validation?blocktype must be one of object, objectelement, buildingblock, component, or part. The validator rejects older values like hardware, software, and hybrid with
SYLANG_INVALID_ENUM_VALUE.2Should MotorPwmCommand be an operation or a signal?
A signal. It is a continuously updated control output that consumers read at their own pace, not a request that waits for a response.
3A signal's sensor drifts. Who notices?
Only whoever monitors the signal's freshness; a consumer that just reads the latest value won't. That is why safety-critical designs often add freshness or cross-check signals.
4You want to show the messages between EpbController, VehicleControlUnit, and GateDriver during a fault response. Which file type do you use?
A
.seqsequence diagram, because it models cross-block message flow within a scenario.