.MACHINE — Arbitrary State Machine

LTspice includes an arbitrary state machine with five commands:

.mach[ine] [<tripdt>] ; tripdt is an optional temporal tolerance
.state <name> <value>
.rule <old state> <new state> <condition>
.output (posnode [, negnode]) <expression>
.endmach[ine] ; end of block

The order of statements between the .mach and .endmach statements is irrelevant, with the exception that the first state declared is the initial state and the rules are checked in order.

The point to assigning a value to a state is so that it can be mentioned in the expression of an output.

There can be as many or few rules as you wish. If the machine is in <old state> and the expression of < condition> evaluates to something larger that .5, the machine advances to <new state>. Only one rule executes per timestep. The character '*' as the value of <old state> matches any state. Such rules are checked first.

The .output statements implement current sources that require external devices to readout the current. As shown in the examples below, 1K ground-referenced resistors are normally used, but you might want to add some parallel capacitance to ground to slow transitions. The <expression> can be an arbitrary mathematical expression. This expression recognizes the special name "state", which represents the value of the current state. It also recognizes the names of all defined states, which represent their corresponding numerical values.

The simplest example of an Arbitrary State Machine would be one with no states. This is an example of an inverter:

* inverter state machine example
V1 1 0 pulse(0 1 0 1u 1u .5m 1m)
R1 2 0 1K ; an impedance for the .output statement
.machine
.output (2) V(1) < .5
.endmachine
.tran 3m
.end

Here is an example of a divide by 2 with a reset:

* divide by 2 example
V1 1 0 pulse(0 1 0 1u 1u .5m 1m)
V2 c 0 pulse(0 1 0 1u 1u 5m 10m)
R1 2 0 1K
R2 3 0 1K
R3 4 0 1K
R4 5 0 1K
.machine
.state S0a 0
.state S0b 0
.state S1a 1
.state S1b 1
.rule S0a S0b V(1) < .5
.rule S0b S1a V(1) > .5
.rule S1a S1b V(1) < .5
.rule S1b S0a V(1) > .5
.rule * S0a V(c) > .5
.output (2) V(1) < .5
.output (3) V(1) > .5
.output (4) state
.output (5) state==S1a
.endmachine
.tran 30m
.end