A pattern detector is a finite state machine that monitors a serial bit stream and raises its output whenever a specific multi-bit pattern has been received. The Verilog Sequence Detector article built a detector for a short pattern. This article applies the same method to a longer pattern, 110101, where choosing the right state after a mismatch becomes more important.

12 min read | Intermediate Level

What You'll Learn

  • Derive every state transition of a pattern detector with the longest-suffix rule
  • Write an overlapping 110101 detector as a Moore FSM in Verilog
  • Compare an FSM detector with a shift register and comparator
  • Choose test stimulus that actually exposes transition bugs

Deriving the Transitions

The detector has one state for each prefix of the pattern that has been matched: IDLE (nothing), S1, S11, S110, S1101, S11010 and S110101 (full match). When the next bit continues the pattern, the FSM moves forward one state. When it does not, the FSM moves to the state for the longest ending of the received bits that is also a start of the pattern. This is the longest-suffix rule.

Current statein = 1in = 0Reasoning for the mismatch case
IDLES1IDLE"0" does not start the pattern
S1S11IDLE"10" ends in nothing useful
S11S11S110"111" still ends in "11"
S110S1101IDLE"1100" ends in nothing useful
S1101S11S11010"11011" ends in "11"
S11010S110101IDLE"110100" ends in nothing useful
S110101S11IDLE"1101011" ends in "11"; "1101010" in nothing useful

The two transitions in bold are easy to get wrong. In S1101, a 1 breaks the pattern, but the last two bits received are "11", which is the start of a new "110101", so the FSM goes to S11, not IDLE. In S110101, a 1 again leaves "11" at the end of the stream. Taking that transition makes this an overlapping detector: a pattern that begins with the last bit of the previous match is still detected.

Quick Check

Q: The stream is 110110101. Where does the pattern 110101 end, and which transition must be correct to detect it?

Show Answer

It occupies bits 4 to 9 and ends at the last bit. After "1101" (bits 1 to 4), bit 5 is a 1, so the FSM must go from S1101 to S11. Bits 4 and 5 form the "11" that starts the match. Going to IDLE instead would lose bit 4, and the pattern would never be detected.

Design


module det_110101 ( input clk,
                  	 input rstn,
                  	 input in,
                  	 output out );

  // 7 states need a 3-bit state register
  localparam IDLE 	= 0,
  			S1 		= 1,
  			S11 	= 2,
  			S110 	= 3,
  			S1101 	= 4,
  			S11010 	= 5,
  			S110101 = 6;

  reg [2:0] cur_state, next_state;

  // Moore output: high only in the state where the full pattern has been received
  assign out = cur_state == S110101 ? 1 : 0;

  // State register
  always @ (posedge clk) begin
    if (!rstn)
      	cur_state <= IDLE;
     else
     	cur_state <= next_state;
  end

  // Next-state logic, following the transition table
  always @ (cur_state or in) begin
    case (cur_state)
      IDLE : begin
        if (in) next_state = S1;
        else 	next_state = IDLE;
      end

      S1: begin
        if (in) next_state = S11;
        else 	next_state = IDLE;
      end

      S11: begin
        if (!in) next_state = S110;
        else 	next_state = S11;       // "111": stay, still have "11"
      end

      S110 : begin
        if (in) next_state = S1101;
        else 	next_state = IDLE;
      end

      S1101 : begin
        if (!in) next_state = S11010;
        else 	next_state = S11;       // "11011": keep the trailing "11"
      end

      S11010: begin
        if (in) next_state = S110101;
        else 	next_state = IDLE;
      end

      S110101: begin
        if (in) next_state = S11;       // "1101011": keep the trailing "11" (overlap)
        else 	next_state = IDLE;
      end

      default : next_state = IDLE;      // Code 7 is unused
    endcase
  end
endmodule

