For Good FPGA Design

ステート・マシンとは?- FPGAでステート・マシンを記述

今回は、ステート・マシンの基礎と、ステート・マシンの書き方について説明します。また、ステート・マシンのミーリ型、ムーア型の違いについても解説します。

ステート・マシンを使うことで、FPGAで”順番に”処理をすることが可能になります。実践的なFPGA記述では、とてもよく使います。

目次

この記事のまとめ

  • ステート・マシンで、順番に行う処理を実現できる
  • ステート・マシンの書き方を解説
  • ステート・マシンにはミーリ型とムーア型がある
  • 通常は、安全なムーア型を使う

ステート・マシンはどんな時に使う?

FPGAはハードウェアなので、基本的にはすべての回路が同時・並列に動作します。しかし、”順番に”処理をしたいケースも結構あります。例えば、

  • 順番に行う演算(図1)
  • 通信のプロトコル(図2)

などです。

図1 演算のステート遷移
図2 プロトコルのステート遷移

図1、図2の楕円がステート(状態)です。

  • それぞれのステートで行う処理を記述
  • ステートを遷移させる

とすることで、順番に処理をする回路が実現でき、このような回路をステート・マシンといいます。

状態遷移図

ステート・マシンのステートがどのように遷移するかを表す図を、状態遷移図といいます。図3に状態遷移図の例を示します。

図3 状態遷移図の例

図3では、リセット(Reset)でステートがSTATE1になります。ステートが遷移する条件 Condition1 が満たされると、STATE2に遷移します。以下同様です。

こういう図は、設計のときにノートに手書きしたりします。

ステート・マシンの書き方

実際にどのようなコードを書けばステート・マシンができるのか見てみましょう。

(1) まずは、ステートを定義します

parameter JANUARY   = 4'd0;
parameter FEBRUARY  = 4'd1;
parameter MARCH     = 4'd2;
parameter APRIL     = 4'd3;
parameter MAY       = 4'd4;
parameter JUNE      = 4'd5;
parameter JULY      = 4'd6;
...

(2) ステートを保持するレジスタを定義します

reg [3:0]    current_state;
reg [3:0]    next_state;

(3) ステートが遷移する条件を記述します

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
always @ (posedge CLK or posedge FSM_RST) begin
    if (FSM_RST) begin
        current_state   <=  JANUARY;
    end else begin
        current_state   <=  next_state;
    end
end
always @ (current_state or j2f_trg or trg_redg) begin
    case (current_state)
        JANUARY     : begin
                if (j2f_trg == 1'b1)
                    next_state  <=  FEBRUARY;
                else
                    next_state  <=  current_state;
            end
        FEBRUARY    : begin
                if (trg_redg == 1'b1)
                    next_state  <=  MARCH;
                else
                    next_state  <=  current_state;
            end
        ...
    endcase
end

9~15行目を見ると、現在のステート(current_state)がJANUARYのとき、

  • j2f_trgが1であれば、次のステート(next_state)がFEBRUARYに遷移
  • j2f_trgが0であれば、次のステート(next_state)は現在のステート(current_state)をキープ

となります。このようにして、ステートが遷移するロジックができます。

あとは、例えば次のように書くことで、ステートがJANUARYの時だけ行う処理を記述できます。

always @ (posedge CLK or posedge RST) begin
    if (RST) begin
        add_result   <=  'd0;
    end else begin
        if (current_state == JANUARY)
            /* some process */
    end
end

ミーリ型とムーア型

ステート・マシンにはミーリ型(Mealy)とムーア型(Moore)があります。

  • ミーリ型ステート・マシン:ステートと入力によって出力が決まる
  • ムーア型ステート・マシン:ステートのみによって出力が決まる

図4にミーリ型ステート・マシンのブロック図を示します。ミーリ型ステート・マシンは、1つのステートの中で、入力値によって複数の出力を出すことができます。したがって、ステートの数を減らすことができ、回路規模を小さくできます。また、入力→出力は組合せ回路なので、1クロックの遅延なく出力できます。しかし、図4の破線のように、ステート・マシンを通過するタイミング・パスがあります。これは、他のブロックと接続した際、伝搬遅延が大きくなり問題になることがあります。

図4 ミーリ型ステート・マシン

図5にムーア型ステート・マシンのブロック図を示します。ムーア型ステート・マシンは、1つのステートに対して1つの出力を出します。したがって、ステートの数が多くなり、回路規模が大きくなります。ステート遷移で1クロック使うため、入力が変化してから出力が変化するまでに1クロックの遅延があります。しかし、他のブロックと接続した際、ステートマシンを通過するタイミング・パスが存在しなくなるので、安全なステート・マシンといえます。

通常は、ムーア型ステート・マシンにします。

図5 ムーア型ステート・マシン
ステート・マシン特徴回路規模入力→出力安全性
ミーリ型1つのステートで複数の出力小さい1クロック遅延 なしステート・マシンを通過するタイミング・パスに注意
ムーア型1つのステートで1つの出力大きい1クロック遅延 ありステート・マシンを通過するタイミング・パス なし → 安全
表1 ミーリ型とムーア型の比較

まとめ

  • ステート・マシンで、順番に行う処理を実現できる
  • ステート・マシンの書き方を解説しました
  • ステート・マシンにはミーリ型とムーア型がある
  • 通常は、安全なムーア型を使う
アバター画像
この記事を書いた人
ジーノ。大手電機メーカーで、基板設計の全般と、FPGAの設計に従事した経験を活かし、FPGAについて情報発信中。
RTL設計、シミュレーション、タイミング・クロージャ、FPGAまわりのハードウェア開発まで、幅広く取り扱っております。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA