Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Logic Synthesis Glossary
  • Logic Synthesis Cheatsheet
  • Synthesis Foundations14
  • Logic Optimisation and Mapping20
  • Constraints and Timing15
  • Sequential, FSM and Memory19
    • Flops, Resets and Enables
    • FSM Synthesis
      • Coding Styles
      • State Encoding
      • Unreachable States
      • Output Registering
      • Yosys FSM Passes
    • Memory and Macro Inference
    • Retiming and Pipelining
  • Datapath Synthesis14
  • Area, Power and Test14
  • Verification, ECO and Handoff15
  • Flows and Debugging15
  • Interview and Judgment11
Loading lesson

‹FSM Synthesis
  1. Topics
  2. Logic Synthesis
  3. Sequential, FSM and Memory
  4. FSM Synthesis
  5. State Encoding

Part 4 · Sequential, FSM and Memory · Intermediate

State Encoding

Binary, one-hot and gray encodings with the area, speed and power trade-off.

On this page

    Three codes for four states

    An encoding assigns a bit pattern to each state. Binary packs states into few bits, one-hot spends one bit per state, and gray orders binary codes so neighbours differ by one bit.

    State

    Binary (2 bits)

    One-hot (4 bits)

    Gray (2 bits)

    S0

    00

    0001

    00

    S1

    01

    0010

    01

    S2

    10

    0100

    11

    S3

    11

    1000

    10

    Down the chain S0 to S1 to S2 to S3, the gray column flips exactly one bit per step. That single-bit property is the whole point of gray.

    What each code costs

    Binary uses the fewest flops but each transition test decodes the full code. One-hot tests a single bit per transition, which shortens next-state paths at the price of more flops.

    Gray keeps the binary flop count and cuts switching on machines that walk neighbour to neighbour, such as counters. No encoding always wins: the machine shape, the library and the timing target decide.

    Diagram
    course.lib teaching-library areas (library units, not a process): DFF = 8
    binary state flops:   2 flops x 8 = 16 area units
    one-hot state flops:  4 flops x 8 = 32 area units
    the flop part is exact; next-state gates and the clock tree vary with the machine, so totals still need the mapped netlist

    Counting next-state literals

    A simple structural estimate counts, per transition arc, the state bits the arc must test plus its guard literals. Binary tests two bits per arc here; one-hot tests one.

    The stated example machine has states S0 to S3 and arcs: S0 to S1 on go, S0 to S0 on not go, S1 to S2 always, S2 to S3 always, S3 to S0 on go, S3 to S3 on not go. The program below recomputes both totals from that arc list.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import sys
    
    # Stated example machine: arcs of (source, guard literals, dest).
    # An empty guard means an unconditional arc (0 guard literals).
    TRANSITIONS = [
        ("S0", ("go",), "S1"),
        ("S0", ("~go",), "S0"),
        ("S1", (), "S2"),
        ("S2", (), "S3"),
        ("S3", ("go",), "S0"),
        ("S3", ("~go",), "S3"),
    ]
    
    FLOPS = {"binary": 2, "one-hot": 4}
    DECODE = {"binary": 2, "one-hot": 1}
    
    def totals(encoding):
        flops = FLOPS[encoding]
        decode = DECODE[encoding]
        lits = 0
        for i in range(len(TRANSITIONS)):
            src, guard, dst = TRANSITIONS[i]
            lits = lits + decode + len(guard)
        return flops, lits
    
    bin_flops, bin_lits = totals("binary")
    oh_flops, oh_lits = totals("one-hot")
    
    checks = [
        (bin_flops, 2),
        (oh_flops, 4),
        (bin_lits, 16),
        (oh_lits, 10),
    ]
    
    for i in range(len(checks)):
        got, want = checks[i]
        if got != want:
            print("FAIL: check " + str(i + 1) + " got " + str(got) + " want " + str(want))
            sys.exit(1)
    
    print("PASS: binary 2 flops 16 literals, one-hot 4 flops 10 literals")

    Hand check: binary arcs cost 3, 3, 2, 2, 3, 3 literals, which sum to 16. One-hot arcs cost 2, 2, 1, 1, 2, 2, which sum to 10.

    Power follows activity

    Clock pins toggle every cycle, so each extra state flop adds clock-pin power. Data pins add further power only when they switch.

    Diagram
    EXAMPLE parameters (illustrative, not a process): C 5 fF per clock pin, V 0.8 V, f 500 MHz, activity 1
    P = alpha x C x V^2 x f = 1 x 5e-15 F x 0.64 V^2 x 5e8 Hz
      = 5 x 0.64 x 5 e(-15 + 8) W = 16e-7 W = 1.6e-6 W = 1.6 uW per clock pin
    binary:   2 pins x 1.6 uW = 3.2 uW of clock-pin power
    one-hot:  4 pins x 1.6 uW = 6.4 uW of clock-pin power
    clock-pin part only; data switching adds on top and can favour either side

    Common pitfall

    Gray helps only walks between neighbours. On a machine that jumps between distant states, gray codes switch as many bits as binary while keeping the deeper decode, so it buys nothing.

    Interview

    Likely probes: flop counts for N states, and which encoding for a fast controller.

    • Binary needs ceiling of log2 of N flops; one-hot needs N.

    • One-hot shortens next-state tests to one bit, which suits fast small controllers.

    • Gray suits neighbour-walking counters; recovery arcs still need a default.

    Check yourself A 5-state machine uses binary. How many flops, and why can one-hot still be faster with more of them?

    Three flops, since 2 bits cover only 4 states. One-hot tests one bit per arc instead of decoding three, so its next-state paths are shallower.

    Check yourself The program prints 16 binary literals against 10 one-hot. What was counted, and what was left out?

    Counted: state-bit tests plus guard literals over the six arcs. Left out: output logic, minimisation sharing, and mapped gate areas, which need the netlist.

    Related topics

    • Up: FSM Synthesis

    • Next: Unreachable states

    • Area, Power and Timing Trade-offs

    Previous

    58 / 139

    Next: Unreachable States

    Up next

    Up nextUnreachable States

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Output Registering
    • Yosys FSM Passes