Skip to content

Fsm

fsm

Implementation of the FSM dialect by CIRCT

See external documentation.

FSM = Dialect('fsm', [MachineOp, OutputOp, StateOp, TransitionOp, UpdateOp, VariableOp, ReturnOp, TriggerOp, InstanceOp, HWInstanceOp], [InstanceType]) module-attribute

InstanceType dataclass

Bases: ParametrizedAttribute, TypeAttribute

Source code in xdsl/dialects/fsm.py
56
57
58
@irdl_attr_definition
class InstanceType(ParametrizedAttribute, TypeAttribute):
    name = "fsm.instancetype"

name = 'fsm.instancetype' class-attribute instance-attribute

MachineOp

Bases: IRDLOperation

Represents a finite-state machine, including a machine name, the type of machine state, and the types of inputs and outputs. This op also includes a $body region that contains internal variables and states.

Source code in xdsl/dialects/fsm.py
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@irdl_op_definition
class MachineOp(IRDLOperation):
    """
    Represents a finite-state machine, including a machine name,
    the type of machine state, and the types of inputs and outputs. This op also
    includes a `$body` region that contains internal variables and states.
    """

    name = "fsm.machine"

    body = region_def()

    sym_name = attr_def(SymbolNameConstraint())
    initialState = attr_def(StringAttr)
    function_type = attr_def(FunctionType)
    arg_attrs = opt_attr_def(ArrayAttr[DictionaryAttr])
    res_attrs = opt_attr_def(ArrayAttr[DictionaryAttr])
    arg_names = opt_attr_def(ArrayAttr[StringAttr])
    res_names = opt_attr_def(ArrayAttr[StringAttr])

    traits = traits_def(NoTerminator(), SymbolTable(), SymbolOpInterface())

    def __init__(
        self,
        sym_name: str,
        initial_state: str,
        function_type: FunctionType | tuple[Sequence[Attribute], Sequence[Attribute]],
        arg_attrs: ArrayAttr[DictionaryAttr] | None,
        res_attrs: ArrayAttr[DictionaryAttr] | None,
        arg_names: ArrayAttr[StringAttr] | None,
        res_names: ArrayAttr[StringAttr] | None,
        body: Region | type[Region.DEFAULT] = Region.DEFAULT,
    ):
        if isinstance(function_type, tuple):
            inputs, outputs = function_type
            function_type = FunctionType.from_lists(inputs, outputs)

        attributes: dict[str, Attribute | None] = {
            "sym_name": StringAttr(sym_name),
            "initialState": StringAttr(initial_state),
            "function_type": function_type,
            "arg_attrs": arg_attrs,
            "res_attrs": res_attrs,
            "arg_names": arg_names,
            "res_names": res_names,
        }
        if not isinstance(body, Region):
            body = Region(Block())

        super().__init__(attributes=attributes, regions=[body])

    def verify_(self):
        if not SymbolTable.lookup_symbol(self, self.initialState):
            raise VerifyException("Can not find initial state")
        if (self.arg_attrs is None) ^ (self.arg_names is None):
            raise VerifyException("arg_attrs must be consistent with arg_names")
        elif self.arg_attrs is not None and self.arg_names is not None:
            if len(self.arg_attrs) != len(self.arg_names):
                raise VerifyException(
                    "The number of arg_attrs and arg_names should be the same"
                )
        if (self.res_attrs is None) ^ (self.res_names is None):
            raise VerifyException("res_attrs must be consistent with res_names")
        elif self.res_attrs is not None and self.res_names is not None:
            if len(self.res_attrs) != len(self.res_names):
                raise VerifyException(
                    "The number of res_attrs and res_names should be the same"
                )

name = 'fsm.machine' class-attribute instance-attribute

body = region_def() class-attribute instance-attribute

sym_name = attr_def(SymbolNameConstraint()) class-attribute instance-attribute

initialState = attr_def(StringAttr) class-attribute instance-attribute

function_type = attr_def(FunctionType) class-attribute instance-attribute

