AD/DA変換器の理論と方式 — アナログとディジタルの橋渡しを理解する

私たちが暮らす物理世界は、温度・音・光といった連続的なアナログ量で満ちています。一方、コンピュータやスマートフォンの内部では、すべてが 0 と 1 のディジタル信号として処理されます。では、マイクに届いた音声はどうやってディジタルデータに変わり、スピーカーから再びアナログの音波として出てくるのでしょうか?

この「アナログ世界とディジタル世界の翻訳」を担うのが AD変換器(ADC: Analog-to-Digital Converter)DA変換器(DAC: Digital-to-Analog Converter) です。ADC はセンサが取得したアナログ電圧をディジタル値に変換し、DAC はコンピュータが計算した結果を再びアナログ電圧に復元します。

AD/DA変換の理論を理解すると、以下のような幅広い分野で設計の勘所が見えてきます。

  • オーディオ工学: CD の 16 bit / 44.1 kHz やハイレゾ 24 bit / 192 kHz の意味が数値的にわかる
  • 通信工学: ソフトウェア無線(SDR)でアナログ受信信号をディジタル処理するための入口が ADC
  • 計測・制御: IoT センサノードでの高精度計測、モータ制御の PWM 出力と DAC の関係

本記事の内容

  • 量子化の基礎理論(量子化ステップ・量子化誤差・SQNR)
  • DAC の代表的方式(重み抵抗型・R-2R ラダー型)
  • ADC の3つの主要方式(フラッシュ型・逐次比較型・ΔΣ型)
  • ΔΣ変調のノイズシェーピング原理
  • サンプル&ホールド回路の役割
  • 性能指標(分解能・SNR・SFDR・ENOB)
  • Python による量子化誤差の可視化と ΔΣ変調シミュレーション

前提知識

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

AD/DA変換とは — アナログとディジタルの翻訳者

まずは全体像をつかみましょう。外国語の通訳を想像してください。日本語(アナログ)をいったん英語(ディジタル)に翻訳し、コンピュータで処理したあと、再び日本語に戻す — この流れが AD/DA変換のイメージです。

ADC は「アナログ → ディジタル」方向の変換器で、連続的なアナログ電圧を離散的なディジタル値(ビット列)に変換します。DAC はその逆で、「ディジタル → アナログ」方向の変換器です。

典型的な信号処理システムの流れは次のとおりです。

$$ \text{センサ(アナログ)} \xrightarrow{\text{ADC}} \text{DSP(ディジタル処理)} \xrightarrow{\text{DAC}} \text{アクチュエータ(アナログ)} $$

この変換の過程では、どうしても「丸め誤差」が発生します。連続値を有限個の離散値で近似するわけですから、完全に情報を保存することはできません。この丸め誤差が「量子化誤差」であり、AD/DA変換の設計において最も本質的な課題です。

では、量子化誤差とは具体的にどの程度の大きさで、どうすれば小さくできるのでしょうか? 次のセクションで数学的に定量化していきます。

量子化の基礎 — 連続値を離散値に丸める

量子化ステップと分解能

量子化とは、連続的なアナログ値を有限個の離散レベルに割り当てる操作です。イメージとしては、無段階に調節できる音量ノブを、カチカチと段階的にしか動かないロータリースイッチに置き換えるようなものです。段階が細かいほど(ビット数が多いほど)元の連続値に近い表現ができます。

$N$ ビットの ADC のフルスケール電圧範囲を $V_\text{FS}$ とすると、量子化レベルの数は $2^N$ 個になります。各レベル間の電圧差が 量子化ステップ(LSB: Least Significant Bit) で、次の式で定義されます。

$$ \Delta = \frac{V_\text{FS}}{2^N} $$

ここで $\Delta$ は量子化ステップ幅、$V_\text{FS}$ はフルスケール電圧、$N$ は分解能(ビット数)です。

例えば、フルスケール $V_\text{FS} = 3.3\,\text{V}$ の 12 ビット ADC では、量子化ステップは次のようになります。

$$ \Delta = \frac{3.3}{2^{12}} = \frac{3.3}{4096} \approx 0.806\,\text{mV} $$

つまり、約 0.8 mV より細かい電圧変化は区別できないということです。この分解能はビット数 $N$ を増やすほど指数関数的に改善されます。

量子化誤差

量子化によって、アナログ入力値 $x(t)$ とディジタル出力値 $x_q(t)$ の間には必ず差が生じます。この差を 量子化誤差(quantization error) と呼びます。

$$ e_q(t) = x_q(t) – x(t) $$

一様量子化(均等ステップ幅の量子化)の場合、量子化誤差は $-\Delta/2$ から $+\Delta/2$ の範囲に収まります。入力信号が量子化ステップ幅に比べて十分に複雑(多くのレベルをまたぐ)であるとき、量子化誤差は区間 $[-\Delta/2,\, +\Delta/2]$ 上の 一様分布 で近似できます。これは量子化理論の重要な仮定です。

この一様分布の仮定のもとで、量子化誤差の平均値と分散を計算しましょう。確率密度関数は次のとおりです。

$$ f(e) = \frac{1}{\Delta}, \quad -\frac{\Delta}{2} \le e \le \frac{\Delta}{2} $$

平均値はゼロです(分布が原点対称のため)。

$$ E[e_q] = \int_{-\Delta/2}^{\Delta/2} e \cdot \frac{1}{\Delta}\, de = 0 $$

分散(= 量子化雑音電力)を求めるために、$e^2$ の期待値を計算します。

$$ \sigma_q^2 = E[e_q^2] = \int_{-\Delta/2}^{\Delta/2} e^2 \cdot \frac{1}{\Delta}\, de $$

被積分関数を展開して積分すると、

$$ \sigma_q^2 = \frac{1}{\Delta} \left[\frac{e^3}{3}\right]_{-\Delta/2}^{\Delta/2} = \frac{1}{\Delta} \cdot \frac{2}{3}\cdot\frac{\Delta^3}{8} = \frac{\Delta^2}{12} $$

つまり、量子化雑音電力は量子化ステップの二乗に比例し、その係数は $1/12$ です。

$$ \boxed{\sigma_q^2 = \frac{\Delta^2}{12}} $$

この結果は AD 変換の理論全体を支える基本公式です。ステップ幅 $\Delta$ を半分にすれば、量子化雑音電力は $1/4$ に減ります。

