Lesson 13: Finite State Machines (FSM)
- FSM = state + transitions + outputs. It is the standard way to model control logic in digital systems (protocols, controllers, UI flows, sequencing).
- Moore: output depends only on state → stable outputs, usually 1 clock later.
- Mealy: output depends on state + input → faster response, sometimes fewer states, but more sensitive to input glitches.
- Typical Verilog structures: 3-tier (clearest), 2-tier (compact), 1-tier (shortest but harder to maintain).
- Quartus: You must do Pin Assignments; you should add a minimal SDC create_clock for meaningful timing analysis.
13.1 Finite State Machine (FSM) Fundamentals
What is a Finite State Machine (FSM)?
A Finite State Machine (FSM) is a formal model used to describe and implement sequential control logic in digital systems. An FSM has a finite set of states, a state register that stores the current state, and logic that determines how the system moves between states. In a synchronous FSM, the next state is computed by combinational next-state logic as a function of the current state and inputs, and the state register updates to the next state on each active clock edge. Outputs are generated either from the state only (Moore FSM) or from the state and inputs (Mealy FSM).
- State: the current mode of the system (e.g., IDLE, RUN, ERROR).
- Transition: the condition for moving from one state to another.
- State Register: flip-flops holding the current state (updated on a clock edge).
- Next-State Logic: combinational logic that computes
next_state. - Output Logic: logic that computes outputs (Moore or Mealy rules).
Why is FSM important in digital circuit design?
FSMs are fundamental building blocks in digital design. They are important because:
- Structured Approach: FSMs provide a disciplined, methodical way to design control logic. Complex behavior is broken into a finite set of clearly defined states.
- Predictable Timing: Being synchronous (clocked), FSMs behave deterministically and meet timing constraints reliably on FPGAs and ASICs.
- Synthesis-Friendly: FSMs described in Verilog are well-understood by synthesis tools (such as Quartus Prime), which can automatically optimize state encoding and logic.
- Debugging Ease: The state variable provides a direct window into the machine's behavior, making simulation and hardware debugging straightforward.
- Scalability: Complex systems can be built by interconnecting multiple FSMs (Hierarchical FSMs), keeping each module manageable.
- Universality: Every digital controller—from a simple LED blinker to a full USB protocol stack—can be modeled as an FSM.
💡Key Takeaway
If your circuit needs to remember what happened before and make decisions based on that history, you need an FSM.
When to Use an FSM
Deploy an FSM whenever a system requires:
- Sequence execution (e.g., initialization sequences and communication protocols such as I2C and SPI).
- State-dependent outputs (e.g., traffic light controllers, vending machines).
- Control path logic to coordinate datapaths.
State Diagrams
A state diagram (also called a state transition diagram) is a visual representation of an FSM. It uses state nodes and transition arrows. Each transition is labeled with a condition. In Moore FSMs, outputs are typically labeled on the inside of states. In Mealy FSMs, outputs are often labeled on transitions as condition/output.
State Diagram Components
| Symbol | Represents | Description |
|---|---|---|
| State | Each circle represents one state. The state name is written inside. | |
| Initial State | An arrow pointing into the circle indicates the reset/initial state. | |
| Transition | Directed arrow from one state to another, labeled with condition(s). | |
| Label on arrow | Condition/Output | Moore: input only. Mealy: input/output. |
| Self Transition | The FSM stays in the same state under this condition. |
State Transition Table
A State Transition Table is a tabular representation of an FSM. It explicitly lists every combination of current state and input, and specifies the next state (and output) for each combination.
Is the State Transition Table useful in Verilog? — Yes, absolutely!
While a state diagram gives a visual overview, the state transition table provides the precise logic needed to write Verilog case statements. Every row in the table maps directly to a case / if condition in the next-state always block.
- Enumerate every state/condition combination to avoid missing corner cases.
- Map cleanly into case(curState) for next-state logic.
- Build self-check testbenches (the table becomes your golden reference).
✅ Practical Rule
Build the state transition table BEFORE writing Verilog. It prevents logic errors and ensures complete coverage of all state/input combinations. Synthesis tools use this same logic internally.
Moore State Diagram
In a Moore machine, outputs are associated with STATES (written inside or below the circle). Transition labels show only the input condition.
Output is labeled INSIDE / BELOW each state