Synthesis result: The tool builds a 3-bit state register with synchronous reset, next-state logic for the 14 transitions, and a decoder for state 6 (3'b110) that drives out. Synthesis tools usually recognize this as an FSM and may re-encode it, for example as one-hot with 7 flip-flops, if that meets timing better.

Where are Pattern Detectors Used?

Wired network frames begin with a preamble of alternating bits followed by a start-of-frame delimiter, a byte whose last two bits break the alternating pattern. The receiver runs a pattern detector on the incoming bits to find that delimiter, which tells it exactly where the frame's first data bit begins.

Testbench

The testbench holds reset for five clock edges, then drives the pattern twice, back to back. A $strobe at each rising edge prints in and out after all updates for that edge.


module tb;
  reg clk, in, rstn;
  wire out;
  integer l_dly;

  always #10 clk = ~clk;

  det_110101 u0 ( .clk(clk), .rstn(rstn), .in(in), .out(out) );

  // Print the values at the end of each rising-edge time step
  always @ (posedge clk)
    $strobe ("T=%0t in=%0b out=%0b", $time, in, out);

  initial begin
  	clk <= 0;
    rstn <= 0;
    in <= 0;

    repeat (5) @ (posedge clk);
    rstn <= 1;

    @(posedge clk) in <= 1;
    @(posedge clk) in <= 1;
    @(posedge clk) in <= 0;
    @(posedge clk) in <= 1;
    @(posedge clk) in <= 0;
    @(posedge clk) in <= 1;   // First 110101 complete
    @(posedge clk) in <= 1;
    @(posedge clk) in <= 1;
    @(posedge clk) in <= 0;
    @(posedge clk) in <= 1;
    @(posedge clk) in <= 0;
    @(posedge clk) in <= 1;   // Second 110101 complete

    #100 $finish;
  end
endmodule
Output
ncsim> run
T=10 in=0 out=0
T=30 in=0 out=0
T=50 in=0 out=0
T=70 in=0 out=0
T=90 in=0 out=0
T=110 in=1 out=0
T=130 in=1 out=0
T=150 in=0 out=0
T=170 in=1 out=0
T=190 in=0 out=0
T=210 in=1 out=0
T=230 in=1 out=1
T=250 in=1 out=0
T=270 in=0 out=0
T=290 in=1 out=0
T=310 in=0 out=0
T=330 in=1 out=0
T=350 in=1 out=1
T=370 in=1 out=0
T=390 in=1 out=0
T=410 in=1 out=0
Simulation complete via $finish(1) at time 430 NS + 0

The first pattern is driven from 110 to 210 ns, and out is 1 at 230 ns, one clock after the last bit, as expected for a Moore output. The second pattern is driven from 230 to 330 ns and detected at 350 ns. Each detection lasts exactly one clock cycle.

This stimulus does not test the difficult transitions.

The two patterns in this testbench are separate and never trigger S1101 with a 1 or S110101 with a 1. A design that sends both of those transitions to the wrong state produces exactly the same log. To catch such bugs, the stimulus must include streams such as 110110101 and 11010110101, or a long random stream checked against a reference model, as in the practice exercise below.

Debug and Test Mode Entry

Many chips enter a test or debug mode only after a specific sequence of values is applied to certain pins or written to a register. A pattern detector watches for that sequence, so the mode cannot be entered by accident during normal operation, for example from noise on a pin during power-up.

FSM vs Shift Register Implementation

The same detector can be built without an FSM: shift each incoming bit into a 6-bit register and compare the register with the pattern.


reg [5:0] sh;
always @(posedge clk)
  if (!rstn) sh <= 6'b0;
  else       sh <= {sh[4:0], in};    // Last 6 bits, newest at bit 0

assign out = (sh == 6'b110101);
FSMShift register + comparator
Flip-flops$clog2(states), 3 herePattern length, 6 here
LogicNext-state logic derived from the transition tableOne 6-input comparison
Design effortEvery transition must be worked out correctlyAlmost none, and always overlapping
Long patterns (e.g. 32 bits)Fewer flip-flops, but many states32 flip-flops and a 32-bit comparator
Changing the patternNew states and transitionsChange one constant, or make it a register input

For short fixed patterns, or patterns that must be programmable, the shift register is often simpler and less error-prone. The FSM approach saves flip-flops for long patterns and extends naturally to detectors whose behavior depends on more than the last N bits, such as patterns with variable gaps.

Quick Check

Q: If both versions are reset and then receive the same stream, will their out signals always match?

Show Answer

Yes. In the FSM, each state stands for the longest ending of the received bits that starts the pattern, so the FSM reaches S110101 exactly when the last six bits are 110101. That is the same condition the comparator checks. Both outputs follow registers updated on the same edge, so they match cycle for cycle. This is why the shift register version is a good reference model for testing the FSM.

Infrared Remote Control Receivers

Infrared remote controls send each command as a burst of pulses that starts with a fixed header and device address. The receiver chip in a television or set-top box decodes the pulses into bits and uses a pattern detector to recognize its own address before it accepts the command that follows.

Common Beginner Mistakes

Mistake #1: Sending every mismatch back to IDLE

Wrong: S1101: if (!in) next_state = S11010; else next_state = IDLE;
Right: else next_state = S11;

Why? After "11011", the last two bits are "11", which can start a new match. Going to IDLE throws them away, so the stream 110110101 is never detected. Apply the longest-suffix rule to every mismatch, using a table like the one at the start of this article.

Mistake #2: Restarting from S1 after a full match

Wrong: S110101: if (in) next_state = S1;
Right: S110101: if (in) next_state = S11;

Why? The last bit of the match is a 1, and the new bit is also a 1, so the stream ends in "11". Going to S1 keeps only one of them. In 11010110101, the second pattern shares its first bit with the end of the first, and the S1 version misses it.

Mistake #3: No default for unused state codes

Wrong: A case with only the seven state items for a 3-bit register
Right: Add default: next_state = IDLE;

Why? Code 7 is not assigned to any state. Without a default, next_state is unassigned in that case, so synthesis infers a latch, and an FSM that reaches code 7 through an upset has no defined way out.

Mistake #4: Testing only clean, separated patterns

Wrong: A testbench that sends the pattern a few times with no near-misses or overlaps
Right: Add streams that exercise every mismatch transition, plus long random streams compared against a reference model

Why? As the log in this article shows, a clean directed test passes even when two transitions are wrong. Each wrong transition only shows up with a specific bit history, which random stimulus finds much more reliably than hand-written patterns.

Practice Exercise

Challenge: Self-Checking Random Testbench

Write a testbench tb_check that drives 500 random bits into det_110101, one per clock, and checks out on every clock against a shift register reference model. Print an error for every mismatch and a pass or fail summary at the end.

Hint

Inside the testbench, keep reg [5:0] sh updated with sh <= {sh[4:0], in} on the same clock edge as the design. The expected output is then (sh == 6'b110101). Compare it with out on the falling edge, when both have settled.

Solution

module tb_check;
  reg clk = 0, rstn = 0, in = 0;
  wire out;
  reg [5:0] sh;                 // Reference model: last 6 sampled bits
  integer i, errors = 0;

  always #10 clk = ~clk;

  det_110101 u0 ( .clk(clk), .rstn(rstn), .in(in), .out(out) );

  // Reference model, clocked exactly like the design
  always @(posedge clk)
    if (!rstn) sh <= 6'b0;
    else       sh <= {sh[4:0], in};

  // Compare on the falling edge, away from the rising edge updates
  always @(negedge clk)
    if (rstn && (out !== (sh == 6'b110101))) begin
      $display("[%0t] ERROR: out=%b expected=%b", $time, out, (sh == 6'b110101));
      errors = errors + 1;
    end

  initial begin
    repeat (3) @(posedge clk);
    rstn <= 1;

    for (i = 0; i < 500; i = i + 1)
      @(posedge clk) in <= $random;   // Bit 0 of a random number

    @(posedge clk);
    if (errors == 0) $display("PASS: 500 random bits, no mismatches");
    else             $display("FAIL: %0d mismatches", errors);
    $finish;
  end
endmodule

With the corrected design, every check passes. If you change the S1101 or S110101 transition back to the wrong state from the mistakes above, 500 random bits almost always produce a stream that exposes it, and the testbench reports the exact time of the first error.

Summary

In this tutorial, you learned:

  • A pattern detector has one state per matched prefix of the pattern, plus IDLE
  • On a mismatch, the FSM goes to the state for the longest ending of the received bits that starts the pattern
  • For 110101, both S1101 and S110101 must go to S11 on a 1, which also makes the detector overlapping
  • The Moore output rises one clock after the last bit of the pattern is sampled and lasts one cycle
  • A shift register with a comparator gives the same result and makes an excellent reference model
  • Directed tests with clean patterns can miss transition bugs; random stimulus with a reference model finds them
Did you find what you were looking for?

Quiz

Test Your Knowledge

1 of 5 Score: 0 / 5