SQNR(信号対量子化雑音比)

量子化誤差の大きさを信号と比較する指標が SQNR(Signal-to-Quantization Noise Ratio) です。フルスケールの正弦波を入力したときの SQNR を導出してみましょう。

振幅 $A$ の正弦波の平均電力は次のとおりです。

$$ P_\text{signal} = \frac{A^2}{2} $$

フルスケール正弦波の場合、振幅はフルスケール電圧範囲の半分ですから $A = V_\text{FS}/2$ です。ここで $V_\text{FS} = 2^N \Delta$ を代入すると、

$$ P_\text{signal} = \frac{(2^N \Delta / 2)^2}{2} = \frac{2^{2N} \Delta^2}{8} $$

SQNR は信号電力を量子化雑音電力で割ったものです。

$$ \text{SQNR} = \frac{P_\text{signal}}{\sigma_q^2} = \frac{2^{2N} \Delta^2 / 8}{\Delta^2 / 12} = \frac{12 \cdot 2^{2N}}{8} = \frac{3}{2} \cdot 2^{2N} $$

これをデシベルに変換します。$10\log_{10}$ を取ると、

$$ \text{SQNR [dB]} = 10\log_{10}\!\left(\frac{3}{2}\cdot 2^{2N}\right) $$

対数の性質を使って展開しましょう。

$$ = 10\log_{10}\frac{3}{2} + 10\log_{10}2^{2N} $$

$10\log_{10}(3/2) \approx 1.76\,\text{dB}$、$10\log_{10}2^{2N} = 20N\log_{10}2 \approx 6.02N\,\text{dB}$ を代入すると、

$$ \boxed{\text{SQNR [dB]} \approx 6.02N + 1.76} $$

この有名な公式は「ビット数を 1 増やすごとに SQNR が約 6 dB 改善する」ことを意味します。16 ビットなら約 98 dB、24 ビットなら約 146 dB の SQNR が得られることになります。

量子化の理論がわかったところで、次はディジタル値をアナログ電圧に戻す DAC の回路方式を見ていきましょう。DAC は ADC の内部にも使われるため、先に理解しておくと後の議論がスムーズになります。

DAC方式 — ディジタルからアナログへ

重み抵抗型 DAC

DAC の最もシンプルな方式は 重み抵抗型(Binary Weighted Resistor DAC) です。天秤のイメージで考えてみてください。1 kg、2 kg、4 kg、8 kg のおもりを組み合わせれば、1 kg から 15 kg まで 1 kg 刻みの重さをすべて表現できます。重み抵抗型 DAC はこれと同じ発想で、各ビットに対応する重みの電流を合算してアナログ電圧を生成します。

$N$ ビットの重み抵抗型 DAC では、最上位ビット(MSB)に抵抗 $R$、次のビットに $2R$、その次に $4R$、…、最下位ビット(LSB)に $2^{N-1}R$ の抵抗を割り当てます。各ビット $b_k$($k = 0, 1, \dots, N-1$、$k=N-1$ が MSB)がオン(1)のとき、基準電圧 $V_\text{ref}$ からその抵抗を通じて電流が流れます。

オペアンプの反転加算回路を用いると、出力電圧は次の式で表されます。

$$ V_\text{out} = -V_\text{ref} \cdot R_f \sum_{k=0}^{N-1} \frac{b_k}{2^{N-1-k} \cdot R} $$

ここで $R_f$ はフィードバック抵抗です。$R_f = R/2$ とおけば、よりきれいな形になります。

$$ V_\text{out} = -\frac{V_\text{ref}}{2} \sum_{k=0}^{N-1} \frac{b_k}{2^{N-1-k}} $$

ここで $b_{N-1}$ が MSB、$b_0$ が LSB です。各ビットが $V_\text{ref}/2$, $V_\text{ref}/4$, … , $V_\text{ref}/2^N$ の重みで寄与していることがわかります。

この方式は原理が明快ですが、実用上は大きな問題があります。ビット数が増えると、MSB と LSB の抵抗比が $2^{N-1}$ にもなります。例えば 12 ビットでは抵抗比が 2048:1 です。このような広い範囲の抵抗値を高精度に製造・マッチングすることは極めて困難です。

R-2R ラダー型 DAC

重み抵抗型の製造上の問題を解決するのが R-2R ラダー型 DAC です。この方式では、回路全体を $R$ と $2R$ のたった2種類の抵抗だけで構成できます。

R-2R ラダーの動作原理を理解するために、回路の各ノードにおけるテブナンの等価回路を考えましょう。ラダーの各段で見ると、右側を見たインピーダンスが常に $2R$ になるように設計されています。これにより、各ノードでは電圧がちょうど半分に分圧されます。

$N$ ビットの R-2R ラダー型 DAC では、出力電圧は次のとおりです。

$$ V_\text{out} = V_\text{ref} \sum_{k=0}^{N-1} \frac{b_k}{2^{N-k}} $$

たとえば 4 ビットの場合、入力が $[b_3, b_2, b_1, b_0] = [1, 0, 1, 1]$(十進数で 11)のとき、

$$ V_\text{out} = V_\text{ref}\left(\frac{1}{2} + \frac{0}{4} + \frac{1}{8} + \frac{1}{16}\right) = V_\text{ref} \cdot \frac{11}{16} $$

$V_\text{ref} = 3.3\,\text{V}$ であれば $V_\text{out} = 3.3 \times 11/16 \approx 2.269\,\text{V}$ となります。

R-2R ラダーの最大の利点は、ビット数をいくら増やしても必要な抵抗値が $R$ と $2R$ の 2 種類だけであることです。集積回路上での抵抗マッチングが容易であるため、現代の高精度 DAC の多くはこの原理に基づいています。

DAC の仕組みが理解できたところで、いよいよ本題の ADC に入りましょう。ADC は DAC よりも設計が複雑で、用途に応じてさまざまな方式が考案されています。まずは最も高速な方式であるフラッシュ型から見ていきます。

ADC方式1: フラッシュ型 — 一瞬で変換する力業

動作原理

