逐次比較型ADCの動作原理と設計 — 二分探索で電圧を測る

マイコンのデータシートを開くと、たいてい「12ビット SAR ADC、1 Msps」という一行が載っています。この「SAR」は Successive Approximation Register(逐次比較レジスタ)の略で、いま世の中で動いているAD変換器の圧倒的多数がこの方式です。センサから来たアナログ電圧を、たった12回の比較でデジタルの数値に変えてしまう。しかもフラッシュ型のように4095個ものコンパレータを並べる必要はなく、コンパレータはたった1個で済みます。なぜそんなことが可能なのでしょうか。

天秤で分銅を重い順に載せ降ろしする様子と、候補の電圧範囲が1回の比較ごとに半分に縮んでいく様子を並べた逐次比較型ADCの概念図

左は天秤の比喩です。重い分銅から順に「載せる/降ろす」を1回ずつ判断していくと、傾きを見るだけの単純な操作で未知の重さが決まります。右はその操作を電圧の候補範囲として描いたもので、比較のたびに幅が 1.000 → 0.500 → 0.250 → … と正確に半分になっていくのが読み取れます。6回でもう幅は 0.016 まで縮んでいて、比較回数と分解能が指数の関係にあることがひと目でわかります。

答えは、誰もが一度は遊んだことのある「数当てゲーム」にあります。1から100までの数を相手が思い浮かべ、こちらが「50より大きい?」「75より大きい?」と質問していく、あの遊びです。1回の質問で候補が半分になるので、100通りなら7回で当たります。逐次比較型ADCがやっているのは、まさにこれを電圧に対して実行することです。$N$ ビットの分解能、つまり $2^N$ 通りの候補を、$N$ 回の「はい/いいえ」で絞り込む。ここには二分探索という、アルゴリズムの世界でおなじみの原理がそのまま埋め込まれています。

この方式を理解しておくと、実務で効いてくる場面が多くあります。ひとつはセンサ計測系の設計です。ひずみゲージや熱電対の微小信号をマイコンで読むとき、「サンプリング前にどれくらいの時間、信号源を安定させておく必要があるのか」「入力インピーダンスが高いとなぜ誤差が出るのか」は、SAR ADC内部の容量アレイの動きを知らないと説明できません。もうひとつはADCの選定です。「なぜ16ビットSARは12ビットSARの数十倍高価なのか」「なぜ高速なオシロスコープはSARではなくパイプライン型を使うのか」といった問いには、容量マッチングと整定時間から導かれる明確な理論的根拠があります。

本記事の内容

  • 逐次比較(SAR)が二分探索そのものであることを、残差 $V_\text{res}$ の更新式から導く
  • $N$ クロックで分解能 $V_\text{ref}/2^N$ に到達することを帰納法で証明する
  • 電荷再分配型容量DACの3フェーズ(サンプル・ホールド・ビットテスト)を電荷保存則から導出する
  • 容量ミスマッチが線形性(INL/DNL)をどう決めるかを統計的に評価する
  • 各ステップの0.5LSB整定条件から、変換時間が $\ln 2 \cdot N(N+1)/2 \cdot \tau$ になることを導く
  • コンパレータのオフセット・ノイズがなぜ「効く誤差」と「効かない誤差」に分かれるのかを示す
  • PythonでSARを実装し、段階近似波形・INL/DNL・方式別の速度分解能マップを描く

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

逐次比較型ADCとは — 分銅で重さを量る天秤

昔ながらの天秤ばかりを想像してください。左の皿に重さのわからない物体を載せ、右の皿に分銅を載せて釣り合いを探します。手元にある分銅は 1 g, 2 g, 4 g, 8 g, 16 g … と、2の冪乗の重さで揃っているとしましょう。

慣れた人はこう操作します。まずいちばん重い分銅を右の皿に載せてみる。天秤が右に傾いたら「重すぎた」ので、その分銅は降ろす。傾かなければ「まだ足りない」ので、その分銅は載せたままにする。次に、ひとつ小さい分銅で同じことをする。これを軽い分銅まで繰り返すと、最後に皿に残った分銅の合計が物体の重さになります。しかも各分銅について「載せる/降ろす」を1回ずつ判断しただけです。

逐次比較型ADCは、この操作を電圧で行う装置です。分銅にあたるのが基準電圧 $V_\text{ref}$ を 2 で割り続けた $V_\text{ref}/2,\ V_\text{ref}/4,\ V_\text{ref}/8, \dots$ という電圧の階段で、天秤にあたるのがコンパレータ(2つの電圧の大小だけを判定する回路)です。載せた分銅の合計を作るのが内部のDAC(デジタル・アナログ変換器)で、どの分銅を載せているかを覚えているのが逐次比較レジスタ(SAR)です。

この「分銅を重い順に試す」という手順が本質的に効率的なのは、1回の判断で残りの候補が必ず半分になるからです。分銅を重い順ではなく軽い順に試したらどうなるか、少し考えてみてください。1 g を載せても物体が 200 g なら何もわからず、判断はほとんど情報を生みません。重い順に試すからこそ、毎回の「はい/いいえ」が最大限の情報(1ビット)を運ぶのです。情報理論の言葉を借りれば、SARは1回の比較あたり1ビットのエントロピーを回収する、情報効率の意味で最適な探索になっています。

構成要素を整理しておきましょう。逐次比較型ADCは次の4つのブロックからできています。

ブロック 役割
サンプル&ホールド(S/H) 変換中に入力が動かないよう、入力電圧を保持する
内部DAC いま推定しているデジタル値 $D$ に対応する電圧 $V_\text{ref} D / 2^N$ を作る
コンパレータ 保持した入力とDAC出力の大小を判定し、1ビットの答えを返す
逐次比較レジスタ(SAR)+ 制御ロジック 判定結果を蓄え、次に試すビットをDACに指示する

サンプル&ホールド・内部DAC・コンパレータ・逐次比較レジスタの4ブロックと信号の流れを示した逐次比較型ADCの構成図

ブロック図で見ると、信号がコンパレータ→SARレジスタ→内部DAC→コンパレータという閉ループを $N$ 周まわる構造だとわかります。矢印をたどると、アナログ信号が通るのは左半分(S/H・DAC・コンパレータ)だけで、右半分は完全にデジタルです。この非対称性が、次に述べる「デジタル的なアーキテクチャ」という性格を生んでいます。

注意したいのは、アナログ回路として重いのはコンパレータ1個とDACだけという点です。制御ロジックはただのシフトレジスタで、微細化が進むほど小さく・低消費電力になります。SAR ADCが「デジタル的(digitally friendly)」なアーキテクチャと呼ばれ、CMOSの微細化とともに性能を伸ばしてきたのはこのためです。フラッシュ型が $2^N – 1$ 個のアナログコンパレータを必要とするのとは対照的です。

天秤のイメージはつかめたはずなので、次はこの操作を数式に翻訳します。「分銅を載せる/降ろす」が、残差の引き算1本で表せることを見ていきましょう。

二分探索としての定式化 — 残差の更新式

入力電圧を $V_\text{in}$、基準電圧を $V_\text{ref}$ とし、$0 \le V_\text{in} < V_\text{ref}$ の範囲にあるとします。求めたいのは $N$ ビットの2進表現

$$ \begin{equation} V_\text{in} \simeq V_\text{ref} \sum_{k=1}^{N} b_k 2^{-k}, \qquad b_k \in \{0, 1\} \end{equation} $$

における係数 $b_1, b_2, \dots, b_N$ です。ここで $b_1$ が MSB(最上位ビット、重み $V_\text{ref}/2$)、$b_N$ が LSB(最下位ビット、重み $V_\text{ref}/2^N$)にあたります。

天秤の比喩でいうと、$b_k = 1$ は「$k$ 番目の分銅(重さ $V_\text{ref} 2^{-k}$)を皿に載せた」という意味です。そこで、まだ説明できていない重さを追いかける変数を用意します。これを残差(residue)と呼び、$k$ ステップ終了時点の値を $V_{\text{res},k}$ と書きます。

$$ \begin{equation} V_{\text{res},k} \;\equiv\; V_\text{in} – V_\text{ref} \sum_{j=1}^{k} b_j 2^{-j} \end{equation} $$

すなわち「入力電圧から、いままでに確定した分を引いた残り」です。初期値は何も引いていないので $V_{\text{res},0} = V_\text{in}$ になります。

さて、ステップ $k$ で何が起きるかを追いましょう。制御ロジックは仮に $b_k = 1$ と置いて、DACに $V_\text{ref} 2^{-k}$ を追加させます。コンパレータが判定するのは、その分銅を載せても重すぎないか、つまり

