For Good FPGA Design

ステートマシンのデッドロックを体験!

「時々FPGAが動かない!」という再現性の低い不具合に遭遇したことはありませんでしょうか?原因の1つとして、ステート・マシン(Finite State Machine, FSM)のデッドロック(Deadlock)が考えられます。

今回は、実際にステートマシンがデッドロックする回路を作成し、デッドロックを体験してみたいと思います。

なお、ソースコードはGitHubに公開しています。DIGILENT ARTY S7ボードに実装することで、実際に試すことができます。

目次

この記事のまとめ

  • ステート・マシンのリセット入力が非同期だと、デッドロックする
  • このデッドロックは再現性が低いため、解析が困難
  • ステート・マシンのリセット入力は、クロック同期にし、リカバリー・リムーバルを満足させる必要がある

デッドロックする回路の仕様

図1のように12個のステートを持つステート・マシンを作成しました。

  • FSM_RST(非同期リセット入力)がアサートされるとステートは JANUARY になる
  • j2f_trgがHighになると、ステートは JANUARY → FEBRUARY と遷移する。今回の実験では、j2f_trgは常にHighなので、FSM_RSTリセット解除して1クロック後に JANUARY → FEBRUARY と遷移する
  • 以降は TRG 入力の立ち上がりエッジを検出するとステートが遷移する
図1 ONE_YEARステート・マシン

回路のブロック図を図2に示します。

  • ONE_YEARステート・マシンを2個インスタンス。一方は11MHz, もう一方は153MHzで動作させる
  • ステート・マシンのステートにより、フルカラーLEDの色を変える。色の対応は図1の通り
  • ステート・マシンの非同期リセット入力 FSM_RST は基板上のボタンBTN0に直結(赤色のネット)
図2 ステート・マシン デッドロック回路のブロック図

この回路では、ステート・マシンが動作していればリセット解除直後(1クロック後)にLEDが赤になります。リセット解除でデッドロックすれば、赤以外になるはずです。

ONE_YEARステート・マシンのコードは下記のようになります。FSM_RSTは「非同期リセット」と呼ばれるリセット入力です。今回の回路では、非同期リセット入力が本当に非同期になっています。人の指で操作するので、11MHzや153MHzに同期することは不可能です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* State machine */
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;     /* Transition immediately to check if the FSM works */
                else
                    next_state  <=  current_state;
            end
        FEBRUARY    : begin
                if (trg_redg == 1'b1)
                    next_state  <=  MARCH;
                else
                    next_state  <=  current_state;
            end
  ...
  ...
        default     : 
            next_state  <=  JANUARY;
    endcase
end

ステート・マシンの非同期リセット入力を、本当に非同期にしてはいけないという内容を下記の記事で解説しました。本来は、ステート・マシンの非同期リセット入力は、ステート・マシンのクロックに同期させ、リカバリー・リムーバルを満足する必要があります

関連記事

ステート・マシンの非同期リセットのリカバリー・リムーバルが満足していないというバグがある今回の回路は、どのように動作するのでしょうか?

タイミング・レポートに不具合の兆候

図3, 4にタイミング・レポートを示します。ステート・マシンはワン・ホット方式でエンコードされており、12個のフリップ・フロップになっています。

FPGAの入力ポートRST_BTNからフリップ・フロップのリセット入力までの遅延に注目してください。遅延の値が12個のフリップ・フロップで異なっています。つまり、各フリップ・フロップは同時にリセット解除されないということです。クロックのエッジのタイミングと、リセット解除のタイミングの関係が絶妙だと、イリーガルス・テートになります。イリーガル・ステートになると、デッドロックします。

図3 RST_BTN→ステート・マシンの非同期リセット入力 間の遅延(11MHz)
図4 RST_BTN→ステート・マシンの非同期リセット入力 間の遅延(153MHz)

デッドロックの発生

正常動作

まずは、正常動作時の動きです。

デッドロック

こちらがデッドロック発生時です。153MHzを入力したステート・マシンが、リセット解除の直後にデッドロックしました。

動画の中では、リセット&解除を12回行ったところでデッドロックが発生しました。この不具合は必ず発生するわけではなく、再現性が低いです。このため、解析がかなり大変です。

撮影前に試したときは、50回くらいボタン押しました…

このような不具合を避けるため、ステート・マシンのリセット入力はクロック同期にし、リカバリー・リムーバルを満足させるようにしましょう

まとめ

  • ステート・マシンのリセット入力が非同期だと、デッドロックする
  • このデッドロックは再現性が低いため、解析が困難
  • ステート・マシンのリセット入力は、クロック同期にし、リカバリー・リムーバルを満足させる必要がある

アバター画像
この記事を書いた人
ジーノ。大手電機メーカーで、基板設計の全般と、FPGAの設計に従事した経験を活かし、FPGAについて情報発信中。
RTL設計、シミュレーション、タイミング・クロージャ、FPGAまわりのハードウェア開発まで、幅広く取り扱っております。

コメントを残す

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

CAPTCHA