arg_attrs = opt_attr_def(ArrayAttr[DictionaryAttr]) class-attribute instance-attribute

res_attrs = opt_attr_def(ArrayAttr[DictionaryAttr]) class-attribute instance-attribute

arg_names = opt_attr_def(ArrayAttr[StringAttr]) class-attribute instance-attribute

res_names = opt_attr_def(ArrayAttr[StringAttr]) class-attribute instance-attribute

traits = traits_def(NoTerminator(), SymbolTable(), SymbolOpInterface()) class-attribute instance-attribute

__init__(sym_name: str, initial_state: str, function_type: FunctionType | tuple[Sequence[Attribute], Sequence[Attribute]], arg_attrs: ArrayAttr[DictionaryAttr] | None, res_attrs: ArrayAttr[DictionaryAttr] | None, arg_names: ArrayAttr[StringAttr] | None, res_names: ArrayAttr[StringAttr] | None, body: Region | type[Region.DEFAULT] = Region.DEFAULT)

Source code in xdsl/dialects/fsm.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def __init__(
    self,
    sym_name: str,
    initial_state: str,
    function_type: FunctionType | tuple[Sequence[Attribute], Sequence[Attribute]],
    arg_attrs: ArrayAttr[DictionaryAttr] | None,
    res_attrs: ArrayAttr[DictionaryAttr] | None,
    arg_names: ArrayAttr[StringAttr] | None,
    res_names: ArrayAttr[StringAttr] | None,
    body: Region | type[Region.DEFAULT] = Region.DEFAULT,
):
    if isinstance(function_type, tuple):
        inputs, outputs = function_type
        function_type = FunctionType.from_lists(inputs, outputs)

    attributes: dict[str, Attribute | None] = {
        "sym_name": StringAttr(sym_name),
        "initialState": StringAttr(initial_state),
        "function_type": function_type,
        "arg_attrs": arg_attrs,
        "res_attrs": res_attrs,
        "arg_names": arg_names,
        "res_names": res_names,
    }
    if not isinstance(body, Region):
        body = Region(Block())

    super().__init__(attributes=attributes, regions=[body])

verify_()

Source code in xdsl/dialects/fsm.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def verify_(self):
    if not SymbolTable.lookup_symbol(self, self.initialState):
        raise VerifyException("Can not find initial state")
    if (self.arg_attrs is None) ^ (self.arg_names is None):
        raise VerifyException("arg_attrs must be consistent with arg_names")
    elif self.arg_attrs is not None and self.arg_names is not None:
        if len(self.arg_attrs) != len(self.arg_names):
            raise VerifyException(
                "The number of arg_attrs and arg_names should be the same"
            )
    if (self.res_attrs is None) ^ (self.res_names is None):
        raise VerifyException("res_attrs must be consistent with res_names")
    elif self.res_attrs is not None and self.res_names is not None:
        if len(self.res_attrs) != len(self.res_names):
            raise VerifyException(
                "The number of res_attrs and res_names should be the same"
            )

StateOp

Bases: IRDLOperation

Represents a state of a state machine. This op includes an $output region with an fsm.output as terminator to define the machine outputs under this state. This op also includes a transitions region that contains all the transitions of this state

Source code in xdsl/dialects/fsm.py
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
@irdl_op_definition
class StateOp(IRDLOperation):
    """
    Represents a state of a state machine. This op includes an
    `$output` region with an `fsm.output` as terminator to define the machine
    outputs under this state. This op also includes a `transitions` region that
    contains all the transitions of this state
    """

    name = "fsm.state"

    output = region_def()

    transitions = region_def()

    sym_name = attr_def(SymbolNameConstraint())

    traits = traits_def(NoTerminator(), SymbolOpInterface(), HasParent(MachineOp))

    def __init__(
        self,
        sym_name: str,
        output: Region | type[Region.DEFAULT] = Region.DEFAULT,
        transitions: Region | type[Region.DEFAULT] = Region.DEFAULT,
    ):
        attributes: dict[str, Attribute] = {
            "sym_name": StringAttr(sym_name),
        }
        if not isinstance(output, Region):
            output = Region(Block())
        if not isinstance(transitions, Region):
            transitions = Region(Block())
        super().__init__(
            attributes=attributes,
            regions=[output, transitions],
        )

    def verify_(self):
        parent = self.parent_op()
        assert isinstance(parent, MachineOp)
        if (
            parent.res_attrs is not None
            and len(parent.res_attrs) > 0
            and self.output.block.first_op is None
        ):
            raise VerifyException(
                "State must have a non-empty output region when the machine has results."
            )
        parent = parent.parent_op()