$$ V_{\text{res},k-1} – V_\text{ref} 2^{-k} \;\ge\; 0 $$

が成り立つかどうかです。成り立てば分銅を残す($b_k = 1$)、成り立たなければ降ろす($b_k = 0$)。判定結果は形式的に

$$ \begin{equation} b_k = \begin{cases} 1 & (V_{\text{res},k-1} \ge V_\text{ref} 2^{-k}) \\ 0 & (\text{それ以外}) \end{cases} \end{equation} $$

と書けます。この $b_k$ を使うと、残差の更新は引くか引かないかの1本の式にまとまります。定義式 (2) の $k$ と $k-1$ の差をとると、

$$ \begin{equation} V_{\text{res},k} = V_{\text{res},k-1} – b_k V_\text{ref} 2^{-k} \end{equation} $$

を得ます。$b_k = 1$ なら実際に引き算が起こり、$b_k = 0$ なら残差はそのまま持ち越されます。SAR ADCの全動作は、この漸化式 (4) を $k = 1$ から $N$ まで回すこと、それだけです。アルゴリズムとしては拍子抜けするほど単純ですが、これが二分探索そのものであることを次に確かめます。

残差が必ず半分に縮むことの証明

主張したいのは次の不変条件です。

命題:$0 \le V_\text{in} < V_\text{ref}$ ならば、すべての $k = 0, 1, \dots, N$ について $$0 \;\le\; V_{\text{res},k} \;<\; V_\text{ref} 2^{-k}$$ が成り立つ。

数学的帰納法で示します。まず $k = 0$ のとき、$V_{\text{res},0} = V_\text{in}$ かつ仮定より $0 \le V_\text{in} < V_\text{ref} = V_\text{ref} 2^{0}$ なので成立します。

次に、$k-1$ で $0 \le V_{\text{res},k-1} < V_\text{ref} 2^{-(k-1)}$ が成り立つと仮定し、$k$ での成立を示します。判定条件 (3) にしたがって2つの場合に分けます。

(i)$V_{\text{res},k-1} \ge V_\text{ref} 2^{-k}$ の場合:このとき $b_k = 1$ なので $V_{\text{res},k} = V_{\text{res},k-1} – V_\text{ref} 2^{-k}$ です。下限は判定条件そのものから $V_{\text{res},k} \ge 0$。上限は帰納法の仮定 $V_{\text{res},k-1} < V_\text{ref} 2^{-(k-1)}$ の両辺から $V_\text{ref}2^{-k}$ を引いて、

$$ V_{\text{res},k} < V_\text{ref} 2^{-(k-1)} - V_\text{ref} 2^{-k} = V_\text{ref} 2^{-k}(2 - 1) = V_\text{ref} 2^{-k} $$

となります。ここで $2^{-(k-1)} = 2 \cdot 2^{-k}$ を使ったことに注意してください。

(ii)$V_{\text{res},k-1} < V_\text{ref} 2^{-k}$ の場合:$b_k = 0$ なので $V_{\text{res},k} = V_{\text{res},k-1}$ がそのまま残ります。下限は帰納法の仮定から $\ge 0$、上限は場合分けの条件そのものから $< V_\text{ref}2^{-k}$。

どちらの場合も $0 \le V_{\text{res},k} < V_\text{ref}2^{-k}$ が成り立つので、帰納法により命題が示されました。

この結果を $k = N$ について読み直すと、決定的な事実が出てきます。

$$ \begin{equation} 0 \;\le\; V_\text{in} – V_\text{ref}\sum_{k=1}^{N} b_k 2^{-k} \;<\; \frac{V_\text{ref}}{2^N} \;\equiv\; V_\text{LSB} \end{equation} $$

つまり $N$ 回の比較だけで、入力電圧を分解能 $V_\text{LSB} = V_\text{ref}/2^N$ の精度で決められるということです。証明の中身を振り返ると、上限が毎ステップちょうど半分になっていました。これが「二分探索」という言葉の正確な意味です。探索空間 $[0, V_\text{ref})$ の幅が $V_\text{ref} \to V_\text{ref}/2 \to V_\text{ref}/4 \to \cdots$ と等比数列で縮み、$N$ ステップで $V_\text{ref}/2^N$ に到達します。

基準3.3V・入力2.0Vのとき探索区間の幅が3300mVから12.9mVまで毎ステップ半分に縮む様子を横棒で示した図

命題の内容をそのまま絵にしたのがこの図です。青い帯が「入力が存在しうる区間」で、幅は 3300.0 → 1650.0 → 825.0 → … mV と、証明した上限 $V_\text{ref}2^{-k}$ にぴったり一致しています。赤破線は各ステップの比較電圧で、入力(黒破線)がその左右どちらにあるかで $b_k$ が決まり、区間の左半分・右半分のどちらを残すかが選ばれます。$k=2,3$ のように $b_k=0$ が続くステップでも帯の幅は確実に半減しており、「情報を得ていないステップは一つもない」ことが視覚的に確認できます。

なお式 (5) は「残差が常に非負」、すなわち切り捨て型の量子化であることを示しています。誤差が $[0, V_\text{LSB})$ の片側に寄っているので、平均 $0.5\,V_\text{LSB}$ のバイアスが乗ります。実際のADCではこれを嫌い、DACの出力全体を $-0.5\,V_\text{LSB}$ だけずらす(あるいは最初の比較の閾値を $V_\text{ref}/2 – 0.5V_\text{LSB}$ にする)ことで、誤差を $[-0.5 V_\text{LSB}, +0.5 V_\text{LSB})$ の四捨五入型にします。データシートに「オフセット誤差」と並んで「$\pm 0.5$ LSB」という書き方が出てくるのは、この補正済みを前提にしているからです。

数式で $N$ ステップの収束が保証されたので、次は具体的な数値で手を動かし、ビット列が立っていく様子を体感してみましょう。

具体例 — 12ビット、$V_\text{ref} = 3.3$ V で 2.0 V を測る

$V_\text{ref} = 3.3$ V、$N = 12$ ビットのADCに $V_\text{in} = 2.0000$ V を入れたときの動きを、1ステップずつ追ってみます。LSBの大きさは

$$ V_\text{LSB} = \frac{3.3}{4096} = 8.0566 \times 10^{-4}\ \text{V} = 805.7\ \mu\text{V} $$

です。以下、電圧の単位はVで、残差は式 (4) にしたがって更新します。

$k$ 試す重み $V_\text{ref}2^{-k}$ 判定前の残差 $V_{\text{res},k-1}$ $b_k$ 判定後の残差 $V_{\text{res},k}$
1 1.650000 2.000000 1 0.350000
2 0.825000 0.350000 0 0.350000
3 0.412500 0.350000 0 0.350000
4 0.206250 0.350000 1 0.143750
5 0.103125 0.143750 1 0.040625
6 0.051563 0.040625 0 0.040625
7 0.025781 0.040625 1 0.014844
8 0.012891 0.014844 1 0.001953
9 0.006445 0.001953 0 0.001953
10 0.003223 0.001953 0 0.001953
11 0.001611 0.001953 1 0.000342
12 0.000806 0.000342 0 0.000342

得られたビット列は $b_1 b_2 \cdots b_{12} = 1001\,1011\,0010$、10進では

$$ D = \sum_{k=1}^{12} b_k 2^{12-k} = 2048 + 256 + 128 + 32 + 16 + 2 = 2482 $$

です。これに対応するDAC出力は

$$ V_\text{ref}\frac{D}{2^{12}} = 3.3 \times \frac{2482}{4096} = 1.999658\ \text{V} $$

で、真値 2.0000 V との差は $0.342$ mV、LSBで測ると $0.342 / 0.8057 = 0.424$ LSB です。式 (5) が保証する通り、誤差は $[0, 1)$ LSB に収まっています。

DAC出力が階段状に入力2.0Vへ近づく様子と各ステップで試した電圧・判定ビットを示したグラフ

青い階段が確定済みのDAC出力、オレンジの三角がそのステップで「試した」電圧です。$k=1$ で 1.65 V まで一気に跳んだあと、$k=2,3$ では試した電圧(2.475 V、2.0625 V)が入力の 2.0 V より上なので分銅を降ろし、階段はまったく動きません。判定ビットの列 1 0 0 1 1 0 1 1 0 0 1 0 がそのまま出力コード 2482 の2進表現になっており、$k=5$ 以降は階段が黒破線にほとんど貼りついて見えなくなります。

