Click through state diagrams for Moore and Mealy machines simultaneously. Watch the 1-cycle output latency difference appear live on the waveform — the concept that trips up every interview.
Feed bits above — amber highlight = Mealy OUT=1 fires 1 cycle before Moore OUT=1
Traffic Light FSM (Moore)3 states · no input
RED
Traffic light is a pure Moore FSM — output depends only on the state, no external input drives transitions (a timer does in real hardware).
Moore vs Mealy — At a Glance
Property
Moore FSM
Mealy FSM
Output depends on
Current state only
Current state + current input
Output type
Registered (glitch-free)
Combinational (may glitch)
Output latency
1 cycle after detection
Same cycle as detection
States for "101" detector
4 states (S0–S3)
3 states (S0–S2)
Timing safety
Easier (registered output)
Harder (long comb. path)
Preferred in RTL
Yes — most common
When latency is critical
Waveform label
State name on waveform
State + input on transition
Verilog RTL — "101" Sequence Detector
verilog · moore_101.v
// Moore FSM — "101" Sequence Detector
// Output = 1 when in state S3 (one cycle after pattern completes)
module moore_101 (
input wire clk, rst_n, x,
output reg z
);
localparam S0=2'd0, S1=2'd1, S2=2'd2, S3=2'd3;
reg [1:0] state, nxt;
// State register
always @(posedge clk or negedge rst_n)
if (!rst_n) state <= S0;
else state <= nxt;
// Next-state logic
always @(*) begin
case (state)
S0: nxt = x ? S1 : S0;
S1: nxt = x ? S1 : S2;
S2: nxt = x ? S3 : S0;
S3: nxt = x ? S1 : S2; // overlap support
default: nxt = S0;
endcase
end
// Output logic (function of state only)
always @(*) z = (state == S3);
endmodule
verilog · mealy_101.v
// Mealy FSM — "101" Sequence Detector
// Output = 1 on the SAME cycle as the final '1' of the pattern
module mealy_101 (
input wire clk, rst_n, x,
output reg z
);
localparam S0=2'd0, S1=2'd1, S2=2'd2;
reg [1:0] state, nxt;
// State register
always @(posedge clk or negedge rst_n)
if (!rst_n) state <= S0;
else state <= nxt;
// Next-state and output logic (function of state AND input)
always @(*) begin
z = 1'b0; nxt = state;
case (state)
S0: if (x) begin nxt = S1; end else nxt = S0;
S1: if (x) begin nxt = S1; end else nxt = S2;
S2: if (x) begin nxt = S1; z = 1'b1; end // z=1 immediately!
else begin nxt = S0; end
default: nxt = S0;
endcase
end
endmodule
Frequently Asked Questions
In a Moore FSM the output depends only on the current state. In a Mealy FSM the output depends on both the current state and the current input. This makes Mealy outputs available one clock cycle earlier — the output fires on the same cycle as the triggering input rather than waiting for the next state register update.
Moore output is registered — it only changes after the state register updates on the next rising clock edge. Mealy output is combinational — it responds to the input in the same clock cycle. Feed "1-0-1" above and watch: MEALY_OUT goes high on the same cycle as the last '1'; MOORE_OUT goes high one cycle later, after the FSM has transitioned into S3.
Moore FSMs are generally safer: outputs are registered (glitch-free), easier to pipeline, and simpler to meet timing constraints with. Mealy FSMs use fewer states and respond one cycle faster, but Mealy outputs form long combinational paths that are harder to constrain and prone to glitches. Most production RTL uses Moore encoding unless low latency is critical.
Moore requires 4 states (S0 start, S1 seen-1, S2 seen-10, S3 seen-101 with output=1). Mealy requires only 3 states (S0, S1, S2) because the output=1 is carried on the S2→S1 transition rather than requiring a dedicated accepting state. Mealy FSMs always require fewer or equal states compared to equivalent Moore FSMs.
Yes. After detecting "101", the trailing '1' is reused as the start of the next potential sequence. In Moore: from S3, input=1 goes to S1 (not S0). In Mealy: from the S2→S1 transition (output=1), the FSM is now in S1 (already has the first '1' of the next pattern). This is the overlapping (non-greedy) variant — the more common implementation in interviews.
Standard 3-always-block style: (1) State register: clocked always block, updates state on posedge clk. (2) Next-state logic: combinational always block with case statement. (3) Output logic: combinational assign or always block — for Moore, output = f(state); for Mealy, output = f(state, input). Parameterize state encoding with localparam.