name = 'fsm.state' class-attribute instance-attribute

output = region_def() class-attribute instance-attribute

transitions = region_def() class-attribute instance-attribute

sym_name = attr_def(SymbolNameConstraint()) class-attribute instance-attribute

traits = traits_def(NoTerminator(), SymbolOpInterface(), HasParent(MachineOp)) class-attribute instance-attribute

__init__(sym_name: str, output: Region | type[Region.DEFAULT] = Region.DEFAULT, transitions: Region | type[Region.DEFAULT] = Region.DEFAULT)

Source code in xdsl/dialects/fsm.py
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def __init__(
    self,
    sym_name: str,
    output: Region | type[Region.DEFAULT] = Region.DEFAULT,
    transitions: Region | type[Region.DEFAULT] = Region.DEFAULT,
):
    attributes: dict[str, Attribute] = {
        "sym_name": StringAttr(sym_name),
    }
    if not isinstance(output, Region):
        output = Region(Block())
    if not isinstance(transitions, Region):
        transitions = Region(Block())
    super().__init__(
        attributes=attributes,
        regions=[output, transitions],
    )

verify_()

Source code in xdsl/dialects/fsm.py
168
169
170
171
172
173
174
175
176
177
178
179
def verify_(self):
    parent = self.parent_op()
    assert isinstance(parent, MachineOp)
    if (
        parent.res_attrs is not None
        and len(parent.res_attrs) > 0
        and self.output.block.first_op is None
    ):
        raise VerifyException(
            "State must have a non-empty output region when the machine has results."
        )
    parent = parent.parent_op()

OutputOp

Bases: IRDLOperation

Represents the outputs of a machine under a specific state. The types of $operands should be consistent with the output types of the state machine

Source code in xdsl/dialects/fsm.py
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
@irdl_op_definition
class OutputOp(IRDLOperation):
    """
    Represents the outputs of a machine under a specific state. The
    types of `$operands` should be consistent with the output types of the state
    machine
    """

    name = "fsm.output"

    operand = var_operand_def()

    traits = traits_def(IsTerminator(), HasParent(StateOp))

    def __init__(
        self,
        operand: Sequence[SSAValue | Operation],
    ):
        super().__init__(
            operands=[operand],
        )

    def verify_(self):
        parent = self.parent_op()
        assert isinstance(parent, StateOp)
        if parent.transitions == self.parent_region() and len(self.operands) > 0:
            raise VerifyException("Transition regions should not output any value")
        while (parent := parent.parent_op()) is not None:
            if isinstance(parent, MachineOp):
                if self.operand_types != parent.function_type.outputs.data:
                    raise VerifyException(
                        "OutputOp output type must be consistent with the machine "
                        + str(parent.sym_name)
                    )

name = 'fsm.output' class-attribute instance-attribute

operand = var_operand_def() class-attribute instance-attribute

traits = traits_def(IsTerminator(), HasParent(StateOp)) class-attribute instance-attribute

__init__(operand: Sequence[SSAValue | Operation])

Source code in xdsl/dialects/fsm.py
196
197
198
199
200
201
202
def __init__(
    self,
    operand: Sequence[SSAValue | Operation],
):
    super().__init__(
        operands=[operand],
    )

verify_()