残差の絶対値と理論上限を対数軸で比較し、12ステップで1LSBを下回ることを示したグラフ

同じ変換を残差の側から対数軸で見ると、灰色の理論上限 $V_\text{ref}2^{-k}$ が等比数列なので直線になり、赤い実測の残差が常にその下側に張りついています。これが証明した不変条件 $0 \le V_{\text{res},k} < V_\text{ref}2^{-k}$ の数値的な裏づけです。$k=1$〜3 や $k=8$〜10 のように残差が水平になるステップでは、上限だけが半分になって差が詰まっていく——つまり「重すぎた」という判定も確実に上限を締め上げていることがわかります。最終的な残差は 0.424 LSB で、緑の1 LSB線を下回っています。

この表で注目してほしいのは残差の列です。2.000000 から始まって 0.350000, 0.143750, 0.040625, 0.014844, 0.001953, 0.000342 と、判定のたびに桁が落ちていきます。命題が保証する上限 $V_\text{ref}2^{-k}$(表の第2列と同じ値)と比べると、残差が常にその下に収まっていることも確認できます。$k=6$ や $k=9,10$ のように残差が動かないステップもありますが、それは「その分銅は重すぎた」という情報を1ビット得ているので、無駄ではありません。

ここまでは数式上の話でした。しかし実際の回路は、どうやってこの引き算を物理的に実行しているのでしょうか。答えが驚くほど美しいのが、次に見る電荷再分配型です。

電荷再分配型容量DAC — 3つのフェーズ

現代のCMOS SAR ADCのほぼすべてが採用しているのが、電荷再分配(charge redistribution)型の容量DACです。1975年に McCreary と Gray が提案したこの方式は、抵抗ラダーを使わず、コンデンサだけでDACとサンプル&ホールドと減算器を兼ねてしまう、恐ろしく経済的な仕掛けです。

構成は単純です。単位容量 $C_u$ を基本として、$k$ 番目のビットに対応する容量を

$$ C_k = 2^{N-k} C_u \qquad (k = 1, 2, \dots, N) $$

とします。MSB($k=1$)が $2^{N-1}C_u$ でいちばん大きく、LSB($k=N$)が $C_u$ です。さらに、合計をちょうど $2^N C_u$ にするためのダミー容量 $C_d = C_u$ を1個足します。すると全容量は

$$ C_\text{tot} = \sum_{k=1}^{N} 2^{N-k}C_u + C_u = (2^{N} – 1)C_u + C_u = 2^N C_u $$

ときれいな値になります。これらの容量は上側の極板(トッププレート)をすべて共通のノード $V_X$ に接続し、下側の極板(ボトムプレート)をスイッチで $V_\text{in}$ / GND / $V_\text{ref}$ のいずれかに切り替えます。コンパレータは $V_X$ とGNDを比較します。

動作は3つのフェーズに分かれます。

容量アレイのボトムプレートを入力・GND・基準電圧に切り替える3フェーズと、そのときのVXの値を示した回路模式図

3つのパネルで違うのは下側の極板がどこにつながっているかだけで、容量アレイそのものは何も変わりません。フェーズ1では全部が入力、フェーズ2では全部がGND、フェーズ3では試すビットの容量だけが基準電圧につながります。その結果として上側の共通ノード $V_X$ が 0 → $-V_\text{in}$ → $-V_\text{res}$ と変化していく、というのがこれから電荷保存則で導く内容です。以下、パネルごとに式で追いかけます。

フェーズ1:サンプル(標本化)

トッププレートのノード $V_X$ をスイッチでGNDに落とし、すべてのボトムプレートを $V_\text{in}$ に接続します。$V_X = 0$、ボトムプレート $= V_\text{in}$ なので、トッププレート側に蓄えられる総電荷は

$$ \begin{equation} Q = \sum_{i} C_i (V_X – V_\text{in}) = -C_\text{tot} V_\text{in} \end{equation} $$

です(電荷はトッププレート側を正としています)。ここで重要なのは、この時点で入力電圧の情報が電荷という形で容量アレイに丸ごと取り込まれることです。つまり容量アレイそのものがサンプル&ホールド回路を兼ねています。別途 S/H アンプを置く必要がないので、部品も消費電力も減ります。

フェーズ2:ホールド(保持)

トッププレートのGNDスイッチを開きます。ノード $V_X$ はどこにもつながっていないフローティングノードになるので、以後この節点の総電荷は保存されます。同時に、すべてのボトムプレートを $V_\text{in}$ からGNDへ切り替えます。

電荷保存則を使いましょう。フェーズ2後のボトムプレートはすべて0 Vなので、

$$ Q = \sum_i C_i (V_X – 0) = C_\text{tot} V_X $$

これがフェーズ1の電荷 (6) に等しいことから、

$$ \begin{equation} C_\text{tot} V_X = -C_\text{tot}V_\text{in} \quad \Longrightarrow \quad V_X = -V_\text{in} \end{equation} $$

を得ます。入力電圧が符号反転してノード $V_X$ に現れました。この瞬間、コンパレータの入力は $-V_\text{in}$ なので、$V_X < 0$、すなわち MSB の比較($V_\text{in} > 0$ か)はすでに済んでいる、という見方もできます。

フェーズ3:ビットテスト(逐次比較)

いよいよ分銅を載せます。ステップ $k$ で「$b_k=1$ を試す」とは、$C_k$ のボトムプレートを GND から $V_\text{ref}$ に切り替えることです。いま $V_\text{ref}$ に接続されている容量の集合を $S$ とすると、電荷保存則は

$$ \sum_{i \in S} C_i (V_X – V_\text{ref}) + \sum_{i \notin S} C_i (V_X – 0) = -C_\text{tot}V_\text{in} $$

となります。左辺の第1項を展開して整理すると、

$$ C_\text{tot}V_X – V_\text{ref}\sum_{i \in S}C_i = -C_\text{tot}V_\text{in} $$

$C_\text{tot}$ で両辺を割り、$V_X$ について解くと

$$ V_X = -V_\text{in} + V_\text{ref}\frac{\sum_{i \in S}C_i}{C_\text{tot}} $$

ここに $C_k = 2^{N-k}C_u$、$C_\text{tot} = 2^N C_u$ を代入します。集合 $S$ に入っているビットを $b_k = 1$ で表せば $\sum_{i \in S} C_i = \sum_k b_k 2^{N-k}C_u$ なので、

$$ \begin{equation} V_X = -V_\text{in} + V_\text{ref}\sum_{k=1}^{N} b_k 2^{-k} = -\left(V_\text{in} – V_\text{ref}\sum_{k=1}^{N}b_k 2^{-k}\right) = -V_{\text{res}} \end{equation} $$

ノード $V_X$ に現れる電圧は、残差の符号を反転したものそのものでした。式 (2) で定義した抽象的な量が、物理的な節点電圧として直接観測できるのです。コンパレータは $V_X$ と 0 を比べるだけでよく、「$V_X < 0 \Leftrightarrow V_\text{res} > 0 \Leftrightarrow$ その分銅は重すぎない」という判定になります。減算器もアンプも不要で、コンデンサの電荷分配だけで引き算が実装されている。これが電荷再分配型の美しさです。

もうひとつ実務的に重要な帰結があります。$V_X$ は常に0 V付近に留まる(残差は縮んでいくので)ため、コンパレータの入力コモンモード電圧がほぼ一定です。これはコンパレータの設計を大幅に楽にします。抵抗ストリング型DACを使う方式では入力コモンモードが全域を動くため、コンパレータのオフセットが入力レベルに依存して変動し、非線形性を生んでしまいます。

サンプル・ホールド・ビットテストの各フェーズにおける比較器入力VXの値を時間軸で示した波形図

$V_X$ の実際の推移を追うと、フェーズ2で $-2.0$ V まで一度深く落ち込み、$k=1$ の比較で $-0.35$ V へ跳ね上がったあとは、0 Vの直下をなぞるように収束していきます。ビットテスト区間で $V_X$ が0 Vからほとんど離れないことが、上で述べた「コンパレータの入力コモンモードがほぼ一定」の意味です。裏を返すと、コンパレータが実際に働かされるのは0 V近傍だけなので、その1点で性能を作り込めばよい——これが設計を楽にしている理由です。

なお、実際のICでは容量比が $2^{N-1}:1$ という極端な比になるのを避けるため、アレイを上位側と下位側に分けてブリッジ容量(アッテネーション容量)でつなぐ分割アレイ構成や、スイッチングエネルギーを減らす MCS(monotonic capacitor switching)、split-capacitor 方式などが使われます。原理はいずれも式 (8) と同じで、重み付き容量比によって $\sum b_k 2^{-k}$ を作っている点は変わりません。