フラッシュ型 ADC は、名前のとおり「一瞬で」変換を完了する方式です。イメージとしては、身長測定を考えてください。壁に 1 cm 刻みの線を引いておけば、人が壁の前に立った瞬間に「どの線を超えてどの線を超えないか」を見るだけで、1 回の観測で身長がわかります。フラッシュ型 ADC はまさにこの方法を電子回路で実現したものです。

$N$ ビットのフラッシュ型 ADC では、$2^N – 1$ 個のコンパレータ(比較器)を並列に配置します。基準電圧 $V_\text{ref}$ を抵抗分圧で均等に分割し、各コンパレータの一方の入力に閾値電圧を設定します。もう一方の入力にはアナログ入力信号 $V_\text{in}$ を共通に接続します。

$k$ 番目のコンパレータ($k = 1, 2, \dots, 2^N – 1$)の閾値は次のとおりです。

$$ V_k = k \cdot \frac{V_\text{ref}}{2^N} = k \cdot \Delta $$

各コンパレータは、$V_\text{in} > V_k$ なら「1」、$V_\text{in} \le V_k$ なら「0」を出力します。すべてのコンパレータの出力を集めると、「温度計コード(サーモメータコード)」と呼ばれるパターンが得られます。例えば $V_\text{in}$ が $V_3$ と $V_4$ の間にある場合、下から 3 個のコンパレータが「1」、残りが「0」になります。

このサーモメータコードを優先エンコーダ(Priority Encoder)で $N$ ビットのバイナリコードに変換すれば、AD変換は完了です。全ての比較が同時並列に行われるため、変換に要する時間は 1 クロックサイクル のみで、極めて高速です。

利点と欠点

フラッシュ型の最大の利点は変換速度です。GHz オーダーのサンプリングレートを実現でき、高速オシロスコープや光通信の受信回路に使われています。

一方、致命的な欠点は回路規模です。$N$ ビットの分解能を得るために $2^N – 1$ 個のコンパレータが必要になります。ビット数を 1 増やすとコンパレータ数は約2倍に増えるため、高分解能化が極めて困難です。

分解能 コンパレータ数
4 bit 15
8 bit 255
10 bit 1,023
12 bit 4,095

8 ビットを超えると回路面積と消費電力が急増するため、フラッシュ型は通常 6〜8 ビット程度に限られます。高速だが低分解能 — これがフラッシュ型の特徴です。

より高い分解能を、そこそこの速度で実現するにはどうすればよいでしょうか。次に紹介する逐次比較型 ADC は、速度と分解能のバランスに優れた方式です。

ADC方式2: 逐次比較型(SAR ADC)— 二分探索の発想

動作原理

逐次比較型 ADC(Successive Approximation Register ADC、略して SAR ADC)は、二分探索のアルゴリズムをハードウェアで実装した方式です。

数当てゲームを想像してください。相手が 0 から 255 の間の数を思い浮かべたとき、「128 より大きい?」→「192 より大きい?」→「160 より大きい?」… と毎回範囲を半分に絞れば、最大 8 回の質問で答えにたどり着けます。SAR ADC はまさにこの戦略でアナログ電圧を特定します。

SAR ADC の内部構成は次のとおりです。

  1. サンプル&ホールド回路: アナログ入力を一定期間保持
  2. DAC: 現在の推定値をアナログ電圧に変換
  3. コンパレータ: 入力電圧と DAC 出力を比較
  4. SAR ロジック(逐次比較レジスタ): 比較結果に基づきビットを確定

$N$ ビットの SAR ADC は、以下の手順を MSB から LSB まで $N$ 回繰り返します。

ステップ1: まず MSB(最上位ビット)を「1」にセットし、残りを「0」とします。このとき内部 DAC の出力は $V_\text{ref}/2$ です。

ステップ2: コンパレータが $V_\text{in}$ と DAC 出力を比較します。

  • $V_\text{in} \ge V_\text{DAC}$ なら、MSB を「1」のまま確定
  • $V_\text{in} < V_\text{DAC}$ なら、MSB を「0」に戻す

ステップ3: 次のビット(MSB-1)を「1」にセットし、同様に比較・確定します。

この操作を LSB まで繰り返せば、$N$ クロックサイクルで $N$ ビットの変換が完了します。

数値例

8 ビット・フルスケール $V_\text{ref} = 3.3\,\text{V}$ の SAR ADC で、$V_\text{in} = 2.0\,\text{V}$ を変換する例を追ってみましょう。量子化ステップは $\Delta = 3.3/256 \approx 12.9\,\text{mV}$ です。

ステップ テストビット レジスタ値 DAC出力 [V] 比較結果 確定ビット
1 bit7 = 1 10000000 1.650 $V_\text{in} > V_\text{DAC}$ bit7 = 1
2 bit6 = 1 11000000 2.475 $V_\text{in} < V_\text{DAC}$ bit6 = 0
3 bit5 = 1 10100000 2.063 $V_\text{in} < V_\text{DAC}$ bit5 = 0
4 bit4 = 1 10010000 1.856 $V_\text{in} > V_\text{DAC}$ bit4 = 1
5 bit3 = 1 10011000 1.959 $V_\text{in} > V_\text{DAC}$ bit3 = 1
6 bit2 = 1 10011100 2.011 $V_\text{in} < V_\text{DAC}$ bit2 = 0
7 bit1 = 1 10011010 1.985 $V_\text{in} > V_\text{DAC}$ bit1 = 1
8 bit0 = 1 10011011 1.998 $V_\text{in} > V_\text{DAC}$ bit0 = 1

最終結果は $10011011_2 = 155_{10}$ で、DAC 出力は約 $1.998\,\text{V}$ です。入力の $2.0\,\text{V}$ との誤差は約 $2\,\text{mV}$ で、量子化ステップ $12.9\,\text{mV}$ の範囲内に収まっています。

SAR ADC の特徴

SAR ADC は以下の特徴から、現在最も広く使われている ADC 方式です。

  • 回路規模が小さい: コンパレータ 1 個 + DAC 1 個 + ロジックだけで構成
  • 消費電力が低い: フラッシュ型に比べて桁違いに省電力
  • 分解能が確保しやすい: 12〜18 ビットが実用的
  • 変換速度は中程度: $N$ クロックサイクルかかるが、数 Msps 程度は実現可能

マイコン内蔵の ADC はほとんどが SAR 方式です。速度と分解能と消費電力のバランスが優れているためです。

