
AIが書いた1,000万ドルのバグ——そして私が、それを潰すために会社を興した理由
Veriprajnaを立ち上げると決めた、まさにその瞬間を私は覚えている。
それはひらめきの瞬間ではなかった。一本の電話だった。相手が言うべきことをどう切り出すか考えあぐねて、最初の5秒間は誰も口を開かない、そういう類の電話だ。ある設計チーム——私が尊敬する、本当に仕事のできる人たち——が、カスタムRISC-Vアクセラレータの初回シリコンをファウンドリから受け取ったばかりだった。そのチップは死んでいた。「回避策が必要」な死ではない。「ファームウェアでパッチできる」死でもない。文鎮化していた。サーマルスロットリングと高帯域メモリトラフィックが特定の、まれな組み合わせで重なったとき、調停モジュールが未定義状態に陥り、システム全体がデッドロックしたのだ。
根本原因は競合状態(レースコンディション)だった。RTLにおけるブロッキング代入とノンブロッキング代入のたった一つの、微妙な食い違い——シミュレーションでは完璧に動き、リントでも一言の警告も出さず、どんなリグレッションテストをぶつけてもパスし、そしてやり直しの効かないシリコンで裏切る、あの類のものだ。
その5nmチップのマスクセットはおよそ1,000万ドルかかった。それが吹き飛んだ。だが本当の損害はマスクではなかった。診断し、修正し、再検証し、再製造するのに必要な6か月だった。製品世代がおよそ18か月で入れ替わるAIアクセラレータ市場では、6か月の遅れが製品のライフタイム総粗利益の50%を蝕みうる。1億ドルの売上を狙う企業にとって、あの競合状態のコストは1,000万ドルではなかった。5,000万ドルだったのだ。
そして、私を夜も眠れなくさせたのはこの部分だ——それを引き起こしたコードは、LLMが生成したものだった。
誰も疑問視しないゴールドラッシュ
いま、半導体業界はゴールドラッシュの真っ只中にある。誰もが——文字どおり誰もが——大規模言語モデルを電子設計自動化(EDA)ワークフローに組み込もうと競い合っている。その触れ込みは抗いがたい。かつては何年もかかっていた設計サイクルを数か月に圧縮する。チップ設計を民主化する。退屈なレジスタ転送レベルのコーディングをAIに任せ、エンジニアはアーキテクチャに集中できるようにする、というわけだ。
その魅力はわかる。私自身も感じたことがある。LLMが自然言語のプロンプトから構文的に正しいVerilogモジュールを生成するのを初めて見たとき、私はこう思った——これはすべてを変える、と。
だがそのあと、ソフトウェアではなくハードウェアを書くとき「構文的に正しい」が実際に何を意味するのか、私はより注意深く見るようになった。そして業界が砂の上に基盤を築いていることに気づいたのだ。
いま市場にあふれているツールは、私が「ラッパー」と呼ぶものだ。汎用のLLM——GPT-4、Claude、Llama——を取り、Verilog風のシステムプロンプトを付けたチャットインターフェースで包み、「チップ設計コパイロット」として売る。中には本当に見事なデモもある。コードは綺麗に見える。コンパイルも通る。シミュレーションさえできる。
だが、これらのツールが根本的に何であるかというと——ハードウェアの皮をかぶった確率的トークン予測器だ。回路トポロジーを理解していない。タイミングクロージャを理解していない。メタスタビリティを理解していない。学習データの統計的パターンに基づいて、次に来そうなトークンを予測しているだけだ。
LLMがソフトウェアでハルシネーションを起こせば、OTAでパッチできるランタイムエラーが出る。LLMがハードウェアでハルシネーションを起こせば、1,000万ドルの文鎮が手に入る。
その非対称性こそが、Veriprajnaが存在するすべての理由だ。
なぜAIは粗悪なハードウェアコードを書くのか?