さて、式 (8) は「容量比が理想通りなら」という前提で成り立っています。現実のコンデンサには製造ばらつきがあります。このばらつきが、ADCの線形性をどこまで劣化させるのかを次に定量化します。

容量マッチングが線形性を決める

容量DACの精度は、容量の絶対値ではなくで決まります。式 (8) を見れば明らかで、$C_u$ が10 %大きくても $C_k / C_\text{tot}$ の比は変わりません。絶対値の誤差はゲイン誤差にすらならないのです。効いてくるのは、$C_1 : C_2 : \cdots : C_N$ という比が理想の $2^{N-1} : 2^{N-2} : \cdots : 1$ からどれだけずれるか、つまりマッチングです。

実際のレイアウトでは、$C_k$ は $2^{N-k}$ 個の単位容量 $C_u$ を並列につないで作ります。同じ形の素子を並べたほうが、エッジ効果や勾配的なプロセス変動の影響を受けにくいからです。個々の単位容量が独立に相対標準偏差 $\sigma_u$ でばらつくとすると、$2^{N-k}$ 個の和である $C_k$ の相対誤差 $\delta_k$ の標準偏差は、平均化の効果で

$$ \begin{equation} \sigma(\delta_k) = \frac{\sigma_u}{\sqrt{2^{N-k}}} \end{equation} $$

になります。大きい容量ほど相対誤差は小さい、という自然な結果です。

DNLが最悪になるのはMSB遷移

DNL(微分非線形性) は隣り合うコード間のステップ幅が理想の1 LSBからどれだけずれているかを表す指標で、コード $D$ における値は

$$ \text{DNL}(D) = \frac{V(D+1) – V(D)}{V_\text{LSB}} – 1 $$

と定義されます。$\text{DNL} = -1$ になるとステップ幅がゼロ、つまりミッシングコード(決して出力されないコード)が発生します。

SAR ADCで DNL が最悪になるのは、$0111\cdots1 \to 1000\cdots0$ というMSB遷移です。理由は直感的で、この遷移では下位すべての容量を降ろして MSB 容量ひとつを載せるという、いちばん大規模な入れ替えが起きるからです。$N-1$ 個の誤差の和と1個の誤差が正面からぶつかります。

単位容量のばらつき0.5%を注入した12ビットADCの全コードにおけるINLとDNLの波形、MSB遷移でDNLが跳ねる様子

単位容量に 0.5 % のばらつきを与えた1個体を実際に測ると、DNL(下)はほとんどのコードで細かく振動しているのに、コード2047→2048 のMSB遷移だけが +0.944 LSB と突出しています。次に大きいのはコード1023と3071(ともに $-0.336$ LSB)、その次が511・1535・2559・3583(いずれも $+0.168$ LSB)と、上位ビットが繰り上がる点ほど大きくなる階層構造になっています。INL(上)が階段状に折れ曲がるのも同じ理由で、上位ビットの容量誤差が、そのビットが立つコード範囲ぜんぶを一斉に持ち上げ/押し下げているからです。この「大きなビットほど誤差の影響範囲が広い」構造を、次に式で定量化します。

定量化しましょう。コード $2^{N-1}$ で接続される容量は $C_1$ のみ、コード $2^{N-1}-1$ で接続される容量は $C_2, \dots, C_N$ です。理想値では

$$ C_1 – \sum_{k=2}^{N}C_k = 2^{N-1}C_u – (2^{N-2} + \cdots + 1)C_u = 2^{N-1}C_u – (2^{N-1}-1)C_u = C_u $$

と、差はちょうど単位容量1個分(=1 LSB)です。ここに誤差 $\delta_k$ を入れると、

$$ \Delta C = C_u + C_u\left[2^{N-1}\delta_1 – \sum_{k=2}^{N}2^{N-k}\delta_k\right] $$

となります。角括弧の中がLSB単位で表したDNLです。各 $\delta_k$ が独立なので分散は二乗の和になり、式 (9) を代入すると

$$ \begin{align} \sigma^2(\text{DNL}_\text{MSB}) &= 2^{2(N-1)}\sigma^2(\delta_1) + \sum_{k=2}^{N}2^{2(N-k)}\sigma^2(\delta_k) \\ &= 2^{2(N-1)}\frac{\sigma_u^2}{2^{N-1}} + \sum_{k=2}^{N}2^{2(N-k)}\frac{\sigma_u^2}{2^{N-k}} \\ &= 2^{N-1}\sigma_u^2 + \sigma_u^2\sum_{k=2}^{N}2^{N-k} \end{align} $$

最後の和は $2^{N-2} + 2^{N-3} + \cdots + 2^0 = 2^{N-1}-1$ なので、

$$ \begin{equation} \sigma(\text{DNL}_\text{MSB}) = \sigma_u\sqrt{2^N – 1} \;\approx\; \sigma_u \, 2^{N/2}\ \ [\text{LSB}] \end{equation} $$

という、覚えやすい形にまとまりました。必要な単位容量のマッチング精度は、分解能ビット数の半分の指数で厳しくなるということです。

数値を入れてみましょう。$N = 12$ なら $2^{6} = 64$ 倍されるので、$\sigma_u = 0.1\ \%$ の単位容量を使っても $\sigma(\text{DNL}_\text{MSB}) = 0.064$ LSB。$3\sigma$ でも 0.19 LSB なので余裕があります。逆に「$3\sigma < 0.5$ LSB」を設計目標にすると、必要なマッチングは

$$ \sigma_u < \frac{0.5}{3 \times 64} = 0.26\ \% $$

と求まります。ところが $N = 16$ にすると $2^8 = 256$ 倍なので、$\sigma_u < 0.065\ \%$ が必要になります。半導体の容量マッチングは Pelgrom の法則により $\sigma_u \propto 1/\sqrt{A}$($A$ は素子面積)でしか改善しないため、マッチングを4倍良くするには面積を16倍にしなければなりません。16ビットSARが12ビットSARよりはるかに大きく高価になる理由が、この一本の式に凝縮されています。実際には14ビットを超えると素のマッチングでは足りず、デジタル的な容量誤差校正やダイナミック・エレメント・マッチング(DEM)が併用されます。

INL(積分非線形性)についても同様の議論ができ、中間コードでの標準偏差は $\sigma(\text{INL}_\text{mid}) = \tfrac{1}{2}\sigma_u 2^{N/2}$ LSB になります。$N=12$、$\sigma_u = 0.1\ \%$ で 0.032 LSB です。

モンテカルロ300回で測ったDNL・INLと理論式の一致、および分解能に対する必要マッチング精度を示した2枚組のグラフ

左は12ビットのアレイを $\sigma_u$ を変えながら300回ずつ生成して測った結果です。黒破線の理論値 $\sigma_u\sqrt{2^N-1}$ に、実測のMSB遷移DNLの標準偏差(赤)がぴたりと重なり、全コードの最大 $|\text{DNL}|$ の平均(オレンジ)もほぼ同じ線に乗ります。式 (10) が「MSB遷移という1点」の話でありながら、そのままADC全体の最悪値を言い当てていることの証拠です。最大 $|\text{INL}|$(青)は一貫して理論線の 0.83 倍で、中間コードの標準偏差 $\tfrac{1}{2}\sigma_u2^{N/2}$(理論線のちょうど半分)の 1.7 倍程度——全コードの最大値をとればこのくらいになる、という自然な関係です。右のグラフは $3\sigma < 0.5$ LSB という設計目標から逆算した必要マッチングで、12ビットの 0.260 % から16ビットの 0.065 % へと4倍厳しくなり、Pelgromの法則によって素子面積は16倍必要になります。

後ほどPythonでも同じモンテカルロ実験を行い、この理論値が実測と合うことを数値で確認します。

容量のばらつきは「どれだけ正確か」を決める静的な誤差でした。次は「どれだけ速くできるか」を決める動的な制約、整定時間を見ていきます。

整定時間と変換速度 — 0.5 LSB ルールの導出

ビットテストのたびに、容量アレイのボトムプレートを $V_\text{ref}$ に切り替えます。スイッチには必ずオン抵抗 $R_\text{on}$ があり、容量アレイの合成容量とで1次のRC回路を作るため、ノード $V_X$ は階段状には動かず指数関数的に整定します。時定数を $\tau = R_\text{on}C_\text{tot}$ とすると、目標値までの残り誤差は

$$ \varepsilon(t) = \Delta V \, e^{-t/\tau} $$

で減衰します。ここで $\Delta V$ はそのステップでのDAC出力の変化量です。ステップ $k$ では $\Delta V = V_\text{ref}2^{-k}$ です。

では、どこまで整定させれば十分でしょうか。ここで重要なのは、整定が不十分だと比較の閾値がずれるという点です。ステップ $k$ でDAC出力が $\varepsilon_k$ だけ足りないと、コンパレータは実質的に $V_\text{res} > V_\text{ref}2^{-k} – \varepsilon_k$ という、ずれた条件で判定してしまいます。閾値のずれはそのまま出力コードの誤差になり(この点は後の節で数値的に確認します)、しかもコードに依存するのでINLとして現れます。したがって「整定誤差を 0.5 LSB 未満に抑える」という設計則になります。

$$ V_\text{ref}2^{-k}e^{-t/\tau} < \frac{1}{2}\cdot\frac{V_\text{ref}}{2^N} = V_\text{ref}2^{-(N+1)} $$

両辺を $V_\text{ref}2^{-k}$ で割ると

$$ e^{-t/\tau} < 2^{-(N+1-k)} $$

自然対数をとって符号に注意して整理すると、ステップ $k$ に必要な時間は

$$ \begin{equation} t_k > (N + 1 – k)\ln 2 \cdot \tau \end{equation} $$

と求まります。MSB側ほど長く待たなければならないことがわかります。$k=1$(MSB)では $N \ln 2 \cdot \tau$、$k=N$(LSB)では $\ln 2 \cdot \tau$ だけで済みます。動く電圧が小さいステップほど早く落ち着く、という直感通りです。

全ビットの合計をとると、変換に要する時間は

$$ \begin{equation} T_\text{conv} = \sum_{k=1}^{N}(N+1-k)\ln 2 \cdot \tau = \ln 2 \cdot \tau \sum_{j=1}^{N} j = \frac{N(N+1)}{2}\ln 2 \cdot \tau \end{equation} $$

です(途中で $j = N+1-k$ と置き換え、$1$ から $N$ までの和 $N(N+1)/2$ を使いました)。

ステップごとに必要な整定時間の棒グラフと、各ステップの残り誤差が0.5LSBに達するまでの指数減衰曲線

左の棒グラフが式 (11) の中身で、MSB($k=1$)に $8.32\tau$ 必要なのに対し、LSB($k=12$)は $0.69\tau$ で済み、合計は $54.1\tau$ です。右の対数プロットで理由が見えます。$k=1$ のステップはDAC出力が $2048$ LSB も動くので、0.5 LSBまで落ちるには $\ln(4096) = 8.32$ 倍の時定数がいる。一方 $k=12$ は最初から 1 LSB しか動かないので、半分に減るだけの $\ln 2 = 0.69\tau$ で足ります。3本の直線が同じ傾きで平行に並んでいるのは、必要時間の差が出発点の高さの差だけで決まっていることを示しています。実際のADCではクロック周期を全ビットで共通にすることが多く、その場合は最悪ケースの MSB に合わせるので

$$ T_\text{conv}^\text{uniform} = N \cdot (N+1)\ln 2 \cdot \tau $$

となり、ちょうど2倍の時間がかかります。式の形から読み取るべき教訓は3つあります。

第一に、変換時間は $N$ の2乗で伸びます。 8ビットなら $\ln 2 \cdot 8\cdot9/2 = 25.0\,\tau$ で済むところ、12ビットでは $54.1\,\tau$、14ビットでは $72.8\,\tau$ です。ビット数を増やすと「回数が増える」だけでなく「1回あたりの待ち時間も増える」ため、二重に効いてきます。

第二に、$\tau$ 自体が分解能とともに増えます。 前節で見たように、マッチングの要求から単位容量 $C_u$ には下限があり、$C_\text{tot} = 2^N C_u$ は指数的に大きくなります。$\tau = R_\text{on}C_\text{tot}$ なので、スイッチを大きくして $R_\text{on}$ を下げなければ $\tau$ も指数的に伸びます。しかしスイッチを大きくすると寄生容量とスイッチング電力が増える。この綱引きが、高分解能SARの速度を頭打ちにします。

第三に、$T_\text{conv}$ に加えてサンプリング時間 $T_\text{sample}$ が必要です。 フェーズ1で入力を $C_\text{tot}$ に充電するには、信号源のインピーダンス $R_s$ とスイッチ抵抗の合計で決まる時定数 $\tau_s = (R_s + R_\text{on})C_\text{tot}$ が効きます。マイコンのADCで「ソースインピーダンスは 10 kΩ 以下にせよ」「サンプリング時間を長く設定せよ」と書かれているのは、これが理由です。センサの出力にそのまま高抵抗の分圧回路をつなぐと誤差が出るという現場のトラブルは、ほぼこの整定不足で説明できます。

具体的な数値で見ましょう。$\tau = 1$ ns、$N = 12$ とすると変換部分は $54.1$ ns、サンプリングに同程度の時間を取ると1変換あたり約 110 ns、すなわち約 9 Msps になります。これは市販の12ビットSAR ADCの典型的な性能とよく一致します。

なお、この厳しい整定条件を緩める工夫として冗長性(redundancy) があります。ビット重みを 2 ではなく 1.8 程度のサブラジックス2にすると、各ステップの判定が多少間違っても後段のステップで回復できる余地が生まれます。すると初期ビットの整定を意図的に不完全なまま先へ進めることができ、変換速度を数割向上できます。高速SARの論文でよく出てくる手法です。

整定は「時間をかければ解決する」誤差でした。一方、コンパレータには時間では解決しない誤差があります。ただし面白いことに、その一部はSARの構造上ほとんど無害です。

コンパレータのオフセットとノイズ

コンパレータは「$V_X$ と 0 の大小を判定する」と説明してきましたが、現実のコンパレータには入力オフセット電圧 $V_\text{os}$ があります。判定条件は実際には

$$ V_X + V_\text{os} < 0 $$

になってしまいます。これがADCの精度にどう効くかを考えましょう。

ここで、SAR ADCの構造上のきわめて重要な性質が効いてきます。SARはコンパレータを1個しか使わず、$N$ 回の判定すべてを同じコンパレータで行うのです。したがって $V_\text{os}$ はすべてのステップに同じ量だけ乗ります。式 (8) と合わせると、判定条件は

$$ -V_{\text{res},k-1} + V_\text{ref}2^{-k} + V_\text{os} < 0 \quad \Longleftrightarrow \quad V_{\text{res},k-1} > V_\text{ref}2^{-k} + V_\text{os} $$

となり、すべての閾値が一律に $V_\text{os}$ だけずれることがわかります。閾値が一律にずれるということは、伝達特性のグラフが横に平行移動するだけで、階段の幅(DNL)も直線からの曲がり(INL)もまったく変化しません。つまり

静的なコンパレータオフセットは、SAR ADCではオフセット誤差のみを生み、線形性を劣化させない。

という結論になります。これは実務上とてもありがたい性質です。オフセット誤差はデジタル領域で定数を引くだけで補正でき、そもそも多くのアプリケーションでは無視できます。だからこそSARのコンパレータは、オフセットを気にせず速度と低消費電力に全振りしたダイナミックラッチ型(静的電流をまったく消費しない構成)を使えるのです。

対照的に、フラッシュ型ADCは $2^N – 1$ 個のコンパレータを並べ、それぞれが別々の閾値を担当します。各コンパレータのオフセットは互いに独立なので、閾値の間隔がランダムにばらつきます。これは直接DNL/INLになり、しかもオフセットが1 LSBを超えるとコンパレータの順序が入れ替わって「バブル」と呼ばれる異常出力を起こします。フラッシュ型が8ビット程度で頭打ちになる主要因はここにあります。同じ「オフセット」でも、アーキテクチャによって致命傷にも無害にもなる、という好例です。

ノイズは自己制限的、整定不足は非可逆

一方、コンパレータのランダムノイズは毎回の判定で値が変わるため、平行移動では説明できません。ただし、こちらもSARでは思ったほど悪さをしません。理由を考えてみましょう。

ステップ $k$ で誤判定が起きるのは、コンパレータ入力 $T_k = V_{\text{res},k-1} – V_\text{ref}2^{-k}$ の絶対値がノイズ振幅より小さいとき、すなわち残差がちょうど閾値の近くにいるときに限られます。いま真の値が $T_k = -\epsilon$($\epsilon$ は小さい正の数、正しくは $b_k=0$)なのに、ノイズで $b_k=1$ と誤判定したとしましょう。すると残差は $V_{\text{res},k} = -\epsilon$ と負になり、以降のステップでは常に $T_j < 0$ となって $b_{j} = 0$ が並びます。最終的な残差は $-\epsilon$ のままです。