Source code in xdsl/dialects/fsm.py
204
205
206
207
208
209
210
211
212
213
214
215
def verify_(self):
    parent = self.parent_op()
    assert isinstance(parent, StateOp)
    if parent.transitions == self.parent_region() and len(self.operands) > 0:
        raise VerifyException("Transition regions should not output any value")
    while (parent := parent.parent_op()) is not None:
        if isinstance(parent, MachineOp):
            if self.operand_types != parent.function_type.outputs.data:
                raise VerifyException(
                    "OutputOp output type must be consistent with the machine "
                    + str(parent.sym_name)
                )

TransitionOp

Bases: IRDLOperation

Represents a transition of a state with a symbol reference of the next state. This op includes an optional $guard region with an fsm.return as terminator that returns a Boolean value indicating the guard condition of this transition. This op also includes an optional $action region that represents the actions to be executed when this transition is taken

Source code in xdsl/dialects/fsm.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@irdl_op_definition
class TransitionOp(IRDLOperation):
    """
    Represents a transition of a state with a symbol reference
    of the next state. This op includes an optional `$guard` region with an `fsm.return`
    as terminator that returns a Boolean value indicating the guard condition of
    this transition. This op also includes an optional `$action` region that represents
    the actions to be executed when this transition is taken
    """

    name = "fsm.transition"

    guard = region_def()

    action = region_def()

    nextState = attr_def(FlatSymbolRefAttrConstr)

    traits = traits_def(NoTerminator(), HasParent(StateOp))

    def __init__(
        self,
        nextState: FlatSymbolRefAttr,
        guard: Region | type[Region.DEFAULT] = Region.DEFAULT,
        action: Region | type[Region.DEFAULT] = Region.DEFAULT,
    ):
        if isinstance(nextState, str):
            nextState = SymbolRefAttr(nextState)
        attributes: dict[str, Attribute] = {
            "nextState": nextState,
        }
        if not isinstance(action, Region):
            action = Region(Block())
        if not isinstance(guard, Region):
            guard = Region(Block())
        super().__init__(
            attributes=attributes,
            regions=[guard, action],
        )

    def verify_(self):
        if SymbolTable.lookup_symbol(self, self.nextState) is None or not isinstance(
            SymbolTable.lookup_symbol(self, self.nextState), StateOp
        ):
            raise VerifyException("Can not find next state")
        if self.guard.blocks and not isinstance(self.guard.block.last_op, ReturnOp):
            raise VerifyException("Guard region must terminate with ReturnOp")
        var = self.parent_op()
        assert isinstance(var, StateOp)
        if var.transitions != self.parent_region():
            raise VerifyException("Transition must be located in a transitions region")

name = 'fsm.transition' class-attribute instance-attribute

guard = region_def() class-attribute instance-attribute

action = region_def() class-attribute instance-attribute

nextState = attr_def(FlatSymbolRefAttrConstr) class-attribute instance-attribute

traits = traits_def(NoTerminator(), HasParent(StateOp)) class-attribute instance-attribute

__init__(nextState: FlatSymbolRefAttr, guard: Region | type[Region.DEFAULT] = Region.DEFAULT, action: Region | type[Region.DEFAULT] = Region.DEFAULT)

Source code in xdsl/dialects/fsm.py
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
def __init__(
    self,
    nextState: FlatSymbolRefAttr,
    guard: Region | type[Region.DEFAULT] = Region.DEFAULT,
    action: Region | type[Region.DEFAULT] = Region.DEFAULT,
):
    if isinstance(nextState, str):
        nextState = SymbolRefAttr(nextState)
    attributes: dict[str, Attribute] = {
        "nextState": nextState,
    }
    if not isinstance(action, Region):
        action = Region(Block())
    if not isinstance(guard, Region):
        guard = Region(Block())
    super().__init__(
        attributes=attributes,
        regions=[guard, action],
    )

verify_()

Source code in xdsl/dialects/fsm.py
258
259
260
261
262
263
264
265
266
267
268
def verify_(self):
    if SymbolTable.lookup_symbol(self, self.nextState) is None or not isinstance(
        SymbolTable.lookup_symbol(self, self.nextState), StateOp
    ):
        raise VerifyException("Can not find next state")
    if self.guard.blocks and not isinstance(self.guard.block.last_op, ReturnOp):
        raise VerifyException("Guard region must terminate with ReturnOp")
    var = self.parent_op()
    assert isinstance(var, StateOp)
    if var.transitions != self.parent_region():
        raise VerifyException("Transition must be located in a transitions region")

UpdateOp

Bases: IRDLOperation

Updates the $variable with the $value. The definition op of $variable should be an fsm.variable. This op should only appear in the action region of a transtion

Source code in xdsl/dialects/fsm.py
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@irdl_op_definition
class UpdateOp(IRDLOperation):
    """
    Updates the `$variable` with the `$value`. The definition op of
    `$variable` should be an `fsm.variable`. This op should *only* appear in the
    `action` region of a transtion
    """

    name = "fsm.update"

    variable = operand_def(Attribute)

    value = operand_def(Attribute)

    traits = traits_def(HasParent(TransitionOp))

    def __init__(
        self,
        variable: SSAValue | Operation,
        value: SSAValue | Operation,
    ):
        super().__init__(
            operands=[variable, value],
        )

    def verify_(self) -> None:
        if not isinstance(self.variable.owner, VariableOp):
            raise VerifyException("Destination is not a variable operation")

        parent = self.parent_op()
        assert isinstance(parent, TransitionOp)

        found = 0
        for op in parent.action.walk():
            if isinstance(op, UpdateOp) and op.variable == self.variable:
                found += 1
        if found == 0:
            raise VerifyException(
                "Update must only be located in the action region of a transition"
            )
        elif found > 1:
            raise VerifyException(
                "Multiple updates to the same variable within a single action region is disallowed"
            )

name = 'fsm.update' class-attribute instance-attribute

variable = operand_def(Attribute) class-attribute instance-attribute

value = operand_def(Attribute) class-attribute instance-attribute

traits = traits_def(HasParent(TransitionOp)) class-attribute instance-attribute

__init__(variable: SSAValue | Operation, value: SSAValue | Operation)

Source code in xdsl/dialects/fsm.py
287
288
289
290
291
292
293
294
def __init__(
    self,
    variable: SSAValue | Operation,
    value: SSAValue | Operation,
):
    super().__init__(
        operands=[variable, value],
    )

verify_() -> None

Source code in xdsl/dialects/fsm.py
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
def verify_(self) -> None:
    if not isinstance(self.variable.owner, VariableOp):
        raise VerifyException("Destination is not a variable operation")

    parent = self.parent_op()
    assert isinstance(parent, TransitionOp)

    found = 0
    for op in parent.action.walk():
        if isinstance(op, UpdateOp) and op.variable == self.variable:
            found += 1
    if found == 0:
        raise VerifyException(
            "Update must only be located in the action region of a transition"
        )
    elif found > 1:
        raise VerifyException(
            "Multiple updates to the same variable within a single action region is disallowed"
        )

VariableOp

Bases: IRDLOperation

Represents an internal variable in a state machine with an initialization value

Source code in xdsl/dialects/fsm.py
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
@irdl_op_definition
class VariableOp(IRDLOperation):
    """
    Represents an internal variable in a state machine with an
    initialization value
    """

    name = "fsm.variable"

    initValue = attr_def()
    name_var = opt_attr_def(StringAttr)

    result = var_result_def(Attribute)

    def __init__(
        self,
        initValue: Attribute,
        name_var: str | None,
        result: Sequence[Attribute],
    ):
        attributes: dict[str, Attribute] = {
            "initValue": initValue,
        }
        if name_var is not None:
            attributes["name_var"] = StringAttr(name_var)
        super().__init__(
            result_types=[result],
            attributes=attributes,
        )

name = 'fsm.variable' class-attribute instance-attribute