これは私が最もよく訊かれる質問で、たいていはLLMが完璧に機能するPythonを書くのを見てきて、なぜVerilogは違うのか理解できないソフトウェアエンジニアからだ。その答えは「ハードウェアの方が難しい」より深いところにある。LLMの考え方とハードウェアの動き方の、根本的な不一致なのだ。
LLMは圧倒的にソフトウェア——Python、Java、C++、JavaScript——で学習されている。これらは命令的で逐次的な言語だ。行Aが実行され、次に行Bが実行される。システムの状態は演算の順序によって定義される。LLMはこのパラダイムを深く内面化しており、事実上それが母語になっている。
VerilogとVHDLは宣言的で並行的だ。ハードウェアモジュールでは、あらゆるalwaysブロック、あらゆるassign文、あらゆるモジュールインスタンス化が同時に、かつ継続的に実行される。ソースコードの行の順序は、シリコン上での実行順序とはまったく関係しないことが多い。
私は初期の実験の一つで、これがリアルタイムで起きるのを目の当たりにした。私たちは3つの異なるフロンティアLLMに、単純な3段パイプラインレジスタを実装させた。3つともブロッキング代入(=)を、ノンブロッキング代入(<=)の代わりに使った。Cのコードのように目を細めて見れば、コードは完璧に妥当そうに見えた。だがハードウェアでは、クロック同期ブロック内のブロッキング代入は次のような結果を招く——stage2がstage1の値で即座に更新され、次にstage3が得るのは新しい値、すなわちstage2の値だ——実質的に2サイクルのパイプラインを1サイクルに潰してしまう。
私のエンジニアの一人、プリヤは、その出力を1分ほど見つめてこう言った。「これはセミコロンを間違った場所に置いたCを書いているんです」。彼女はまったく正しかった。LLMには逐次的バイアスがあった——実際には記述言語であるVerilogを、プログラミング言語のように扱っていたのだ。この違いは構文的には微妙だが、物理的には破滅的だ。
そしてさらに悪いことがある。ハードウェア設計は厳格なインターフェースプロトコル——AXI、AHB、PCIe、TileLink——に依存しており、それらには複雑な時間的規則がある。「ReadyはValidを待ってはならない」。「Grantは5サイクル以内にアサートされなければならない」。LLMはこうした規則を90%の確率で守るコードを生成できるが、それは素晴らしく聞こえる——残りの10%の誤りこそが、まさにチップを殺すコーナーケースだと気づくまでは。あるAXIマスターがWVALIDを、AWREADYより前にアサートするという特定のサブ条項違反は、構文エラーを出さない。コンパイルもシミュレーションも通り、そしてシリコン上で準拠したメモリコントローラに接続されると、ハングするのだ。
学習データの問題がすべてを悪化させる。学習に使える高品質でプロダクショングレードのVerilogの量は、桁違いに少ない——PythonやJavaScriptと比べて。GitHub上のオープンソースVerilogの多くは、学生のプロジェクト、放棄されたプロトタイプ、テープアウトレビューに到底耐えられないおもちゃのような実装だ。凡庸なデータで学習すれば、凡庸な出力が得られる——プロフェッショナルに見えるが、アマチュアの誤りのDNAを内包した出力が。
すべてのチップ設計者を悩ませる法則