しかし、オーディオや精密計測の分野では 20 ビットを超える超高分解能が求められます。SAR ADC で 20 ビットを実現しようとすると、内部 DAC に 20 ビット精度が要求され、現実的ではありません。次に紹介する ΔΣ型 ADC は、まったく異なるアプローチで超高分解能を達成します。

ADC方式3: ΔΣ型 — オーバーサンプリングで精度を稼ぐ

ΔΣ変調の基本アイデア

ΔΣ(デルタシグマ)型 ADC は、1 ビットまたは数ビットの粗い量子化器を極めて高いサンプリングレートで動作させ、後段のディジタルフィルタで高分解能を得る方式です。

これは投票のアナロジーで理解できます。1 回の投票(1 ビット量子化)では「賛成」か「反対」しかわかりませんが、同じ質問を 1000 回繰り返して多数決を取れば、支持率を 0.1% の精度で推定できます。ΔΣ型 ADC もこれと同じ発想で、粗い測定を高速に繰り返すことで高精度を実現します。

ΔΣ型 ADC のシステム構成は次の 2 段階に分かれます。

  1. ΔΣ変調器(アナログ部): オーバーサンプリング + 1 ビット量子化 + フィードバック
  2. デシメーションフィルタ(ディジタル部): 高レートの 1 ビットデータを低レート・高分解能データに変換

オーバーサンプリングの効果

まず、オーバーサンプリングだけでどの程度の改善が得られるかを確認しましょう。ナイキストレート $f_s$ の $K$ 倍のレート $Kf_s$ でサンプリングすることを オーバーサンプリング と呼び、$K$ を オーバーサンプリング比(OSR) と呼びます。

量子化雑音電力 $\sigma_q^2 = \Delta^2/12$ は、サンプリングレートによらず一定です。しかし、この雑音が分布する周波数帯域はサンプリングレートに比例して広がります。具体的には、ナイキストレートでは雑音が帯域 $[0, f_s/2]$ に均一に分布しますが、$K$ 倍のオーバーサンプリングでは帯域 $[0, Kf_s/2]$ に均一に分布します。

信号帯域 $[0, f_s/2]$ 内の雑音電力は、オーバーサンプリングにより $1/K$ に低減されます。

$$ \sigma_{q,\text{band}}^2 = \frac{\Delta^2}{12} \cdot \frac{1}{K} $$

これを SQNR の改善量として計算すると、

$$ \Delta\text{SQNR} = 10\log_{10} K \,\,\text{[dB]} $$

1 ビットの分解能改善(約 6 dB)を得るには OSR を 4 倍にする必要があり、効率はあまり良くありません。オーバーサンプリングだけでは限界があるのです。

ここで登場するのが ノイズシェーピング です。ΔΣ変調器は、量子化雑音を信号帯域の外(高周波側)に押しやることで、信号帯域内の雑音を劇的に低減します。

では、ΔΣ変調器は具体的にどのようなメカニズムでノイズシェーピングを実現するのでしょうか? 次のセクションでその動作原理を詳しく見ていきましょう。

ΔΣ変調の動作原理 — ノイズシェーピング

1次ΔΣ変調器のブロック図

1次ΔΣ変調器は、以下の要素で構成されます。

  1. 加算器: 入力 $x[n]$ から DAC 出力 $y[n-1]$ を引く(差分 = Δ)
  2. 積分器: 差分を累積する(積分 = Σ)
  3. 量子化器: 積分器の出力を 1 ビットに量子化
  4. 1 ビット DAC: 量子化器の出力をアナログに戻してフィードバック

$z$ 変換を用いて解析します。入力信号を $X(z)$、量子化雑音を $E(z)$、出力を $Y(z)$ とします。積分器の伝達関数は $H(z) = z^{-1}/(1 – z^{-1})$ です。

量子化器を「入力にノイズ $E(z)$ を加算するブロック」とモデル化すると、積分器の出力 $U(z)$ は次のようになります。

$$ U(z) = \frac{z^{-1}}{1 – z^{-1}} \bigl(X(z) – Y(z)\bigr) $$

量子化器の出力は $Y(z) = U(z) + E(z)$ です。ここで $Y(z)$ をフィードバックしているので、上の式に代入して $Y(z)$ について解きましょう。

まず、$U(z) = Y(z) – E(z)$ なので、

$$ Y(z) – E(z) = \frac{z^{-1}}{1 – z^{-1}} \bigl(X(z) – Y(z)\bigr) $$

両辺に $(1 – z^{-1})$ を掛けて展開します。

$$ (1 – z^{-1})\bigl(Y(z) – E(z)\bigr) = z^{-1}\bigl(X(z) – Y(z)\bigr) $$

左辺を展開すると、

$$ Y(z) – z^{-1}Y(z) – E(z) + z^{-1}E(z) = z^{-1}X(z) – z^{-1}Y(z) $$

$-z^{-1}Y(z)$ が両辺にあるので消去できます。

$$ Y(z) – E(z) + z^{-1}E(z) = z^{-1}X(z) $$

$Y(z)$ について整理すると、

$$ Y(z) = z^{-1}X(z) + (1 – z^{-1})E(z) $$

この結果は非常に重要です。出力 $Y(z)$ は次の 2 項の和であることがわかります。

$$ \boxed{Y(z) = \underbrace{z^{-1}}_{\text{STF}} X(z) + \underbrace{(1 – z^{-1})}_{\text{NTF}} E(z)} $$

  • 信号伝達関数(STF): $\text{STF}(z) = z^{-1}$ — 信号は 1 サンプル遅延するだけでそのまま通過
  • 雑音伝達関数(NTF): $\text{NTF}(z) = 1 – z^{-1}$ — 量子化雑音には高域通過フィルタがかかる

ノイズシェーピングの周波数特性

NTF の周波数特性を確認しましょう。$z = e^{j\omega}$($\omega$ は正規化角周波数)を代入すると、

$$ \text{NTF}(e^{j\omega}) = 1 – e^{-j\omega} $$

この振幅は次のように計算できます。$1 – e^{-j\omega} = e^{-j\omega/2}(e^{j\omega/2} – e^{-j\omega/2}) = e^{-j\omega/2} \cdot 2j\sin(\omega/2)$ なので、

$$ |\text{NTF}(e^{j\omega})| = 2\sin\!\left(\frac{\omega}{2}\right) $$

