7-3. FSM 설계 예제: 제어기 설계

1. 제어기의 역할과 FSM의 활용

제어기는 디지털 시스템의 핵심 부품으로서, 시스템의 전체적인 동작을 조율하고 관리하는 역할을 담당합니다. 마치 오케스트라의 지휘자와 같이, 제어기는 각 구성 요소들이 정해진 순서와 타이밍에 따라 작업을 수행하도록 지시합니다. 이러한 제어 로직을 효과적으로 설계하기 위해 유한 상태 기계(Finite State Machine, FSM)가 널리 사용됩니다.

FSM은 시스템의 상태를 정의하고, 입력에 따라 상태를 변경하며, 각 상태에서 특정 출력을 생성하는 수학적 모델입니다. 제어기를 FSM으로 설계하면, 시스템의 동작을 명확하고 체계적으로 표현할 수 있으며, 하드웨어 구현 또한 용이해집니다. 이번 예제에서는 간단한 제어기를 설계함으로써, FSM 설계가 실질적으로 어떻게 이루어지는지 살펴보고, 시스템 제어에 FSM이 어떻게 활용되는지 알아보겠습니다.

2. 제어기 설계 예제: 간단한 신호등 제어

다음과 같은 간단한 신호등 제어 시스템을 설계해 보겠습니다. 이 시스템은 두 개의 신호등, 즉 'A'와 'B'를 제어합니다. 각 신호등은 빨간색(R), 노란색(Y), 녹색(G) 신호를 가질 수 있습니다.

요구사항:

  1. 신호등 'A'가 녹색일 때 신호등 'B'는 빨간색이어야 합니다.
  2. 신호등 'A'가 녹색에서 노란색으로 바뀌기 전에, 잠시 동안(예: 3초) 노란색을 유지해야 합니다.
  3. 신호등 'B'도 마찬가지입니다.
  4. 각 신호등의 녹색 신호는 최소 10초 동안 켜져 있어야 합니다.

이러한 요구사항을 만족하는 제어기를 FSM으로 설계해 봅시다.

3. FSM 설계 단계

FSM 설계를 위해 다음 단계를 따릅니다.

  1. 상태 정의: 시스템의 각 상태를 정의합니다.
  2. 입력 정의: 시스템에 들어오는 입력을 정의합니다.
  3. 출력 정의: 각 상태에서 발생하는 출력을 정의합니다.
  4. 상태 전이 정의: 입력과 현재 상태에 따라 다음 상태로 어떻게 전이되는지 정의합니다.

1) 상태 정의

신호등 제어 시스템의 상태를 정의합니다. 각 신호등의 상태를 독립적으로 제어할 수 있지만, 간결성을 위해 전체 시스템의 상태를 정의합니다.

  • S_AG_BR: 신호등 'A'는 녹색, 신호등 'B'는 빨간색
  • S_AY_BR: 신호등 'A'는 노란색, 신호등 'B'는 빨간색
  • S_AR_BG: 신호등 'A'는 빨간색, 신호등 'B'는 녹색
  • S_AR_BY: 신호등 'A'는 빨간색, 신호등 'B'는 노란색

2) 입력 정의

이 예제에서는 외부 입력이 없지만, 시뮬레이션을 위해 "타이머 만료" 신호를 입력으로 사용할 수 있습니다.

  • timer_expired: 타이머가 만료되었음을 나타내는 신호 (1비트)

3) 출력 정의

제어기는 신호등의 색상을 제어하는 출력을 생성합니다.

  • A_red: 신호등 'A'의 빨간색 신호 (1비트)
  • A_yellow: 신호등 'A'의 노란색 신호 (1비트)
  • A_green: 신호등 'A'의 녹색 신호 (1비트)
  • B_red: 신호등 'B'의 빨간색 신호 (1비트)
  • B_yellow: 신호등 'B'의 노란색 신호 (1비트)
  • B_green: 신호등 'B'의 녹색 신호 (1비트)

4) 상태 전이 정의

상태 전이도는 시스템의 동작을 시각적으로 표현하는 데 유용합니다. 다음과 같은 상태 전이도를 고려할 수 있습니다. 각 상태에서 타이머가 만료되면 다음 상태로 전이됩니다. 녹색 신호의 최소 유지 시간을 고려하여, 타이머 값을 적절하게 설정해야 합니다.

상태 전이도 설명 뒤