一方、正しく $b_k = 0$ としていたら残差は $V_\text{ref}2^{-k} – \epsilon$ で、これは閾値のわずかに下ですから、以降のビットはすべて1が並びます。つまり正解のコードは $\cdots 0111\cdots1$、誤答は $\cdots 1000\cdots 0$ で、この2つは隣接するコードです。誤差はたかだか1 LSB程度にしかなりません。

ノイズによる誤りは、閾値近傍でしか起きないがゆえに、結果の誤差も小さい。 この自己制限性がSARの頑健さの源です。だからコンパレータのノイズは、量子化雑音と同程度($\sigma_c \lesssim 0.3\,V_\text{LSB}$ 程度)に抑えれば十分で、それ以上ノイズを削っても総合SNRはあまり改善しません。低ノイズ=大電力なので、この見極めは電力設計上とても重要です。

これに対し、整定不足は自己制限的ではありません。整定誤差 $\varepsilon_k$ は決定論的な閾値シフトなので、残差が閾値から $\varepsilon_k$ 以内にある入力すべてで同じ向きの誤りを引き起こし、その誤差は約 $\varepsilon_k$ の大きさで最終コードに残ります。ランダムに平均されて消えることもありません。ゆえに $\varepsilon_k < 0.5\,V_\text{LSB}$ という厳しい設計則が課されるわけです。「時間で買える誤差は必ず買っておけ」というのがSAR設計の鉄則になっています。

もうひとつ触れておくべきはメタスタビリティです。$|T_k|$ が極端に小さいと、ラッチが確定状態に落ちるまでの再生時間が対数的に伸び、決められたクロック周期内に答えが出ないことがあります。確率は低いものの、$10^6$ 回/秒で変換していれば無視できない頻度になります。実装ではメタスタビリティ検出+既定値への強制、あるいは前述の冗長性による回復が使われます。

コンパレータの誤差の効き方が整理できたところで、SARの分解能を最終的に縛る物理限界にも触れておきましょう。

$kT/C$ ノイズが決めるスケーリング限界

容量アレイでサンプリングする以上、スイッチの熱雑音がサンプル瞬間に容量へ「凍結」されます。その実効値は有名な $kT/C$ ノイズで、

$$ \overline{v_n^2} = \frac{k_B T}{C_\text{tot}} $$

です($k_B$ はボルツマン定数、$T$ は絶対温度)。これが量子化雑音 $V_\text{LSB}^2/12$ を下回っていないと、ビットを増やしても意味がありません。条件は

$$ \frac{k_B T}{C_\text{tot}} < \frac{1}{12}\left(\frac{V_\text{ref}}{2^N}\right)^2 \quad \Longrightarrow \quad C_\text{tot} > \frac{12 k_B T\, 2^{2N}}{V_\text{ref}^2} $$

$C_\text{tot}$ は $4^N$ で増える、つまり1ビット増やすごとに容量を4倍にしなければなりません。$T = 300$ K、$V_\text{ref} = 1$ V で計算すると、10ビットで 0.052 pF、12ビットで 0.83 pF、14ビットで 13.3 pF、16ビットで 213 pF です。16ビットになると容量アレイだけで200 pFを超え、充放電に必要な電力($\propto C V^2 f$)も整定時間($\propto \tau = R_\text{on}C_\text{tot}$)も跳ね上がります。

マッチング制約と熱雑音制約による必要総容量を分解能に対して対数プロットし、12ビット付近で主役が交代する様子を示したグラフ

2つの制約を同じ軸に載せると、傾きの違いが一目瞭然です。マッチング由来の $2^N C_u$(紫、単位容量0.2 fFの場合)は緩やかな直線ですが、熱雑音由来の $12k_BT\,4^N/V_\text{ref}^2$(赤)はその2倍の傾きで駆け上がり、12ビット付近で紫を追い抜きます。実際に必要な容量は両者の大きい方(灰色の太線)なので、11ビットまでは紫、13ビット以降は赤が設計を支配します。16ビットで 213 pF という値が、そのまま消費電力と変換時間の跳ね上がりに直結します。

ここでマッチングの制約($C_\text{tot} \propto 2^N$)と熱雑音の制約($C_\text{tot} \propto 4^N$)を比べると、低分解能ではマッチングが、高分解能では熱雑音が容量を決めるという交代が起きることがわかります。おおよそ12ビット前後がその境目です。SAR ADCの消費電力が12ビットあたりを境に急に増え始めるのは、この物理が背景にあります。

こうした制約を踏まえると、SARが他方式と比べてどの領域を得意とするのかが見えてきます。次に方式間の住み分けを整理しましょう。

他方式との比較 — 速度・分解能マップ

主要なADCアーキテクチャを、1変換に要するクロック数と得意領域で並べてみます。

方式 1変換のクロック数 典型分解能 典型速度 特徴
フラッシュ 1 4〜8 ビット 1〜50 Gsps $2^N-1$ 個のコンパレータ。最速だが面積・電力が指数的
パイプライン 1(レイテンシ $N$/段) 10〜16 ビット 50 Msps〜1 Gsps 段間にアンプが必要で電力大。高速高分解能の主役
逐次比較(SAR) $N$ 8〜18 ビット 10 ksps〜100 Msps コンパレータ1個。電力効率が最良。中速中分解能の王者
デルタシグマ OSR × 数十 16〜24 ビット 数 sps〜数 Msps オーバーサンプリングとノイズシェーピング。低速超高分解能
二重積分(デュアルスロープ) $2 \times 2^N$ 16〜22 ビット 数〜数十 sps 部品変動に強い。デジタルマルチメータの定番

フラッシュ型・パイプライン型・SAR・デルタシグマ型・二重積分型の得意領域を分解能とサンプリング周波数の平面に矩形で示したマップ

マップにすると、SARの青い領域が縦(速度で4桁)にも横(分解能で10ビット)にも最も広く、他の4方式すべてと一部で重なっていることがわかります。重なった領域では「同じ性能を最も低い電力で実現できるのはどれか」が勝負になり、そこでSARが選ばれ続けています。もうひとつ重要なのは右上(高分解能かつ高速)が空白であることで、これは前節までに見た $C_\text{tot} \propto 4^N$(熱雑音)と $T_\text{conv} \propto N^2\tau$(整定)が同時に効く物理的な壁です。

この表を貫いている原則は明快です。1変換あたりに使える「比較の回数」と、それを実行するハードウェアの物量とのトレードオフ。フラッシュは物量を極大化して比較を1回で終わらせ、デルタシグマは時間を極大化して1ビットのコンパレータで24ビットを達成します。SARはその中間に位置し、$N$ 回という「ちょうどよい」回数で、$N$ ビットの情報を回収します。情報理論的にいえば、SARは比較1回あたり1ビットという上限を達成している唯一の方式であり、これが電力効率(Walden FoM で数 fJ/conversion-step)で他を圧倒する根本理由です。

ちなみに、デルタシグマ型の原理についてはデルタシグマ変調とオーバーサンプリング、デジタルマルチメータで使われる二重積分型についてはデジタルマルチメータと二重積分型ADCで詳しく扱っています。

理論の全体像が揃ったので、いよいよPythonで動かして確かめていきます。

Pythonでの実装

3つの実験を行います。(1) SARアルゴリズムをそのまま実装して段階近似の波形を描く、(2) コンパレータオフセットと容量ミスマッチを注入して INL/DNL を測る、(3) 各方式を速度分解能マップ上に配置する、の3本立てです。

実験1:段階近似の可視化

まずは式 (4) の漸化式をそのままコードにして、DAC出力が入力に段階的に近づく様子と、残差が半分ずつ縮む様子を描きます。

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

# 日本語フォント設定
for cand in ["Hiragino Sans", "Yu Gothic", "Noto Sans CJK JP", "IPAexGothic", "Meiryo"]:
    if any(cand == f.name for f in matplotlib.font_manager.fontManager.ttflist):
        plt.rcParams["font.family"] = cand
        break
plt.rcParams["axes.unicode_minus"] = False

