This is the core chapter on finite state machine (FSM) design. The systematic design procedure is presented: from state diagram to state table, state assignment, choice of flip-flops, derivation of next-state and output logic, to timing verification. Both Moore machines (output depends only on state) and Mealy machines (output depends on state and current inputs) are covered with clear examples. State assignment strategies include binary encoding and one-hot encoding. The chapter includes a thorough treatment of state minimization using the partitioning procedure. A serial adder is designed in both Moore and Mealy styles to illustrate the tradeoffs. Arbiter circuits, counter design using the sequential-circuit approach, analysis of existing sequential circuits, and ASM (Algorithmic State Machine) charts are also covered. Verilog code examples use parameter, case, and multi-block FSM coding styles.
Both styles describe the same kind of FSM, but the output is drawn in different places. This shows up in flow tables (ch 9) the same way it shows up in synchronous state diagrams (ch 6).
Side-by-side example — both detect the input sequence "11" and assert $z=1$. Same behavior, different drawing convention:
Reading the labels:
| style | state circle | arrow label | output rule |
|---|---|---|---|
| Moore | name + output value (e.g. A/0, C/1) | just the input value (w=1) | $z = f(\text{state})$ — registered, stable for full cycle |
| Mealy | just the state name (no output) | input/output (w=1/1) | $z = f(\text{state}, \text{input})$ — combinational, may change mid-cycle |
Same job, different state count. The Moore version above needs 3 states (A, B, C — with C dedicated to "saw 11" so $z=1$ can live in a state). The Mealy version needs only 2 states (A, B) because the "$z=1$" event is fired on the B→B transition itself, no extra state required.
Quick visual cues to tell them apart at a glance:
A/0) and arrow labels are just inputs → Moore.w=1/1) and circles only contain state names → Mealy.w and output z that outputs z=1 whenever the input sequence 101 is detected. Overlapping sequences should be detected.Recap of exercise 6.1. The FSM detects the input sequence 101 on input $w$ and asserts $z=1$ when the sequence completes. Overlapping is allowed — e.g., on $w = 1,0,1,0,1$ the detector should fire twice: at position 3 (first "101") and at position 5 (second "101", reusing the "1" at position 3).
Moore state diagram (4 states):
Overlapping comes from D\'s transitions: the "1" that completed the sequence is reused as the prefix of the next attempt.
State table with 2-bit Gray-style binary assignment $A=00, B=01, C=10, D=11$:
| Present $y_2 y_1$ | $w=0$ next $Y_2 Y_1$ | $w=1$ next $Y_2 Y_1$ | $z$ |
|---|---|---|---|
| A=00 | 00 (A) | 01 (B) | 0 |
| B=01 | 10 (C) | 01 (B) | 0 |
| C=10 | 00 (A) | 11 (D) | 0 |
| D=11 | 10 (C) | 01 (B) | 1 |
Next-state equations (D flip-flops):
$Y_1$ K-map by inspection — $Y_1 = 1$ only in cells where $w=1$ (regardless of present state):
$$Y_1 = w$$$Y_2$ K-map — $Y_2 = 1$ in cells: $(w=0, y_2 y_1 = 01)$, $(w=0, y_2 y_1 = 11)$, $(w=1, y_2 y_1 = 10)$. Group: the first two cells share $\overline{w}\,y_1$; the third is $w\,y_2\,\overline{y_1}$.
$$Y_2 = \overline{w}\,y_1 + w\,y_2\,\overline{y_1}$$Output: $z = 1$ only in state D = 11.
$$z = y_2 \cdot y_1$$Implementation: 2 D flip-flops + a few gates. Total cost: 1 buffer ($Y_1 = w$ — no logic), 1 AND2 + 1 AND3 + 1 OR2 ($Y_2$), 1 AND2 ($z$) ≈ 5 gates / 9 inputs. Modern synthesis tools would derive this exactly.
Verification. Trace input $w = 1,0,1,0,1$ starting in A:
| cycle | state in | $w$ | state out | $z$ |
|---|---|---|---|---|
| 0 | A | 1 | B | 0 |
| 1 | B | 0 | C | 0 |
| 2 | C | 1 | D | 0 → 1 |
| 3 | D | 0 | C | 1 → 0 |
| 4 | C | 1 | D | 0 → 1 |
Two "101" detections at cycles 2 and 4 — overlap correctly detected.
z=1 when it has received at least three consecutive 1s on input w.Recap of exercise 6.3 (Moore version). The FSM outputs $z=1$ once it has received at least three consecutive 1s on input $w$. As soon as a 0 arrives, the run breaks and the count resets.
Moore state diagram — 4 states:
The Moore output is a function of state alone, so distinguishing "saw 3" from "saw ≥3" requires a separate "detection" state D where $z=1$ is registered.
Mealy version — 3 states:
Notation $w/z$ means input/output on the transition. The Mealy form fires $z=1$ on the transition from C to itself when $w=1$, so we don\'t need a separate "saw three" state — the third 1\'s effect is registered as the output of the very transition that observes it.
Mealy state diagram (return arrows from B and C to A are routed at distinct depths so they never overlap):
Verilog (Mealy, 3 states) — combinational output uses both state and input $w$ on the C→C transition:
module mealy_three_ones (
input clock, resetn, w,
output reg z
);
reg [1:0] y;
parameter A = 2'b00, B = 2'b01, C = 2'b10;
// single always block: state register + registered Mealy output
always @(posedge clock or negedge resetn) begin
if (!resetn) begin
y <= A;
z <= 1'b0;
end else begin
case (y)
A: begin y <= (w ? B : A); z <= 1'b0; end
B: begin y <= (w ? C : A); z <= 1'b0; end
C: begin y <= (w ? C : A); z <= w; end // z=1 on C&&w=1
default: begin y <= A; z <= 1'b0; end
endcase
end
end
endmoduleComparison:
| Property | Moore (ex 6.3) | Mealy (ex 6.4) |
|---|---|---|
| States | 4 (A, B, C, D) | 3 (A, B, C) |
| Flip-flops | 2 | 2 |
| Output | $z = f(\text{state})$ | $z = f(\text{state}, w)$ |
| Output timing | synchronous (clock edge) | combinational (input-driven) |
Key takeaways:
case statement and parameter declarations for the states.01. Use a three-block coding style (state register, next-state logic, output logic).The three-block style separates an FSM into three distinct always blocks, each with one focused responsibility. It cleanly mirrors the FSM's conceptual decomposition into a state register, a next-state function, and an output function:
The three blocks at a glance:
| block | sensitivity | assignment | role |
|---|---|---|---|
| 1. State register | @(posedge clk) | non-blocking <= | commits next-state to FFs on every clock edge |
| 2. Next-state logic | @(*) | blocking = | combinational: $Y = \delta(y, w)$ |
| 3. Output logic | @(*) or assign | blocking = / assign | combinational: Moore $z = f(y)$ or Mealy $z = f(y, w)$ |
Skeleton for the "last two inputs = 01" Mealy detector (2 states):
module detect_01_mealy (
input clk, resetn, w,
output reg z
);
reg y, Y;
parameter A = 1'b0, // have not just seen a 0
B = 1'b1; // last input was 0
// ── Block 1: state register ─────────────────────────────
always @(posedge clk or negedge resetn) begin
if (!resetn) y <= A;
else y <= Y;
end
// ── Block 2: next-state logic (combinational) ───────────
always @(*) begin
case (y)
A: Y = (w == 1'b0) ? B : A; // saw a 0 → go to B
B: Y = (w == 1'b0) ? B : A; // saw 0 again → stay; saw 1 → done, return to A
default: Y = A;
endcase
end
// ── Block 3: output logic (Mealy — uses state AND input) ──
always @(*) z = (y == B) && (w == 1'b1);
endmoduleWhy split it up:
<=; Blocks 2 & 3 always use =. Mixing them in a single block is the most common synthesis-vs-simulation mismatch.Variants: some authors merge Blocks 2 & 3 into one combinational always @(*) (a "two-block" style). Others reduce Block 3 to a single assign when the output is a one-state Moore decode. The invariant: state register stays sequential and isolated; everything else is combinational and explicitly labeled.
You are given a state-assigned table — a state table where each abstract state has already been replaced by a concrete bit pattern. The job is to convert that abstract description into three Boolean expressions that you could wire up with logic gates and flip-flops.
How to read the table:
Notation like "$00 \to 10/11$" reads: when present state is 00, next state is 10 if $w=0$, or 11 if $w=1$.
Why "using D flip-flops" matters: a D flip-flop has the property $Q^+ = D$ — whatever you put on the D input becomes the output after the next clock edge. So if you want next-state bit $i$ to equal $Y_i$, you simply connect the combinational signal $Y_i$ to the D input of flip-flop $i$. No conversion through excitation tables is needed (unlike JK or T flip-flops, which require an extra translation step).
What you must produce — three Boolean expressions:
Recommended procedure:
Sanity-check at the end: plug each row of the original table into your equations — every row's $Y_2 Y_1$ and $z$ should match. If they all match, the equations are correct (whether or not they're minimum). Then verify your K-map groupings are the largest possible to confirm minimality.
The swap operation: swap contents of registers R1 and R2 using R3 as temp storage. Three transfers in sequence: R3 ← R2, then R2 ← R1, then R1 ← R3.
FSM: Moore-type, 4 states, started by a one-cycle pulse on input w:
State diagram:
Straightforward state assignment (book convention): $A=00$, $B=01$, $C=10$, $D=11$ on $(y_2, y_1)$. With D flip-flops, the textbook derives:
$$Y_1 = w\,\overline{y_1}\,\overline{y_2} + \overline{y_1}\,y_2 \qquad Y_2 = y_1\,\overline{y_2} + \overline{y_1}\,y_2$$What problem 6.14 asks: redo the next-state and output expressions with C and D swapped in the assignment ($A=00$, $B=01$, $C=11$, $D=10$). Compare the gate count to the original assignment — different state assignments produce algebraically different equations, often with different costs. The textbook lesson: state assignment is a non-trivial optimization knob.
One-hot encoding = each state gets its own dedicated flip-flop, and exactly one is 1 ("hot") at any moment.
Comparison for a 4-state FSM (A, B, C, D):
| Encoding | A | B | C | D | # of flip-flops |
|---|---|---|---|---|---|
| Binary | 00 | 01 | 10 | 11 | $\lceil\log_2 4\rceil = 2$ |
| One-hot | 0001 | 0010 | 0100 | 1000 | $N = 4$ |
Trade-off:
| Binary | One-hot | |
|---|---|---|
| Flip-flops | $\lceil\log_2 N\rceil$ | $N$ |
| Next-state logic | decoded from binary state | each transition is one product term |
| State-output decode | equality check (e.g. y2 && y1) | a single wire — assign R1out = y3; |
| Speed | slower (deeper logic) | faster (one AND/OR layer) |
| FF cost | minimum | linear in $N$ |
Applied to the swap FSM ($y_1{=}A, y_2{=}B, y_3{=}C, y_4{=}D$):
Y1 = (y1 & ~w) | y4 // stay in A while w=0; come back from D Y2 = y1 & w // A→B when w=1 Y3 = y2 // B→C (unconditional) Y4 = y3 // C→D (unconditional) R2out = R3in = y2 // outputs come "for free" R1out = R2in = y3 R3out = R1in = Done = y4
Each next-state expression is one tiny product term — that's the win. The cost is using 4 flip-flops instead of 2.
When to use which: Binary when area / FF count is the bottleneck. One-hot when you want simpler logic, faster combinational paths, and "free" state-output decoding — the standard choice on FPGAs where flip-flops are plentiful but routing/depth is the limit.
always for the next-state logic and one sequential always for the state register, with the outputs derived as assign expressions of the present state.— example 6.1Figure 6.51 — original state table (7 states, Moore output $z$ depends only on present state):
| Present | $w=0$ | $w=1$ | $z$ |
|---|---|---|---|
| A | B | C | 1 |
| B | D | F | 1 |
| C | F | E | 0 |
| D | B | G | 1 |
| E | F | C | 0 |
| F | E | D | 0 |
| G | F | G | 0 |
Partitioning procedure (each $P_k$ groups states whose $k$-step successors stay in the same block):
Equivalence classes: $\{A,D\}, \{B\}, \{C,E,G\}, \{F\}$ — four classes, so the minimized FSM has 4 states. Rename $\{A,D\} \to A$ and $\{C,E,G\} \to C$ to obtain Figure 6.52:
| Present | $w=0$ | $w=1$ | $z$ |
|---|---|---|---|
| A | B | C | 1 |
| B | A | F | 1 |
| C | F | C | 0 |
| F | C | A | 0 |
Implementation savings: $\lceil\log_2 7\rceil = 3$ flip-flops shrink to $\lceil\log_2 4\rceil = 2$. The merged states have indistinguishable behavior — any input sequence produces the same output sequence whether you start in $A$ or $D$, or in any of $C, E, G$.
分割程序是一種系統化方法,用來找出等價狀態——也就是對所有可能的未來輸入序列都表現相同的狀態,並將它們合併。兩個狀態等價的條件是:(1) 它們有相同的輸出,且 (2) 對每一種輸入,它們的下個狀態也彼此等價。此程序逐步精煉分割,直到達到不動點 (fixed point)。
演算法:
為什麼有效(非正式證明):若兩個狀態 $X$ 和 $Y$ 不等價,必定存在某個輸入序列能區分它們——也就是經過若干步後抵達輸出不同的狀態。分割程序在第 $k$ 步追蹤的是:「只看前 $k$ 個輸入時,哪些狀態仍無法被區分」。當不再有新的區別出現時,精煉就停止;此時的分割恰好等於行為等價類。
小範例:假設:
| 狀態 | $w=0$ | $w=1$ | $z$ |
|---|---|---|---|
| A | A | B | 0 |
| B | A | C | 0 |
| C | A | C | 1 |
為什麼要做?每減少一個狀態通常能省下一個或多個正反器(因為 FF 數量為 $\lceil\log_2 N ceil$),而且推導出來的下一狀態方程式與輸出方程式會有更少的最小項——電路更小、更快。對於手工設計的 FSM 來說,這個程序也能找出設計者誤以為不同、但其實重複的多餘狀態。
套用至問題 6.19:先畫出販賣機 FSM 的初始狀態圖(包含 "0¢", "5¢", "10¢", "15¢", "20¢",若允許兩個一角硬幣連續投入則還有 "25¢"),再以此程序合併行為相同的狀態(例如「20¢——找零 5¢」狀態,若機器在下一輪投幣時會重置找零紀錄,可能等價於「5¢」狀態)。
Specification: output $z=1$ whenever the previous two values of input $w$ were both 0 or both 1; otherwise $z=0$.
FSM: Moore-type, 5 states (A reset, B/D = "saw a 0/1", C/E = "saw 00/11"):
| State | Meaning | $z$ | Next on $w$=0 | Next on $w$=1 |
|---|---|---|---|---|
| A | after reset | 0 | B | D |
| B | last input was 0 | 0 | C | D |
| C | last two were 00 | 1 | C | D |
| D | last input was 1 | 0 | B | E |
| E | last two were 11 | 1 | B | E |
State diagram (output is the digit after the slash):
Why exactly 5 states? The machine must remember three things: just-reset, just-saw-0, just-saw-1, plus the "00" / "11" run-detection states. Tracking only "last input" (3 states: A, B, D) isn't enough — you need to distinguish "first 0 ever" (B) from "second 0 in a row" (C) to decide whether $z$ goes high.
What problem 6.25 asks: instead of the single 5-state machine, build two parallel FSMs — one detects "two consecutive 0s" (3 states), the other detects "two consecutive 1s" (3 states). OR their outputs to get the combined $z$. The lesson: parallel decomposition often produces simpler FSMs than a single monolithic one (6 flip-flops total split between two machines vs. 3 flip-flops for the 5-state version, but with simpler next-state logic per machine).
The arrows labeled w=0 / w=1 in any state diagram are conditions, not events. The actual event that changes the state in a synchronous FSM is the rising edge of the clock.
What happens during one clock cycle:
So an arrow "B → C on $w=$0" really means: "if the FSM is in state B and $w=$0 during a clock cycle, then at the rising edge that ends that cycle, the state register loads C."
What the input does: $w$ doesn't cause the transition — it selects which transition will happen at the next clock edge. Changes to $w$ between edges only matter if $w$ is at the right level when the edge fires (must satisfy setup/hold times).
Consequences:
Mnemonic: the state diagram is a rulebook, not a movie. It says "in state X, if input is Y at the next clock edge, go to state Z." The clock is the implicit metronome that turns rules into transitions.
Figure 6.89 is an improved state assignment for the same 5-state "00 or 11" detector that Example 6.12 uses. The straightforward assignment in Figure 6.88 wastes the natural don't-cares; the improved one assigns codes so that $y_3$ acts as a "have we left reset?" flag — once the machine leaves state A, $y_3$ stays 1 forever.
Improved state assignment:
| State | $y_3 y_2 y_1$ | Next on $w=0$ | Next on $w=1$ | $z$ |
|---|---|---|---|---|
| A (reset) | 000 | 100 (B) | 110 (D) | 0 |
| B (saw 0) | 100 | 101 (C) | 110 (D) | 0 |
| C (saw 00) | 101 | 101 (C) | 110 (D) | 1 |
| D (saw 1) | 110 | 100 (B) | 111 (E) | 0 |
| E (saw 11) | 111 | 100 (B) | 111 (E) | 1 |
With D flip-flops, the textbook derives:
$$Y_1 = w\,\overline{y_2} + \overline{w}\,y_3\,y_2 \qquad Y_2 = w \qquad Y_3 = 1 \qquad z = y_1$$Since $Y_3 = 1$ always (after leaving reset), $y_3$ collapses to a constant and the FSM reduces to two flip-flops + the trivial $y_3$ — much cheaper than the Figure 6.88 assignment.
What problem 6.27 asks: redo the implementation using JK flip-flops instead of D. For each state bit $y_i$, derive $J_i$ and $K_i$ such that the next state matches.
JK excitation table (the recipe for converting present→next into $J,K$):
| Present $y_i$ | Next $Y_i$ | $J_i$ | $K_i$ |
|---|---|---|---|
| 0 | 0 | 0 | d |
| 0 | 1 | 1 | d |
| 1 | 0 | d | 1 |
| 1 | 1 | d | 0 |
Apply this row-by-row to every (present-state, $w$) combination in the table above to get a 10-row excitation table; then K-map-minimize each of $J_1, K_1, J_2, K_2, J_3, K_3$. Don't-care entries (the unused codes 001, 010, 011 and the don't-cares from the JK recipe) make the K-maps very loose — minimum-cost JK expressions are typically simpler than the corresponding D expressions for the same FSM.
always block.Same specification as Example 6.12 (output 1 when previous two inputs were both 0 or both 1), but realized as a Mealy FSM. The Mealy form needs only 3 states instead of 5 because the output can depend on the current input as well as the state — so we don't need separate "saw 00" / "saw 11" states; the output fires on the transition itself.
States and transitions:
w=0 → B / z=0; w=1 → C / z=0w=0 → B / z=1 (00 detected); w=1 → C / z=0w=0 → B / z=0; w=1 → C / z=1 (11 detected)State table (transitions show next-state / output):
| State | $w=0$ → next/$z$ | $w=1$ → next/$z$ |
|---|---|---|
| A | B / 0 | C / 0 |
| B (saw 0) | B / 1 | C / 0 |
| C (saw 1) | B / 0 | C / 1 |
Textbook state assignment ($y_2 y_1$): A=00, B=01, C=11. Code 10 is unused (don't-care). The clever bit: $y_1$ becomes a "have we left reset?" flag — once we leave A, $y_1$ stays 1, so $Y_1 = 1$ is the next-state equation. Effectively only one real flip-flop ($y_2$) is needed.
Why Mealy is more compact here: the Moore version (Example 6.12) needs separate states C and E to register "I've seen 00" / "I've seen 11" because Moore output is a function of state alone. Mealy fires its output the moment the qualifying input arrives, so the run-detection states aren't needed.
What problem 6.29 asks: write Verilog using the combinational always block style — both next-state and output are set inside always @*, with a separate always @(posedge clk) block for the state register. The Mealy nature means $z$ depends on both state and $w$, so $z$'s assignment lives in the same combinational block where state transitions are decided.
module mealy_seq (input w, clk, rst,
output reg z);
parameter A = 2'b00, B = 2'b01, C = 2'b11;
reg [1:0] state, next;
always @(posedge clk or posedge rst) // state register
if (rst) state <= A;
else state <= next;
always @* begin // next-state + output
z = 1'b0;
case (state)
A: next = w ? C : B;
B: begin next = w ? C : B; z = (w == 1'b0); end
C: begin next = w ? C : B; z = (w == 1'b1); end
default: next = A;
endcase
end
endmodule