initValue = attr_def() class-attribute instance-attribute

name_var = opt_attr_def(StringAttr) class-attribute instance-attribute

result = var_result_def(Attribute) class-attribute instance-attribute

__init__(initValue: Attribute, name_var: str | None, result: Sequence[Attribute])

Source code in xdsl/dialects/fsm.py
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
def __init__(
    self,
    initValue: Attribute,
    name_var: str | None,
    result: Sequence[Attribute],
):
    attributes: dict[str, Attribute] = {
        "initValue": initValue,
    }
    if name_var is not None:
        attributes["name_var"] = StringAttr(name_var)
    super().__init__(
        result_types=[result],
        attributes=attributes,
    )

ReturnOp

Bases: IRDLOperation

Marks the end of a region of fsm.transition and return values if the parent region is a $guard region

Source code in xdsl/dialects/fsm.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
@irdl_op_definition
class ReturnOp(IRDLOperation):
    """
    Marks the end of a region of `fsm.transition` and return
    values if the parent region is a `$guard` region
    """

    name = "fsm.return"

    operand = opt_operand_def(signlessIntegerLike)

    traits = traits_def(IsTerminator(), HasParent(TransitionOp))

    def __init__(
        self,
        operand: SSAValue | Operation,
    ):
        super().__init__(
            operands=[operand],
        )

name = 'fsm.return' class-attribute instance-attribute

operand = opt_operand_def(signlessIntegerLike) class-attribute instance-attribute

traits = traits_def(IsTerminator(), HasParent(TransitionOp)) class-attribute instance-attribute

__init__(operand: SSAValue | Operation)

Source code in xdsl/dialects/fsm.py
361
362
363
364
365
366
367
def __init__(
    self,
    operand: SSAValue | Operation,
):
    super().__init__(
        operands=[operand],
    )

InstanceOp

Bases: IRDLOperation

Represents an instance of a state machine, including an instance name and a symbol reference of the machine

Source code in xdsl/dialects/fsm.py
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
@irdl_op_definition
class InstanceOp(IRDLOperation):
    """
    Represents an instance of a state machine, including an
    instance name and a symbol reference of the machine
    """

    name = "fsm.instance"

    sym_name = attr_def(SymbolNameConstraint())

    machine = attr_def(FlatSymbolRefAttrConstr)

    res = result_def(InstanceType)

    def __init__(
        self, sym_name: str, machine: FlatSymbolRefAttr, instance: InstanceType
    ):
        if isinstance(machine, str):
            machine = SymbolRefAttr(machine)
        attributes: dict[str, Attribute] = {
            "sym_name": StringAttr(sym_name),
            "machine": machine,
        }
        super().__init__(result_types=[instance], attributes=attributes)

    def verify_(self):
        if not isinstance(SymbolTable.lookup_symbol(self, self.machine), MachineOp):
            raise VerifyException("Machine definition does not exist")

    def getMachine(self) -> MachineOp | None:
        m = SymbolTable.lookup_symbol(self, self.machine)
        if isinstance(m, MachineOp):
            return m
        else:
            return None

name = 'fsm.instance' class-attribute instance-attribute

sym_name = attr_def(SymbolNameConstraint()) class-attribute instance-attribute

machine = attr_def(FlatSymbolRefAttrConstr) class-attribute instance-attribute

res = result_def(InstanceType) class-attribute instance-attribute

__init__(sym_name: str, machine: FlatSymbolRefAttr, instance: InstanceType)

Source code in xdsl/dialects/fsm.py
385
386
387
388
389
390
391
392
393
394
def __init__(
    self, sym_name: str, machine: FlatSymbolRefAttr, instance: InstanceType
):
    if isinstance(machine, str):
        machine = SymbolRefAttr(machine)
    attributes: dict[str, Attribute] = {
        "sym_name": StringAttr(sym_name),
        "machine": machine,
    }
    super().__init__(result_types=[instance], attributes=attributes)

verify_()

