Warning放置で溶かした話 ベスト5
「Warningだから動くんですよね?」──この言葉を聞くたびに、もふねこの背筋が凍るんだ🐾
このページでは、もふねこが実習の現場で実際に見てきた「Warning放置で時間を溶かした事故」の中から、特にインパクトの大きかった5つを紹介するよ。全部、実際に起きた話だよ。
1. なぜWarningは「無視していいもの」ではないのか
HDL設計で一番怖いのは「コンパイルエラー」ではありません。エラーはツールが止めてくれるから、むしろ安全です。
本当に怖いのは、「Warningだけ出して、普通に合成が通ってしまう」ケースです。
ツールは親切ではありません。「あなたが書いたコードは曖昧だったから、多分こういう意味だと思って、勝手に別の回路にしておいたよ」と静かに宣告してくるだけです。そしてそのまま実機に書き込むと、シミュレーションでは絶対に再現しない謎のバグとして自分に返ってきます。
🐾 もふねこ:
就職した学生から「大量のWarningが出たけど『Errorじゃないからいいや』と放置して実機に進もうとしたら、先輩に『これ全部読んだ?』と詰められました」と聞いたことがあるんだ。実務ではWarningの理由を1件残らず説明できなければ、実機には進めない。これが現場のルールだよ。
2. 第5位:信号名のタイポで謎の1bit配線が出現
| 項目 | 内容 |
|---|---|
| Warning名 | Implicit wire declaration(暗黙のwire宣言) |
| 溶かした時間 | 約3時間 |
| 症状 | 出力が常に0のまま変化しない |
🐾 現場で起きたこと:
学生が8ビットのセレクタ回路を書いていたんだけど、信号名 sel を sl とタイポしていた。Verilogの仕様上、宣言していない信号名を使うと勝手に1bitのwireとして作ってしまうため、エラーにならずWarningだけで合成が通ってしまう。結果、8ビットのつもりの信号が1ビットに切り詰められて、出力がずっと0のまま。「コードは合ってるはずなのに動かない」と3時間悩んだ末、原因がたった1文字のタイポだったことが発覚。
タイポした信号名がエラーにならず、Warningだけで素通りしてしまうのがVerilogの罠です。Warningログに「Implicit wire」と出ていたら、信号名のスペルミスを真っ先に疑ってください。
3. 第4位:ビット幅のミスマッチで上位ビットが消滅
| 項目 | 内容 |
|---|---|
| Warning名 | Signal truncated / Width mismatch(ビット切り捨て) |
| 溶かした時間 | 約半日 |
| 症状 | 演算結果が128以上の値になると突然0に戻る |
🐾 現場で起きたこと:
加算回路で8ビットの演算結果を7ビットの信号に代入していた学生がいた。127までは正常に動くけど、128になった瞬間に値が0に戻る。シミュレーションでは小さな値しかテストしていなかったので気づかなかった。Warningには「Width mismatch」とはっきり書いてあったのに、「Warningだし大丈夫だろう」と読み飛ばしていたんだ。
ビット幅が合っていないと、合成ツールは黙って上位ビットを切り捨てます。小さな値でテストしているうちは動いてしまうため、「テストは通ったのに本番で壊れる」という最悪のパターンに陥ります。
4. 第3位:タイミング違反で「昨日まで動いていた回路」が突然死
| 項目 | 内容 |
|---|---|
| Warning名 | Timing not met / Negative slack(タイミング違反) |
| 溶かした時間 | 約2日 |
| 症状 | クロック周波数を少し上げただけで出力がでたらめになる。しかも毎回壊れ方が違う |
🐾 現場で起きたこと:
就職した学生から「実機で動作周波数を少し高くしただけで、昨日まで完璧に動いていた回路が突然でたらめな計算結果を出す」と相談が来た。シミュレーションは高い周波数でも完璧に動く。なぜなら、シミュレーションは遅延ゼロの理想世界だから。でも実機では、信号がゲートを通過するたびにわずかに遅れる。この遅れが積み重なって「クロックが来た瞬間、まだデータが届いていない」という事故が起きていた。しかも配置配線を変えるたびに遅延も変わるから、毎回壊れ方が違う。原因特定に2日かかったよ。
タイミング違反はRTLシミュレーションでは原理的に再現できません。「シミュで完璧に動く」のに実機で壊れるという、最も原因特定が困難なバグです。Timing ReportでSlackがマイナスになっていないかの確認は、実機に焼く前の絶対条件です。
5. 第2位:2つのalwaysブロックが同じ信号を引っ張り合い
| 項目 | 内容 |
|---|---|
| Warning名 | Multiple drivers(マルチプルドライバ) |
| 溶かした時間 | 約3日 |
| 症状 | 実機でボタンの反応が不安定。押すたびに違う動作をする |
🐾 現場で起きたこと:
2つのalwaysブロックで同じ信号を操作していた学生がいた。シミュレーション上では「後から書いたほうが勝つ」ように見えていたため、「動いてるからOK」と判断して実機に書き込んだ。結果、FPGA内で信号が衝突し、ボタンを押すたびに挙動が変わる謎の動作に。ハードウェアで言えば「1本の配線に2つの出力ピンを繋いでショートさせた」のと同じこと。原因特定に3日かかった。近年のツールではWarningではなく一発Errorで止まることもあるけど、古いプロジェクトでは素通りするから要注意。
シミュレータはソフトウェアなので「後勝ち」で動いてしまいますが、実機では物理的な信号衝突が起きます。1つの信号は必ず1つのalwaysブロックだけで制御する──この鉄則を破ると、再現性のないバグに3日間苦しめられます。
6. 第1位:たった1箇所のelse漏れで丸2日溶かした
| 項目 | 内容 |
|---|---|
| Warning名 | Latch inferred(意図しないラッチ生成) |
| 溶かした時間 | 丸2日 |
| 症状 | FPGAに焼いたらボタンを押すたびに挙動が変わる。シミュレーションでは完璧 |
🐾 現場で起きたこと:
堂々の第1位。シミュレーションでは完璧に動いていたのに、FPGAに焼いたらボタンを押すたびに挙動が変わる。原因はたった1箇所のelse漏れ。合成ツールが「値が定義されていないから、前の値を保持する回路(ラッチ)を勝手に作った」結果、意図しないタイミングで過去のデータを記憶して誤動作していた。シミュレーション上ではこの動きが見えなかったため、特定に丸2日溶かした。Warningには「Latch inferred」とはっきり書いてあったのに、「Errorじゃないから大丈夫」と読み飛ばしていたのが全ての原因だった。
もふねこが実習の現場で見てきた「時間を溶かしたWarning」の中で、ダントツで多いのがこれです。ラッチはクロックに依存しない記憶素子のため、タイミング解析との相性が最悪。しかも「シミュレーションでは動く」のが罠で、実機でしか発症しないバグを生み出します。
7. もふねこの鉄則:「Warningゼロ」でFPGAに焼く
5つのエピソードを読んで気づいたと思いますが、すべてに共通するのは「Warningを読んでいれば防げた」ということです。
| 致命度 | 意味 | 対応 |
|---|---|---|
| 🔴 致命的 | 実機で必ずバグる(Latch / Multiple drivers / Loop) | 絶対に修正 |
| 🟡 要注意 | 条件次第で実機バグになる(Timing / CDC / Implicit wire) | 原因を理解して対処方針を決める |
| 🟢 情報通知 | 回路に影響しないことが多い(Memory inferred等) | 内容を確認してスキップ判断 |
🐾 もふねこ:
「Warningの理由を1件残らず説明できる状態」でFPGAに焼く。これが実務のルール。最初は面倒に感じるかもしれないけど、Warning放置で3日溶かすのと、10分でWarningを全部読むのと、どちらがいいかは明らかだよね🐾
このページでは「Warning放置でどんな目に遭うか」のエピソードを紹介しましたが、それぞれのWarningに対する具体的な修正パターンと安全な記述テンプレートは、もふねこの有料教材にWarning対策カタログとしてまとめてあります。
8. まとめ
📝 Warning放置で溶かした話 ベスト5
| 順位 | Warning名 | 溶かした時間 | 症状 |
|---|---|---|---|
| 🥇 1位 | Latch inferred | 丸2日 | ボタンを押すたびに挙動が変わる |
| 🥈 2位 | Multiple drivers | 3日 | 信号衝突で挙動不審 |
| 🥉 3位 | Timing violation | 2日 | 周波数を上げたら突然死。毎回壊れ方が違う |
| 4位 | Width mismatch | 半日 | 特定の値を超えると0に戻る |
| 5位 | Implicit wire | 3時間 | 出力が常に0 |
「Warningは未来の自分からの警告」です。今5分でWarningを読む手間を惜しむと、未来の自分が3日間のデバッグで泣くことになります。論理合成が終わったら、FPGAに焼く前に必ずWarningを全件確認する──これだけで実機デバッグの時間は劇的に短くなります。
関連するページ: 実験ログ1: Sim/Synthミスマッチを解剖する | 実験ログ2: Latch地獄から脱出した3日間 | 応用実験5: ラッチを生む3つの原因と対策