$\omega = 0$(DC)では $|\text{NTF}| = 0$ であり、$\omega = \pi$(ナイキスト周波数)では $|\text{NTF}| = 2$ です。つまり、低周波では量子化雑音が強く抑圧され、高周波に押しやられていることがわかります。これが ノイズシェーピング です。

信号帯域が十分に狭い(OSR が十分に大きい)場合、$\omega \ll 1$ の近似 $\sin(\omega/2) \approx \omega/2$ が使えるので、

$$ |\text{NTF}(e^{j\omega})| \approx \omega $$

となり、雑音のパワースペクトル密度は $\omega^2$ に比例します。つまり、1次ΔΣ変調器では信号帯域内の雑音電力が $\text{OSR}^3$ に反比例して減少することが知られています。

1次ΔΣ変調器の帯域内雑音電力は次のとおりです。

$$ \sigma_{q,\text{band}}^2 = \frac{\Delta^2}{12} \cdot \frac{\pi^2}{3} \cdot \frac{1}{\text{OSR}^3} $$

$L$ 次($L$ 段積分器)のΔΣ変調器に拡張すると、NTF は $(1 – z^{-1})^L$ となり、帯域内雑音電力の OSR 依存性はさらに強くなります。

$$ \sigma_{q,\text{band}}^2 \propto \frac{1}{\text{OSR}^{2L+1}} $$

OSR を 2 倍にするごとの SQNR 改善量は次のとおりです。

次数 $L$ OSR 2倍あたりの改善
0(オーバーサンプリングのみ) 3 dB
1 9 dB(= 1.5 bit)
2 15 dB(= 2.5 bit)
3 21 dB(= 3.5 bit)

2次ΔΣ変調器で OSR = 256 の場合、$15 \times \log_2 256 = 15 \times 8 = 120\,\text{dB}$ の SQNR 改善が得られ、これは約 20 ビットの分解能に相当します。これが、オーディオ DAC や精密計測器で ΔΣ方式が採用される理由です。

ΔΣ変調でどのように高分解能が実現されるかが理解できました。次に、AD/DA変換器の性能をどのような指標で評価するかを見ていきましょう。

性能指標 — AD/DA変換器の実力を測る

AD/DA変換器の性能は、理想的な特性からのずれをさまざまな角度から評価します。ここでは実用上重要な指標を整理します。

分解能(Resolution)

分解能はビット数 $N$ で表され、ADC が区別できる最小の電圧変化を決めます。ただし、ビット数が大きいからといって本当にその分解能が有効に使われているとは限りません。雑音によって下位ビットが埋もれる場合があるためです。この「実効的な分解能」が次に述べる ENOB です。

SNR(信号対雑音比)

実際の ADC では量子化雑音以外にも、熱雑音、ジッタ雑音、電源雑音などが加わります。これらすべてを含めた雑音に対する信号の比が SNR です。

$$ \text{SNR [dB]} = 10\log_{10}\frac{P_\text{signal}}{P_\text{noise}} $$

理想的な ADC では $\text{SNR} = \text{SQNR} = 6.02N + 1.76$ ですが、実際の ADC では SNR はこれより低くなります。

SINAD(信号対雑音+歪み比)

SINAD は、雑音に加えて高調波歪みも含めた指標です。

$$ \text{SINAD [dB]} = 10\log_{10}\frac{P_\text{signal}}{P_\text{noise} + P_\text{distortion}} $$

SINAD は SNR よりも常に小さく(悪く)なり、ADC の総合的な性能を表します。

ENOB(有効ビット数)

ENOB(Effective Number of Bits)は、実際の ADC の SINAD から逆算した「実効的なビット数」です。

$$ \boxed{\text{ENOB} = \frac{\text{SINAD [dB]} – 1.76}{6.02}} $$

この式は、先ほど導出した $\text{SQNR} = 6.02N + 1.76$ を $N$ について解いた形です。例えば、SINAD が 72 dB であれば、

$$ \text{ENOB} = \frac{72 – 1.76}{6.02} \approx 11.67\,\text{bit} $$

つまり、仮に 14 ビットの ADC であっても、実効的には約 11.7 ビットしか使えていないということです。ENOB はデータシートの「ビット数」よりも実用的な性能の目安であり、ADC を選定する際に最も重視される指標の一つです。

SFDR(スプリアスフリーダイナミックレンジ)

SFDR は、信号の基本波と最大のスプリアス(不要信号成分)との電力比です。

$$ \text{SFDR [dBc]} = P_\text{signal} – P_\text{max spurious} $$

SFDR が高いほど、小さな信号を検出する能力が高いことを意味します。これはレーダーや通信の受信機で特に重要な指標です。微弱な目標信号が強い不要信号に埋もれないことを保証するためです。

変換速度(サンプリングレート)

ADC が 1 秒間に何回の変換を行えるかを表す指標です。単位はサンプル毎秒(SPS)または Msps、Gsps で表されます。方式によって大きく異なります。

方式 典型的な変換速度 典型的な分解能
フラッシュ型 1〜10 Gsps 4〜8 bit
SAR型 100 ksps〜10 Msps 10〜18 bit
ΔΣ型 10 sps〜1 Msps 16〜32 bit
パイプライン型 10〜500 Msps 10〜16 bit

速度と分解能はトレードオフの関係にあり、用途に応じて適切な方式を選ぶ必要があります。

性能指標の意味がわかったところで、ADC の前段に不可欠なサンプル&ホールド回路について解説します。

サンプル&ホールド回路 — 変換中にアナログ値を固定する

なぜ必要か

ADC はアナログ入力をディジタル値に変換するのに一定の時間(変換時間)がかかります。SAR ADC なら $N$ クロックサイクル、フラッシュ型でも有限の比較時間が必要です。この変換中にアナログ入力が変化してしまうと、正しい変換結果が得られません。

写真を撮る場面を想像してください。シャッターが開いている間に被写体が動くとブレた写真になります。サンプル&ホールド(S/H)回路は、いわば電子回路のシャッターです。ある瞬間のアナログ電圧を「撮影」して固定(ホールド)し、ADC が変換を完了するまで一定に保ちます。

動作原理

