This article presents two distinct methods for detecting a predefined binary sequence 01110001 in a serial input stream. The output signal match is asserted when the target sequence is detected.
Method 1: Moore Finite State Machine (FSM)
The first approach implements a Moore-type FSM that transitions through states representing progress toward matchign the desired pattern. Each state corresponds to how many bits of the sequence have been correctly matched so far.
`timescale 1ns/1ns
module sequence_detector_fsm (
input clk,
input rst_n,
input data_in,
output reg match
);
// Define states for Moore FSM
localparam IDLE = 4'd0;
localparam B0 = 4'd1;
localparam B01 = 4'd2;
localparam B011 = 4'd3;
localparam B0111= 4'd4;
localparam B01110 = 4'd5;
localparam B011100 = 4'd6;
localparam B0111000 = 4'd7;
localparam B01110001 = 4'd8;
reg [3:0] current_state, next_state;
// State transition logic
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
current_state <= IDLE;
else
current_state <= next_state;
end
// Next state decoding
always @(*) begin
case (current_state)
IDLE: next_state = data_in ? IDLE : B0;
B0: next_state = data_in ? B01 : B0;
B01: next_state = data_in ? B011 : B0;
B011: next_state = data_in ? B0111 : B0;
B0111: next_state = data_in ? IDLE : B01110;
B01110: next_state = data_in ? IDLE : B011100;
B011100: next_state = data_in ? B01 : B0111000;
B0111000: next_state = data_in ? B01110001 : B0;
B01110001: next_state = data_in ? IDLE : B0;
default: next_state = IDLE;
endcase
end
// Output logic (Moore)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
match <= 1'b0;
else if (next_state == B01110001)
match <= 1'b1;
else
match <= 1'b0;
end
endmodule
Testbench for FSM Implemantation
`timescale 1ns/1ns
module tb_sequence_detector_fsm;
reg clk, rst_n, data_in;
wire match;
initial begin
clk = 0;
rst_n = 0;
#10 rst_n = 1;
forever #20 data_in = {$random} % 2;
#1000 $stop;
end
always #10 clk = ~clk;
sequence_detector_fsm uut (
.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.match(match)
);
endmodule
Method 2: Shift Register with Comparator
The second method uses an 8-bit shift register to store the most recent inputs. On each clock cycle, new data enters at the LSB position while older data shifts left. A comparator checks whether the stored value matches the expceted pattern.
`timescale 1ns/1ns
module sequence_detector_shiftreg (
input clk,
input rst_n,
input serial_data,
output reg sequence_match
);
parameter TARGET_SEQ = 8'b01110001;
reg [7:0] shift_reg;
// Update shift register on every clock edge
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
shift_reg <= 8'h00;
else
shift_reg <= {shift_reg[6:0], serial_data};
end
// Compare register contents with target sequence
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
sequence_match <= 1'b0;
else if (shift_reg == TARGET_SEQ)
sequence_match <= 1'b1;
else
sequence_match <= 1'b0;
end
endmodule
Testbench for Shift Register Method
`timescale 1ns/1ns
module tb_sequence_detector_shiftreg;
reg clk, rst_n, serial_data;
wire sequence_match;
initial begin
$dumpfile("waveform.vcd");
$dumpvars(0, tb_sequence_detector_shiftreg);
clk = 0;
rst_n = 0;
#30 rst_n = 1;
forever #20 serial_data = {$random} % 2;
#1000 $stop;
end
always #10 clk = ~clk;
sequence_detector_shiftreg uut (
.clk(clk),
.rst_n(rst_n),
.serial_data(serial_data),
.sequence_match(sequence_match)
);
endmodule
Both implementations provide reliable detection mechanisms for identifying the specified bit pattern within a continuous data stream. The choice between them depends on design constraints such as area, timing requirements, and coding style preferences.