def sar_convert(v_in, v_ref, N):
    """逐次比較の1変換。各ステップのDAC出力と残差の履歴を返す"""
    res = v_in          # 残差 V_res,0 = V_in
    acc = 0.0           # 確定済みの重みの和 Σ b_j 2^-j
    bits, dac_hist, res_hist, trial_hist = [], [], [], []
    for k in range(1, N + 1):
        w = 2.0 ** (-k)                    # k番目の分銅の重み
        trial_hist.append((acc + w) * v_ref)  # 試しに載せたときのDAC出力
        b = 1 if res - w * v_ref >= 0 else 0  # コンパレータの判定(式3)
        if b:
            res -= w * v_ref                  # 残差更新(式4)
            acc += w
        bits.append(b)
        dac_hist.append(acc * v_ref)
        res_hist.append(res)
    code = sum(b << (N - k) for k, b in enumerate(bits, start=1))
    return code, np.array(bits), np.array(dac_hist), np.array(res_hist), np.array(trial_hist)

V_REF, N = 3.3, 12
V_IN = 2.0
code, bits, dac, res, trial = sar_convert(V_IN, V_REF, N)
lsb = V_REF / 2 ** N
print(f"入力 {V_IN:.4f} V -> コード {code} ({''.join(map(str, bits))})")
print(f"DAC出力 {code / 2**N * V_REF:.6f} V, 誤差 {(V_IN - code / 2**N * V_REF) / lsb:.3f} LSB")

実行すると 入力 2.0000 V -> コード 2482 (100110110010)DAC出力 1.999658 V, 誤差 0.424 LSB と表示されます。手計算で追った表と完全に一致しており、式 (5) が保証する「誤差は $[0,1)$ LSB」も満たされています。ビット列の先頭が 1 なのは $V_\text{in} > V_\text{ref}/2 = 1.65$ V だからで、続く 00 は $V_\text{in} < 1.65 + 0.825$ かつ $< 1.65 + 0.4125$ であることを意味します。

続いて、この履歴を階段グラフにします。描かれるのは、先に「具体例」の節で示した2枚の図(DAC出力の階段と残差の対数プロット)を1枚にまとめたものです。

fig, axes = plt.subplots(1, 2, figsize=(13, 4.6))

ax = axes[0]
ks = np.arange(1, N + 1)
ax.step(np.r_[0, ks], np.r_[0, dac], where="post", lw=2, color="tab:blue",
        label="DAC出力(確定値)")
ax.scatter(ks, trial, marker="v", color="tab:orange", zorder=5, s=45,
           label="試した電圧(比較の相手)")
ax.axhline(V_IN, color="black", ls="--", lw=1.5, label=f"入力電圧 {V_IN} V")
ax.set_xlabel("比較ステップ $k$"); ax.set_ylabel("電圧 [V]")
ax.set_title("DAC出力が入力に段階的に近づく(12ビット)")
ax.legend(fontsize=9); ax.grid(alpha=0.3)

ax = axes[1]
ax.semilogy(ks, np.abs(res) / lsb, "o-", lw=2, color="tab:red", label="残差 $|V_{res,k}|$")
ax.semilogy(ks, V_REF * 2.0 ** (-ks) / lsb, "s--", lw=1.5, color="gray",
            label="理論上限 $V_{ref}2^{-k}$")
ax.axhline(1.0, color="tab:green", ls=":", lw=2, label="1 LSB")
ax.set_xlabel("比較ステップ $k$"); ax.set_ylabel("残差 [LSB](対数軸)")
ax.set_title("残差は毎ステップ半分以下に縮む")
ax.legend(fontsize=9); ax.grid(alpha=0.3, which="both")
plt.tight_layout(); plt.show()

左のグラフでは、DAC出力(青の階段)が最初の1歩で 1.65 V まで一気に跳び、その後は歩幅を半分ずつ縮めながら入力の 2.0 V(黒破線)に漸近していきます。オレンジの三角は各ステップで「試した」電圧で、これが黒破線より上にあれば分銅を降ろす(青の階段は動かない)、下にあれば残す、という対応が読み取れます。右のグラフは残差の対数プロットで、灰色の理論上限 $V_\text{ref}2^{-k}$ が一定の傾きの直線(対数軸なので指数減衰が直線になる)を描き、赤い実測の残差が常にその下側に張りついています。命題で証明した不変条件 $0 \le V_{\text{res},k} < V_\text{ref}2^{-k}$ が数値的にも確認できました。最終ステップで残差が1 LSBの線(緑)を下回っていることが、12ビットの分解能に到達した証拠です。

実験2:オフセットとミスマッチが INL/DNL に与える影響

次に、容量アレイのミスマッチとコンパレータオフセットを注入して、伝達特性の全コードを測定します。前節の理論予測($\sigma(\text{DNL}_\text{MSB}) = \sigma_u\sqrt{2^N-1}$、静的オフセットは線形性に無害)が正しいかを検証します。

import numpy as np

N = 12
def build_array(sigma_u, seed):
    """単位容量のばらつきから重み付き容量アレイを作る"""
    rng = np.random.default_rng(seed)
    w = np.array([2.0 ** (N - k) for k in range(1, N + 1)])   # 理想の単位容量数
    # 2^(N-k) 個の単位容量の和なので、相対誤差の標準偏差は σ_u/√(2^(N-k))(式9)
    Cw = w * (1 + rng.normal(0, sigma_u / np.sqrt(w)))
    Cd = 1.0 * (1 + rng.normal(0, sigma_u))                   # ダミー容量
    return Cw, Cd

def transfer_curve(Cw, Cd, v_os_lsb=0.0):
    """全コードのDAC出力を求め、端点直線基準の INL / DNL を返す"""
    Ctot = Cw.sum() + Cd
    codes = np.arange(2 ** N)
    bmat = (codes[:, None] >> np.arange(N - 1, -1, -1)[None, :]) & 1  # 各コードのビット
    V = bmat @ Cw / Ctot                       # 正規化DAC出力(0〜1)
    Vn = (V - V[0]) / ((V[-1] - V[0]) / (2 ** N - 1))   # 端点直線でLSB単位に正規化
    inl = Vn - codes + v_os_lsb * 0            # 静的オフセットは線形性に無関係
    return inl, np.diff(Vn) - 1

for sigma_u in [0.001, 0.005, 0.01]:
    Imax, Dmax = [], []
    for s in range(300):
        inl, dnl = transfer_curve(*build_array(sigma_u, s))
        Imax.append(np.abs(inl).max()); Dmax.append(np.abs(dnl).max())
    theo = sigma_u * np.sqrt(2 ** N - 1)
    print(f"σ_u={sigma_u*100:4.1f}% : max|INL|={np.mean(Imax):.3f} LSB, "
          f"max|DNL|={np.mean(Dmax):.3f} LSB, 理論σ(DNL_MSB)={theo:.3f} LSB")

出力は次のようになります。

σ_u= 0.1% : max|INL|=0.053 LSB, max|DNL|=0.066 LSB, 理論σ(DNL_MSB)=0.064 LSB
σ_u= 0.5% : max|INL|=0.265 LSB, max|DNL|=0.332 LSB, 理論σ(DNL_MSB)=0.320 LSB
σ_u= 1.0% : max|INL|=0.530 LSB, max|DNL|=0.663 LSB, 理論σ(DNL_MSB)=0.640 LSB

理論式 (10) の予測値と、モンテカルロで測った最大DNLの平均がほぼ一致しています。式 (10) は MSB遷移という1点のDNLの標準偏差でしたが、実際に全コードの最大DNLもその値に近い——つまりMSB遷移が確かに最悪点になっていることが数値的に裏付けられました。また、$\sigma_u$ を10倍にすると INL/DNL も10倍になる線形関係も見て取れます。$\sigma_u = 1\ \%$ では最大DNLの平均が0.66 LSBに達し、シミュレーション300回のうち約8 %の試行でミッシングコード(DNL $= -1$)が発生しました。12ビットのSARを設計するなら単位容量のマッチングは 0.1 % オーダーが必要、という結論はここからも支持されます。

続いて、コンパレータのオフセットと整定不足を実際のSAR動作に注入して比較します。

import numpy as np

N, V_REF = 12, 1.0
LSB = V_REF / 2 ** N

def sar_real(v_in, v_os=0.0, n_tau=None):
    """v_os: コンパレータオフセット [V], n_tau: 各ステップの整定時間(τの倍数)"""
    res, acc = v_in, 0.0
    for k in range(1, N + 1):
        step = V_REF * 2.0 ** (-k)
        settled = step if n_tau is None else step * (1 - np.exp(-n_tau))  # 整定不足
        if res - settled + v_os >= 0:     # コンパレータの判定(オフセット込み)
            res -= step; acc += 2.0 ** (-k)
    return acc * V_REF