最もシンプルな S/H 回路は、スイッチ(アナログスイッチまたは MOSFET)とキャパシタ $C_H$ で構成されます。

  • サンプルフェーズ: スイッチ ON。入力電圧 $V_\text{in}$ がキャパシタに充電される
  • ホールドフェーズ: スイッチ OFF。キャパシタに蓄えられた電荷 $Q = C_H V_\text{in}$ が保持され、ADC に安定した電圧を供給する

ホールドフェーズでの問題は ドループ(droop) です。キャパシタからのリーク電流 $I_\text{leak}$ により、ホールド電圧が徐々に低下します。

$$ \Delta V_\text{droop} = \frac{I_\text{leak}}{C_H} \cdot t_\text{hold} $$

ドループを小さくするには、キャパシタ容量 $C_H$ を大きくするか、ホールド時間 $t_\text{hold}$ を短くします。ただし $C_H$ を大きくするとサンプルフェーズでの充電時間が長くなり、サンプリングレートが制限されます。このトレードオフの設計が S/H 回路の要点です。

アパーチャジッタ

S/H 回路のもう一つの重要なパラメータが アパーチャジッタ $\Delta t_a$ です。スイッチが OFF になるタイミングにばらつきがあると、サンプルする瞬間が不確定になります。入力信号の変化率が大きいほど、このジッタの影響は深刻です。

周波数 $f_\text{in}$ の正弦波入力に対するジッタ由来の SNR は次の式で見積もれます。

$$ \text{SNR}_\text{jitter} = -20\log_{10}(2\pi f_\text{in} \cdot \Delta t_a) $$

例えば、$f_\text{in} = 10\,\text{MHz}$、$\Delta t_a = 1\,\text{ps}$ の場合、

$$ \text{SNR}_\text{jitter} = -20\log_{10}(2\pi \times 10^7 \times 10^{-12}) \approx 84\,\text{dB} $$

これは約 13.7 ビットの ENOB に相当します。つまり、14 ビット以上の分解能を 10 MHz の入力で活かすには、1 ps 以下のアパーチャジッタが必要になります。高分解能・高速 ADC では、ジッタの管理がシステム性能の鍵を握ります。

ここまでで理論的な基盤は一通り整いました。次のセクションでは、Python を使って量子化誤差と ΔΣ変調の動作をシミュレーションし、理論を数値的に確認しましょう。

Python実装1: 量子化誤差の可視化

まず、量子化の過程と量子化誤差がどのように分布するかを Python で確認します。正弦波をさまざまなビット数で量子化し、量子化誤差のヒストグラムと SQNR の理論値・実測値を比較するコードを実装します。

import numpy as np
import matplotlib.pyplot as plt

# --- パラメータ ---
fs = 10000           # サンプリング周波数 [Hz]
f_in = 37            # 入力正弦波の周波数 [Hz](fs と互いに素に近い値)
N_samples = 10000    # サンプル数
V_fs = 3.3           # フルスケール電圧 [V]
bit_list = [4, 8, 12, 16]  # 量子化ビット数のリスト

t = np.arange(N_samples) / fs
x_analog = (V_fs / 2) * np.sin(2 * np.pi * f_in * t)  # 振幅 V_fs/2 の正弦波

fig, axes = plt.subplots(2, 2, figsize=(12, 9))
axes = axes.ravel()

sqnr_theory = []
sqnr_measured = []

for idx, N_bit in enumerate(bit_list):
    n_levels = 2 ** N_bit
    delta = V_fs / n_levels  # 量子化ステップ

    # 量子化(中間値丸め)
    x_shifted = x_analog + V_fs / 2  # [0, V_fs] にシフト
    x_q_shifted = np.round(x_shifted / delta) * delta
    x_q_shifted = np.clip(x_q_shifted, 0, V_fs - delta)
    x_quantized = x_q_shifted - V_fs / 2  # 元のレンジに戻す

    # 量子化誤差
    error = x_quantized - x_analog

    # SQNR 計算
    P_signal = np.mean(x_analog ** 2)
    P_noise = np.mean(error ** 2)
    sqnr_meas = 10 * np.log10(P_signal / P_noise)
    sqnr_theo = 6.02 * N_bit + 1.76

    sqnr_theory.append(sqnr_theo)
    sqnr_measured.append(sqnr_meas)

    # 量子化誤差のヒストグラム
    axes[idx].hist(error, bins=80, density=True, alpha=0.7, color='steelblue',
                   edgecolor='white', linewidth=0.5)
    axes[idx].axvline(-delta / 2, color='red', linestyle='--', linewidth=1.2, label=f'±Δ/2 = ±{delta/2:.4f} V')
    axes[idx].axvline(delta / 2, color='red', linestyle='--', linewidth=1.2)
    axes[idx].set_title(f'{N_bit}-bit (SQNR: theory={sqnr_theo:.1f} dB, measured={sqnr_meas:.1f} dB)',
                        fontsize=11)
    axes[idx].set_xlabel('Quantization Error [V]')
    axes[idx].set_ylabel('Probability Density')
    axes[idx].legend(fontsize=9)

plt.suptitle('Quantization Error Distribution for Different Bit Depths', fontsize=13, y=1.01)
plt.tight_layout()
plt.show()

上のグラフでは、ビット数ごとに量子化誤差の分布を確認できます。4つのサブプロットから、以下の重要な特徴が読み取れます。

  1. 量子化誤差は $\pm\Delta/2$ の範囲内に収まっている — 赤い破線で示した理論的な上下限の内側にヒストグラムが分布しています。これは一様量子化の基本的な性質を裏付けています。
  2. ビット数が増えるほど $\Delta$ が指数関数的に小さくなる — 4 ビットでは $\Delta/2 \approx 0.1\,\text{V}$ ですが、16 ビットでは $\Delta/2 \approx 25\,\mu\text{V}$ と 4 桁以上小さくなります。量子化ステップ幅のこの急激な減少が SQNR の改善に直結しています。
  3. 実測 SQNR は理論値とよく一致する — $6.02N + 1.76$ の公式が実際に成り立っていることを数値的に確認できます。わずかな差は有限サンプル数による統計的揺らぎです。

次に、SQNR がビット数に対して線形に増加する様子をグラフで確認しましょう。

import numpy as np
import matplotlib.pyplot as plt

bit_range = np.arange(1, 25)
sqnr_formula = 6.02 * bit_range + 1.76

fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(bit_range, sqnr_formula, 'b-', linewidth=2, label='Theory: 6.02N + 1.76')
ax.plot([4, 8, 12, 16],
        [6.02*4+1.76, 6.02*8+1.76, 6.02*12+1.76, 6.02*16+1.76],
        'ro', markersize=8, label='Common ADC bit depths')

ax.set_xlabel('Number of Bits N', fontsize=12)
ax.set_ylabel('SQNR [dB]', fontsize=12)
ax.set_title('SQNR vs. Number of Quantization Bits', fontsize=13)
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
ax.set_xlim([1, 24])
ax.set_ylim([0, 160])

# 右側にビット数ごとの具体的な値を注釈
for n in [8, 12, 16, 24]:
    sqnr_val = 6.02 * n + 1.76
    ax.annotate(f'{n}-bit: {sqnr_val:.1f} dB',
                xy=(n, sqnr_val), xytext=(n + 1.5, sqnr_val - 5),
                fontsize=9, arrowprops=dict(arrowstyle='->', color='gray'))

plt.tight_layout()
plt.show()

このグラフから、SQNR がビット数 $N$ に対して完全に線形に増加していることが明確にわかります。CD 品質の 16 ビットでは SQNR が約 98 dB、ハイレゾの 24 ビットでは約 146 dB です。しかし実際の ADC では熱雑音やジッタの影響で理論限界には届かないため、ENOB が実用的な指標として重視されます。

続いて、ΔΣ変調のシミュレーションに進みましょう。

Python実装2: ΔΣ変調のシミュレーション

ΔΣ変調のノイズシェーピング効果を直接確認するために、1次および2次のΔΣ変調器を Python で実装し、出力のパワースペクトル密度を可視化します。

import numpy as np
import matplotlib.pyplot as plt

def delta_sigma_1st(x, n_levels=2):
    """1次ΔΣ変調器のシミュレーション"""
    N = len(x)
    y = np.zeros(N)        # 量子化器出力
    integrator = 0.0       # 積分器の状態

    for n in range(N):
        # 差分: 入力 - フィードバック
        diff = x[n] - y[n - 1] if n > 0 else x[n]
        # 積分
        integrator += diff
        # 量子化(1ビット: +1 or -1)
        if n_levels == 2:
            y[n] = 1.0 if integrator >= 0 else -1.0
        else:
            step = 2.0 / (n_levels - 1)
            y[n] = np.round(integrator / step) * step
            y[n] = np.clip(y[n], -1.0, 1.0)
    return y

def delta_sigma_2nd(x, n_levels=2):
    """2次ΔΣ変調器のシミュレーション"""
    N = len(x)
    y = np.zeros(N)
    int1 = 0.0  # 1段目積分器
    int2 = 0.0  # 2段目積分器

    for n in range(N):
        diff1 = x[n] - (y[n - 1] if n > 0 else 0.0)
        int1 += diff1
        diff2 = int1 - (y[n - 1] if n > 0 else 0.0)
        int2 += diff2
        # 量子化
        if n_levels == 2:
            y[n] = 1.0 if int2 >= 0 else -1.0
        else:
            step = 2.0 / (n_levels - 1)
            y[n] = np.round(int2 / step) * step
            y[n] = np.clip(y[n], -1.0, 1.0)
    return y

# --- シミュレーション設定 ---
OSR = 256
f_sig = 1000        # 信号周波数 [Hz]
f_nyquist = 2 * f_sig
fs = f_nyquist * OSR  # オーバーサンプリング後のサンプリング周波数
N_samples = 2 ** 16   # FFT サンプル数(2のべき乗)

t = np.arange(N_samples) / fs
x_input = 0.5 * np.sin(2 * np.pi * f_sig * t)  # 入力正弦波(振幅 0.5)

# 1次・2次 ΔΣ変調
y_1st = delta_sigma_1st(x_input)
y_2nd = delta_sigma_2nd(x_input)

# 比較用: 単純な1ビット量子化(ΔΣなし)
y_simple = np.where(x_input >= 0, 1.0, -1.0)

変調器の出力が得られたので、パワースペクトル密度(PSD)を計算して比較します。

import numpy as np
import matplotlib.pyplot as plt

def compute_psd(signal, fs, N_fft):
    """パワースペクトル密度を計算"""
    window = np.hanning(N_fft)
    windowed = signal[:N_fft] * window
    spectrum = np.fft.rfft(windowed)
    psd = (np.abs(spectrum) ** 2) / (fs * np.sum(window ** 2))
    psd_db = 10 * np.log10(psd + 1e-20)
    freqs = np.fft.rfftfreq(N_fft, d=1.0 / fs)
    return freqs, psd_db

N_fft = min(N_samples, 2 ** 16)
freqs, psd_simple = compute_psd(y_simple, fs, N_fft)
_, psd_1st = compute_psd(y_1st, fs, N_fft)
_, psd_2nd = compute_psd(y_2nd, fs, N_fft)

fig, axes = plt.subplots(3, 1, figsize=(11, 10), sharex=True)

titles = ['Simple 1-bit Quantization (No Noise Shaping)',
          '1st-order ΔΣ Modulator',
          '2nd-order ΔΣ Modulator']
psds = [psd_simple, psd_1st, psd_2nd]
colors = ['gray', 'steelblue', 'darkorange']

for i, (ax, title, psd, color) in enumerate(zip(axes, titles, psds, colors)):
    ax.plot(freqs / 1000, psd, color=color, linewidth=0.5, alpha=0.8)
    ax.axvline(f_sig / 1000, color='red', linestyle='--', linewidth=1.0,
               label=f'Signal: {f_sig/1000:.0f} kHz')
    ax.axvline(f_nyquist / 1000, color='green', linestyle='--', linewidth=1.0,
               label=f'Signal BW: {f_nyquist/1000:.0f} kHz')
    ax.set_ylabel('PSD [dB/Hz]', fontsize=11)
    ax.set_title(title, fontsize=12)
    ax.legend(fontsize=9, loc='upper right')
    ax.set_ylim([-160, 0])
    ax.grid(True, alpha=0.3)

axes[-1].set_xlabel('Frequency [kHz]', fontsize=11)
axes[-1].set_xscale('log')
plt.tight_layout()
plt.show()