Source code in xdsl/dialects/fsm.py
396
397
398
def verify_(self):
    if not isinstance(SymbolTable.lookup_symbol(self, self.machine), MachineOp):
        raise VerifyException("Machine definition does not exist")

getMachine() -> MachineOp | None

Source code in xdsl/dialects/fsm.py
400
401
402
403
404
405
def getMachine(self) -> MachineOp | None:
    m = SymbolTable.lookup_symbol(self, self.machine)
    if isinstance(m, MachineOp):
        return m
    else:
        return None

TriggerOp

Bases: IRDLOperation

Triggers a state machine instance. The inputs and outputs are correponding to the inputs and outputs of the referenced machine of the instance

Source code in xdsl/dialects/fsm.py
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
@irdl_op_definition
class TriggerOp(IRDLOperation):
    """
    Triggers a state machine instance. The inputs and outputs are
    correponding to the inputs and outputs of the referenced machine of the
    instance
    """

    name = "fsm.trigger"

    inputs = var_operand_def()

    instance = operand_def(InstanceType)

    outputs = var_result_def()

    def __init__(
        self,
        inputs: Sequence[SSAValue | Operation],
        instance: SSAValue,
        outputs: Sequence[Attribute],
    ):
        super().__init__(
            operands=[inputs, instance],
            result_types=[outputs],
        )

    def verify_(self):
        if not isinstance(self.instance.owner, InstanceOp):
            raise VerifyException("The instance operand must be Instance")

        m = self.instance.owner.getMachine()

        if m is None:
            raise VerifyException("Machine definition does not exist.")

        if self.inputs.types != tuple(result for result in m.function_type.inputs):
            raise VerifyException(
                "TriggerOp input types must be consistent with the machine "
                + str(m.sym_name)
            )

        if self.outputs.types != tuple(result for result in m.function_type.outputs):
            raise VerifyException(
                "TriggerOp output types must be consistent with the machine "
                + str(m.sym_name)
            )

name = 'fsm.trigger' class-attribute instance-attribute

inputs = var_operand_def() class-attribute instance-attribute

instance = operand_def(InstanceType) class-attribute instance-attribute

outputs = var_result_def() class-attribute instance-attribute

__init__(inputs: Sequence[SSAValue | Operation], instance: SSAValue, outputs: Sequence[Attribute])

Source code in xdsl/dialects/fsm.py
424
425
426
427
428
429
430
431
432
433
def __init__(
    self,
    inputs: Sequence[SSAValue | Operation],
    instance: SSAValue,
    outputs: Sequence[Attribute],
):
    super().__init__(
        operands=[inputs, instance],
        result_types=[outputs],
    )

verify_()

Source code in xdsl/dialects/fsm.py
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
def verify_(self):
    if not isinstance(self.instance.owner, InstanceOp):
        raise VerifyException("The instance operand must be Instance")

    m = self.instance.owner.getMachine()

    if m is None:
        raise VerifyException("Machine definition does not exist.")

    if self.inputs.types != tuple(result for result in m.function_type.inputs):
        raise VerifyException(
            "TriggerOp input types must be consistent with the machine "
            + str(m.sym_name)
        )

    if self.outputs.types != tuple(result for result in m.function_type.outputs):
        raise VerifyException(
            "TriggerOp output types must be consistent with the machine "
            + str(m.sym_name)
        )

HWInstanceOp

Bases: IRDLOperation

Represents a hardware-style instance of a state machine, including an instance name and a symbol reference of the machine. The inputs and outputs are correponding to the inputs and outputs of the referenced machine.

