LTspice XVII includes an arbitrary state machine and introduces a new programming language called Contraption Programming Language. There are five new commands:
.mach[ine] [<tripdt>] ; tripdt is an optional temporal tolerance
.state <name> <value>
.rule <old state> <new state> <condition>
.output (node) <expression>
.endmach[ine] ; end of block
The order of statements between the .mach and .endmach statements makes no difference as is common in a declarative language(vs a procedural language like C), 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 combine combinatorial logic and/or state.
The simplest example of a 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
.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
.endmachine
.tran 30m
.end
Note: Current monitoring is not implemented. If a state machine output is connected to a pin, current monitoring for the pin will not be correct.