위 그림은 상태 전이 다이어그램의 예시입니다. 실제 설계에서는 각 상태에 대한 타이머 값과 타이머 만료 시점을 고려하여 더욱 상세한 다이어그램을 구성해야 합니다. 예를 들어, S_AG_BR 상태에서는 10초 타이머를 설정하고, timer_expired 신호가 발생하면 S_AY_BR 상태로 전이합니다. S_AY_BR 상태에서는 3초 타이머를 설정하고, timer_expired 신호가 발생하면 S_AR_BG 상태로 전이합니다.

4. Verilog 코드 구현

위에서 정의한 FSM을 Verilog 코드로 구현해 보겠습니다.

module traffic_light_controller(
  input clk,          // Clock
  input rst,          // Reset
  input timer_expired, // Timer expiration signal

  output reg A_red,
  output reg A_yellow,
  output reg A_green,
  output reg B_red,
  output reg B_yellow,
  output reg B_green
);

  // Define states using a state variable
  parameter S_AG_BR = 2'b00;  // A - Green, B - Red
  parameter S_AY_BR = 2'b01;  // A - Yellow, B - Red
  parameter S_AR_BG = 2'b10;  // A - Red, B - Green
  parameter S_AR_BY = 2'b11;  // A - Red, B - Yellow
  reg [1:0] current_state, next_state;

  // State transition logic (Combinational always block)
  always @(*) begin
    case (current_state)
      S_AG_BR: begin
        if (timer_expired)
          next_state = S_AY_BR;
        else
          next_state = S_AG_BR;
      end
      S_AY_BR: begin
        if (timer_expired)
          next_state = S_AR_BG;
        else
          next_state = S_AY_BR;
      end
      S_AR_BG: begin
        if (timer_expired)
          next_state = S_AR_BY;
        else
          next_state = S_AR_BG;
      end
      S_AR_BY: begin
        if (timer_expired)
          next_state = S_AG_BR;
        else
          next_state = S_AR_BY;
      end
      default:
        next_state = S_AG_BR; // Default state
    endcase
  end

  // State register (Sequential always block)
  always @(posedge clk or posedge rst) begin
    if (rst)
      current_state <= S_AG_BR;  // Initialize to a default state
    else
      current_state <= next_state;
  end

  // Output logic (Combinational always block)
  always @(*) begin
    // Default values
    A_red = 1'b0;
    A_yellow = 1'b0;
    A_green = 1'b0;
    B_red = 1'b0;
    B_yellow = 1'b0;
    B_green = 1'b0;

    case (current_state)
      S_AG_BR: begin
        A_green = 1'b1;
        B_red = 1'b1;
      end
      S_AY_BR: begin
        A_yellow = 1'b1;
        B_red = 1'b1;
      end
      S_AR_BG: begin
        A_red = 1'b1;
        B_green = 1'b1;
      end
      S_AR_BY: begin
        A_red = 1'b1;
        B_yellow = 1'b1;
      end
    endcase
  end

endmodule

위 코드는 다음과 같은 세 부분으로 구성됩니다.

  1. 상태 정의 및 변수 선언: FSM의 각 상태를 parameter로 정의하고, 현재 상태 (current_state)와 다음 상태 (next_state)를 저장할 레지스터를 선언합니다.
  2. 상태 전이 로직: always @(*) 블록을 사용하여, 현재 상태와 입력(timer_expired)에 따라 다음 상태를 결정합니다. case문을 사용하여 각 상태에 대한 전이 조건을 정의합니다.
  3. 상태 레지스터: always @(posedge clk or posedge rst) 블록을 사용하여, 클럭 엣지 또는 리셋 신호에 따라 current_state를 업데이트합니다.
  4. 출력 로직: always @(*) 블록을 사용하여, 현재 상태에 따라 출력 신호(A_red, A_yellow, A_green, B_red, B_yellow, B_green)를 결정합니다. case문을 사용하여 각 상태에 해당하는 출력 값을 설정합니다.

5. 시뮬레이션 및 검증

설계된 FSM이 예상대로 동작하는지 확인하기 위해, 시뮬레이션을 수행해야 합니다. 시뮬레이션은 Verilog 시뮬레이터(예: ModelSim, Vivado Simulator)를 사용하여 수행할 수 있습니다. 시뮬레이션을 위해서는 테스트벤치를 작성해야 합니다. 테스트벤치는 제어기에 클럭, 리셋, 입력 신호를 제공하고, 출력 신호를 관찰하여 시스템의 동작을 검증합니다.