半導体設計には「10倍の法則」と呼ばれる経験則があり、それを理解すれば、なぜ私がバグを早期に捕まえることにこれほど執着するのかが分かる。
欠陥を修正するコストは、10倍ずつ、設計ライフサイクルの後続の各段階ごとに増大する。RTL設計中に捕まえたバグの修正コストは約100ドル——誰かがファイルを編集してチェックを再実行するだけだ。同じバグをブロック検証で捕まえると1,000ドル。システム検証では10,000ドル。ポストシリコン検証まですり抜ければ——実際のチップを実験室でデバッグする段階では——再製造(リスピン)に1,000万ドル以上かかる。そして、現場の顧客のもとに届いてしまえば?それは1億ドルの世界だ。リコール、訴訟、ブランドの破壊。インテルにPentiumのFDIVバグについて訊いてみるといい。
ラッパー型のAIツールは、ほぼRTL設計段階でしか機能しない。エンジニアがより速くコードを書くのを助ける。だが「コンパイルが通るか」を超えた検証能力を一切持たないため、それらはブロック検証やシステム検証をすり抜け、シリコンで初めて炸裂するバグを注入してしまう。
残酷な皮肉はこうだ——検証の厳密さを高めないままコード生成の速度を高めることで、これらのツールは高コストな欠陥をパイプラインに注入する速度を加速させる。あなたはただ「速く動いて物事を壊している」だけではない。速く動きながら、1,000万ドルのマスクセットにバグを焼き付けているのだ。
業界のデータがこれを裏付けている。初回シリコンで成功する設計はわずか32%にすぎない。残りの68%は少なくとも1回のリスピンを必要とし、その主因は論理的・機能的な欠陥だ——まさに、LLMがプロトコルをハルシネーションしたり並行性を誤解したりするときに生成する類の誤りである。
私はかつて、資金調達の初期にこれをある投資家に説明した。彼は辛抱強く聞いたあと、こう言った。「もっと良いプロンプトでGPT-4を使えばいいだけじゃないですか?」
私はあのパイプラインレジスタの例を呼び出した。ブロッキング代入のバグを見せた。それがリントを通り、シミュレーションを通り、ラッパーツールが提供するあらゆる自動チェックを通ることを見せた。そして、それがシリコン上で何をするかを見せた。
彼は二度と、もっと良いプロンプトについて訊かなかった。
コードをただテストするのではなく、正しいと証明できるとしたら?
ここで話は転換する。なぜなら、LLMのハルシネーション問題への答えは、より良いプロンプトでも、より大きなモデルでも、より多くの学習データでもないからだ。それは、検証に対する根本的に異なるアプローチなのだ。
従来の検証はシミュレーションに依存している——テストベンチを書き、何百万サイクルも走らせ、設計が期待どおりに動くかを確認する。これは、街区を1,000回ぐるぐる走り回って車のブレーキをテストするようなものだ。ブレーキが故障しなければ、安全だと仮定する。だがもし、雨が降っていて、時速ちょうど62マイルで走っていて、ラジオが特定の周波数に合っているときにだけ故障するとしたら?シミュレーションは、明示的にテストしたシナリオしか検証できない。それ以外はすべて祈りだ。
形式的検証(フォーマルベリフィケーション)は、設計をまったく走らせない。設計全体を数学的な論理式に変換し、充足可能性モジュロ理論(SMT)ソルバー——マイクロソフトのZ3のようなツール——を用いて、ある性質が次の条件のもとで成り立つことを網羅的に証明する——あらゆる可能な入力の組み合わせと、あらゆる内部状態のもとで。その一つひとつすべて。サンプルではない。統計的近似でもない。数学的な証明だ。
シミュレーションはこう問う。「私がテストしたケースで、これは動くか?」。形式的検証はこう問う。「これが失敗する可能性のあるケースは、一つでも存在するか?」。その違いは、希望と証明の違いだ。
ソルバーが「UNSAT」——充足不能——を返せば、反例が存在しないことを意味する。その性質は数学的に保証される。「SAT」を返せば、あなたの設計を壊す具体的な入力のシーケンスを、正確なクロックサイクルに至るまで手渡してくれる。
形式的検証は数十年前から存在している。それが業界を席巻してこなかった理由は、形式的な性質——SystemVerilogアサーション、すなわちSVA——を書くことが悪名高いほど難しいからだ。ほとんどの設計チームが持たない専門的なスキルセットを要する。アサーションはハードウェアの「契約」だ。「requestがハイになれば、grantはNサイクル以内に続かなければならない」。「アドレスXから読み出したデータは、Xに最後に書き込まれたデータと一致しなければならない」。「パイプラインは決してデッドロックしてはならない」。これらを正しく書くことは一種の芸術であり、それをこなせる実践者は足りていない。
そして、まさにここでAIが役に立つ——ハードウェアのコードを書くためではなく、証明を書くためにだ。
「フォーマル・サンドイッチ」——私たちが実際にこれをどう作ったか