Transition Labels: Input condition ONLY (SW=0 or SW=1)
Output Labels: Written INSIDE/BELOW each state circle
Figure 1: Moore FSM State Diagram — LED Toggle Example
State Transition Table for the LED Toggle FSM (Moore):
| Current State | Input (SW) | Next State | Output (LED) |
| S0 | 0 | S0 | OFF |
| 1 | S1 | ||
| S1 | 0 | S2 | ON |
| 1 | S1 | ||
| S2 | 0 | S2 | ON |
| 1 | S3 | ||
| S3 | 0 | S0 | OFF |
| 1 | S3 |
Timing Diagram:

Figure 2: Moore timing (output follows registered state; often 1-cycle later)
Mealy State Diagram
In a Mealy machine, outputs are associated with TRANSITIONS (labeled Input/Output on the arrows). The output can change as soon as the input changes, even before the next clock edge.
Output is labeled ON THE TRANSITION ARROW

Transition Labels: Input/Output (e.g., SW=1 / LED=1)
State Circles: No output inside (unlike Moore)
Figure 3: Mealy FSM State Diagram — LED Toggle Example
State Transition Table for the LED Toggle FSM (Mealy):
| Current State | Input (SW) | Next State | Output (LED) |
| S0 | 0 | S0 | OFF |
| 1 | S1 | ON | |
| S1 | 0 | S2 | ON |
| 1 | S1 | ON | |
| S2 | 0 | S2 | ON |
| 1 | S3 | OFF | |
| S3 | 0 | S0 | OFF |
| 1 | S3 | OFF |
Timing Diagram:

Figure 4: Mealy Timing (output can change in the same cycle)
Types of FSM: Moore and Mealy:
| Characteristic | Moore FSM | Mealy FSM |
|---|---|---|
| Output depends on | Current state only | Current state + inputs |
| State diagram labels | Output inside/below state node | Output on transition arrow (in/out) |
| Number of states | More states required | Fewer states (often 1 less per output) |
| Output glitches | Glitch-free (registered output) | Possible if inputs are noisy |
| Response speed | Output changes 1 cycle after input | Output can change same cycle as input |
| Typical use | Safe, registered outputs for FPGAs | Fast response, fewer states |
13.2 Moore and Mealy FSM Architecture
Types of FSM:
- Moore Machine: Outputs depend only on the current state.
- Mealy Machine: Outputs depend on both the current state and the current inputs.
The Moore FSM
Understanding Moore FSM
A Moore Finite State Machine is an FSM where the OUTPUTS are a function of the CURRENT STATE ONLY. The inputs only affect what the next state will be — they do not directly affect the output.
This means output changes happen only at clock edges (when the state register updates), making Moore outputs inherently registered and glitch-free. This property is highly desirable in FPGA designs.
Moore FSM characteristics
- Stable outputs (outputs depend only on the registered state).
- Often 1-cycle latency: input → next_state → state update (clock edge) → output update.
- Good for outputs that must be glitch-free (chip enables, control strobes, critical control signals).
Moore FSM Block Diagram
A Moore FSM consists of three logical blocks:
- Next-State Logic: Combinational logic. Takes current state and inputs → computes next state.
- State Register: Sequential logic (flip-flops). Stores the current state. Updates on the clock edge.
- Output Logic: Combinational logic. Takes only the current state → produces outputs.
MOORE FSM — BLOCK DIAGRAM
Figure 5: Moore FSM Block Diagram (3-Block Architecture)
The Mealy FSM
Understanding Mealy FSM
A Mealy Finite State Machine is an FSM in which the OUTPUTS are a function of BOTH the current state AND the current inputs. The output can change as soon as the input changes, without waiting for the next clock edge.
This means Mealy machines can respond faster (in the same clock cycle as the input), and often require fewer states than an equivalent Moore machine. However, the outputs may exhibit glitches if the inputs change unpredictably.
Mealy FSM characteristics
- Fast response: output can change in the same cycle as input changes (combinational output).
- Potentially fewer states than Moore for some behaviors.
- More sensitive to glitches: inputs must be synchronized/debounced to avoid unstable outputs.
Mealy FSM Block Diagram
Like Moore, a Mealy FSM also consists of three logical blocks, but the Output Logic receives both the current state AND the inputs:
- Next-State Logic: Combinational logic. Takes current state and inputs → computes next state.
- State Register: Sequential logic (flip-flops). Stores the current state. Updates on the clock edge.
- Output Logic: Combinational logic. Takes current state AND inputs → produces outputs.
MEALY FSM — BLOCK DIAGRAM
Figure 6: Mealy FSM Block Diagram (3-Block Architecture)
Moore vs. Mealy: Comparison
Key Differences
| Aspect | Moore FSM | Mealy FSM |
|---|---|---|
| Output definition | Output = f(Current State) | Output = f(Current State, Input) |
| State diagram label | Output inside/below state node | Output on transition arrow (in/out) |
| Number of states | More states required | Fewer states needed |
| Output glitches | Glitch-free (registered output) | Possible if inputs are noisy |
| Response speed | 1 cycle after input | Same cycle as input |
| Initial output | Defined by the initial state | Depends on the state and current input |
Timing of Output
This is one of the most critical differences. Consider a simple sequence where the input goes HIGH at clock cycle N:

