Verilog_RTL 설계

[Verilog_RTL]_FSM_moore

juniha 2025. 6. 20. 18:36

유한 상태 머신 (Finite State Machine, FSM)

  •   지털 논리 설계, 컴퓨터 제어 시스템의 동작을 상태와 상태 간의 전이로 표현하는 개념적 모델이다. 
  • 입력에 따라 일정한 상태(state)를 가지며, 현재 상태와 입력 값에 의해 다음 상태(next state) 와 출력이 결정된다.
  • 시스템이 가질 수 있는 상태의 수가 유한하므로 Finte(유한) 상태 머신이라 부른다.
  • 동작 방식에는 Mealy modelMoore model 이 있다.

Moore Machine 특징

  • 출력이 현재 상태에만 의존한다. _출력이 상태에만 의존하므로 Mealy FSM와 비교적 간단하다
  • 출력 = f(현재 상태)
  • 출력이 state가 바뀔 때만 변한다.
  • 건트롤러, 상태 기반 시스템 저어 등에서 사용된다.
  • 출력이 상태에만 의존하므로 더 안정적이고 예슥 가능한 동작을 요구하는 시스템에 적합하다.

Moore Model FSM의 상태도

 

사용 코드

module fsm_moore (
    iCLK,      // 1MHz 기준 클록
    iRESETn,   // Active-Low reset (0이면 FSM 리셋)
    iIN,       // Moore FSM 입력 신호 (1비트 입력)
    oOUT,      // Moore FSM 출력 (상태에 따라 결정됨)
    oSTATE     // Moore FSM의 현재 상태 (디버그용)
);

    // 상태 코드 (localparam으로 상태 코드 상수 정의)
    localparam A = 2'b00,  // 상태 A (초기 상태)
               B = 2'b01,  // 상태 B
               C = 2'b10,  // 상태 C
               D = 2'b11;  // 상태 D
   
    input          iCLK;       // 클록 입력
    input          iRESETn;    // 비동기 active-low 리셋 입력
    input          iIN;        // FSM 입력 신호 (1비트)
    output         oOUT;       // Moore FSM 출력 (현재 상태 기반 출력)
    output   [1:0] oSTATE;     // 현재 상태를 출력 (디버그/모니터링용)
   
    reg            out;        // Moore FSM 출력 (레지스터 타입)
    reg [1:0]      curr_state; // 현재 상태 저장
    reg [1:0]      next_state; // 다음 상태 계산 결과 저장
    
    // 상태 전이 조합 논리 (다음 상태 결정)
    always @ (curr_state or iIN) begin
        case (curr_state)
            A : begin
                if (iIN)
                    next_state = B;   // 입력이 1이면 B 상태로 전이
                else
                    next_state = A;   // 입력이 0이면 A 상태 유지
            end

            B : begin
                if (iIN)
                    next_state = D;   // 입력이 1이면 D 상태로 전이
                else
                    next_state = C;   // 입력이 0이면 C 상태로 전이
            end

            C : begin
                if (iIN)
                    next_state = D;   // 입력이 1이면 D 상태로 전이
                else
                    next_state = C;   // 입력이 0이면 C 상태 유지
            end

            D : begin
                if (iIN)
                    next_state = A;   // 입력이 1이면 A 상태로 전이
                else
                    next_state = D;   // 입력이 0이면 D 상태 유지
            end

            default : 
                next_state = A;       // 예외 방지용 기본값 (안전 코드)
        endcase
    end
     
    // 상태 레지스터 (상승 에지 클록 + 비동기 리셋)
    always @ (posedge iCLK or negedge iRESETn) begin
        if (!iRESETn)
            curr_state <= A;          // 리셋이 걸리면 A 상태로 초기화
        else
            curr_state <= next_state; // 클록 상승 에지에서 상태 갱신
    end

    // 출력 결정 (Moore FSM: 상태에만 의존)
    always @ (curr_state) begin
        case (curr_state)
            A : out = 0;              // 상태 A일 때 출력 0
            B : out = 0;              // 상태 B일 때 출력 0
            C : out = 0;              // 상태 C일 때 출력 0
            D : out = 1;              // 상태 D일 때 출력 1
            default : out = 0;        // 예외 방지용 기본 출력 값
        endcase
    end
     
    // 출력 포트 연결
    assign oOUT = out;                // Moore FSM 출력 연결
    assign oSTATE = curr_state;       // 현재 상태를 출력 포트에 연결

endmodule

 

Testbench

`timescale 1ns/10ps   // 시뮬레이션 단위: 1ns, 정밀도: 10ps

module tb_fsm_moore;

  reg          iCLK;       // 클록 신호
  reg          iRESETn;    // 비동기 active-low 리셋
  reg          iIN;        // FSM 입력
  wire         oOUT;       // FSM 출력
  wire   [1:0] oSTATE;     // FSM 현재 상태 출력 (모니터용)

  localparam TCLK = 60;    // 클록 주기 60ns

  // 테스트할 DUT (Design Under Test) 인스턴스
  fsm_moore UFSM_MR (
    .iCLK (iCLK),         // 클록 연결
    .iRESETn (iRESETn),   // 리셋 연결
    .iIN (iIN),           // 입력 연결
    .oOUT (oOUT),         // 출력 연결
    .oSTATE (oSTATE)      // 상태 출력 연결
  );

  // 초기 조건 및 입력 신호 생성
  initial begin
    iCLK = 0;               // 클록 초기값 0
    iRESETn = 1;            // 리셋 비활성화 상태에서 시작
    #(TCLK/2);              // 클록의 절반 주기 동안 대기

    iRESETn = 0;            // 리셋 활성화 (FSM 초기화)
    #30;                    // 30ns 동안 리셋 유지

    iRESETn = 1;            // 리셋 비활성화 (동작 시작)
    iIN = 0;                // 입력 초기값 0
    #(TCLK*20);             // FSM 동작을 충분히 관찰할 시간 제공 (60ns * 20 = 1.2us)

    $stop;                  // 시뮬레이션 정지
  end

  // 클록 생성: TCLK/2 간격으로 iCLK 반전 => TCLK 주기 클록
  always #(TCLK/2) iCLK = ~iCLK;

  // 입력 신호 생성: TCLK 간격으로 iIN 반전 => 입력 주기 = TCLK * 2
  always #(TCLK) iIN = ~iIN;

endmodule

 

Simulation

'Verilog_RTL 설계' 카테고리의 다른 글

[Verilog_RTL]_모듈 분할  (0) 2025.06.26
[Verilog_RTL]_FSM_mealy  (0) 2025.06.20
[Verilog_RTL]_7-Seg_DECODER  (0) 2025.06.20
[Verilog_RTL]_2-to-10_DECODER  (0) 2025.06.16
[Verilog_RTL]_10-to-2_ENCODER  (0) 2025.06.16