Source code in xdsl/dialects/fsm.py
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
@irdl_op_definition
class HWInstanceOp(IRDLOperation):
    """
    Represents a hardware-style instance of a state machine,
    including an instance name and a symbol reference of the machine. The inputs
    and outputs are correponding to the inputs and outputs of the referenced
    machine.
    """

    name = "fsm.hw_instance"

    sym_name = attr_def(SymbolNameConstraint())
    machine = attr_def(FlatSymbolRefAttrConstr)
    inputs = var_operand_def()
    clock = operand_def(signlessIntegerLike)
    reset = operand_def(signlessIntegerLike)

    outputs = var_result_def()

    def __init__(
        self,
        sym_name: str | StringAttr,
        machine: str | FlatSymbolRefAttr,
        inputs: Sequence[SSAValue | Operation],
        clock: SSAValue | Operation,
        reset: SSAValue | Operation,
        outputs: Sequence[Attribute],
    ):
        if isinstance(machine, str):
            machine = SymbolRefAttr(machine)
        clock = SSAValue.get(clock)
        reset = SSAValue.get(reset)
        if isinstance(sym_name, str):
            sym_name = StringAttr(sym_name)
        attributes: dict[str, Attribute] = {
            "sym_name": sym_name,
            "machine": machine,
        }
        super().__init__(
            operands=[inputs, clock, reset],
            result_types=[outputs],
            attributes=attributes,
        )

    def verify_(self):
        m = SymbolTable.lookup_symbol(self, self.machine)
        if isinstance(m, MachineOp):
            if self.inputs.types != tuple(result for result in m.function_type.inputs):
                raise VerifyException(
                    "HWInstanceOp "
                    + str(self.sym_name)
                    + " input type must be consistent with the machine "
                    + str(m.sym_name)
                )
            if self.outputs.types != tuple(
                result for result in m.function_type.outputs
            ):
                raise VerifyException(
                    "HWInstanceOp "
                    + str(self.sym_name)
                    + " output type must be consistent with the machine "
                    + str(m.sym_name)
                )
        else:
            raise VerifyException("Machine definition does not exist")

name = 'fsm.hw_instance' class-attribute instance-attribute

sym_name = attr_def(SymbolNameConstraint()) class-attribute instance-attribute

machine = attr_def(FlatSymbolRefAttrConstr) class-attribute instance-attribute

inputs = var_operand_def() class-attribute instance-attribute

clock = operand_def(signlessIntegerLike) class-attribute instance-attribute

reset = operand_def(signlessIntegerLike) class-attribute instance-attribute

outputs = var_result_def() class-attribute instance-attribute

__init__(sym_name: str | StringAttr, machine: str | FlatSymbolRefAttr, inputs: Sequence[SSAValue | Operation], clock: SSAValue | Operation, reset: SSAValue | Operation, outputs: Sequence[Attribute])

Source code in xdsl/dialects/fsm.py
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
def __init__(
    self,
    sym_name: str | StringAttr,
    machine: str | FlatSymbolRefAttr,
    inputs: Sequence[SSAValue | Operation],
    clock: SSAValue | Operation,
    reset: SSAValue | Operation,
    outputs: Sequence[Attribute],
):
    if isinstance(machine, str):
        machine = SymbolRefAttr(machine)
    clock = SSAValue.get(clock)
    reset = SSAValue.get(reset)
    if isinstance(sym_name, str):
        sym_name = StringAttr(sym_name)
    attributes: dict[str, Attribute] = {
        "sym_name": sym_name,
        "machine": machine,
    }
    super().__init__(
        operands=[inputs, clock, reset],
        result_types=[outputs],
        attributes=attributes,
    )

verify_()

Source code in xdsl/dialects/fsm.py
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
def verify_(self):
    m = SymbolTable.lookup_symbol(self, self.machine)
    if isinstance(m, MachineOp):
        if self.inputs.types != tuple(result for result in m.function_type.inputs):
            raise VerifyException(
                "HWInstanceOp "
                + str(self.sym_name)
                + " input type must be consistent with the machine "
                + str(m.sym_name)
            )
        if self.outputs.types != tuple(
            result for result in m.function_type.outputs
        ):
            raise VerifyException(
                "HWInstanceOp "
                + str(self.sym_name)
                + " output type must be consistent with the machine "
                + str(m.sym_name)
            )
    else:
        raise VerifyException("Machine definition does not exist")