.MACHINE -- Arbitrary State Machine

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.