「シミュレーションは通ったのに実機で動かない」を解剖する
「シミュでは完璧に動いたのに、実機だけ壊れる」──これ、毎年必ず誰かがハマるんだ🐾
このページでは、もふねこが実習の現場で実際に見てきた「Sim/Synthミスマッチ」の3大原因を、チェックリスト形式で体系的にまとめたよ。実機に書き込む前に、ここを一通り確認する習慣をつけてほしいな!
シミュレーション(RTL検証)では完璧に動くのに、実機(FPGA / ASIC)だけ壊れる現象を「Sim/Synthミスマッチ」と呼びます。このページでは、もふねこが大学の実習指導や就職した学生からの相談で実際に遭遇した3つの主要原因を体系的に整理し、実機書き込み前に使えるチェックリストとしてまとめます。
1. Sim/Synthミスマッチとは何か
HDL設計の開発フローでは、まずシミュレーションで回路の機能を確認し、次に論理合成で実際のゲートに変換します。この2つの工程で結果が一致しない現象を「Sim/Synthミスマッチ」と呼びます。
以下の3つが、もふねこが現場で実際に見てきた主要原因です。
| # | 原因 | 壊れ方の特徴 | 検出の難しさ |
|---|---|---|---|
| ① | センシティビティリストの漏れ | 特定の入力変化に反応しない | Warningを見れば気づける |
| ② | リセット忘れによるX伝搬 | 電源投入直後だけ暴走する | 波形にXが隠れていることがある |
| ③ | ゲートレベル検証の省略 | 数分後にカウンタが暴走など | RTL検証では絶対に再現しない |
2. 原因①:センシティビティリストの漏れ
🐾 もふねこの現場メモ:
これが一番多い。always @(A) と書いて B を入れ忘れるやつ。シミュレータは「Aが変化したときだけ計算する」という挙動になるけど、合成ツールは右辺の論理式を見て普通にANDゲートを作ってしまう。結果、シミュの動きと実機の動きが全く別物になるんだ。
❌ NG例:Bがリストから漏れている
// シミュレータ → Aが変わったときだけ計算(Bの変化は無視)
// 合成ツール → AとBのANDゲートを普通に生成
always @(A) begin
Z = A & B; // ← Bがセンシティビティリストにない!
end
- シミュレーション:Bが変化してもZは更新されない(Aの変化でしか動かない)
- 実機(合成後):AとBのどちらが変化してもZは即座に更新される
- 結果:シミュレーション結果と実機の動作が完全に不一致
⭕ OK例:always @(*) を使う
// Verilog-2001以降:ツールが自動で全入力を拾ってくれる
always @(*) begin
Z = A & B; // ← AもBも自動で検出!
end
✨ ベストプラクティス:always_comb(SystemVerilog)
// 「ここは組合せ回路です」とツールに明示的に宣言
always_comb begin
Z = A & B; // ← ラッチが生まれそうになるとエラーで教えてくれる!
end
- 組合せ回路では手書きのセンシティビティリストを使わない
- Verilog-2001以降なら
always @(*)を原則にする - SystemVerilog環境なら
always_combが最強(ラッチ生成時にエラーが出る) - 合成ツールのWarningに「signal not in sensitivity list」があれば即座に修正
3. 原因②:リセット忘れによるX伝搬
🐾 もふねこの現場メモ:
「電源を入れた直後だけ壊れて、リセットボタンを押すと直る」という相談も何度か受けたことがあるんだ。原因は、一部のフリップフロップにリセットを入れ忘れていたこと。シミュレーションでは全信号が最初から x(不定値)として表示されるけど、波形ウィンドウで x が赤く表示されても「まあ最初はそうだよね」と見過ごしてしまうんだ。
X伝搬の恐ろしさ
シミュレーションの世界では、リセットされていない信号の初期値は x(不定値)です。この x は演算に使われると後段にも伝搬します(これを「X伝搬」と呼びます)。
| 状況 | シミュレーション | 実機 |
|---|---|---|
| リセット忘れのFF | 初期値 = x(不定値) | ASICでは電源投入時のランダム値。FPGAではコンフィグレーション時の初期値(多くは0)になるが、初期値頼みの設計は危険 |
| X伝搬の影響 | 後段の演算結果もすべて x になる | ランダムな値で動くため「たまたま動く」ことがある |
| 発見しやすさ | 波形を注意深く見れば x で気づける | 再現性が低く原因特定が困難 |
0 か 1 のどちらかにランダムに初期化されます。たまたま正しい値になれば動いてしまうため、「何度か試して動いた」だけでは安全とは言えません。温度変化や電源電圧の変動で初期値が変わり、突然壊れることがあります。FPGAではコンフィグレーション時に既定の初期値(多くは0)が入りますが、リセット解除のタイミングや別ボード・別デバイスへの移植で挙動が変わるため、「初期値頼みの設計」が危険であることは同じです。
- すべてのフリップフロップに非同期リセットまたは同期リセットを入れる
- シミュレーション波形で
xが残っているFFがないか確認する - テストベンチの最初に必ずリセットシーケンスを入れる
- 合成ツールのWarningに「initial value」「uninitialized」があれば確認
4. 原因③:ゲートレベル検証の省略
🐾 もふねこの現場メモ:
就職した学生から「論理合成も通ったしシミュレーションで動作確認したので実機に書き込もうとしたら、先輩に『ゲートレベル検証は?』と止められました。シミュレーション、もう一回やるんですか?」と言われたことがあるんだ。この「2回目の検証」を飛ばして実機で数日溶かすケースを、何度も見てきたよ。
RTL検証とゲートレベル検証の違い
| 項目 | RTL検証(1回目) | ゲートレベル検証(2回目) |
|---|---|---|
| タイミング | 論理合成の前 | 論理合成の後 |
| 確認する対象 | 回路の機能(動作) | タイミング(遅延)を含めた動作 |
| 信号の遅延 | 理想的(瞬間移動) | 実際のゲート遅延を含む |
| 入力ファイル | RTLソースコード | ネットリスト + シミュレーション用ライブラリ |
| 検出できるバグ | 論理エラー | タイミング違反・セットアップ/ホールド違反 |
RTL検証では信号が「理想的に瞬間移動」する前提でシミュレーションが行われます。しかし現実の回路では、ANDゲートやフリップフロップを通るたびにわずかな遅延が生じます。この遅延が積み重なると、「クロックが来た瞬間、まだデータが届いていない」というタイミング違反が発生します。
- 実機に書き込む前に必ずゲートレベル検証を実施する
- シミュレーション用ライブラリは論理合成用ライブラリとは別物(間違えやすい)
- テストベンチはRTL検証のものをそのまま流用できる
- 現代のFPGA開発ではSTA(静的タイミング解析)ツールも活用する
5. 実機書き込み前チェックリスト
もふねこが実習の現場で使っている「実機に書き込む前の最終確認リスト」をまとめました。1つでも「いいえ」があれば、実機書き込みは待ったほうがいいです。
| # | チェック項目 | 対応する原因 |
|---|---|---|
| 1 | 組合せ回路のalways文で @(*) または always_comb を使っているか? | 原因① |
| 2 | 合成ツールのWarningに「sensitivity list」関連の警告がないか? | 原因① |
| 3 | すべてのフリップフロップにリセット(非同期 or 同期)が入っているか? | 原因② |
| 4 | シミュレーション波形でリセット後に x が残っているFFがないか? | 原因② |
| 5 | 論理合成後にゲートレベル検証(またはSTA)を実施したか? | 原因③ |
| 6 | ゲートレベル検証でシミュレーション用ライブラリ(合成用とは別)を使っているか? | 原因③ |
| 7 | if文/case文でdefault/elseを省略していないか?(ラッチ生成防止) | 共通 |
🐾 もふねこの現場メモ:
「7つも確認するの大変じゃない?」と思うかもしれないけど、これをサボって実機デバッグに3日溶かすのと、5分でチェックリストを確認するのと、どちらがいいかは明らかだよね。最初は面倒でも、これを習慣にした学生は実機デバッグで圧倒的に速くなっていったんだ🐾
6. まとめ
📝 Sim/Synthミスマッチ 3大原因と対策
| 原因 | 症状 | 対策 |
|---|---|---|
| センシティビティリスト漏れ | 特定信号の変化に反応しない | always @(*) or always_comb を使う |
| リセット忘れ(X伝搬) | 電源投入直後に暴走 | 全FFにリセットを入れる。波形でXを確認 |
| ゲートレベル検証の省略 | 数分後に突然壊れる | 合成後にGL検証 or STAを必ず実施 |
「シミュレーションで動いた ≠ 実機で動く」。この認識があるだけで、実機でトラブルが起きたときに「どの工程に問題があるか」を絞り込めるようになります。RTL検証・論理合成・ゲートレベル検証を、頭の中で「3つの別工程」として分けて考えることが出発点です。
関連するページ: 文法実験3: シミュレーションと論理合成を体験する | 応用実験5: ラッチを生む3つの原因と対策 | 合成実験1: 論理合成の仕組みを知る