Verilog 시퀀스 디텍터: FSM으로 패턴 '1011' 검출하기
유한 상태 머신(FSM)의 고전적 예제인 시퀀스 디텍터를 Verilog로 구현합니다. 입력 비트 스트림에서 고정 패턴 1011이 나타날 때 출력을 어서트합니다.
상태 정의
| 상태 | 값 | 의미 |
| IDLE | 0 | 초기/매칭 없음 |
| S1 | 1 | '1' 검출 |
| S10 | 2 | '10' 검출 |
| S101 | 3 | '101' 검출 |
| S1011 | 4 | '1011' 완전 매칭 → 출력 1 |
RTL 구현 (무어 머신)
module det_1011 (
input wire clk,
input wire rstn,
input wire in,
output wire out
);
parameter IDLE = 0, S1 = 1, S10 = 2, S101 = 3, S1011 = 4;
reg [2:0] cur_state, next_state;
assign out = (cur_state == S1011); // 무어: 출력은 현재 상태만 의존
// 상태 레지스터 (순차)
always @(posedge clk) begin
if (!rstn) cur_state <= IDLE;
else cur_state <= next_state;
end
// 다음 상태 로직 (조합)
always @(cur_state or in) begin
case (cur_state)
IDLE: next_state = in ? S1 : IDLE;
S1: next_state = in ? IDLE : S10;
S10: next_state = in ? S101 : IDLE;
S101: next_state = in ? S1011 : IDLE;
S1011: next_state = IDLE; // 패턴 완료 후 IDLE로 복귀
default: next_state = IDLE;
endcase
end
endmodule
테스트벤치
module tb;
reg clk, in, rstn; wire out;
always #10 clk = ~clk;
det_1011 u0 (.clk(clk), .rstn(rstn), .in(in), .out(out));
initial begin
clk=0; rstn=0; in=0;
repeat(5) @(posedge clk); rstn=1;
// 직접 패턴 입력: 1-0-1-1
@(posedge clk) in=1;
@(posedge clk) in=0;
@(posedge clk) in=1;
@(posedge clk) in=1; // 여기서 out=1 되어야 함
@(posedge clk) in=0;
@(posedge clk) in=0;
@(posedge clk) in=1;
@(posedge clk) in=1;
@(posedge clk) in=0;
@(posedge clk) in=1;
@(posedge clk) in=1; // 다시 패턴 완료
#100 $finish;
end
endmodule
시뮬레이션 결과 분석
T=190 in=0 out=1 ← 첫 패턴 완료 시점
T=330 in=1 out=1 ← 두 번째 패턴 완료 시점
버그 찾기 챌린지
위 설계에 미묘한 버그가 있습니다. 찾을 수 있나요?
힌트: 오버래핑 패턴 처리
패턴 '1011'에서 마지막 '1'이 다음 패턴의 첫 '1'로 재사용될 수 있습니다 (오버래핑). 현재 설계는 매칭 후 무조건 IDLE로 가므로 오버래핑 패턴을 놓칩니다. 예: 입력 '1011011'에서 두 번째 패턴 시작 '1'이 첫 패턴 끝 '1'과 겹치는데, IDLE로 가버려 검출 실패.
수정 방향 (미리 보기)
S1011 상태에서 in==1이면 S1로 전이 (마지막 1을 다음 패턴의 첫 1로 재사용), in==0이면 IDLE로. 다음 글에서 다룹니다.