3つのスペクトルを比較すると、ΔΣ変調のノイズシェーピング効果が一目瞭然です。

  1. 単純1ビット量子化(上段): 量子化雑音が全帯域にわたってほぼ均一に分布しています。信号のピーク(赤い破線)と雑音フロアの差は小さく、SNR は非常に低い状態です。
  2. 1次ΔΣ変調(中段): 低周波域の雑音が明らかに低下し、高周波域に押し上げられています。信号帯域(緑の破線より左側)では雑音が大幅に抑圧されており、NTF の $|\text{NTF}| = 2\sin(\omega/2)$ の特性(低周波で小さく、高周波で大きい)が確認できます。
  3. 2次ΔΣ変調(下段): ノイズシェーピングの傾きがさらに急峻になっています。信号帯域内の雑音フロアは1次よりもさらに 10〜20 dB 低下しており、NTF が $(1 – z^{-1})^2$ であることから $\omega^2$ に比例する特性を示しています。

このように、ΔΣ変調器の次数を上げるほどノイズシェーピングが強力になり、信号帯域内の SNR が向上します。デシメーションフィルタで信号帯域外の高周波雑音を除去すれば、1 ビットの量子化器から 20 ビット以上の実効分解能を引き出すことが可能です。

最後に、SAR ADC の二分探索アルゴリズムを可視化するコードも実装してみましょう。

import numpy as np
import matplotlib.pyplot as plt

def sar_adc(v_in, v_ref, n_bits):
    """SAR ADC の逐次比較プロセスをシミュレーション"""
    register = 0
    history = []  # 各ステップの (レジスタ値, DAC出力, 比較結果) を記録

    for i in range(n_bits - 1, -1, -1):
        register |= (1 << i)              # テストビットを1に
        v_dac = v_ref * register / (2 ** n_bits)

        if v_in >= v_dac:
            result = 'keep'                # ビットを1のまま
        else:
            register &= ~(1 << i)          # ビットを0に戻す
            result = 'clear'

        v_dac_final = v_ref * register / (2 ** n_bits)
        history.append((i, register, v_dac_final, result))

    return register, history

# --- SAR ADC の動作可視化 ---
V_ref = 3.3
N_bits = 8
V_in = 2.0

result, history = sar_adc(V_in, V_ref, N_bits)

fig, ax = plt.subplots(figsize=(10, 6))

steps = np.arange(1, N_bits + 1)
dac_values = [h[2] for h in history]
results = [h[3] for h in history]

ax.axhline(V_in, color='red', linewidth=2, linestyle='-', label=f'Input: {V_in:.3f} V')
ax.step(steps, dac_values, where='mid', color='steelblue', linewidth=2, label='DAC output')

for s, v, r in zip(steps, dac_values, results):
    marker = '▲' if r == 'keep' else '▼'
    color = 'green' if r == 'keep' else 'orange'
    ax.plot(s, v, 'o', color=color, markersize=10, zorder=5)
    ax.annotate(f'bit{N_bits - s}={"1" if r == "keep" else "0"}',
                xy=(s, v), xytext=(s + 0.2, v + 0.08),
                fontsize=8, color=color)

ax.set_xlabel('SAR Step', fontsize=12)
ax.set_ylabel('DAC Output Voltage [V]', fontsize=12)
ax.set_title(f'{N_bits}-bit SAR ADC: Vin={V_in:.3f}V → Code={result} ({result:#010b})',
             fontsize=12)
ax.legend(fontsize=11)
ax.set_xlim([0.5, N_bits + 0.5])
ax.set_xticks(steps)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

このグラフでは、SAR ADC が入力電圧 $2.0\,\text{V}$ に向かって二分探索で収束していく様子が可視化されています。

  1. 最初のステップで大きくジャンプし、徐々に微調整に入る — MSB から確定するため、最初のステップで $V_\text{ref}/2 = 1.65\,\text{V}$ にジャンプし、以降のステップでの電圧変化は半分ずつ小さくなっていきます。これは二分探索の収束の速さを反映しています。
  2. 緑のマーカー(keep)とオレンジのマーカー(clear)が交互に現れる — 各ステップで「テストビットを保持するか戻すか」の判定が行われ、最終的に入力電圧に最も近いディジタルコードが得られます。
  3. 8ステップ(= 8ビット)で量子化ステップ以内に収束 — 最終的な DAC 出力と入力電圧の差は量子化ステップ $\Delta = 3.3/256 \approx 12.9\,\text{mV}$ の範囲内に収まっており、理論どおりの精度です。

まとめ

本記事では、AD/DA変換器の基礎理論から主要な回路方式、性能評価指標まで体系的に解説しました。

  • 量子化の基礎: 量子化ステップ $\Delta = V_\text{FS}/2^N$ と量子化雑音電力 $\sigma_q^2 = \Delta^2/12$ を導出し、SQNR の公式 $6.02N + 1.76\,\text{dB}$ を得ました。ビット数を 1 増やすごとに約 6 dB の改善が得られます
  • DAC方式: 重み抵抗型は原理が明快だが高精度の抵抗マッチングが困難、R-2R ラダー型は 2 種類の抵抗だけで構成でき集積回路に適しています
  • フラッシュ型 ADC: 全レベルを並列比較するため最高速だが、コンパレータ数が $2^N – 1$ 個必要で高分解能化が困難です
  • SAR ADC: 二分探索アルゴリズムで $N$ クロックサイクルで変換し、回路規模・消費電力・分解能のバランスに優れた最も汎用的な方式です
  • ΔΣ型 ADC: オーバーサンプリングとノイズシェーピングにより、1 ビット量子化器から 20 ビット超の実効分解能を実現できます。NTF $(1 – z^{-1})^L$ による雑音の高周波シフトが鍵です
  • 性能指標: ENOB = (SINAD – 1.76) / 6.02 は ADC の実効的な性能を一つの数値で表す最も実用的な指標です
  • サンプル&ホールド回路: 変換中の入力変動を防ぐ不可欠な前段回路であり、アパーチャジッタが高分解能・高速動作時の性能を支配します

AD/DA変換は、センサからの信号取得、音声・映像のディジタル処理、通信システムの受信フロントエンドなど、あらゆるディジタルシステムの入口と出口に位置する技術です。本記事で学んだ理論は、ディジタルフィルタの設計やソフトウェア無線の実装に直結していきます。

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