JP / EN
SPICE Internal / Coffee Break

SPICEの限界を暴く:.DISTOコマンドとBソースの埋もれた真実

完璧な理論が、ツールの内部実装に敗北する瞬間。
シミュレータにテイラー展開を解かせようとして起きた、セグフォと沈黙のドキュメンタリー。

1. .DISTO解析の正体と内部計算

SPICEには、.SENS(感度解析)の他にも、非常に高度な数学的計算を行っているコマンドが存在します。それが.DISTO(歪み解析)です。

本来、このコマンドはオーディオアンプや無線の高周波回路などで使われます。トランジスタなどの非線形性によって生じる「2次高調波(元の2倍の周波数のノイズ)」や「3次高調波」といった波形の「歪み」の大きさを求めるための機能です。

通常、波形の歪みを見るなら過渡解析(.TRAN)を行ってFFTをかければ良いと思いがちですが、微小な歪みは計算誤差(ノイズフロア)に埋もれてしまいます。そこで .DISTO は時間を進めるシミュレーションを一切行わず、「現在の動作点における非線形モデルの2階微分・3階微分を解析的に計算し、ボルテラ級数(周波数領域のテイラー展開のようなもの)に当てはめて理論値を直接算出する」という、極めて高度な行列計算を内部で行っているのです。

2. エンジニアの閃き「これ、テイラー展開に使えるのでは?」

この .DISTO の内部計算の仕様を知ったとき、ふとあるアイデアが閃きました。

「SPICEが内部で2階微分と3階微分を計算して歪みを出力しているのなら、その出力値は数学的なテイラー展開(マクローリン展開)の係数そのものではないか?」

ある関数 $f(x)$ を $x=0$ の付近でテイラー展開すると、以下のようになります。

$$f(x) \approx f(0) + f'(0)x + \frac{f''(0)}{2!}x^2 + \frac{f'''(0)}{3!}x^3$$

.DISTO が出力する2次高調波(HD2)と3次高調波(HD3)は、まさにこの $x^2$ や $x^3$ にかかる係数に相当します。つまり、任意の数式をBソース(非線形従属電源)で記述し、そこに .DISTO を叩き込めば、手計算では面倒な多変数関数のマクローリン展開が一撃で求まる「究極の数学ソルバー」が完成するはずだと考えたのです。

3. 悪魔の実験: $y = e^x$ のテイラー展開

ターゲットは、何度微分しても形が変わらない美しい関数、$y = e^x$ です。このマクローリン展開の係数をSPICEに解かせるべく、以下のようなネットリストを組みました。

***** SPICE Taylor Expansion exp(x) ***** * x=0 を中心に、歪み解析用の入力(DISTOF1=1)を設定 Vx x 0 DC 0 AC 1 DISTOF1 1 * y = exp(x) を計算する非線形従属「電流源」 By 0 y I = exp(V(x)) Ry y 0 1 * 1Hzから2Hzまで歪み(テイラー展開の係数)を計算 .DISTO LIN 2 1 2 .END

理論上は、2次歪みとして $\frac{1}{2}$(0.5)、3次歪みとして $\frac{1}{6}$(約0.166...)に相当する値が出力されるはずです。しかし、この数行のコードが、歴史あるシミュレータの「パンドラの箱」を開けることになります。

4. シミュレータの悲鳴:爆発と沈黙

このネットリストを、現在広く使われているオープンソースのSPICE派生シミュレータに食わせた結果、信じられない事態が発生しました。

Ngspiceの場合:問答無用の Fatal Error

Windows環境のNgspiceで run を実行した瞬間、GUIは「Fatal error in NGSPICE」という残酷なダイアログを残し、ツールごと強制終了(クラッシュ)しました。俗に言うセグフォです。

MacSpiceの場合:沈黙のオールゼロ

一方、MacSpiceではツールは落ちずに最後まで走り切りました。しかし、出力された結果は以下の通りでした。

Index frequency y ----------------------------------------------------- 0 1.00000e+00 ( 0.00000e+00, 0.00000e+00 ) 1 1.33333e+00 ( 0.00000e+00, 0.00000e+00 ) 2 1.66667e+00 ( 0.00000e+00, 0.00000e+00 )

見事にすべてゼロです。何も計算されていません。

5. なぜこんなことが起きたのか?(種明かし)

完璧な数式を与えたはずなのに、なぜシミュレータは崩壊したのでしょうか。答えは、SPICEの内部実装(C言語のソースコード)の限界にありました。

.DISTO は、あらかじめC言語レベルで「2階微分・3階微分の数式」がハードコードされている純正部品(ダイオードやトランジスタなど)に対してしか機能しません。ユーザーが任意の数式を打ち込める「Bソース」のパーサーには、高階微分を自動導出する機能がそもそも実装されていなかったのです。

Ngspiceは、存在しない高階微分のメモリ領域(Nullポインタ)を参照してパニックを起こし、自爆しました。一方のMacSpiceは、「機能がないなら、とりあえずゼロを返しておけ」と安全側に倒して逃げ切った(Silent Failure)わけです。

6. Dr.WataWata's Insight

数学的な理論が完璧であっても、最終的にはツールの「中の人」のCコードの実装状況に左右される。

これは、ファームウェア開発において「マイコンのデータシートにはできると書いてあるのに、実際に特殊な条件でレジスタを叩くとペリフェラルがハングアップする」という現象(エラッタ)にそっくりです。

今回はシミュレータにテイラー展開を解かせるという目的こそ果たせませんでしたが、ツールの限界点を文字通り「物理的」に突き止めたという意味で、非常に痛快な検証結果となりました。ブラックボックスを叩いてシステムの限界を知ることもまた、エンジニアの醍醐味ではないでしょうか。