A modulo-6 counter cycles through six states and then returns to the beginning. Because six is not a power of two, a binary implementation needs three flip-flops and has two unused codes. A K-map can derive the next-state equation for each register bit, but the unused codes require a design decision: should they be don't-cares, or should the counter recover from them?
This worked design uses the sequence 000→001→010→011→100→101→000 and explicitly sends unused states 110 and 111 back to 000. We derive the three D-input functions from the state table, verify each transition, and explain why using unused codes as X cells might produce a smaller but non-self-recovering circuit. The example connects state-machine tables, K-maps, and practical synchronous design.
Specify the count sequence
A modulo-6 counter has six stable count values. Use state bits A,B,C, with A the most significant bit. The desired sequence is decimal 0 through 5, then back to 0: 000, 001, 010, 011, 100, 101, and repeat. A three-bit register can encode eight patterns, so 110 and 111 are unused during normal counting.
We will use three positive-edge D flip-flops. At the active edge, the values DA,DB,DC become the next state bits A⁺,B⁺,C⁺. The counter has no enable or asynchronous load in this example. Reset sets the register to 000. For robust recovery, define both unused states to transition to 000 on the next edge. That decision determines the K-map zeros for those rows.
Do not start grouping until the full transition policy is clear. If 110 and 111 are left unspecified, they might be used as don't-cares for minimization, but then the resulting circuit's behavior there is whatever the selected equations happen to produce. Here the design requirement is explicit recovery, so both rows must be entered as specified zeros in the next-state columns.
Write all eight state rows
| Present ABC | Decimal | Next A⁺B⁺C⁺ | Purpose |
|---|---|---|---|
| 000 | 0 | 001 | Count 0→1 |
| 001 | 1 | 010 | Count 1→2 |
| 010 | 2 | 011 | Count 2→3 |
| 011 | 3 | 100 | Count 3→4 |
| 100 | 4 | 101 | Count 4→5 |
| 101 | 5 | 000 | Wrap 5→0 |
| 110 | 6 | 000 | Illegal-state recovery |
| 111 | 7 | 000 | Illegal-state recovery |
Now make one column per next-state bit. A⁺ is 1 for present states 3 and 4, so A⁺=Σm(3,4). B⁺ is 1 for states 1 and 2, giving B⁺=Σm(1,2). C⁺ is 1 for present states 0,2,4, giving C⁺=Σm(0,2,4). These minterm lists are for the present-state variables ABC. Each equation is minimized separately.
Build next-state maps
Use a four-variable-free three-variable K-map for each bit. Put A on one axis and BC in Gray order 00,01,11,10. For A⁺, the two 1-cells are m3=011 and m4=100. They differ in all three bits and are not adjacent, so each remains a singleton: m3 gives A′BC, while m4 gives AB′C′. Therefore A⁺=A′BC+AB′C′.
For B⁺, minterms 1=001 and 2=010 are also not adjacent. They yield A′B′C and A′BC′. Factor A′ to get B⁺=A′(B′C+BC′)=A′(B⊕C). For C⁺, the 1-cells are 0=000, 2=010, and 4=100. Cells 0 and 2 are adjacent because B changes; cells 0 and 4 are adjacent because A changes. The two pairs overlap at m0, which is allowed. They produce A′C′ and B′C′, so C⁺=A′C′+B′C′=C′(A′+B′).
Wraparound still applies on the K-map. For this example, the selected pairs do not rely on left-right wrap, but map layout must remain Gray-coded. If using a truth table or a solver, preserve the ABC significance order. A wrong variable order can place a minterm in a different cell and produce equations for a different counter.
Derive the three equations
The final D-input equations are:
DB = A′(B⊕C)
DC = C′(A′+B′)
These expressions assume that the unused states are specified to recover to 000. The first two equations use isolated minterms, while C⁺ uses overlapping pairs. The factorization for B⁺ and C⁺ is algebraically convenient, though an implementation library may choose a different structure. If XOR gates are unavailable or expensive, expand B⊕C into its two product terms.
Do not confuse the complemented state signal A′ with the next-state bit A⁺. The prime mark means logical NOT of the present state bit. The superscript plus means the value to be loaded at the next active clock edge. Write each notation explicitly when deriving the maps, then label the flip-flop input DA as equal to A⁺ for a D-flop implementation.
Verify operation and recovery
Substitute the states one by one. At 000, DA=0, DB=0, and DC=1, so the next state is 001. At 001, the equations give 010. At 010, they give 011. At 011, they give 100. At 100, they give 101. At 101, all three next-state values are 0, so the counter wraps to 000.
Now check invalid states. At 110, A′BC is 0, AB′C′ is 0, A′(B⊕C)=0, and C′(A′+B′)=0, so the next state is 000. At 111, the first two equations are 0, the B equation is 0 because A′=0, and the C equation is 0 because C′=0. It also recovers to 000. This exhaustive eight-row check proves the combinational transition table for the chosen policy.
Reset must still establish 000 reliably. A counter can be logically self-recovering after an invalid code and still require reset for deterministic startup or for system control. If a clock edge occurs while reset is asserted, the behavior depends on synchronous versus asynchronous reset implementation; follow the flip-flop and system timing specifications.
What changes if illegal states are X?
If the design requirement guarantees that 110 and 111 never occur and does not require fault recovery, those rows might be marked X in the next-state maps. A minimizer can use each X as either 0 or 1 when forming groups. This may simplify the equations, but it can produce next states other than 000 from the illegal codes. It may even make them part of a cycle that never reaches the valid count sequence.
The word “unused” only describes normal operation. A flip-flop upset, scan load, partial reset, or design error can place the register in one of those encodings. If recovering from that condition matters, specify the recovery transitions rather than marking X. The article on FSM unused-state codes and don't-cares explains how to prove reachability assumptions and inspect the implementation's behavior.
A K-map X is an optimization permission. It is not a prediction that the hardware will output an unknown value or automatically reset. Once simplified, the circuit implements a definite 0 or 1 for every input combination. Always evaluate the resulting equations on the X rows and decide whether that behavior is acceptable.
Implement and test the counter
Connect three D flip-flops with a common clock. Feed each D input from the corresponding equation and use reset to initialize ABC=000. Ensure that the clock edge polarity matches the rest of the system. If the counter drives another synchronous block, check setup time on the receiving inputs and avoid using a combinationally decoded output as a clock.
For a simulation, begin at 000 and apply clock edges. The expected trace is 001,010,011,100,101,000 repeatedly. Also force 110 and 111 into the register in a fault-injection test and confirm that the next edge returns to 000. Check both the state bits and any decoded outputs. A waveform is particularly helpful for distinguishing present state from next-state values.
For a hardware implementation, the next-state equations may map to gates, LUTs, or dedicated logic. Synthesis can factor terms, duplicate logic for timing, or absorb reset and enable functions into cells. Compare the mapped design against the requirement, especially if the counter's outputs have tight timing or safety consequences.
Extensions and design choices
An enable input E can make the counter hold its value when E=0 and advance when E=1. The state table then doubles in rows: for each present state, specify a hold transition for E=0 and the modulo-6 transition for E=1. Add E as a K-map variable and minimize each next-state bit again. Do not simply gate the final equations without checking the hold condition; that can produce the wrong behavior for some state bits.
An asynchronous clear is different from a synchronous modulo transition. It forces the register independently of the active clock edge, while the K-map equations determine what is loaded on a clock edge. If the application requires a particular output sequence immediately after reset, account for reset release and any output decoding. A counter used as a clock divider may require additional glitch considerations.
This design illustrates the full procedure: define state codes and recovery, write the complete table, make one map per next-state bit, simplify, then check every row. The arithmetic pattern is small, but the method scales to more complicated FSMs and prevents an elegant K-map result from hiding an unspecified state policy.
Read the state waveforms
When reviewing a waveform, label the register value immediately before each active edge and the value captured after that edge. The combinational equations continuously compute the next state from the present bits; the state does not advance until a clock edge. A trace that lists only the next-state values can make a counter appear to skip a count because the sampling instant was not identified.
For the modulo-6 sequence, the stable register values after reset are 000,001,010,011,100,101, then 000. The binary output is not a conventional modulo-8 count because 110 and 111 are forced to 000. If another circuit decodes the counter, define whether it samples on the same edge or one cycle later. This avoids off-by-one confusion in terminal-count and enable logic.