codes = np.arange(2 ** N)
v_test = (codes + 0.5) * LSB                       # 各コード中心を入力
ideal = np.array([sar_real(v) for v in v_test])
for label, kw in [("オフセット +3LSB", dict(v_os=3 * LSB)),
                  ("整定 12τ", dict(n_tau=12)),
                  ("整定 8τ", dict(n_tau=8)),
                  ("整定 6τ", dict(n_tau=6))]:
    out = np.array([sar_real(v, **kw) for v in v_test])
    err = (out - ideal) / LSB
    print(f"{label:14s}: 誤差 平均={err.mean():+.2f} LSB, 標準偏差={err.std():.2f} LSB, "
          f"最大|誤差|={np.abs(err).max():.1f} LSB, 誤差が出たコード数={np.count_nonzero(err)}")

結果はこうなります。

オフセット +3LSB  : 誤差 平均=+3.00 LSB, 標準偏差=0.06 LSB, 最大|誤差|=3.0 LSB, 誤差が出たコード数=4095
整定 12τ        : 誤差 平均=+0.00 LSB, 標準偏差=0.00 LSB, 最大|誤差|=0.0 LSB, 誤差が出たコード数=0
整定 8τ         : 誤差 平均=+0.00 LSB, 標準偏差=0.02 LSB, 最大|誤差|=1.0 LSB, 誤差が出たコード数=1
整定 6τ         : 誤差 平均=+0.01 LSB, 標準偏差=0.15 LSB, 最大|誤差|=5.0 LSB, 誤差が出たコード数=23

オフセット+3LSBでは全コードが一律にずれ、整定不足6τではメジャー遷移近傍だけがスパイク状に外れることを比較したグラフ

同じ数値をコードごとの誤差としてプロットすると、性質の違いが形として現れます。左のオフセットは4096コードのほぼ全域で高さ +3 LSB の平坦な直線(フルスケール端でだけ折れる)で、これは伝達特性の平行移動そのものです。右の整定不足は逆に、ほとんどのコードで誤差ゼロなのに、コード255・511・767・1023・…・2047・3071 というメジャー遷移の位置だけに細いスパイクが立ちます。$6\tau$(赤)ではコード2047のスパイクが 5 LSB に達し、$8\tau$(オレンジ)ではそこが 1 LSB に縮んで他はすべて消えます。

2つの誤差の性質の違いが、統計の形にはっきり現れています。オフセットの行では、4096コードのうち4093コードが「きっちり +3 LSB」ずれています(誤差の内訳を数えると、$+3$ LSB が4093個、$+2, +1, 0$ LSB が各1個。標準偏差がわずか0.06 LSBしかないのは、ほぼ全コードが同じ量だけ動いた証拠です。例外の3個はフルスケール端でコードが飽和しているだけ)。伝達特性がそっくり平行移動しただけで、階段の幅は一切変わっていません。前節で議論した「静的オフセットはオフセット誤差のみを生む」が、そのまま数値になった形です。

一方、整定不足の行はまったく違う顔をしています。$6\tau$ では平均が $+0.01$ LSB とほぼゼロなのに、最大誤差は5 LSBに達します。誤差が出たコードはわずか23個で、その内訳を調べると 255, 511, 767, 1021〜1023, 2043 …と、いずれも上位ビットが繰り上がる「メジャー遷移」の近傍に集中していました。理論式 (11) によれば $N=12$、$k=1$ のMSBステップに必要な整定は $12 \ln 2 = 8.32\,\tau$ ですから、$6\tau$ では足りません。実際、MSBステップの整定誤差は $V_\text{ref}2^{-1}e^{-6} = 1.24\times10^{-3}V_\text{ref} = 5.08$ LSB で、シミュレーションの最大誤差5 LSBとぴったり一致します。$8\tau$(理論値 8.32τ をわずかに下回る)では誤差が出るコードがコード2047ただ1つ・1 LSBだけ、$12\tau$ では誤差ゼロ——理論の閾値をまたいだ瞬間に誤差が立ち上がる様子が見事に再現されました。INLのグラフがメジャー遷移でスパイク状に跳ねるという、SAR ADCの実測データでおなじみの波形が、この整定不足から生まれているわけです。

実験3:方式別の速度・分解能マップ

最後に、各アーキテクチャがどの領域を担当しているかをマップにします。前節で示したマップを描くコードです。

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# (方式名, ビット下限, ビット上限, サンプリング速度下限[Hz], 上限[Hz], 色)
archs = [
    ("フラッシュ型",      4,  8,  1e8, 5e10, "tab:red"),
    ("パイプライン型",   10, 16,  5e7, 1e9,  "tab:orange"),
    ("逐次比較型(SAR)",   8, 18,  1e4, 1e8,  "tab:blue"),
    ("デルタシグマ型",   16, 24,  1e0, 5e6,  "tab:green"),
    ("二重積分型",       16, 22,  1e0, 1e2,  "tab:purple"),
]
fig, ax = plt.subplots(figsize=(9.5, 6))
for name, b0, b1, f0, f1, c in archs:
    ax.add_patch(Rectangle((b0, f0), b1 - b0, f1 - f0, alpha=0.28,
                           facecolor=c, edgecolor=c, lw=2))
    ax.text((b0 + b1) / 2, (f0 * f1) ** 0.5, name, ha="center", va="center",
            fontsize=11, color=c, fontweight="bold")
ax.set_yscale("log"); ax.set_xlim(3, 25); ax.set_ylim(1e0, 1e11)
ax.set_xlabel("分解能 [ビット]"); ax.set_ylabel("サンプリング周波数 [Hz](対数軸)")
ax.set_title("ADCアーキテクチャの得意領域マップ")
ax.grid(alpha=0.3, which="both")
plt.tight_layout(); plt.show()

マップを見ると、SARの領域(青)が縦にも横にも最も広いことがわかります。8ビットから18ビット、10 kspsから100 Mspsまでをカバーし、フラッシュ型・パイプライン型・デルタシグマ型のすべてと一部で重なっています。重なった領域では「同じ性能を最も低い電力で実現できるのはどれか」が勝負になり、そこでSARが選ばれ続けているわけです。また、右上(高分解能かつ高速)が空白になっているのも重要な読み取りです。$C_\text{tot} \propto 4^N$ という $kT/C$ の制約と $T_\text{conv} \propto N^2 \tau$ という整定の制約が同時に効くため、この領域には物理的に手が届きにくい。ADCの性能限界(Walden/Schreier の FoM が示す壁)が、こうしたアーキテクチャ論から自然に立ち上がってくるのです。

まとめ

本記事では、逐次比較型(SAR)ADCの動作原理と設計トレードオフを解説しました。

  • 二分探索そのもの:残差の更新式 $V_{\text{res},k} = V_{\text{res},k-1} – b_k V_\text{ref}2^{-k}$ を回すだけで、不変条件 $0 \le V_{\text{res},k} < V_\text{ref}2^{-k}$ が保たれ、$N$ ステップで分解能 $V_\text{ref}/2^N$ に到達する
  • 電荷再分配型の美しさ:サンプル・ホールド・ビットテストの3フェーズで電荷保存則を適用すると、コンパレータ入力に $V_X = -V_\text{res}$ がそのまま現れる。S/Hと減算器とDACをコンデンサだけで兼ねている
  • マッチングが線形性を決める:MSB遷移のDNLの標準偏差は $\sigma_u\sqrt{2^N-1}$。12ビットなら $\sigma_u \lesssim 0.26\ \%$、16ビットなら $\sigma_u \lesssim 0.065\ \%$ が必要で、面積は $1/\sigma_u^2$ で増える
  • 整定が速度を決める:ステップ $k$ の整定を0.5 LSB以内にする条件は $t_k > (N+1-k)\ln 2 \cdot \tau$、合計で $T_\text{conv} = \tfrac{N(N+1)}{2}\ln 2 \cdot \tau$。変換時間は $N^2$ で伸びる
  • 誤差の効き方は一様ではない:静的なコンパレータオフセットは全閾値を一律にずらすだけなのでオフセット誤差しか生まない。コンパレータノイズは閾値近傍でしか誤らないので自己制限的。一方、整定不足は決定論的な閾値シフトなので INL として残る

SARの原理を押さえると、その先のトピックが自然につながります。分解能をさらに上げたいなら、オーバーサンプリングとノイズシェーピングを使うデルタシグマ型へ。速度を上げたいなら、SARを複数並べる時間インターリーブや、段間増幅を挟むパイプライン型へ。いずれも「1回の比較で1ビット」という制約をどう回避するかの工夫だと捉えると、見通しがよくなります。

次のステップとして、以下の記事も参考にしてください。