FPGA washing machine controller
A 13-state finite-state machine controlling a full wash cycle on real FPGA hardware, with the entire program expressed as control-unit outputs.

- 13
- 27 (2,402 lines)
- 7
The problem
A washing machine’s control logic and its physical operations — filling, heating, spinning, draining — are two different concerns, and the easy way to build one is to let them tangle: sequencing logic creeping into the same modules that drive the motor and the valve. That’s fine for one wash program; it falls apart the moment the program needs to change.
The approach
A 13-state Moore FSM — S0_OFF through S12_CLEANUP — drives a datapath split across 27 VHDL files, about 2,400 lines, built as a two-person project with responsibilities shared across the FSM, the datapath, and the documentation. All sequencing lives in the control unit alone, expressed purely as its outputs; the datapath resources — timers, debouncers, frequency dividers, decoders — don’t know what phase they’re in, they just respond to enable and reset signals. Five factory wash programs, from a 30°C quick wash to a 90°C antiallergic cycle, sit in an 8×6-bit ROM alongside a fully manual mode toggled by a switch, and optional phases (prewash, extra rinse) branch the FSM only when a program actually calls for them.
What was hard
Two decisions we’re actually glad we made, both still visible as comments in the source rather than added after the fact for a write-up. First: an early version had a separate preview/configure state, until we noticed its outputs were identical to idle’s — a mode switch already reads program settings straight from hardware regardless of FSM state, so the extra state was dead weight, and removing it means one button press now goes directly from idle to preview instead of through an indistinguishable extra step. Second: the controller supports pausing mid-cycle by gating the heater and timers behind a pause flag — except the one-minute door-unlock timer after the final spin, which we deliberately left ungated. Pausing right at the end of a cycle still lets the door unlock on schedule; a paused machine was never supposed to mean a permanently locked door.
Result
A working wash cycle running on a Nexys A7-100T — five real factory programs plus manual configuration, the door interlocked to the running state, and a control/datapath split clean enough that changing the wash sequence means editing one file.