第12章 徹底検証 ― シミュレーションとAI活用
ここは、本講座の集大成のひとつです。これまで各章で「最小確認」を積み上げてきましたが、その背骨にあったのが検証でした。次章のテープアウト(実チップ製造)は一発勝負――焼き上がったシリコンは、バグがあっても書き換えられません。だからこそ、製造の前にシミュレーションで徹底的に確かめ、異常系まで網羅し、AIを検証に活かす。本章は、私たちが専用ビルド工程(M1〜M5)で実際にやってきた検証のやり方を言語化し、サインオフ(製造GOの判断)前のチェックリストまで一気に通します。
12.1 なぜ検証に最大の時間を割くのか
ソフトウェアなら、バグは見つけ次第パッチを当てられます。けれどチップは違います。製造には時間(数ヶ月)と費用がかかり、届いたチップに欠陥があれば、原則作り直し。この非対称が、ハード開発の鉄則を生みます――「設計より検証に時間を割く」。本講座でも、各章のRTLは「骨格・未検証」と正直に表示し、専用ビルド工程で一つずつシミュレーションにかけて初めて"検証済み"としてきました。テープアウトを前に、その姿勢を最大化します。
12.2 検証の思想 ― 思想は人間、実装はAI、最終審判は物理
本講座を貫く一行を、ここで改めて掲げます。「思想(アーキテクチャ・設計判断)は人間が担い、実装と検証の高速な反復はAIが回し、最終的な正しさの審判は物理(実機)が下す」。この三者の役割分担が、検証の地図になります。
検証における役割分担
───────────────────────────────────────────────────────────────
人間(アーキテクト) 何を作るか・どう設計するか・何を"正しい"とするか を決める
↓ 指示・判断
AI(実装・検証の手) ラッパ/テストベンチの生成、IP探索、デバッグ補助 を高速に回す
↓ 生成物
シミュレーション 論理の正しさを「机上で」確かめる(速い・安いが、現実の近似)
↓ 通ったもの
物理(実機・最後は製造) 最終審判。クロック・タイミング・現物の部品で「本当に動くか」
───────────────────────────────────────────────────────────────
※ AIは速いが間違える。だから「人間の判断」と「物理の審判」を、AIの上下に必ず置く。
12.3 道具 ― Icarus Verilog と Verilator
シミュレータには性格の違う二つがよく使われる、とされます。本講座のM1〜M5はIcarus Verilogで回してきました。
Icarus Verilog(軽量・教材向き)
導入が容易で、iverilog → vvp の素直な流れ。小〜中規模の機能検証や学習に向く。M1〜M5の結合検証はこれで実証した。
Verilator(高速・大規模向き)
RTLをC++に変換して回す方式で非常に速い、とされる。大規模な回帰テストや、長いプログラムを流す検証に向く。使い分けの選択肢。
※どちらを使うかは規模と目的で選ぶ(断定回避)。 まずIcarusで「型」を作り、検証が重くなったらVerilatorを検討する、という順序が現実的、と著者は考えます。各ツールの導入手順・対応範囲・版は変動するので、最新は公式で確認してください。
12.4 テストベンチの型 ― 「仕事をするC」と「合否を出す番人TB」を分ける
本講座の検証の一番の発明が、この役割分担です。チップ上で動くCプログラムは「仕事をするだけ」に徹し、合否の判定はテストベンチ(TB)という"番人"が独立に持つ。M5を例にとると、Cは「SPIでmicroSDダミーと1バイト、UART2で無線ダミーと1バイトやり取りし、結果を gpio_out と LED に出す」だけ。正しいかどうかは一切判断しません。判断はTBの仕事です。
// テストベンチ=検査の番人(tb_soc.v の型・骨格)
// Cは「仕事」だけ。合否はこのTBが独立に判定する。
initial begin
$dumpfile("soc.vcd"); $dumpvars(0, tb_soc); // 波形(VCD)を残す
repeat (16) @(posedge clk); rst = 0; // リセットを十分かけてから解除
// 完了の印(signature)が立つまで待つ。ただし上限つき=ハングしても必ず止まる
while ((led !== 8'h5A) && (cyc < 2000000)) begin
@(posedge clk); cyc = cyc + 1;
end
// 独立した2つの検査。どちらも満たして初めて PASS
chk1 = (gpio_out === 16'h5A4F); // 検査1:結合往復(上位=SD/下位=無線)
chk2 = (led === 8'h5A); // 検査2:signature(完了の印)
$display(chk1 && chk2 ? "==== RESULT: PASS ====" : "==== RESULT: FAIL ====");
$finish;
end
// 安全網:いつまでも終わらないときの大域タイムアウト(ハング対策)
initial begin #300000000; $display("==== RESULT: FAIL (timeout) ===="); $finish; end
※この分離が効く理由(著者の整理)。 判定をCに混ぜると、Cのバグとハードのバグが見分けにくくなる。Cを「一直線・最小(第6章の4イディオム)」に保ち、検査をTBに集約すれば、失敗したとき"どこが悪いか"が切り分けやすい。さらに、上限つきの待機と大域タイムアウトという二重の安全網で、「テストが固まって終わらない」事故を防ぎます。これはM1〜M5で実際に効いた型です。
12.5 異常系を網羅する ― 正常系だけでは足りない
「期待どおりに動く」ことの確認(正常系)は、検証の半分でしかありません。実チップが現場で壊れるのは、たいてい想定外の入力・境界・タイミングです。だからテープアウト前には、異常系を意図的に突きます。
- 境界値: FIFOが満杯/空のときの読み書き、カウンタの桁あふれ、最小/最大のサンプル値やデューティ。
- タイミング: リセットの最中にアクセスが来たら、クロックの境目でデータが変わったら。準備不足の周辺を叩いたら。
- 不正アクセス: 割り当てのない番地を読み書きしたとき、ハングせず無難に応答するか(バスが固まらないか)。
- 止まらない事故: 応答が永遠に返らないケースを、タイムアウトで必ず捕まえる(12.4の安全網)。
12.6 ダミーと本物の差 ― シミュPASSは実機OKではない
ここは、本講座が最も正直でありたいところです。M5の検証で相手をしたのは、教材用ダミーでした。microSDダミーは「受けたビットを反転して返す」だけ、無線ダミーは「合図に 'O' を返す」だけ。これらは「結合経路が通る」ことを最小に実証しますが、本物のSDカードの初期化(CMD0…)やファイルシステム、本物の無線モジュールのATコマンドや技適ではありません。
シミュレーションで言えること / 言えないこと
───────────────────────────────────────────────────────────────
◎ 言える ・論理(バス・レジスタ・状態遷移)が設計どおり動く
・経路が通る(信号が正しく届き、往復する)
× 言えない ・本物の外部部品の作法(SD初期化手順・AT応答・実タイミング)
・実クロックでのタイミング成立、現物の電気的振る舞い、温度・電源
───────────────────────────────────────────────────────────────
→ だから本講座は、未確定を [改訂マーカー] で明示し、実機で回収する。
この差を曖昧にしないために、本講座は[改訂マーカー]という印を一貫して使ってきました。「シミュで検証済み/実機で最終確認」を区別し、誇張せずに前進する――この規律こそ、一発勝負のテープアウトに耐える検証の土台です。
12.7 波形とログ ― VCD・検査ログ・無害な警告の見分け
検証の現場で頼るのは、二つの目です。
波形(VCD)
$dumpfile/$dumpvars で残した波形を波形ビューアで見る。「いつ・どの信号が・どう変わったか」を目で追い、想定とのズレを見つける。
検査ログ($display)
TBが出す 検査1 … OK/NG や RESULT: PASS、到達サイクル数。まずここで合否と"どこまで進んだか"を掴む。
※"無害な警告"と"本物のエラー"を見分ける。 M1〜M5でも、$readmemh: Not enough words(Flashモデルの空き)や @* sensitive to all 1024 words(非同期メモリの通知)といった無害なメッセージが出ました。これらに動じず、本当に問題のあるエラー(未結線・幅不一致・X伝播)と切り分けるのも検証の技術です。すべての警告を消すのが目的ではなく、意味を理解して仕分けること。
12.8 AIを検証に活かす ― 何を任せ、何を任せないか
本講座は「人がアーキテクト、AIが実装と検証を高速に回す」現代的な開発を実演してきました。検証でも、AIは強力な手になります。ただし節度が要ります。
AIに任せて効くこと
IP候補の探索、Wishboneラッパ等のグルーコード生成、テストベンチの叩き台作り、波形・エラーログからの原因推定。反復が速くなる。
AIに任せてはいけないこと
最終判断。AIはもっともらしく間違える(実在しないIP名・ポート・レジスタを"自信満々"に出す)。設計の正否と"何を正しいとするか"は人間が握る。
発展:AIに「良いテストベンチ」を書かせるコツ
丸投げではなく、「何を正しいとするか(合否基準)」を人間が先に定義して渡すと、AIのTB生成は精度が上がります。M5なら「gpio_out が 0x5A4F、LED が 0x5A なら PASS、上限サイクルで FAIL、大域タイムアウトも置く」と基準を明示する。判定の言語化は人間の仕事、その実装の高速化はAIの仕事――役割分担がそのままプロンプトの設計になります。
12.9 サインオフ前チェックリスト
テープアウト(第13章)にGOを出す前に通す、機能検証側のチェックリストです(配置配線・DRC/LVS/STA はテープアウト工程の領域。ここは「論理として正しいか」を固めます)。
サインオフ前チェックリスト(機能検証) ─────────────────────────────────────────────────────────────── □ 全周辺が個別にシミュ検証済み(M1〜M5 の各検査が PASS) □ 結合状態でも検査が PASS(周辺を載せた状態で破綻しない) □ 異常系を網羅(境界・タイミング・不正番地・タイムアウト) □ 警告をすべて仕分け済み(無害 / 本物のエラー を区別し、後者はゼロ) □ メモリマップが「本文・実装・ソフト」で一致(番地整合) □ リセット/クロックの扱いを確認(初期化・乱れに耐える) □ [改訂マーカー] を棚卸し(実機で確認すべき項目が一覧化されている) □ 実機(FPGA)で主要機能を確認(シミュPASS≠実機。物理で最終確認) ─────────────────────────────────────────────────────────────── ※ ここまで通って初めて、第13章(LibreLane/OpenROAD)へ進む。
12.10 この章のまとめ
- 検証に最大の時間を割く: チップは一発勝負。直せないからこそ、机上で徹底的に確かめる。
- 三者の役割分担: 思想は人間、実装・検証はAI、最終審判は物理。AIの上下に人間と物理を必ず置く。
- 番人TBの型: Cは仕事だけ、合否は独立したTBが判定。上限待機+大域タイムアウトの安全網。M1〜M5で実証した型。
- 異常系を歓迎する: 正常系のPASSだけでは危険。境界・タイミング・不正・ハングを意図的に突き、机上でFAILを出す。
- シミュPASS≠実機OK: 教材用ダミーは経路を実証するが本物ではない。差を [改訂マーカー] で明示し、実機で回収する。
- AIは速さ、確かさは人間と物理: 探索・生成・デバッグはAIに、最終判断は人間に、審判は物理に。断定を避け、必ず検算する。
機能の正しさを固め、チェックリストを通しました。いよいよ、固めたRTLをシリコンへ渡す番です。次章は、LibreLane(内部でOpenROADが配置配線を担う)にRTLを渡し、GDSIIへ変換、DRC/LVS/STAでサインオフしてシャトルへ提出する――ASIC化の本筋への入口、第13章:テープアウト ― LibreLane/OpenROADです。