module traffic_light_controller_tb;

  // Inputs
  reg clk;
  reg rst;
  reg timer_expired;

  // Outputs
  wire A_red;
  wire A_yellow;
  wire A_green;
  wire B_red;
  wire B_yellow;
  wire B_green;

  // Instantiate the UUT (Unit Under Test)
  traffic_light_controller uut (
    .clk(clk),
    .rst(rst),
    .timer_expired(timer_expired),
    .A_red(A_red),
    .A_yellow(A_yellow),
    .A_green(A_green),
    .B_red(B_red),
    .B_yellow(B_yellow),
    .B_green(B_green)
  );

  // Clock generation
  parameter CLOCK_PERIOD = 10;
  always #(CLOCK_PERIOD/2) clk = ~clk;

  // Stimulus
  initial begin
    // Initialize
    clk = 0;
    rst = 1;
    timer_expired = 0;
    #20 rst = 0; // Release reset
    #10;

    // Simulate timer expiration
    #100 timer_expired = 1; // Simulate the timer expiring after 1 second
    #30 timer_expired = 0;
    #100 timer_expired = 1;
    #30 timer_expired = 0;
    #100 timer_expired = 1;
    #30 timer_expired = 0;

    #500 $finish; // End simulation
  end

endmodule

위 테스트벤치는 다음과 같은 역할을 합니다.

  1. 클럭 생성: always 블록을 사용하여 클럭 신호를 생성합니다.
  2. 리셋 및 초기화: initial 블록에서 리셋 신호를 설정하고, 초기 상태로 진입하도록 합니다.
  3. 입력 자극 (stimulus): timer_expired 신호에 펄스를 가하여 상태 전이를 유발합니다. 실제 하드웨어에서는 타이머가 만료되면 timer_expired 신호가 자동으로 활성화됩니다.
  4. UUT 인스턴스화: traffic_light_controller 모듈을 인스턴스화하여 테스트 대상 모듈을 연결합니다.

시뮬레이션 결과를 통해 신호등의 색상이 올바르게 변경되는지 확인할 수 있습니다.

시뮬레이션 결과에 대한 설명 뒤

위 그림은 시뮬레이션 파형의 예시입니다. 파형을 분석하여 신호등의 색상 변화가 설계 요구사항에 부합하는지 확인합니다. 예를 들어, A_green 신호가 켜진 후 최소 10초 이상 유지되는지, 노란색 신호는 3초 동안 켜져 있는지 등을 확인할 수 있습니다.

6. 제어기 설계의 장점과 고려사항

FSM을 이용한 제어기 설계는 다음과 같은 장점을 제공합니다.

  • 명확성: 시스템의 동작을 상태와 전이로 명확하게 표현하여, 설계 및 유지보수를 용이하게 합니다.
  • 체계성: 시스템을 구조적으로 설계하여, 복잡한 시스템의 설계에도 효과적으로 대응할 수 있습니다.
  • 재사용성: 설계된 FSM은 다른 시스템에서도 재사용할 수 있습니다.
  • 테스트 용이성: FSM의 각 상태와 전이에 대한 테스트를 수행하여, 시스템의 신뢰성을 높일 수 있습니다.
  • 합성 용이성: FSM은 하드웨어로 쉽게 합성할 수 있으며, FPGA 또는 ASIC으로 구현할 수 있습니다.

제어기를 설계할 때 다음과 같은 사항을 고려해야 합니다.

  • 상태 정의의 적절성: 시스템의 모든 동작을 정확하게 표현할 수 있도록 상태를 정의해야 합니다.
  • 상태 전이 조건: 각 상태에서 다음 상태로의 전이 조건을 정확하게 정의해야 합니다.
  • 타이밍: 시스템의 타이밍 요구사항을 고려하여, 타이머 값을 적절하게 설정해야 합니다.
  • 예외 처리: 시스템의 예외 상황(예: 센서 오류)에 대한 처리를 고려해야 합니다.
  • 최적화: 성능 및 자원 활용을 위해 FSM 코드를 최적화할 수 있습니다. 예를 들어, 불필요한 상태를 제거하고, 상태 코딩 기법을 사용하여 회로 크기를 줄일 수 있습니다.

7. 결론

이번 예제에서는 간단한 신호등 제어 시스템을 설계함으로써, FSM 설계의 기본 원리와 실질적인 구현 방법을 살펴보았습니다. FSM은 시스템의 동작을 명확하게 표현하고, 체계적으로 설계할 수 있도록 돕는 강력한 도구입니다. 제어기는 디지털 시스템의 핵심 요소이며, FSM을 이용하여 효과적으로 설계할 수 있습니다. 실무에서는 FSM 설계 기법을 활용하여 다양한 복잡한 시스템을 제어할 수 있습니다.

비슷한 글 추천

Comments (0)

No comments yet. Be the first to comment!