
有限状態機械(FSM)をPythonで実装する|回路が"手順"を進めるしくみ
2026-09-19 ・ 実践
信号機の「青→黄→赤」、自動販売機の「投入→選択→排出」——こうした順序立った動作を表すのが 有限状態機械(FSM) です。フリップフロップで作る順序回路の設計図にあたります。Pythonで実装して考え方を掴みます。
FSMの3要素
FSMは「状態」「入力による遷移」「各状態での出力」で表せます。今どの状態かを覚え、入力に応じて次の状態へ移る——記憶を持つ回路そのものです。
状態を遷移させる
現在の状態
FFが記憶
入力で遷移
次状態を決定
状態で出力
動作が決まる
準備
Python標準機能だけ。
① 信号機のFSM
状態と遷移を辞書で表します。
# 遷移表:現在の状態 → 次の状態
transitions = {"青": "黄", "黄": "赤", "赤": "青"}
state = "青"
for _ in range(6):
print(state, end=" → ")
state = transitions[state]
print(state)
# 青 → 黄 → 赤 → 青 → 黄 → 赤 → 青
状態を記憶し、遷移表に従って進むだけ。信号機の制御ロジックそのものです。
② 入力で分岐するFSM:パターン検出器
「1が2回連続したら検出」する回路をFSMで作ります。ビット列を1つずつ食べて状態を進めます。
def detect_11(bits):
state = "S0" # S0=まだ / S1=1が1回 / 検出でフラグ
detected = []
for b in bits:
if state == "S0":
state = "S1" if b == 1 else "S0"
elif state == "S1":
if b == 1:
detected.append(True) # 11 を検出!
state = "S1"
else:
state = "S0"
return detected
seq = [0, 1, 1, 0, 1, 1, 1]
print("11の検出回数:", len(detect_11(seq))) # 3
0,1,1,0,1,1,1 の中に「1が2連続」は3回(位置1-2、4-5、5-6)。入力履歴を状態で覚えることで、単発の値だけでは無理な「連続」の検出ができました。通信のパターン検出やプロトコル解析の基礎です。
ハードとソフトの共通言語
FSMはハードウェア(順序回路)でもソフトウェア(プログラム)でも同じ考え方で使えます。だから回路設計者もプログラマも学ぶ基礎概念。フリップフロップが状態を記憶し、組合せ回路が遷移を計算する——これがFSMの物理的な姿です。
状態数を増やしすぎない
状態が増えるほど回路(や理解)が複雑になります。設計では「本当に必要な状態は何か」を見極め、なるべく少なくするのが定石。状態爆発は、ハードでもソフトでもバグの温床です。
まとめ
- FSMは「状態・遷移・出力」で順序立った動作を表す
- 状態を記憶し、入力に応じて次状態へ遷移する
- 信号機やパターン検出など、履歴が必要な処理に使う
- 順序回路(フリップフロップ+組合せ回路)の設計図
もう少し詳しく(背景と理論)
有限状態機械(FSM)は、有限個の状態と、入力に応じた状態遷移で振る舞いを記述する計算モデルで、オートマトン理論の基礎です1。ハードウェア設計では2つの型が重要です——出力が現在の状態だけで決まる Moore 機械と、出力が状態と入力の両方で決まる Mealy 機械。Mealy はより少ない状態で書けることがある一方、入力変化が即出力に伝わる違いがあります2。実装では、状態をフリップフロップで保持し、次状態論理と出力論理を組合せ回路で作ります。信号処理・通信プロトコル・制御など「順序のある動作」の設計の中核で、状態数を減らす状態最小化が回路コストの削減につながります3。
次の一歩 🌸
記憶素子はフリップフロップ、選択回路はマルチプレクサとデコーダ、設計の流れはチップ設計の流れへどうぞ。