私は数か月にわたり、正しいアーキテクチャをめぐってチームと議論した。その論争は激しく、そして振り返れば、頭を整理してくれるものだった。ある陣営は、デフォルトで正しいVerilogを生成するまでLLMをファインチューニングしたがった。もう一方の陣営——最終的に私が味方した側——は、学習による正しさは幻想だと主張した。ハルシネーションは学習で消し去れない。捕まえることしかできないのだ。
私たちがたどり着いたのは、私たちが「フォーマル・サンドイッチ」と呼ぶものだった——LLMが創造のエンジンであり、形式的検証ソルバーが妥協しない批評家である、ニューロシンボリックなアーキテクチャだ。どちらも単独では機能しない。両者が組み合わさって初めて、どちらも単独ではできないことを成し遂げる。
実際にどう機能するかを説明しよう。設計者が仕様を与える——「APB-to-AXIブリッジを設計せよ」、あるいはタイミング図のスクリーンショットでもよい。私たちのSpec Analyzerエージェントが、これを機能要件へと分解する。そして、ここで鍵となるイノベーションが登場する。LLMは単にコードを生成するのではなく、二つのアーティファクトを同時に生成する。
アーティファクトAはRTL実装——Verilogコードそのものだ。アーティファクトBは形式仕様——同じ要件から導かれたSVA性質の集合だ。仕様が「GrantはRequestに続かなければならない」と言うなら、LLMはステートマシンを生成し、かつそのステートマシンが主張どおりに動くことを証明するアサーションも生成する。
それから私たちはソルバーを解き放つ。ソルバーはアーティファクトAを取り、アーティファクトBを使ってそれを壊そうとする。まず、空虚性チェック——アサーションが自明に真(トリガー条件が決して発火しない「怠慢な」生成)でないことを確かめる。次に有界モデル検査で、深い状態空間——50、100サイクルもの深さ——を探索し、デッドロック、競合状態、プロトコル違反を狩る。
ソルバーがバグを見つけたとき、それはただ印を付けるだけではない。生成するのは反例トレースだ——バグがどのように現れるかを正確に示す精密な波形だ。そして、ここでループが閉じる。私たちはそのトレースをプロンプトとしてLLMに送り返す。「あなたの設計は失敗した。トレースはこうだ。サイクル1、Resetがデアサートされる。サイクル2、Requestがハイになる。サイクル10、Grantはまだローのままだ。grantは決して到着しなかった。ステートマシンを修正せよ」
LLMはそのトレースを分析し、欠けていた状態遷移を特定し、コードを書き直す。ソルバーが再びチェックする。このループは、設計が正しいと証明されるまで自動的に繰り返される。
私はこのアーキテクチャについて、私たちの研究のインタラクティブ版で、はるかに深く掘り下げて書いた。だが核心となる洞察はシンプルだ——私たちはAIを使って証明を書き、数学を使ってそのAIをチェックする。どちらも相手を信頼しない。だが両者が互いをより良くする。
私を信者にしたバグたち
私がこのアプローチの真の信者になったのは、理論を通じてではなく、他の何をもってしても見つけられなかったであろう、私たちが捕まえた具体的なバグを通じてだった。
オープンソースのRISC-Vコミュニティは、本当に優れたプロセッサコアを生み出してきた——Ibex(GoogleのOpenTitanセキュリティチップで使われている)、チューリッヒ工科大学(ETH Zurich)のPULPプラットフォームなどだ。これらは実力あるエンジニアリングの才能に支えられ、厳しく精査された設計だ。それでもなお、形式的検証でしか見つけられないバグを抱えている。
形式的検証のコンサルティング会社であるAxiomiseは、Ibexコアの中に、分岐命令の実行中の特定のサイクルに到着したデバッグ要求が、コアをデッドロックさせたり誤った命令を実行させたりしうるバグを発見した。考えてみてほしい——数十人のエンジニアがレビューしたセキュリティ上重要なコアで、シミュレーションが完全に見逃したバグを、形式的ツールが見つけたのだ。
PULPプラットフォームでは、AXIインターコネクトが、特定の「ビジー」パターンのもとでバスマスターを無期限に飢餓状態に陥らせうるバグが発見された。そのパターンとは、AWVALIDとAWREADYの相互作用によるものだった。古典的なライブネス障害だ——システムはクラッシュせず、ただ前進しなくなる。その特定の相互作用パターンに対して、狙いを定めたテストを書くことは決してないだろう。列挙するには、可能なパターンが多すぎるのだ。
私たちがVeriprajnaをRISC-Vのロード・ストアユニットに向けると、それは自動的にアサーションを生成する——インターフェース準拠(「validがアサートされたら、readyになるまでハイを保たなければならない」)、データ整合性(「アドレスXから読み出したデータは、Xへの最後の書き込みと一致する」)、そして前進保証(「ユニットは最終的に応答を返さなければならない」)についてだ。これらはコードに後付けで取って付けたものではない。同じ仕様から、コードと並んで生成され、一行のRTLも私たちのシステムから出る前に強制される。
私たちの方法論と形式的検証エンジンの完全な技術的解説については、私たちの詳細な研究論文をご覧いただきたい。
「だが形式的検証はスケールしない」
人々はいつもこの点で反論してくるし、その理由も理解できる。形式的検証には計算量が爆発するという評判がある——現代のSoCの状態空間は天文学的に巨大で、素朴な形式的アプローチはおもちゃ以上の規模の設計では詰まってしまう。
私たちはこれに多大な労力を費やしてきた。私たちのシステムは、形式的検証を大規模でも扱えるようにするため、自動化された抽象化技術を用いる。ブラックボックス化は、RAMや複雑なALUのような大きなサブブロックを、定義されたインターフェースを持つ抽象的な実体として扱いながら、グルーロジックを検証することを可能にする。カットポイントは、valid/readyのハンドシェイク経路を切断し、データ処理とは独立にフロー制御を検証できるようにする。対称性削減は、マルチポートルーターの一つのチャネルについてある性質を証明し、それを数学的にすべてのNチャネルへと帰納的に一般化することを可能にする。
完全に解決したのか?いや。アナログの物理は、形式的手法が触れられない課題を常に突きつけてくる。だが論理バグ——競合状態、デッドロック、プロトコル違反——は、生成されたコードにおいて数学的に不可能になる。そしてそれらこそが、リスピンを引き起こすバグなのだ。
私が耳にするもう一つの反論は、速度についてだ。「形式的ソルバーを走らせると、設計プロセスが遅くなるのでは?」。そう、計算コストは増える。だが私は、スケジュールの確実性のためなら、計算時間をいつだって喜んで差し出す。形式的ソルバーが1時間余計に走ることは、6か月のリスピンに比べれば無限に安いのだ。
「AIが設計したチップ」についての不都合な真実
業界で勢いを増しつつある物語がある——AIがまもなくチップをエンドツーエンドで設計するようになる、私たちはコンピュータ支援設計(CAD)からコンピュータ自動設計へと移行しつつある、という物語だ。私はその物語は方向としては正しいが、危険なほど不完全だと考えている。
私たちは、自律的なAIエージェントが協働するエージェント型ワークフローに向けて構築を進めている——高レベルのパーティショニングを担うArchitectエージェント、実装を担うRTL Coder、テストベンチとアサーションを書くVerification Engineer、そして電力・性能・面積の制約に対してフローを統括するManagerだ。私たちは検索拡張生成(RAG)を、コードのためだけでなく知識のためにも使う——特定のプロトコル規則、プロセス設計キットの制約、社内のコーディング標準を引き出し、LLMがハルシネーションを起こさずに準拠したコードを生成できるようにするのだ。
だが、これらはどれ一つとして機能しない——どれ一つも——形式的検証というバックボーンがなければ。AIが自律的になればなるほど、あらゆる出力が下流に進む前に数学的に検証されることが、より決定的に重要になる。より速くコードを生成するAIエージェントは、そのコードが正しい場合にのみ価値がある。より速くコードを生成し、かつそれが正しいと証明もするAIエージェントは?それこそが未来だ。
半導体業界の問題は、AIがハードウェアコードを書くのが遅すぎることではない。問題は、AIが、微妙に間違ったハードウェアコードを書くのが速すぎることなのだ。
私たちはコパイロットではない。チャットボットでもない。私たちは、たまたま生成AIをフロントエンドとして使っている、形式的検証のファウンドリだ。この区別が重要なのは、それが何を最適化しているかを決めるからだ。コパイロットは速度を最適化する。私たちは正しさを最適化する。すり抜けたたった一つのバグがマスクに1,000万ドル、失われた売上に5,000万ドルを要する世界で、私はどちらの最適化を選ぶか分かっている。
選択はすでになされている
半導体業界はもはや「生成して祈る」アプローチを許容できない。10倍の法則は提案ではない——それは、検証されていないシリコンを出荷する者を罰しようと共謀する、物理と経済だ。5nm以下、マスクセットが2,000万ドルに迫る世界では、誤りの許容範囲はゼロにまで崩壊している。
毎週、私は設計チームと話す。彼らはLLMが自分たちの生産性のために何をできるかに胸を躍らせ、同時にLLMがテープアウトのスケジュールに何をしでかしかねないかに怯えている。その両方を同時に感じるのは正しい。この技術は本当に変革的だ。だが、セーフティネットがなければ、本当に危険でもある。
Veriprajnaは、そのセーフティネットだ。私たちは、数学の確実性を伴ったAIの速度を提供する。「おそらく正しい」ではない。「リグレッションを通った」でもない。正しいと証明された——あらゆる可能な入力、あらゆる可能な状態、シミュレーションが決してテストしようとは思いつかないあらゆる可能なコーナーケースにわたって。
今日、すべてのチップ設計者が直面している選択は、AIを使うかどうかではない。その船はもう出てしまった。選択とは、自らの成果を証明できるAIを使うか、それともただ最善を祈るだけのAIを使うか、である。
私は、どちらに1,000万ドルを賭けるか分かっている。
