State Encoding: Binary, Gray, One-Hot and More
Since Volume 03 you have been choosing bit patterns for your states. That choice is called the state encoding, and it matters more than it looks. This volume codes one washing machine five ways, weighs each in flip-flops, logic, speed and power, and shows what the synthesis tool does with your choice.
- Binary and Gray codes, and why the number of bits that change matters
- One-hot encoding, and why FPGA tools like it so much
- Johnson codes, and output-coded states that need no output logic
- How to weigh area, speed and power when you choose
- What synthesis does to your encoding, and how to control it
5.1 Binary and Gray encoding
Binary encoding numbers the states and uses the fewest flip-flops. Gray encoding orders the codes so that each usual step changes only one bit.
One machine for the whole volume
To compare encodings fairly, we will encode the same machine every time. It is a simple washing machine with five states:
Each arrow is labelled with the input that must be 1 to take it. The label "else" on a loop means "when that input is 0, stay". The machine has three outputs:
- valve lets water in. It is on in FILL.
- motor turns the drum. It is on in WASH and in SPIN.
- pump pumps water out. It is on in DRAIN and in SPIN.
Binary encoding
The simplest choice is to number the states in order - 0, 1, 2, 3, 4 - and write each number in binary. This is binary encoding. Five states need three flip-flops, because 23 = 8 is the first power of two that is at least 5.
| State | Binary code |
|---|---|
| IDLE | 000 |
| FILL | 001 |
| WASH | 010 |
| DRAIN | 011 |
| SPIN | 100 |
Now count how many bits change on each step around the machine. The number of bit positions in which two codes differ is called their Hamming distance:
| Step | Binary codes | Bits that change |
|---|---|---|
| IDLE to FILL | 000 to 001 | 1 |
| FILL to WASH | 001 to 010 | 2 |
| WASH to DRAIN | 010 to 011 | 1 |
| DRAIN to SPIN | 011 to 100 | 3 |
| SPIN to IDLE | 100 to 000 | 1 |
Why the number of changing bits matters
On the step from DRAIN to SPIN, all three flip-flops change at once. In theory they change at the same instant. In a real chip, one is always a little faster than another. For a split second the state register may hold 111, or 000, or 101 - codes that are not the state you want. Anything decoded from those bits can glitch for that moment. Also, every bit that flips uses a little energy. More flips mean more power.
Gray encoding
Gray encoding chooses the codes so that each usual step changes only one bit - the same idea as the Gray-code order of a K-map in Volume 03:
| State | Gray code | Bits that change on the next step |
|---|---|---|
| IDLE | 000 | 1 (to 001) |
| FILL | 001 | 1 (to 011) |
| WASH | 011 | 1 (to 010) |
| DRAIN | 010 | 1 (to 110) |
| SPIN | 110 | 2 (back to 000) |
Four of the five steps now change a single bit. The step from SPIN back to IDLE still changes two. That is not bad luck, as the box below explains.
Going deeper: why a loop of five cannot be all one-bit steps
Follow any single bit around the loop and back to where it started. It must end with the value it began with, so it must flip an even number of times. Add up the flips of all the bits, and the total around the loop is even. A loop of 5 steps with one flip per step would total 5 - an odd number. So at least one step must flip more than one bit. A loop of 4, 6 or 8 states can be all one-bit steps; a loop of 3, 5 or 7 cannot.
Binary is the most compact code. Gray costs no extra flip-flops, but moves more gently: one bit at a time along the machine's usual path.
Gray encoding is not always better. It helps only when the machine mostly walks in a fixed order, like a counter. A machine with many branches - where one state can go to four others - cannot make every step a one-bit step, and the gain shrinks.
With binary encoding, a machine steps from state 3 (011) to state 4 (100). How many flip-flops change?
Show the answer
Answer: C. Compare 011 with 100 bit by bit: all three positions differ. So all three flip-flops change on this step - the worst case for glitches and power.
5.2 One-hot and one-cold
One-hot encoding uses one flip-flop per state, with exactly one of them at 1. The state is simply "whichever flip-flop is hot".
One flip-flop per state
In one-hot encoding, every state gets its own flip-flop. At any moment, exactly one flip-flop holds 1 - it is "hot" - and all the others hold 0. You met this code already: the Medvedev traffic light in Volume 02 was one-hot.
| State | One-hot code (SPIN DRAIN WASH FILL IDLE) |
|---|---|
| IDLE | 00001 |
| FILL | 00010 |
| WASH | 00100 |
| DRAIN | 01000 |
| SPIN | 10000 |
Five states now need five flip-flops instead of three. What do we get for the extra two?
Decoding is free
To ask "is the machine in WASH?" with binary codes, you need a gate that checks all three bits: Q2'·Q1·Q0'. With one-hot, you just read the WASH flip-flop. No gates at all. The outputs become very simple:
- valve = FILL
- motor = WASH + SPIN
- pump = DRAIN + SPIN
Next-state logic you can read off the diagram
One-hot next-state logic follows one rule, and needs no K-maps:
For each state, OR together one term for every arrow that enters it. Each term is: the state the arrow comes from, AND the arrow's condition. Do not forget the self-loop.
Apply the rule to the washing machine:
| Flip-flop | Arrows into it | Next value |
|---|---|---|
| IDLE | stay while start = 0; from SPIN when done | IDLE·start' + SPIN·done |
| FILL | from IDLE when start; stay while full = 0 | IDLE·start + FILL·full' |
| WASH | from FILL when full; stay while done = 0 | FILL·full + WASH·done' |
| DRAIN | from WASH when done; stay while empty = 0 | WASH·done + DRAIN·empty' |
| SPIN | from DRAIN when empty; stay while done = 0 | DRAIN·empty + SPIN·done' |
Here, each flip-flop's logic looks at only two state bits and one input. In any one-hot machine, a flip-flop's logic grows only with the number of arrows into its own state - not with the size of the whole machine. In Verilog, you can write it exactly like that:
// one flip-flop per state: s[0]=IDLE s[1]=FILL s[2]=WASH s[3]=DRAIN s[4]=SPIN
reg [4:0] s;
always @(posedge clk)
if (rst) s <= 5'b00001; // start with IDLE hot
else begin
s[0] <= (s[0] & ~start) | (s[4] & done); // IDLE
s[1] <= (s[0] & start) | (s[1] & ~full); // FILL
s[2] <= (s[1] & full ) | (s[2] & ~done); // WASH
s[3] <= (s[2] & done ) | (s[3] & ~empty); // DRAIN
s[4] <= (s[3] & empty) | (s[4] & ~done); // SPIN
end
assign valve = s[1];
assign motor = s[2] | s[4];
assign pump = s[3] | s[4];
You will rarely write one-hot by hand like this - sub-module 5.5 shows that the tool can do it for you. But writing it once makes clear why one-hot logic is so small.
The price: many illegal codes
Five flip-flops can hold 25 = 32 codes. Only 5 of them are real states. The other 27 are illegal states - for example 00110, where WASH and FILL are both hot, and the machine seems to be in two states at once. A correct one-hot machine never reaches them, but a glitch or a radiation hit could put it there. Volume 11 deals with that.
One-cold
One-cold encoding is the mirror image: one flip-flop per state, with exactly one of them at 0. It is rare, but it can suit outputs that are active low. Everything said about one-hot applies to it, turned upside down.
Do not start a one-hot machine with all flip-flops at 0. The all-zero code is not a state, so the
machine has no hot state and nothing will ever become hot. The reset must set exactly one flip-flop
to 1 - here, s <= 5'b00001.
A one-hot machine has states A, B and C. B is entered from A when x = 1, and B stays in B while y = 0. What is the next value of the B flip-flop?
Show the answer
Answer: B. List the arrows into B: one from A with condition x, and the self-loop on B with condition y'. OR the two terms together: A·x + B·y'.
5.3 Johnson and custom encodings
A Johnson code moves through its states by shifting in the opposite of its last bit. An output-coded machine chooses its codes so that the outputs are the state bits themselves.
The Johnson code
Take three flip-flops in a row. On every step, shift the bits one place to the left, and feed the opposite of the leftmost bit into the right-hand end. Starting from 000:
| Step | Code | What happened |
|---|---|---|
| 0 | 000 | start |
| 1 | 001 | shifted in a 1 (the opposite of the leftmost 0) |
| 2 | 011 | shifted in a 1 |
| 3 | 111 | shifted in a 1 |
| 4 | 110 | shifted in a 0 (the opposite of the leftmost 1) |
| 5 | 100 | shifted in a 0 |
| 6 | 000 | back to the start |
This is a Johnson code. Three flip-flops give six states, and every step changes exactly one bit - including the step from the last state back to the first. In general, n flip-flops give 2n states. That is fewer than binary gives (2n), but more than one-hot gives (n).
A Johnson code has one more gift: any state can be recognised from just two neighbouring bits. For example, 011 is the only code whose left bit is 0 and whose middle bit is 1. So each state needs only one 2-input gate to decode, however many flip-flops there are. Johnson counters come back in Volume 07.
For the five-state washing machine, a 3-bit Johnson code gives IDLE = 000, FILL = 001, WASH = 011, DRAIN = 111, SPIN = 110. The step from SPIN back to IDLE skips the sixth code, 100, and so changes two bits.
Output encoding: make the outputs the state
Now look at the washing machine's outputs in each state:
| State | valve | motor | pump |
|---|---|---|---|
| IDLE | 0 | 0 | 0 |
| FILL | 1 | 0 | 0 |
| WASH | 0 | 1 | 0 |
| DRAIN | 0 | 0 | 1 |
| SPIN | 0 | 1 | 1 |
Every row is different. So use each row as the state code: IDLE = 000, FILL = 100, WASH = 010, DRAIN = 001, SPIN = 011, with the bits in the order valve, motor, pump. This is output encoding. The state register now drives the valve, the motor and the pump directly. There is no output logic, and the outputs can never glitch. It is the Medvedev machine from Volume 02, built on purpose.
If two states have the same outputs, their rows are equal, and they cannot share a code. Add an extra bit - used only to tell those states apart - and the idea still works.
Output encoding ties the codes to the outputs. If someone later changes an output - "turn the pump on in WASH too" - the codes change, and the next-state logic changes with them. Choose it for outputs that are fixed and important, not for every machine.
How many states can a Johnson counter with 4 flip-flops step through?
Show the answer
Answer: D. A Johnson code gives 2n states for n flip-flops: 2 × 4 = 8. It shifts four 1s in, one at a time, and then four 0s in: 0000, 0001, 0011, 0111, 1111, 1110, 1100, 1000.
5.4 Area, speed and power trade-offs
Choosing an encoding trades flip-flops against logic. Fewer flip-flops usually means more complicated logic; more flip-flops usually means simpler, faster logic.
Here is the washing machine in every encoding from this volume:
| State | Binary | Gray | One-hot | Johnson | Output-coded |
|---|---|---|---|---|---|
| IDLE | 000 | 000 | 00001 | 000 | 000 |
| FILL | 001 | 001 | 00010 | 001 | 100 |
| WASH | 010 | 011 | 00100 | 011 | 010 |
| DRAIN | 011 | 010 | 01000 | 111 | 001 |
| SPIN | 100 | 110 | 10000 | 110 | 011 |
Area
Area means how much of the chip the machine uses: flip-flops plus gates.
- Binary and Gray use the fewest flip-flops, ⌈log2N⌉. But each next-state bit may depend on every state bit, so the gates grow as the machine grows.
- One-hot uses N flip-flops. Its gates stay small, because each flip-flop's logic only looks at the states with arrows into it.
- Johnson sits between the two: about N/2 flip-flops, and simple decoding.
Speed
The fastest clock a circuit can use is set by its slowest path of logic between two flip-flops - its critical path. In a state machine, that path usually runs through the next-state logic. One-hot keeps that logic shallow - two or three gates - so one-hot machines usually run fastest. Binary logic that must look at every state bit is deeper, and slower. Volume 13 measures this properly.
Power
Power in a digital circuit comes mostly from signals changing. How often they change is called their switching activity. Count the flip-flops that change per step around the washing machine:
| Encoding | Bits changed over one full wash | Flip-flops |
|---|---|---|
| Binary | 1 + 2 + 1 + 3 + 1 = 8 | 3 |
| Gray | 1 + 1 + 1 + 1 + 2 = 6 | 3 |
| Johnson | 1 + 1 + 1 + 1 + 2 = 6 | 3 |
| One-hot | 2 + 2 + 2 + 2 + 2 = 10 | 5 |
One-hot changes the most flip-flops - two on every step, one off and one on - but its small logic switches less. Gray and Johnson change the fewest bits. The real winner depends on the whole design, and is found by measuring, not guessing.
The summary
| Encoding | Flip-flops for N states | Bits changed per step | Decoding a state | Unused codes when N = 5 | Typical use |
|---|---|---|---|---|---|
| Binary | ⌈log2N⌉ | varies, up to all | gates on every bit | 3 | small machines on chips (ASICs) |
| Gray | ⌈log2N⌉ | usually 1 | gates on every bit | 3 | counters, low power, state read by another clock |
| One-hot | N | 2 | one bit, no gates | 27 | FPGAs and fast machines |
| Johnson | ⌈N/2⌉ | 1 | one 2-input gate | 3 | counters and sequencers |
| Output-coded | at least the number of outputs | depends | none for the outputs | depends | outputs that must never glitch |
On FPGAs, flip-flops are plentiful - there is one in every logic cell - so one-hot is usually the best choice. On ASICs, a flip-flop costs several gates' worth of area, so small machines often use binary or Gray.
Do not spend hours choosing an encoding by hand before you have measured anything. For most machines, the synthesis tool picks a good encoding by itself - the next sub-module. Hand-picking matters for the special cases: glitch-free outputs, very low power, or state that another clock domain reads.
A state machine on an FPGA fails to reach the clock speed you need. Which encoding is most likely to help?
Show the answer
Answer: A. Speed is set by the deepest logic between flip-flops. One-hot next-state logic looks at only a few bits, so it is shallow, and FPGAs have flip-flops to spare. Using fewer flip-flops, as binary does, usually makes the logic deeper, not shallower.
5.5 What synthesis tools do to your encoding
Synthesis tools usually recognise state machines and may give them new codes. The codes you wrote are not always the codes in the hardware.
The tool finds your state machine
When you write a state machine in the style of Volume 04, synthesis tools such as Vivado recognise
it. They notice a register whose next value is chosen by a case statement on its own current
value. This is called FSM extraction. The tool then works out the
states and the arrows - and often re-encodes the machine. On FPGAs it usually picks one-hot,
for the reasons in sub-module 5.4. The synthesis log reports each state with its old and its new
code.
So you can write your states with any names and codes you like, and still get one-hot hardware. For most machines, that is good news.
When re-encoding is a problem
Sometimes you need the codes you wrote:
- Output-coded machines. The outputs are the state bits. Re-encoding would break them.
- State read from outside. Another block, a debug probe, or software may read the state register and expect your codes.
- Safe machines. Recovery from illegal states can be removed during re-encoding - Volume 11.
- Debugging on hardware. You probe the state register and see values you never wrote, because the tool changed them.
Telling the tool what you want
You control the choice with a tool setting, or with a
synthesis attribute - a note in the code that the tool reads.
In Vivado, the attribute is fsm_encoding:
(* fsm_encoding = "one_hot" *) reg [2:0] state; // make it one-hot
(* fsm_encoding = "gray" *) reg [2:0] state; // or Gray
(* fsm_encoding = "none" *) reg [2:0] state; // keep exactly the codes I wrote
Vivado also accepts "sequential" (binary), "johnson" and "auto", and it has a project-wide setting for the same choice. Other tools have their own names for it, so check the tool's documentation. For more about attributes, see synthesis attributes in the FPGA course.
"I probed the state register on the board and it shows 01000, but my codes are 0 to 4 - the chip
is broken." It is almost certainly not broken. The tool re-encoded the machine as one-hot. Check
the synthesis log, or keep your encoding with fsm_encoding = "none" while you debug.
Your state machine drives three outputs straight from its state bits (output encoding). What should you tell the synthesis tool?
Show the answer
Answer: C. The outputs only work if the state bits hold exactly your codes. If the tool re-encodes the machine, the outputs are wrong. So tell it to keep the encoding you wrote.
What you learned
- Binary uses the fewest flip-flops, but some steps change many bits at once.
- Gray codes change one bit on each usual step - though a loop of an odd number of states cannot be all one-bit steps.
- One-hot uses one flip-flop per state. Decoding is free, and the next-state logic can be read straight off the diagram.
- A Johnson code gives 2n states from n flip-flops, changes one bit per step, and decodes any state with a 2-input gate.
- Output encoding makes the outputs the state bits: no output logic, no glitches.
- Fewer flip-flops usually means deeper logic; one-hot is usually fastest, and best on FPGAs.
- Synthesis tools often re-encode state machines. Use a setting or attribute when you need your own codes.
Key words from this volume
Every word below has a plain-English entry in the glossary.
- Binary encoding
- Hamming distance
- Glitch
- Gray encoding
- One-hot encoding
- Illegal state
- One-cold encoding
- Johnson code
- Output encoding
- Critical path
- Switching activity
- FSM extraction
- Synthesis attribute
Practice
Encode a six-state ring
A machine steps around six states in a ring: S0, S1, S2, S3, S4, S5, then back to S0. Give its codes in binary, one-hot and Johnson. How many flip-flops does each need, and how many bits change on the step from S5 back to S0?
Show the solution
| State | Binary | One-hot | Johnson |
|---|---|---|---|
| S0 | 000 | 000001 | 000 |
| S1 | 001 | 000010 | 001 |
| S2 | 010 | 000100 | 011 |
| S3 | 011 | 001000 | 111 |
| S4 | 100 | 010000 | 110 |
| S5 | 101 | 100000 | 100 |
Binary needs 3 flip-flops, one-hot needs 6, and Johnson needs 3. On the step from S5 to S0, binary changes 2 bits (101 to 000), one-hot changes 2, and Johnson changes only 1 (100 to 000). For a ring of six, the Johnson code is also a perfect Gray code: every step changes one bit.
One-hot next-state logic
A machine has states IDLE, BUSY and DONE, coded one-hot. IDLE goes to BUSY when go = 1. BUSY stays in BUSY while fin = 0, and goes to DONE when fin = 1. DONE always returns to IDLE on the next cycle. Write the next-state equation for each flip-flop.
Show the solution
OR one term per arrow into each state, including self-loops:
- IDLE+ = IDLE·go' + DONE
- BUSY+ = IDLE·go + BUSY·fin'
- DONE+ = BUSY·fin
DONE has no condition on its arrow to IDLE, so its term is just DONE. And DONE has no self-loop, so it lasts exactly one cycle.
Output-code a controller
A controller has four states and two outputs, a and b:
| State | a | b |
|---|---|---|
| A | 0 | 0 |
| B | 1 | 0 |
| C | 1 | 0 |
| D | 0 | 1 |
Can you output-code it with two flip-flops? If not, what is the smallest fix?
Show the solution
No. States B and C have the same outputs (a = 1, b = 0), so they would need the same code. Add a third bit, used only to tell B and C apart: A = 000, B = 100, C = 101, D = 010, with the bits in the order a, b, extra. The outputs a and b are still read straight from the first two bits, with no output logic.
Interview corner
Binary or one-hot?
"When would you use one-hot encoding instead of binary?"
Show the solution
"One-hot uses one flip-flop per state, so decoding a state is a single bit. The next-state logic for each flip-flop only depends on the few states that lead to it, which makes it fast. On an FPGA, flip-flops are almost free, so one-hot is usually the right choice, and the tools often pick it themselves. On an ASIC, flip-flops are expensive, so for a small machine I would use binary, or Gray if power or glitches matter. One-hot also has many illegal codes, so a safety-critical machine needs recovery logic."
Count the flip-flops
"How many flip-flops does a 10-state machine need in binary, one-hot and Johnson encoding?"
Show the solution
- Binary: 23 = 8 is too few and 24 = 16 is enough, so 4.
- One-hot: one per state, so 10.
- Johnson: 2n states from n flip-flops, so n = 10 / 2 = 5.
A good answer adds the trade-off: binary is smallest, one-hot fastest, and Johnson in between with one-bit steps.
Next, Volume 06 puts everything so far to work on the most famous state machine problem of all: the sequence detector.