Figure 7: Moore vs. Mealy Output Timing Comparison
Complexity and Efficiency
State Count: Mealy machines typically require one fewer state than Moore FSMs for the same behavior, because Mealy machines can produce output during a transition rather than requiring an intermediate state.
Logic Complexity: Mealy output logic is more complex (depends on both state and input), but the reduced state count can result in fewer flip-flops. Moore has simpler output logic but may need more states.
FPGA Resource Usage: For most practical MAX-10 designs, both types use comparable LUT counts. Moore is generally preferred because registered outputs reduce timing concerns.
Applications in Digital Circuits
| Application | Preferred FSM | Reason |
|---|---|---|
| LED / Relay control | Moore | Stable, glitch-free registered output |
| Sequence detector | Mealy | Fewer states, faster recognition |
| UART / SPI protocol | Mealy | Output response needed in the same cycle |
| Traffic light controller | Moore | Clean, synchronous output transitions |
| Debounce logic | Moore | Output stability is a priority |
| Handshake / ACK signals | Mealy | Immediate response to a valid signal |
| Game controller logic | Moore | Predictable state-based outputs |
13.3 Moore FSM Implementation in Verilog
Moore FSM Lab: "Two-Consecutive-High" Detector with a One-Cycle Pulse Output
Introduction
This document presents a structured, engineering-oriented guide to implementing a Moore finite state machine (FSM) in Verilog HDL using three widely used coding styles: 3-tier, 2-tier, and 1-tier. The purpose is not to provide a laboratory procedure, but to demonstrate how the same behavioral specification can be mapped into different RTL organizations, and to clarify the practical trade-offs in readability, maintainability, and verification.
As a running example, we implement a synchronous “two-consecutive-high” detector: when the input ain is asserted for two consecutive clock cycles, the circuit generates a single-clock-cycle pulse on output z; otherwise, z remains low. The FSM is designed as a Moore machine, meaning the output is determined solely by the current state. This example is intentionally small (three states) so that the structural differences among the three implementation styles are easy to see and compare.
Inputs and Outputs
- Inputs:
- clk : system clock
- rst_n : active-low reset
- ain : 1-bit input signal
- Output:
- z : 1-bit output pulse
Functional Specification
- If ain is high for two consecutive clock cycles, then output z becomes high for exactly one clock cycle (one-cycle pulse).
- In all other cases, z = 0.
- The design must be a Moore FSM (output depends only on the current state).

You will implement the same Moore FSM using three Verilog HDL coding styles:
- 3-tier (3 always blocks)
- 2-tier (2 always blocks)
- 1-tier (1 always block)
3-Tier Moore Implementation (3 always blocks)
3-Tier Implementation (3 always blocks)
The 3-tier style is the most recommended. It separates three concerns into three always blocks:
- Block A: always @(*) for Next-State Logic (combinational)
- Block B: always @(posedge clk or negedge rst_n) for the State Register (sequential, clocked)
- Block C: always @(*) for Moore Output Logic (z = f(curState), combinational)

