ステートマシンの考え方

条件分岐やループはソフトウェアだけの話ではありません。論理回路でも実現できます。それがステートマシンです。後のユニットでHDLを使って記述しますが、その容易さは感動的です。

もふねこ

「ステートマシン(状態遷移機械)」って必殺技みたいな名前だね🐾
これを使えば、自動販売機や信号機みたいな『順番に動く賢いシステム』が作れるようになるんだ!

1. ステートマシンとは

ステートマシン(状態機械)とは、いくつかの状態(ステート)を持ち、条件によって次の状態に遷移する回路です。

状態遷移図の読み方

状態遷移図は「どの状態にいるとき、どの条件で、どの状態に移るか」を表した図です。

現在の状態条件次の状態
A条件1 を満たすB へ遷移
A条件1 を満たさないA のまま(自己ループ)
B条件2 を満たすC へ遷移
B条件2 を満たさないB のまま
C条件3 を満たすA へ遷移
C条件3 を満たさないC のまま
💡
活用例 ステートマシンはエアコン・電子炊飯器などの家電製品、自動車のエンジン制御、工業用ロボットなど幅広い機器の制御に使用されています。状態数・条件が非常に多い場合はマイクロコントローラが使われます。

2. 回路構成

ステートマシンは以下の2つのブロックで構成されます。

ブロック役割回路の種類
状態保持「現在の状態」を記憶するD-FF(フリップフロップ)
次状態生成現在の状態 + 外部入力 → 「次の状態」を計算組み合わせ回路

動作の流れ

  1. 組み合わせ回路が「現在の状態」と「外部入力」から「次の状態」を計算する
  2. CLK の立ち上がりで「次の状態」を D-FF に取り込み「現在の状態」になる
  3. 「次の状態」が「現在の状態」と同じ場合は自己ループ(状態を保持)

3. 実例:CDトレイ制御

CDプレイヤーのトレイ開閉動作をステートマシンで表現します。

状態の定義(4つのステート)

状態名状態コードモータ動作説明
CLOSED00OFFトレイが完全に閉じた状態
OPENING01ON(開く方向)トレイが開いている途中
OPEN10OFFトレイが完全に開いた状態
CLOSING11ON(閉じる方向)トレイが閉じている途中

状態遷移テーブル

現在の状態遷移条件次の状態モータ
CLOSEDボタンが押されたOPENING へOFF → ON(開く)
CLOSEDボタン未押下CLOSED のままOFF 継続
OPENINGトレイが完全に開いたOPEN へON → OFF
OPENINGまだ開いていないOPENING のままON 継続
OPENボタンが押されたCLOSING へOFF → ON(閉じる)
OPENボタン未押下OPEN のままOFF 継続
CLOSINGトレイが完全に閉じたCLOSED へON → OFF
CLOSINGまだ閉じていないCLOSING のままON 継続

4. ステートマシン vs カウンタ

🔵 カウンタ

  • 遷移条件:クロックのみ
  • 状態変化:単調増加 / 単調減少
  • 状態値(カウント値)そのものに意味がある
  • ステートマシンの特殊ケースと見なせる

🟣 ステートマシン

  • 遷移条件:任意の外部信号
  • 状態変化:任意の状態へ遷移可能
  • 状態値そのものに意味はない(符号化は設計者が決める)
  • カウンタより複雑な制御が可能
ステート符号化 回路規模削減やスピード向上のため、意図的にステート値の割り付けを変える場合があります(バイナリ・グレイコード・ワンホット符号化など)。

5. 状態設計の手順

ステートマシンを設計するときは、いきなりVerilogのコードを書き始めるよりも、まず「何を状態として記憶する必要があるか」を整理すると迷いにくくなります。状態は、過去の入力や動作の履歴を回路の中に残しておくための名前です。

手順考えることCDトレイ制御での例
1外から入ってくる信号を決めるボタン、開端センサ、閉端センサ
2回路が覚えておく状態を列挙するCLOSED、OPENING、OPEN、CLOSING
3各状態で出力をどうするか決めるモータを止める、開く方向に回す、閉じる方向に回す
4どの条件で次の状態へ移るか決めるボタン押下、完全に開いた、完全に閉じた
5想定外の状態に入ったときの戻り先を決める安全側として CLOSED へ戻す、またはモータを止める
💡
状態と出力を分けて考える 「今どこにいるか」と「今なにを出力するか」は、似ていますが別の観点です。たとえば OPENING という状態は「開いている途中」を表し、その状態にいる間の出力として「モータを開く方向に回す」を決めます。状態名を動作名に近づけると、後でコードにしたときも読みやすくなります。

6. つまずきやすいポイント

ステートマシンは便利ですが、状態が増えるほど見落としも増えます。設計図の段階で次の点を確認しておくと、Verilogで書いた後のデバッグがかなり楽になります。

⚠️
よくある失敗
  • 状態を増やしすぎて、どの状態からどこへ戻るのか分からなくなる。
  • 入力がないときの遷移を書き忘れ、意図しない状態保持やラッチのような動きに見える。
  • リセット後にどの状態から始めるかを決めていない。
  • 存在しない状態コードに入った場合の復帰先を用意していない。

このページでは概念を中心に見ましたが、実際にVerilogでステートマシンを書くときは、状態レジスタ、次状態計算、出力計算を分けて考えるのが基本です。具体的な書き方は、後の 応用実験3: ステートマシンを回路で書く で詳しく扱います。

もふねこ

お疲れさま!これでLシリーズ(基礎ノート)はすべて完了だよ🐾
次からは、いよいよお待ちかねの「Verilog-HDLの書き方(文法ノート)」に突入するよ!一緒にコードを書いていこう!

📌 まとめ

  • ステートマシンはいくつかの状態を持ち、条件によって次の状態に遷移する回路
  • D-FF(状態保持)と組み合わせ回路(次状態生成)で構成される
  • CLK の立ち上がりで「次の状態」が「現在の状態」になる
  • 状態遷移図で状態・遷移条件・遷移先を視覚的に表現する
  • CDトレイ制御では CLOSED → OPENING → OPEN → CLOSING → CLOSED の4状態で動作する
  • カウンタはクロックのみを遷移条件とするステートマシンの特殊ケース
  • ステートマシンはカウンタと異なり任意の外部信号を遷移条件にできる
  • ステートの符号化方法(バイナリ・グレイコード・ワンホットなど)は設計者が決める

🐾 もふねこの現場FAQ

Q. 自動販売機のステートマシンを作りました。シミュレーションは完璧なのに、実機で動かしていると完全にフリーズします…

A. case文の中に「未知の世界からの脱出ルート(default)」を書き忘れている可能性が高いよ🐾

ハードウェアの実機環境では、ノイズなどの影響で設計者が意図していない「ありえない状態」に突然飛ばされる事故が普通に起こるんだ。

その時に default への指定がないと、回路が行き先を見失って二度と復帰できない「デッドロック(完全フリーズ)」に陥ってしまうんだ。入門書には載っていない実務の恐怖だから、絶対に忘れないでね!