fsm_pulse_3tier / Verilog
// =====================================================================================
// Moore FSM — 3-Tier / 3-Always Block Style
// =====================================================================================
// Description : Two-Consecutive-High Detector with a One-Cycle Pulse Output (Moore FSM)
// Synthesizer : Altera Quartus Prime V2x
// Platform : Intel Altera MAX-10 FPGA
// =====================================================================================
module fsm_pulse_3tier (clk, rst_n, ain, z);
input clk;
input rst_n;
input ain;
output z;
// State encoding (2 bits is enough for 3 states)
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [1:0] currState;
reg [1:0] nextState;
reg z;
//----------------------------------------------------------------------------------
// A) Next-state logic (combinational)
always @(*) begin
nextState = currState; // default
case (state)
S0: begin
if (ain) nextState = S1;
else nextState = S0;
end
S1: begin
if (ain) nextState = S2;
else nextState = S0;
end
S2: begin
nextState = S0; // regardless of ain
end
default: begin
nextState = S0;
end
endcase
end
//----------------------------------------------------------------------------------
// B) State register (sequential)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
currState <= S0;
else
currState <= nextState;
end
//----------------------------------------------------------------------------------
// C) Output logic (Moore: z depends only on currState)
always @(*) begin
case (currState)
S0: z = 1'b0;
S1: z = 1'b0;
S2: z = 1'b1;
default: z = 1'b0;
endcase
end
endmodule
Testbench
This testbench verifies the expected timing of the 3-tier/2-tier Moore structure (where z is driven by the current state).
Testbench / Verilog
`timescale 1ns/1ps
module fsm_pulse_tb();
reg clk;
reg rst_n;
reg ain;
wire z;
// Select one DUT
fsm_pulse_3tier DUT (.clk(clk), .rst_n(rst_n), .ain(ain), .z(z));
// fsm_pulse_2tier DUT (.clk(clk), .rst_n(rst_n), .ain(ain), .z(z));
// fsm_pulse_1tier DUT (.clk(clk), .rst_n(rst_n), .ain(ain), .z(z));
// 10ns clock period
initial clk = 1'b0;
always #5 clk = ~clk;
//----------------------------------------------------------------------------------
// Apply ain for N cycles (update at negedge to avoid race)
task apply_ain;
input val;
input integer cycles;
integer i;
begin
for (i = 0; i < cycles; i = i + 1) begin
@(negedge clk);
ain = val;
end
end
endtask
//----------------------------------------------------------------------------------
// Expected z for 3-tier/2-tier Moore FSM:
// z(k) = 1 if ain was 1 in BOTH of the two previous sampled cycles.
reg ain_d1, ain_d2;
reg expected_z;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ain_d1 <= 1'b0;
ain_d2 <= 1'b0;
expected_z <= 1'b0;
end else begin
ain_d2 <= ain_d1;
ain_d1 <= ain;
expected_z <= (ain_d2 & ain_d1);
end
end
//----------------------------------------------------------------------------------
initial begin
// init
ain = 1'b0;
rst_n = 1'b0;
// reset
repeat (2) @(negedge clk);
rst_n = 1'b1;
// Test 1: all zeros
apply_ain(1'b0, 2);
// Test 2: single '1' only (no pulse)
apply_ain(1'b1, 1);
apply_ain(1'b0, 3);
// Test 3: two consecutive '1' (one pulse)
apply_ain(1'b1, 2);
apply_ain(1'b0, 3);
// Test 4: long run of '1' (pulses repeat as machine restarts)
apply_ain(1'b1, 6);
apply_ain(1'b0, 3);
// Test 5: broken pattern 1,0,1,1
apply_ain(1'b1, 1);
apply_ain(1'b0, 1);
apply_ain(1'b1, 2);
apply_ain(1'b0, 3);
$display("PASS: All tests passed.");
$stop;
end
endmodule
Waveform Screen Capture and Waveform Explanation
The waveform from your simulator (ModelSim/Questa/Quartus simulation) is shown below:
Waveform Screen Capture and Waveform Explanation
You must capture waveforms from your simulator (ModelSim/Questa/Quartus simulation). Add these signals: clk, rst_n, ain, z (add internal state if possible).
Expected waveform behavior:
- z goes high for exactly one cycle only after ain has been high for two consecutive cycles.
- After the pulse, z returns to 0.
- If ain stays high for a long time, the FSM repeats S0→S1→S2→S0, so z will periodically pulse (once per cycle when S2 is reached).
Advantages and Disadvantages
| Type | Details |
|---|---|
| ✅ Advantage | Maximum readability — each block has one clear purpose. |
| ✅ Advantage | Easiest to debug — trace next-state, state, and output separately in simulation. |
| ✅ Advantage | Industry standard — most Verilog style guides recommend this approach. |
| ✅ Advantage | Synthesis-friendly — tools can easily identify and optimize each block independently. |
| ✅ Advantage | Safe — separate always blocks reduce the risk of unintentional latches. |
| ❌ Disadvantage | Slightly more verbose — more lines of code for the same logic. |
| ❌ Disadvantage | Three always blocks can feel repetitive for very simple FSMs. |
2-Tier Moore Implementation (2 always blocks)
2-Tier Implementation (2 always blocks)
The 2-tier style merges Next-State Logic and Output Logic into a single combinational block.
- Block A: always @(*) combines next-state logic and Moore output
- Block B: always @(posedge clk or negedge rst_n) is the state register

fsm_pulse_2tier / Verilog
// ================================================================
// Moore FSM — 2-Tier / 2-Always Block Style
// ================================================================
module fsm_pulse_2tier (clk, rst_n, ain, z);
input clk;
input rst_n;
input ain;
output z;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [1:0] currState;
reg [1:0] nextState;
reg z;
// A) Next-state + output combined (combinational)
always @(*) begin
// Moore output from current state
if (currState == S2) z = 1'b1;
else z = 1'b0;
// Next-state default
nextState = currState;
case (currState)
S0: nextState = (ain) ? S1 : S0;
S1: nextState = (ain) ? S2 : S0;
S2: nextState = S0;
default: nextState = S0;
endcase
end
// B) State register
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
currState <= S0;
else
currState <= nextState;
end
endmodule
Advantages and Disadvantages
| Type | Details |
|---|---|
| ✅ Advantage | More compact — fewer lines of code. |
| ✅ Advantage | Output and next-state are co-located — easy to see what each state does at a glance. |
| ✅ Advantage | Clear separation between sequential (Block 2) and combinational (Block 1) intent. |
| ❌ Disadvantage | Harder to read for large FSMs with many outputs or many states. |
| ❌ Disadvantage | Must always provide default assignments to avoid latches. |
| ❌ Disadvantage | Mixing output and next-state can cause confusion, especially for Mealy FSMs. |
1-Tier Moore Implementation (1 always block)
The 1-tier style combines ALL logic — next-state, state register, and output — into a SINGLE clocked always block.
- Set a default z <= 0 every cycle
- In S2, set z <= 1 for one cycle, and return to S0
Important: In a 1-tier style, z is typically a registered output. The behavior still meets the specification (one-cycle pulse), but the output timing is driven by the clocked block.

fsm_pulse_1tier / Verilog
module fsm_pulse_1tier (clk, rst_n, ain, z);
input clk;
input rst_n;
input ain;
output z;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [1:0] state;
reg z;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= S0;
z <= 1'b0;
end else begin
// default output each cycle
z <= 1'b0;
case (state)
S0: begin
if (ain) state <= S1;
else state <= S0;
end
S1: begin
if (ain) state <= S2;
else state <= S0;
end
S2: begin
z <= 1'b1; // one-cycle pulse
state <= S0; // return to S0 regardless of ain
end
default: begin
state <= S0;
z <= 1'b0;
end
endcase
end
end
endmodule
Advantages and Disadvantages
| Type | Details |
|---|---|
| ✅ Advantage | Maximum readability — each block has one clear purpose. |
| ✅ Advantage | Easiest to debug — trace next-state, state, and output separately in simulation. |
| ✅ Advantage | Industry standard — most Verilog style guides recommend this approach. |
| ✅ Advantage | Synthesis-friendly — tools can easily identify and optimize each block independently. |
| ✅ Advantage | Safe — separate always blocks reduce the risk of unintentional latches. |
| ❌ Disadvantage | Slightly more verbose — more lines of code for the same logic. |
| ❌ Disadvantage | Three always blocks can feel repetitive for very simple FSMs. |
Comparison: 3-Tier vs. 2-Tier vs. 1-Tier (Moore)
| Criterion | 3-Tier | 2-Tier | 1-Tier |
|---|---|---|---|
| Code length | Longest | Medium | Shortest |
| Readability | Highest | Good | Lowest (large FSMs) |
| Debugging ease | Easiest | Good | Hardest |
| Latch risk | Lowest | Low (need defaults) | None (all clocked) |
| Output latency | Combinational (fast) | Combinational (fast) | Registered (+1 cycle) |
| Output glitch risk | Low | Low | None |
| Recommended for | All FSMs / complex | Small–medium FSMs | Simple FSMs only |
| Industry use | Most common | Common | Rare |
13.4 Mealy FSM Implementation in Verilog
Mealy FSM Lab: "Two-Consecutive-High" Detector with a One-Cycle Pulse Output
Introduction
Here, explains how to implement the same “two-consecutive-high detector” as a Mealy finite state machine (FSM) using Verilog HDL. Three RTL coding organizations are presented: 3-tier, 2-tier, and 1-tier. The objective is to show how a Mealy output (a function of state and input) affects RTL structure, output timing, and verification expectations.
In a Mealy machine, outputs can change immediately with input changes (within the same clock cycle), reducing latency compared to a Moore machine. However, because outputs may depend directly on the input, the design must assume the input is synchronous (or properly synchronized) to avoid glitches.
Inputs and Outputs
- Inputs:
- clk : system clock
- rst_n : active-low reset
- ain : 1-bit input signal
- Output:
- z : 1-bit output pulse
Behavioral Requirement (Same Project Goal)
- If ain is high for two consecutive clock cycles, generate a one-clock-cycle pulse on z; otherwise, z = 0.
- Keep the same conceptual "count consecutive highs" behavior, but we implement z as a Mealy output, i.e., z = f(state, ain).
Mealy FSM Model (states and transitions)

3-Tier Mealy Implementation (3 always blocks)
3-Tier Mealy Implementation (3 always blocks)
The 3-tier style is the most recommended. It separates three concerns into three always blocks:
- Block A: always @(*) for Next-State Logic (combinational)
- Block B: always @(posedge clk or negedge rst_n) for the State Register (sequential, clocked)
- Block C: always @(*) for Mealy Output Logic (z = f(curState, ain), combinational)

fsm_pulse_3tier / Verilog
// =====================================================================================
// Mealy FSM — 3-Tier / 3-Always Block Style
// =====================================================================================
// Description : Two-Consecutive-High Detector with a One-Cycle Pulse Output (Moore FSM)
// Synthesizer : Altera Quartus Prime V2x
// Platform : Intel Altera MAX-10 FPGA
// =====================================================================================
module fsm_mealy_pulse_3tier (clk, rst_n, ain, z);
input clk;
input rst_n;
input ain;
output z;
// State encoding
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [1:0] currState;
reg [1:0] nextState;
reg z;
//----------------------------------------------------------------------------------
// (1) Next-state logic (combinational)
always @(*) begin
case (currState)
S0: begin
if (ain) nextState = S1;
else nextState = S0;
end
S1: begin
if (ain) nextState = S2; // second consecutive high
else nextState = S0;
end
S2: begin
nextState = S0;
end
default: begin
nextState = S0;
end
endcase
end
//----------------------------------------------------------------------------------
// (2) State register (sequential)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
currState <= S0;
else
currState <= nextState;
end
//----------------------------------------------------------------------------------
// (3) Output logic (Mealy: depends on currState and input)
// Pulse asserted immediately when the second '1' is observed while in S1.
always @(*) begin
case (currState)
S0: z = 1'b0;
S1: z = 1'b0;
S2: z = 1'b1;
default: z = 1'b0;
endcase
end
endmodule
Testbench
Testbench / Verilog
`timescale 1ns/1ps
module fsm_mealy_pulse_tb();
reg clk;
reg rst_n;
reg ain;
wire z;
// Select ONE DUT:
fsm_mealy_pulse_3tier DUT (.clk(clk), .rst_n(rst_n), .ain(ain), .z(z));
// fsm_mealy_pulse_2tier DUT (.clk(clk), .rst_n(rst_n), .ain(ain), .z(z));
// fsm_mealy_pulse_1tier DUT (.clk(clk), .rst_n(rst_n), .ain(ain), .z(z));
// 10ns clock
initial clk = 1'b0;
always #5 clk = ~clk;
//----------------------------------------------------------------------------------
// Apply ain on negedge to avoid race
task apply_ain;
input val;
input integer cycles;
integer i;
begin
for (i = 0; i < cycles; i = i + 1) begin
@(negedge clk);
ain = val;
end
end
endtask
//----------------------------------------------------------------------------------
// Expected z for THIS Mealy FSM:
// z should assert when the second consecutive '1' occurs.
// That corresponds to: ain_d1==1 AND ain==1 (current sampled cycle is second '1').
reg ain_d1;
reg expected_z;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ain_d1 <= 1'b0;
expected_z <= 1'b0;
end else begin
expected_z <= (ain_d1 & ain);
ain_d1 <= ain;
end
end
//----------------------------------------------------------------------------------
initial begin
ain = 1'b0;
rst_n = 1'b0;
repeat (2) @(negedge clk);
rst_n = 1'b1;
// Test 1: all zeros -> no pulse
apply_ain(1'b0, 2);
// Test 2: single 1 -> no pulse
apply_ain(1'b1, 1);
apply_ain(1'b0, 3);
// Test 3: two consecutive 1s -> one pulse on second 1
apply_ain(1'b1, 2);
apply_ain(1'b0, 3);
// Test 4: long run of 1s -> pulses every other cycle (second, fourth, sixth, ...)
apply_ain(1'b1, 6);
apply_ain(1'b0, 3);
// Test 5: broken pattern 1,0,1,1 -> pulse only at the end
apply_ain(1'b1, 1);
apply_ain(1'b0, 1);
apply_ain(1'b1, 2);
apply_ain(1'b0, 3);
$display("PASS: All tests passed.");
$stop;
end
endmodule
Waveform Screen Capture and Explanation
You must capture waveforms in your simulator. Add signals:
- clk, rst_n, ain, currState, nextState, z
(optionally internal state/next_state)
Explain in the report:
- z asserts when the second consecutive high occurs (Mealy output reacts within the same cycle).
- For input pattern "… 1, 1 …", z becomes 1 during the second "1" cycle.
- After that, the FSM enters S2 and then re-arms based on ain.
Expected Waveform Behavior (conceptual)
- Example: ain = 0 1 1 0
z should pulse on the second '1' immediately:
- Long run example: ain = 0 1 1 1 1 1 0
z pulses every other cycle after the first two highs:
Advantages and Disadvantages
| Type | Details |
|---|---|
| ✅ Advantage | Cleanly separates next-state, state register, and output — industry best practice. |
| ✅ Advantage | Correct Mealy behavior: output is combinational (depends on input + state simultaneously). |
| ✅ Advantage | Easier to verify in simulation — each block can be inspected separately. |
| ❌ Disadvantage | Output is combinational — susceptible to glitches if sw is noisy (use debounce logic). |
| ❌ Disadvantage | Slightly more verbose than 2-tier or 1-tier styles. |
2-Tier Mealy Implementation (2 always blocks)

fsm_pulse_2tier / Verilog
// =====================================================================================
// Mealy FSM — 2-Tier / 2-Always Block Style
// =====================================================================================
// Description : Two-Consecutive-High Detector with a One-Cycle Pulse Output (Moore FSM)
// Synthesizer : Altera Quartus Prime V2x
// Platform : Intel Altera MAX-10 FPGA
// =====================================================================================
module fsm_mealy_pulse_2tier (clk, rst_n, ain, z);
input clk;
input rst_n;
input ain;
output z;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [1:0] currState;
reg [1:0] nextState;
reg z;
// (1) Next-currState + output combined (combinational)
always @(*) begin
// Mealy output
case (currState)
S0: z = 1'b0;
S1: z = 1'b0;
S2: z = 1'b1;
default: z = 1'b0;
endcase
case (currState)
S0: nextState = (ain) ? S1 : S0;
S1: nextState = (ain) ? S2 : S0;
S2: nextState = S0;
default: nextState = S0;
endcase
end
// (2) currState register (sequential)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
currState <= S0;
else
currState <= nextState;
end
endmodule
Testbench
Reuse the same testbench as in the 3-tier section; just switch the DUT instance.
Waveform + Expected Behavior
Should match 3-tier, because both implement the same Mealy equations.
Advantages and Disadvantages
| Type | Details |
|---|---|
| ✅ Advantage | Compact — fewer always blocks while maintaining correct Mealy behavior. |
| ✅ Advantage | Transition and output are co-located — easy to see what happens in each state/input combination. |
| ✅ Advantage | Default assignments prevent latches. |
| ❌ Disadvantage | Mixing next-state and output can make large FSMs harder to read. |
| ❌ Disadvantage | Still has combinational output — glitch risk from noisy inputs. |
1-Tier Mealy Implementation (1 always block)
⚠️ Important Warning
A true Mealy FSM should NOT be implemented in a single clocked always block, because the Mealy output must be COMBINATIONAL. If you put everything in a clocked block, the output becomes registered (making it behave like a Moore machine). The example below shows a Registered Mealy variant — use it only when glitch-free output is more important than immediate response.

fsm_pulse_1tier / Verilog
// ================================================================
// Mealy FSM — 1-Tier / 1-Always Block Style
// ================================================================
// ⚠️ WARNING: Output is registered here (delayed 1 cycle).
// This is a "Registered Mealy" — output is NOT purely combinational.
// Use this only when glitch-free output is more important than
// immediate response. For true Mealy behavior → use 3-tier.
// ================================================================
module fsm_mealy_pulse_1tier ( clk, rst_n, ain, z);
input clk;
input rst_n;
input ain;
output z;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [1:0] currState;
// Single clocked block: currState update only
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
currState <= S0;
end else begin
case (currState)
S0: currState <= (ain) ? S1 : S0;
S1: currState <= (ain) ? S2 : S0;
S2: currState <= S0;
default: currState <= S0;
endcase
end
end
// True Mealy output (combinational from currState and input)
assign z = (currState == S2) ? 1'b1 : 1'b0;
endmodule
Advantages and Disadvantages
| Type | Details |
|---|---|
| ✅ Advantage | Most compact style. |
| ✅ Advantage | Registered output — no glitches from noisy inputs. |
| ✅ Advantage | No latches — everything is in a single clocked block. |
| ❌ Disadvantage | The output is delayed by 1 clock cycle — this is NOT true Mealy behavior. |
| ❌ Disadvantage | Semantically incorrect for a true Mealy FSM (output should be combinational). |
| ❌ Disadvantage | Difficult to debug and extend to more complex FSMs. |
| ❌ Disadvantage | Not recommended if immediate output response is required. |
Comparison: 3-Tier vs. 2-Tier vs. 1-Tier (Mealy)
| Criterion | 3-Tier | 2-Tier | 1-Tier |
|---|---|---|---|
| Code length | Longest | Medium | Shortest |
| True Mealy behavior | ✅ Yes (combinational) | ✅ Yes (combinational) | ❌ No (registered) |
| Output latency | Same cycle as input | Same cycle as input | 1 cycle after input |
| Glitch risk | Yes (comb. path) | Yes (comb. path) | None (registered) |
| Recommended for | Standard Mealy design | Compact designs | Glitch-free priority |
| Industry use | Most common | Common | Rare/special purpose |
13.5
13.6
13.7
13.8
13.9
13.10
Conclusion
Finite State Machines are a cornerstone of digital system design. Mastering FSM theory and implementation in Verilog HDL enables you to build reliable, well-structured digital controllers on FPGAs and ASICs.
In this lecture article, we have covered:
- The theoretical foundation of FSMs: states, transitions, inputs, and outputs.
- The two primary FSM types: Moore (output from state) and Mealy (output from state and input).
- How to construct state diagrams and state transition tables as design tools.
- Three different Verilog coding styles (3-tier, 2-tier, 1-tier) for both Moore and Mealy FSMs.
- Practical implementation considerations, including timing, glitch-free outputs, and latch avoidance.
- Step-by-step guidance for synthesizing, pin-assigning, and programming FSMs on Altera MAX-10 FPGAs using Quartus Prime v25.
As a general rule of thumb for FPGA-based FSM design:
| Scenario | Recommendation |
|---|---|
| Default FSM style | Moore FSM with 3-tier always blocks |
| Need fewer states / fast output | Mealy FSM with 3-tier always blocks |
| Glitch-free output critical | Moore FSM (all tiers) or 1-tier Mealy |
| Quick prototyping | 2-tier style (compact, readable) |
| Complex multi-output FSM | Always use 3-tier style |
| Quartus encoding | One-Hot for performance, User-Encoded for clarity |
With this knowledge, you are well-equipped to design FSM-based controllers for a wide range of embedded and digital systems projects on the Intel MAX-10 platform.

