R-2Rラダー型DACの原理と誤差解析

デジタルオシロスコープの任意波形発生器、オーディオアンプのボリューム制御、自動試験装置の電圧源 — これらの内部には必ず「デジタルの数値をアナログ電圧に変える」回路が入っています。12ビットのDACなら、0から4095までの整数を受け取って、4096段階の電圧を作り分けなければなりません。

素朴に考えると、これは簡単そうです。ビットごとに 1:2:4:8:… の電流を作って足し合わせればいい。実際そういうDAC(重み付き抵抗型)は存在します。ところが12ビットでこれをやろうとすると、いちばん小さい抵抗といちばん大きい抵抗の比が2048倍になり、その比を0.01%の精度で合わせろ、という無理難題に突き当たります。1 kΩ と 2.048 MΩ を、互いに 0.01% の精度で揃えて作る — 半導体プロセスでは絶望的です。

そこでR-2Rラダーが登場します。使う抵抗値は $R$ と $2R$ の2種類だけ。それだけで、きれいな2進重み $1/2, 1/4, 1/8, \dots$ が出てきます。しかも出力抵抗は入力コードによらず常に $R$ で一定です。初めて見ると手品のようですが、種を明かせば「末端から順にテブナン等価を折り畳む」という一本道の計算です。

R-2Rラダー型DACの回路構成。各ビットは2Rを介してVrefか接地に倒れるスイッチにつながり、ノード間は直列Rで結ばれ、末端に終端抵抗2Rが入る。1段通るごとに信号が半分になる

これがR-2Rラダーの全体像です。どのビットもまったく同じ回路($2R$ とスイッチ)で構成されていて、抵抗の種類は $R$ と $2R$ の2つしかありません。それでも各ビットの信号は出力に向かって1段進むごとにきっちり半分に減衰するため、出力に届く量は自動的に $1/2, 1/4, 1/8, \dots$ という2進の重みになります。左端にぶら下がっている終端抵抗が $R$ ではなく $2R$ である点が、この「ちょうど半分」を成立させる要です。以降ではこの図の各部分が、どうしてその値でなければならないのかを順に解きほぐしていきます。

R-2Rラダーを理解すると、次のような場面で効いてきます。

  • 計測器・信号発生器の設計: DACの分解能を上げたときに何が律速になるのか(抵抗マッチングか、スイッチのオン抵抗か)を切り分けられます
  • オーディオDAC: 「マルチビットDACはMSB遷移でグリッチが出る」という定番の話が、なぜMSBなのか式で説明できます
  • IC設計・レイアウト: 単位抵抗をどう並べるか、どこまでトリミングすべきか、という判断に直結します
  • データシートの読み方: INL / DNL / 単調性保証ビット数という3つのスペックが、内部の抵抗誤差とどう結びついているかが見えます

本記事の内容

  • R-2Rラダーの回路構成と、重み付き抵抗型DACが破綻する理由の定量比較
  • 末端から見た等価抵抗が常に $R$ になる再帰構造の証明
  • テブナン変換を1段ずつ折り畳んで、$n$ 段目のビットの寄与が $2^{-(N-n)}$ になることの導出
  • 出力抵抗がコードに依存しないという性質
  • 静特性の誤差指標 INL・DNL の定義と、抵抗誤差からの感度解析
  • DNL最悪点がMSB遷移($011\dots1 \to 100\dots0$)に現れる理由の式による説明
  • 単調性を保証する抵抗マッチング精度の要件($\sqrt{4/3}$ という係数の導出)
  • Python実装: 理想伝達特性、誤差付きINL/DNL曲線、非単調確率の $\sigma$ 依存性

前提知識

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

とくにテブナンの定理は本記事の主役です。「任意の線形2端子回路は、電圧源1個と抵抗1個に置き換えられる」というあの定理を、ラダーの端から順に適用していくだけで、R-2Rの重みがすべて出てきます。

DACに求められること — まず素朴な回路から

DACの仕事は、$N$ ビットの2進数

$$ D = \sum_{n=0}^{N-1} b_n 2^{n}, \qquad b_n \in \{0, 1\} $$

を受け取って、それに比例した電圧を出すことです。ここで $n = 0$ が最下位ビット(LSB)、$n = N-1$ が最上位ビット(MSB)です。目標の出力は

$$ V_{\text{out}} = V_{\text{ref}} \cdot \frac{D}{2^N} = V_{\text{ref}} \sum_{n=0}^{N-1} b_n 2^{-(N-n)} $$

です。$b_n$ の係数 $2^{-(N-n)}$ に注目してください。$n = N-1$(MSB)なら $2^{-1} = 1/2$、$n = 0$(LSB)なら $2^{-N}$。つまりMSBは基準電圧の半分、そこから1ビット下がるごとに半分ずつという重みを、回路で物理的に作ればよいわけです。

重み付き抵抗型DACという素朴解

いちばん素直な作り方は、ビットごとに違う抵抗を用意することです。各ビットのスイッチを $V_{\text{ref}}$ か接地に倒し、抵抗 $R_n$ を通して1点(オペアンプの仮想接地)に電流を流し込みます。抵抗を通る電流は $I_n = V_{\text{ref}} b_n / R_n$ ですから、$I_n \propto 2^n$ にしたければ

$$ R_n = \frac{R}{2^{n}} \quad \Longleftrightarrow \quad R_{N-1} : \dots : R_1 : R_0 = 1 : \dots : 2^{N-2} : 2^{N-1} $$

とすればいい。MSBに最小の抵抗、LSBに最大の抵抗を割り当てるわけです。原理は完璧です。問題は作れるかどうかでした。

なぜ破綻するのか — 抵抗レンジという壁

$N$ ビットに必要な抵抗値の範囲は $2^{N-1}$ 倍に広がります。12ビットなら 2048:1、16ビットなら 32768:1 です。最小抵抗を 1 kΩ にとると、16ビットではMSBが 1 kΩ、LSBが 32.8 MΩ。この2つを「互いに」高精度で揃えることを要求されます。

集積回路で抵抗の比精度を稼ぐ常套手段は、同じ形・同じ大きさの単位抵抗をたくさん並べて、直列・並列で必要な値を作ることです。同一形状・同一向き・隣接配置なら、エッチングの寸法ばらつきもシート抵抗の勾配も温度係数も共通に効くため、比だけは驚くほど正確に揃います。では重み付き抵抗型を単位抵抗で作るとどうなるか。必要な単位抵抗の総数は

$$ 1 + 2 + 4 + \dots + 2^{N-1} = 2^N – 1 $$

個です。12ビットで4095個、16ビットで65535個。1個のDACのために6万個以上の単位抵抗を並べるというのは、面積の観点でも寄生容量(=整定時間)の観点でも現実的ではありません。かといって単位抵抗を使わず、幅と長さを変えて大小の抵抗を直接描けば、形状が違う以上「比」の精度は絶対精度と同程度(0.1〜1%)に落ちてしまいます。

R-2Rラダーは、この単位抵抗の個数を一気に減らす発明です。 後で数えますが、$N$ ビットのR-2Rに必要な単位抵抗はたった $3N + 1$ 個。16ビットでも49個で済みます。65535個が49個。これがR-2Rが100年近く使われ続けている理由です。

重み付き抵抗型とR-2Rラダーの比較。左は必要な抵抗値のレンジが分解能とともに指数的に広がること、右は必要な単位抵抗の個数が16ビットで65535個対49個になることを対数軸で示す

左のグラフは、重み付き抵抗型に必要な「最大抵抗 ÷ 最小抵抗」が分解能1ビットごとに2倍に膨れ上がり、16ビットでは 32768:1 に達することを示しています。R-2Rはどの分解能でも $2R/R = 2$ のまま水平線です。右のグラフはそれを素子数に翻訳したもので、重み付き型の $2^N-1$ 個が指数的に爆発するのに対し、R-2Rの $3N+1$ 個はほぼ横ばい。18ビットでも55個です。どちらも縦軸が対数であることに注意してください。片方は直線的に伸び、片方はほとんど動かない — この差が「作れるか作れないか」を分けます。

では、たった2種類の抵抗値でどうやって $2^{-1}, 2^{-2}, \dots, 2^{-N}$ という指数的な重みを作るのでしょうか。ここからが本題です。

R-2Rラダーとは — 「大きくする」のではなく「半分にし続ける」

重み付き抵抗型の発想は「MSBの重みを基準に、下位ビットほど大きな抵抗で電流を絞る」でした。抵抗値そのものに重みを担わせるので、抵抗値のレンジが指数的に広がります。

R-2Rの発想は逆です。すべてのビットをまったく同じ回路($2R$ を通して $V_{\text{ref}}$ か接地に倒すスイッチ)で作り、その信号を出力に向かって運ぶ途中で、1段通過するごとにきっかり半分に減衰させる。 減衰器を $N$ 個数珠つなぎにすれば、LSBの信号は $N$ 回半分にされて $2^{-N}$、MSBは1回だけ半分にされて $2^{-1}$ になります。指数的な重みは、抵抗値の指数的な大小ではなく、同じ減衰を繰り返した回数から生まれるのです。

左は各ビットの信号が0.5から出発して1段進むごとに半分になる様子を対数軸で示した図、右は節点解析で実測した8ビットR-2Rの各ビットの重みが2の-(N-n)乗にぴたり一致することを示す棒グラフ

左のグラフでは、すべてのビットが同じ高さ $0.5$ から出発していることが重要です。ビットごとに違うのは「出発点」ではなく「出力に届くまでに何段通るか」だけで、LSBは7段通って $2^{-8}$ まで薄まり、MSBは1段だけで $1/2$ を保ちます。対数軸で見ると、どの線も同じ傾き(1段で半分)の平行線になっているのがわかります。右は後の節で節点解析により実測した重みで、$2^{-8}$ から $2^{-1}$ まできれいに2倍刻みに並んでいます。指数的な重みは、抵抗値を指数的に変えたからではなく、同じ減衰を繰り返した回数の違いから生まれているわけです。

身近な例えを使うなら、階段状の水路を想像してください。各段に同じ大きさの水門があり、水門から流し込まれた水は下流に進むたびに毎回ちょうど半分がバイパスに逃げていく。いちばん下流の水門から入れた水はそのまま半分だけ出口に届き、いちばん上流から入れた水は何度も半分にされてごくわずかしか届かない。水門はすべて同じ規格でいいのに、届く量は $1/2, 1/4, 1/8, \dots$ と2進の重みになる。R-2Rラダーがやっているのはまさにこれです。

回路構成

具体的な構成を決めておきます。ノードを $0, 1, \dots, N-1$ と番号づけ、ノード $0$ がLSB側の端、ノード $N-1$ がMSB側で、ここが出力です。

  • 各ノード $n$ には、抵抗 $2R$ を介してビット $n$ のスイッチがつながる。スイッチは $b_n = 1$ なら $V_{\text{ref}}$、$b_n = 0$ なら接地に倒れる
  • 隣り合うノード $n$ と $n+1$ の間は、抵抗 $R$ でつながる($n = 0, \dots, N-2$)
  • ノード $0$ のさらに外側に、終端抵抗 $2R$ が接地との間に入る
  • 出力(ノード $N-1$)は、入力インピーダンスの十分高いバッファで受ける(=開放とみなす)

使う抵抗は $R$ と $2R$ の2種類だけ。個数は、シャントの $2R$ が $N$ 本、直列の $R$ が $N-1$ 本、終端の $2R$ が1本で、合計 $2N$ 本です。単位抵抗 $R$ に換算すると $2N + (N-1) + 2 = 3N+1$ 個。これが先ほどの数字の出どころです。

ここで最初の疑問が湧きます。なぜ終端抵抗が $R$ ではなく $2R$ なのか。そして、なぜ「1段で半分」がぴったり成り立つのか。鍵はラダーがもつ再帰構造にあります。

再帰構造 — 末端から見た抵抗が常に $R$ になる

R-2Rラダーの魔法はすべて、次のひとつの事実に集約されます。

どのノードから左(LSB側)を覗いても、そこに見える抵抗は必ず $R$ である。

これを示しましょう。電圧源(スイッチが倒れる先の $V_{\text{ref}}$ と接地)は、抵抗を見るときには理想電圧源なので短絡して接地扱いにします。つまり各シャントの $2R$ は、抵抗を数えるうえでは単に「接地への $2R$」です。

基底段(ノード $0$): ノード $0$ から左を見ると、終端抵抗 $2R$ とビット $0$ のシャント $2R$ が並列になっています。したがって

$$ R_0 = 2R \parallel 2R = \frac{2R \cdot 2R}{2R + 2R} = R $$

終端抵抗を $2R$ にしたのは、まさにこの $2R \parallel 2R = R$ を成立させるためです。もし終端が $R$ だったら $R \parallel 2R = 2R/3$ となり、以降の議論がすべて崩れます。

帰納段: ノード $k-1$ から左を見た抵抗が $R_{k-1} = R$ であると仮定します。ノード $k$ から左を見ると、まず直列抵抗 $R$ を通ってノード $k-1$ に至り、そこから先が $R_{k-1} = R$ なので、この経路の抵抗は $R + R_{k-1} = 2R$。これがビット $k$ のシャント $2R$ と並列になるので

$$ R_k = (R + R_{k-1}) \parallel 2R = 2R \parallel 2R = R $$

仮定と同じ $R$ が再び現れました。数学的帰納法により、すべての $k$ で $R_k = R$ が成り立ちます。∎

Rから出発して直列Rを足して2Rにし、シャント2Rと並列にしてRに戻るという閉じたサイクルの図解と、節点解析で求めた出力テブナン抵抗が分解能Nによらず常にRであることを示すグラフ

左の図が示すのは、$R \to 2R \to R$ という3ステップが円環になっていて、何段通ってもスタート地点に戻るということです。この閉じ方は終端抵抗が $2R$ のときにしか成立せず、終端を $R$ にすると基底段で $R \parallel 2R = 2R/3$ となってサイクルが開いてしまいます。右のグラフは節点解析で実際に出力抵抗を計算した結果で、$N = 2$ から $16$ まで偏差ゼロ(機械精度で完全一致)の $1.000000R$ が並びます。証明が数値実験でもそのまま裏づけられました。

この計算の美しさは、「$R$ から出発して、直列に $R$ を足して $2R$ にし、$2R$ と並列にして $R$ に戻る」という操作が閉じているところにあります。ラダーは自分自身を再生産する構造になっていて、何段つないでも左を見たインピーダンスは $R$ のまま変わりません。だからこそ、各段の減衰比も何段目かによらず一定になります。

ついでに、出力から右(負荷側)ではなく回路内部を見たテブナン抵抗も同じ議論で $R$ になります。ノード $N-1$ から見ると、左側が $R + R_{N-2} = 2R$、MSBのシャントが $2R$ で、並列にして $R$。つまり入力コードが何であっても、DACの出力インピーダンスは常に $R$ で一定です。これは実用上ありがたい性質で、後段のバッファから見た信号源抵抗が変わらないため、整定時間もノイズ帯域もコードによらず一定になります。コードによって出力抵抗が変動すると、整定時間がコード依存になって高速動作時の誤差要因になりますが、R-2Rにはそれがありません。

等価抵抗が常に $R$ だとわかったので、次はいよいよ電圧です。各ビットが出力にどれだけの重みで届くかを、テブナン等価を1段ずつ折り畳んで求めましょう。

テブナン変換による重みの導出

折り畳みの漸化式

$T_k$ を、「ノード $0$ からノード $k$ までのラダー部分を、ノード $k$ から見たときのテブナン等価電圧」と定義します。前節で示したとおり、テブナン等価抵抗はどの段でも $R$ です。求めたいのは $T_{N-1}$、すなわち出力電圧です。

まず、2つの等しい抵抗が1つのノードで出会うときの合成を用意しておきます。あるノードに、抵抗 $\rho$ を介して電圧 $A$ の源が、同じく抵抗 $\rho$ を介して電圧 $B$ の源がつながっているとします。重ね合わせ(あるいは節点方程式)から、このノードの開放電圧は

$$ V = \frac{A/\rho + B/\rho}{1/\rho + 1/\rho} = \frac{A + B}{2} $$

で、テブナン抵抗は $\rho \parallel \rho = \rho/2$ です。等しい抵抗どうしなら、単純な平均が出る。この事実だけを繰り返し使います。

基底段: ノード $0$ には、終端抵抗 $2R$ を介して接地(電圧 $0$)が、シャント $2R$ を介して $V_{\text{ref}} b_0$ がつながっています。抵抗が等しいので平均をとって

$$ T_0 = \frac{0 + V_{\text{ref}} b_0}{2} = \frac{V_{\text{ref}} b_0}{2} $$

テブナン抵抗は $2R \parallel 2R = R$ です。

帰納段: ノード $k-1$ までを $(T_{k-1},\ R)$ のテブナン等価に置き換えたとします。これを直列抵抗 $R$ を通してノード $k$ から見ると、抵抗が足されて $(T_{k-1},\ R + R = 2R)$ になります。一方、ノード $k$ にはシャント $2R$ を介して $V_{\text{ref}} b_k$ がつながっています。ここで両者の抵抗がともに $2R$ で等しくなることが決定的です。先ほどの平均の公式がそのまま使えて、

$$ T_k = \frac{T_{k-1} + V_{\text{ref}} b_k}{2}, \qquad R_{\text{th}} = 2R \parallel 2R = R $$

テブナン抵抗はまた $R$ に戻り、次の段でも同じことが起きます。これが「1段通過するごとにきっかり半分」の正体です。直列 $R$ を足すと $2R$ になり、シャント $2R$ と出会って平均され、抵抗は $R$ に戻る — この閉じたサイクルが、$R$ と $2R$ の2種類しか使わないのに正確な2進重みを生む仕組みです。

漸化式を解く

漸化式

$$ T_k = \frac{1}{2} T_{k-1} + \frac{1}{2} V_{\text{ref}} b_k, \qquad T_{-1} \equiv 0 $$

を解きます。まず $T_k = V_{\text{ref}} \sum_{n=0}^{k} b_n 2^{-(k-n+1)}$ を主張し、帰納法で確かめましょう。

$k = 0$ のときは $V_{\text{ref}} b_0 2^{-1} = V_{\text{ref}} b_0 / 2$ で、基底段の結果と一致します。

$k$ で成り立つと仮定して $k+1$ を計算します。漸化式に仮定を代入すると、

$$ T_{k+1} = \frac{1}{2} \left( V_{\text{ref}} \sum_{n=0}^{k} b_n 2^{-(k-n+1)} \right) + \frac{1}{2} V_{\text{ref}} b_{k+1} $$

第1項の $1/2$ を総和の中に取り込むと、指数の肩が1つずつ下がって $2^{-(k-n+2)}$ になります。ここで $k – n + 2 = (k+1) – n + 1$ と書き直せば、ちょうど主張したい形の指数です。

$$ T_{k+1} = V_{\text{ref}} \sum_{n=0}^{k} b_n 2^{-((k+1)-n+1)} + \frac{1}{2} V_{\text{ref}} b_{k+1} $$

残った第2項も $n = k+1$ のときの $2^{-((k+1)-n+1)} = 2^{-1}$ にほかならないので、総和の上限を $k+1$ に伸ばして1本にまとめられます。

$$ T_{k+1} = V_{\text{ref}} \sum_{n=0}^{k+1} b_n 2^{-((k+1)-n+1)} $$

これは $k+1$ に対する主張そのものです。∎

出力電圧と各ビットの重み

$k = N-1$(出力ノード)とおくと、$(N-1) – n + 1 = N – n$ なので、

$$ \begin{equation} V_{\text{out}} = T_{N-1} = V_{\text{ref}} \sum_{n=0}^{N-1} b_n \, 2^{-(N-n)} \end{equation} $$

$n$ 段目のビットは出力に $2^{-(N-n)}$ の重みで寄与する — 冒頭で目標として掲げた式が、そのまま出てきました。MSB($n = N-1$)は $2^{-1} = 1/2$、LSB($n = 0$)は $2^{-N}$ です。$D = \sum_n b_n 2^n$ を使えば

$$ V_{\text{out}} = V_{\text{ref}} \cdot \frac{D}{2^{N}} $$

と書け、フルスケール(全ビット1)でも $V_{\text{ref}}(1 – 2^{-N})$ にとどまり、$V_{\text{ref}}$ には届きません。1 LSB は $V_{\text{ref}}/2^N$ です。

ここで終端抵抗の役割をもう一度確認しておきましょう。終端抵抗は「常に接地に倒れている、重み $2^{-N}$ の $0$ 番目のビット」に相当します。式 (1) の総和には現れませんが、これが無いと $R_0 = R$ が成立せず、以降の段の $2R$ どうしの対等性が崩れて、全ビットの重みが狂います。データシートに「未使用でも終端は必ず接地せよ」と書かれるのはこのためです。

理論式が出ましたので、次は具体的な数値で手を動かして確かめてみましょう。

具体例 — 4ビットR-2Rを手で折り畳む

$N = 4$、$V_{\text{ref}} = 5$ V、入力コード $D = 11 = (b_3 b_2 b_1 b_0) = (1011)_2$ で計算します。1 LSB は $5/16 = 0.3125$ V、期待される出力は $5 \times 11/16 = 3.4375$ V です。

ノード0: 終端の $2R$ が接地、$b_0 = 1$ なので $2R$ の先は $5$ V。平均して

$$ T_0 = \frac{0 + 5}{2} = 2.5\ \text{V}, \qquad R_{\text{th}} = R $$

ノード1: 直列 $R$ を通した $(2.5\ \text{V},\ 2R)$ と、$b_1 = 1$ より $(5\ \text{V},\ 2R)$。

$$ T_1 = \frac{2.5 + 5}{2} = 3.75\ \text{V}, \qquad R_{\text{th}} = R $$

ノード2: $(3.75\ \text{V},\ 2R)$ と、$b_2 = 0$ より $(0\ \text{V},\ 2R)$。ここでビット2が0なので、直前までの信号がちょうど半分に減衰します。

$$ T_2 = \frac{3.75 + 0}{2} = 1.875\ \text{V} $$

ノード3(出力): $(1.875\ \text{V},\ 2R)$ と、$b_3 = 1$ より $(5\ \text{V},\ 2R)$。

$$ T_3 = \frac{1.875 + 5}{2} = 3.4375\ \text{V} $$

4ビットR-2R(Vref=5V,コード1011)のテブナン折り畳みを1段ずつ図示。各ノードで前段の電圧とそのビットのVrefが平均され、T0=2.5V,T1=3.75V,T2=1.875V,T3=3.4375Vと進む

このグラフは折り畳みの各ステップを可視化したものです。赤い四角がそのビットのスイッチ電圧($b=1$ なら5 V、$b=0$ なら0 V)、青い折れ線が各ノードのテブナン等価電圧で、青い点は必ず「直前の青い点」と「その段の赤い四角」のちょうど中点に来ています。とくにノード2では $b_2 = 0$ のため $3.75$ V が $1.875$ V へ半減しており、0を入れることが「これまでの信号を半分に薄める」操作そのものだとわかります。最後のノード3で緑の破線(期待値3.4375 V)にぴたりと着地しました。

期待値 $3.4375$ V にぴたりと一致しました。重み分解で検算すると $5 \times (2^{-1} + 2^{-3} + 2^{-4}) = 5 \times (0.5 + 0.125 + 0.0625) = 5 \times 0.6875 = 3.4375$ V です。

この計算を眺めると、R-2Rの性格がよく見えます。LSB側で作られた電圧は、出力に届くまでに何度も「$0$ との平均」を通って薄められる。ノード0で作った 2.5 V は、最終的に $2.5 \times 2^{-3} = 0.3125$ V = ちょうど1 LSB分の寄与になっています。逆にMSBの 5 V は1回しか平均されず、$2.5$ V = フルスケールの半分をそのまま担います。

この非対称性は、ありがたい性質であると同時に、これから見る誤差解析の主役でもあります。LSB側の抵抗が多少ずれても出力にはほとんど響かない一方で、MSB側の抵抗の誤差はほぼ生のまま出力に出てくるからです。ここから精度の話に入りましょう。

DACの静特性 — INLとDNL

理想DACの伝達特性は、コードに対してぴたりと等間隔な階段です。実物はそこからずれます。そのずれを測る指標が2つあります。

まず平均のLSB幅を、実測の両端から決めます(端点直線基準)。

$$ \Delta_{\text{LSB}} = \frac{V(2^N – 1) – V(0)}{2^N – 1} $$

こうしておくと、$V_{\text{ref}}$ の絶対誤差(ゲイン誤差)やオフセットは自動的に除かれ、「形の歪み」だけが残ります。

DNL(微分非直線性, Differential Non-Linearity) は、隣り合うコード間のステップ幅が1 LSBからどれだけずれているかです。

$$ \text{DNL}(k) = \frac{V(k+1) – V(k)}{\Delta_{\text{LSB}}} – 1 $$

INL(積分非直線性, Integral Non-Linearity) は、理想直線からの累積のずれです。

$$ \text{INL}(k) = \frac{V(k) – V(0)}{\Delta_{\text{LSB}}} – k $$

定義から $\text{INL}(k+1) – \text{INL}(k) = \text{DNL}(k)$、つまりDNLを積分したものがINLです。

抵抗ばらつき10%を与えた4ビットDACの伝達特性と、そのINL・DNL。コード7から8でステップ幅が負になりDNLが-1.57LSBとなって出力が減る非単調が起きている

誤差を10%まで誇張した4ビットDACで2つの指標を見比べています。左の赤い両矢印がINL(理想直線からの縦方向のずれ、ここでは $+0.79$ LSB)、緑の両矢印がステップ幅で、コード7→8では出力が上がるどころか下がっています(DNL $= -1.57$ LSB)。右のグラフを見ると、緑の棒(DNL)のうちメジャーキャリーの1本だけが突出して負に振れ、それに対応して赤い折れ線(INL)がそこで急降下しているのがわかります。INLは端点基準で定義されているので、両端では必ず0に戻ります。DNLは局所的なステップ幅の異常を、INLはその累積のうねりを表すという役割分担がこの2枚から読み取れます。

この2つのうち、実用上より怖いのはDNLです。DNL $= -1$ になると、ステップ幅がゼロ、つまりコードを1つ増やしても出力が変わりません。DNL $< -1$ なら出力が減ってしまう。これが非単調(non-monotonic)な状態です。DACをフィードバックループの中で使っている場合(サーボの指令値生成、逐次比較型ADCの内部DACなど)、非単調性は「増やしたつもりが減る」という符号反転を意味するので、ループが発振したり、探索アルゴリズムが正解にたどり着けなくなったりします。データシートに「$N$ ビット単調性保証」という項目がわざわざ立っているのはこのためです。

INLは歪み率に効きます。オーディオDACなら、INLの曲がりがそのまま高調波歪みとして耳に届きます。

では、抵抗のばらつきはこの2つにどう効くのでしょうか。まずは「MSBの抵抗が1本だけずれている」という最も単純な状況を厳密に解いてみます。

MSBの抵抗誤差はどう効くか

出力ノードでの厳密計算

MSBのシャント抵抗だけが $2R(1 + \varepsilon)$ にずれていて、他はすべて理想だとします。出力ノード $N-1$ には、左側から $(T_{N-2},\ 2R)$ が、MSBのシャントから $(V_{\text{ref}} b_{N-1},\ 2R(1+\varepsilon))$ が来ています。抵抗が等しくないので、もう単純な平均にはなりません。 一般の2源合成の公式に戻ります。抵抗 $\rho_a$ を介して $A$、抵抗 $\rho_b$ を介して $B$ がつながるノードの開放電圧は

$$ V = \frac{A/\rho_a + B/\rho_b}{1/\rho_a + 1/\rho_b} = \frac{A \rho_b + B \rho_a}{\rho_a + \rho_b} $$

です。$\rho_a = 2R$, $A = T_{N-2}$, $\rho_b = 2R(1+\varepsilon)$, $B = V_{\text{ref}} b_{N-1}$ を代入すると、分母分子の $2R$ が約分されて

$$ V_{\text{out}} = \frac{T_{N-2}(1+\varepsilon) + V_{\text{ref}} b_{N-1}}{2 + \varepsilon} $$

理想($\varepsilon = 0$)なら両者とも係数 $1/2$ でしたが、いまMSBの重みは $1/(2+\varepsilon)$ に減り、下位ビット全体の重みは $(1+\varepsilon)/(2+\varepsilon)$ に増えています。相対変化を $\delta$ と書くと、

$$ \delta \equiv \frac{\varepsilon}{2+\varepsilon} \approx \frac{\varepsilon}{2} $$

を使って、MSBの重みは $(1-\delta)$ 倍、下位ビット全体は $(1+\delta)$ 倍です。片方が減った分、もう片方が同じ割合だけ増える — これがポイントです。誤差が2倍になって効きます。

MSB遷移でのDNL

いよいよ核心です。コード $2^{N-1} – 1 = 011\dots1$ から $2^{N-1} = 100\dots0$ への遷移を考えます。ここでは下位 $N-1$ ビットが全部1から全部0に落ち、同時にMSBが0から1に立ち上がります。DACの中でいちばん多くのスイッチが同時に動く瞬間で、「メジャーキャリー(major carry)」と呼ばれます。

理想LSB単位で書くと、MSBの重みは $2^{N-1}$、下位ビットの重みの合計は $1 + 2 + \dots + 2^{N-2} = 2^{N-1} – 1$ です。誤差を入れたステップ幅 $S$ は

$$ S = 2^{N-1}(1 – \delta) – (2^{N-1} – 1)(1 + \delta) $$

第1項は「MSBが立ち上がって増える分」、第2項は「下位ビットが全部落ちて減る分」です。展開して整理します。$2^{N-1}$ の項が打ち消し合うことに注意すると、

$$ S = 2^{N-1} – 2^{N-1}\delta – 2^{N-1} – 2^{N-1}\delta + 1 + \delta = 1 – \delta\left(2^{N} – 1\right) $$

理想では $S = 1$ ですから、DNLは

$$ \begin{equation} \text{DNL}_{\text{MC}} = S – 1 = -\delta\,(2^{N} – 1) \approx -\frac{\varepsilon}{2} \cdot 2^{N} = -\varepsilon \, 2^{N-1} \end{equation} $$

$\varepsilon$ が $2^{N-1}$ 倍に増幅される。 これがMSB遷移が最悪点になる理由です。物理的な意味はこうです。メジャーキャリーでは、ほぼフルスケールの半分にあたる大きな量(MSB)と、同じくフルスケール半分にあたる大きな量(下位全ビット)を引き算して、たった1 LSBという小さな差を作っています。大きな数どうしの引き算で小さな数を作るとき、元の数の相対誤差は差に対して猛烈に拡大されます — 数値計算でいう「桁落ち」とまったく同じ構図です。

しかも、MSBの重みが減れば下位側の重みが増える、という符号が逆の効果が両方効くので、誤差はちょうど2倍になって現れます。式 (2) で $\varepsilon/2$ ではなく $\varepsilon$ が $2^{N-1}$ にかかっているのは、そのためです。

12ビットで $\varepsilon = 0.02\%$($2 \times 10^{-4}$)なら $\text{DNL}_{\text{MC}} \approx -2 \times 10^{-4} \times 2048 = -0.41$ LSB。たった0.02%の抵抗ずれが、0.41 LSBのステップ誤差になります。もし $\varepsilon = 0.1\%$ なら $-2.05$ LSB で、これは完全に非単調です。

INLの形

INLはDNLの積分でした。MSB誤差の場合、DNLはメジャーキャリーの1点にだけ集中して現れます(他のコードでは下位ビットの重みが一様に $(1+\delta)$ 倍されているだけなので、端点直線基準をとると打ち消されます)。したがってINLは、

  • コード $0$ から $2^{N-1}-1$ まで、緩やかに上昇して $+\varepsilon 2^{N-2}$ に達する
  • メジャーキャリーで一気に $\text{DNL}_{\text{MC}}$ だけ落ちて $-\varepsilon 2^{N-2}$ になる
  • そこから再び上昇して、フルスケールで $0$ に戻る

という、中央に1回だけ不連続がある鋸歯状になります。ピーク値はDNLのちょうど半分の $\varepsilon 2^{N-2}$ です。オシロでこの形のINLが見えたら「MSB付近の抵抗が疑わしい」と即断できる、実務的にも有名な波形です。

12ビットR-2RでMSBのシャント2Rだけを+0.02%ずらしたときのINLとDNL。INLは中央で+0.2047から-0.2047へ跳ぶ鋸歯状、DNLはメジャーキャリーの1点だけに-0.4095LSBのスパイクが立つ

左のINLは予告どおりの形です。コード0から2047へ緩やかに $+0.2047$ LSB まで上がり、メジャーキャリーで一気に $-0.2047$ LSB へ落ち、そこからまた上がってフルスケールで0に戻る — 中央に1回だけ不連続をもつ鋸歯です。右のDNLは、4095個あるステップのうちたった1点だけが $-0.4095$ LSB に沈み、他はすべて $0.0001$ LSB 以下という極端な集中を示しています。抵抗の誤差はわずか $0.02\%$ ですから、$2^{11} = 2048$ 倍に増幅されている計算です。MSBの誤差は全域をなだらかに歪ませるのではなく、1点を集中的に壊すという性格をもちます。

MSB1本の話は片づきました。では他の抵抗はどれくらい効くのでしょうか。ここで感度解析に進みます。

感度解析 — どの抵抗が効くのか

$2N$ 本すべての抵抗にそれぞれ独立な相対誤差が乗ったとき、$\text{DNL}_{\text{MC}}$ がどう動くかを調べます。数値微分で感度係数 $s_i = \partial \text{DNL}_{\text{MC}} / \partial \varepsilon_i$ を求めると、驚くほど整った構造が現れます(後のPython節で実際に計算します)。$2^{N-1}$ で規格化して書くと、

$$ \frac{s^{2R}_{n}}{2^{N-1}} = \begin{cases} -1 & (n = N-1,\ \text{MSBのシャント}) \\[4pt] \left(\dfrac{1}{4}\right)^{N-1-n} & (n \le N-2) \end{cases} $$

$$ \frac{s^{R}_{j}}{2^{N-1}} = \frac{1}{2}\left(\frac{1}{4}\right)^{N-2-j} \qquad (j = 0, \dots, N-2) $$

12ビットR-2Rの各抵抗がMSB遷移DNLに与える感度の対数棒グラフと、分散寄与率の内訳。MSBのシャント2Rが74.99%、MSB直前の直列Rが18.75%で上位2本が93.74%を占める

左の対数棒グラフでは、右端(MSB側)から左へ向かって感度が一直線に落ちていきます。点線は「1ビットごとに $1/4$」の目安線で、MSBから4段ほど下(感度 $1.6 \times 10^{-2}$ あたり)までは実測がこの線にぴたりと乗ります。それより下位では $1.6 \times 10^{-4}$ 程度で頭打ちになりますが(端点直線基準のLSB幅を通じたごく弱い経路が残るためです)、水準そのものが上位に比べて4桁小さく、実質ゼロと見なして差し支えありません。右の内訳を見れば結論は一目瞭然で、MSBのシャント $2R$ だけで分散の75%、MSB直前の直列 $R$ を足すと93.74%。残り20本すべてを合わせても6%強にしかなりません。

ここで $s^{2R}_n$ はビット $n$ のシャント $2R$、$s^{R}_j$ はノード $j$ と $j+1$ の間の直列 $R$ の感度です。読み取れることは明快です。

  • MSBのシャント $2R$ が感度 $-1$ で断トツ。式 (2) の再確認です
  • MSB直前の直列 $R$ が感度 $+1/2$ で2番手。符号が逆なのは、この抵抗が大きくなると下位側からの信号がより減衰して、MSBの相対的な重みが増すからです
  • そこから1ビット下がるごとに感度が $1/4$ に落ちる。ラダーを1段下るごとに、信号の減衰($1/2$)とその段が担う重みの減少($1/2$)が両方効くため、掛け合わせて $1/4$ になります
  • LSB側の抵抗の感度は、MSBから4段ほど下まではこの $1/4$ 則にきれいに従い、それより下では $1.6 \times 10^{-4}$ 程度で頭打ちになります(端点直線基準のLSB幅を経由するごく弱い経路が残るためで、$1/4$ 則は上位数ビットに対する近似です)。いずれにせよ上位より4桁小さく、事実上ゼロです

下位ビットの抵抗は、いくらずれても構わない。 12ビットDACで下位6ビット分の抵抗の感度をすべて足しても、全分散に対する寄与は $10^{-4}\%$ 以下です。これはIC設計上きわめて重要な指針で、「上位数ビットの抵抗だけレイアウト面積を奮発し、コモンセントロイド配置やレーザートリミングで追い込む。下位ビットは適当でよい」という設計判断に直結します。実際の高分解能DACは、上位ビットだけを温度計コード化(セグメント化)して個別にトリムし、下位ビットは素のR-2Rで済ませる構成が定石です。

$\sqrt{4/3}$ という係数

すべての抵抗が独立に、標準偏差 $\sigma$ の相対誤差をもつとします。$\text{DNL}_{\text{MC}}$ は各誤差の線形結合なので、その分散は感度の二乗和で決まります。

$$ \frac{\text{Var}(\text{DNL}_{\text{MC}})}{(2^{N-1})^2} = \sigma^2 \left[ \underbrace{1^2}_{\text{MSBシャント}} + \underbrace{\sum_{k \ge 1} \left(4^{-k}\right)^2}_{\text{下位シャント}} + \underbrace{\sum_{k \ge 0} \left(\tfrac{1}{2} \cdot 4^{-k}\right)^2}_{\text{直列}R} \right] $$

ラダーが十分長ければ、和を無限級数に伸ばして評価できます。$\left(4^{-k}\right)^2 = 16^{-k}$ なので、どちらも公比 $1/16$ の等比級数です。第2項は初項 $1/16$ の等比級数で $\dfrac{1/16}{1 – 1/16} = \dfrac{1}{15}$、第3項は係数 $1/4$ がかかった初項 $1$ の等比級数で $\dfrac{1}{4} \cdot \dfrac{1}{1 – 1/16} = \dfrac{1}{4} \cdot \dfrac{16}{15} = \dfrac{4}{15}$ となります。3つを足すと

$$ 1 + \frac{1}{15} + \frac{4}{15} = 1 + \frac{5}{15} = 1 + \frac{1}{3} = \frac{4}{3} $$

ぴたりと $4/3$ です。したがって

$$ \begin{equation} \sigma_{\text{DNL,MC}} = \sqrt{\frac{4}{3}}\; \sigma \, 2^{N-1} = \frac{2}{\sqrt{3}}\, \sigma\, 2^{N-1} \approx 1.1547\, \sigma\, 2^{N-1}\ \ [\text{LSB}] \end{equation} $$

MSB1本だけの寄与(係数1)に対して、他の全抵抗を合わせても $\sqrt{4/3} = 1.155$ 倍にしかなりません。分散の内訳で言えば、MSBのシャントが75%、MSB直前の直列Rが18.75%、この2本だけで93.75%を占めます。R-2Rラダーの精度は、実質的に上位2本の抵抗で決まっているのです。

なお同じ議論はメジャーキャリー以外の「小さなキャリー」にも当てはまります。コード $2^m – 1 \to 2^m$ の遷移では、関わる重みが $2^m$ スケールなので

$$ \sigma_{\text{DNL}}(m) = \sqrt{\tfrac{4}{3}}\,\sigma\, 2^{m} $$

となり、$m$ が1つ下がるごとにDNLのばらつきは半分になります。DNL曲線をコード全体でプロットすると、中央のメジャーキャリーが最も高く、$1/4$ と $3/4$ の位置がその半分、$1/8$ 刻みの位置がさらに半分…という自己相似なスパイク列が見えるはずです。実際にPythonで確かめます。

感度の構造がわかったので、いよいよ設計仕様に翻訳しましょう。「何%の精度で抵抗を揃えれば単調性が保証されるのか」です。

単調性を保証する抵抗マッチング精度

非単調になるのは $\text{DNL}_{\text{MC}} < -1$ のときです。$\text{DNL}_{\text{MC}}$ が平均 $0$、標準偏差 $\sigma_{\text{DNL,MC}}$ の正規分布に従うとみなせば、1個体が非単調になる確率は

$$ \begin{equation} P_{\text{非単調}} \approx \Phi\!\left( \frac{-1}{\sqrt{4/3}\,\sigma\, 2^{N-1}} \right) \end{equation} $$

です($\Phi$ は標準正規分布の累積分布関数)。歩留まりの観点から $3\sigma$ の余裕をもたせる、つまり $3\sigma_{\text{DNL,MC}} < 1$ LSB を要求すると、必要な抵抗マッチング精度は

$$ \begin{equation} \sigma < \frac{1}{3\sqrt{4/3}\;2^{N-1}} = \frac{\sqrt{3}}{6} \cdot 2^{-(N-1)} \approx 0.2887 \times 2^{-(N-1)} \end{equation} $$

となります。具体的な数値を並べると次の通りです。

分解能 $N$ 必要な $\sigma$ ppm換算 重み付き型の抵抗レンジ 単位抵抗数(R-2R / 重み付き)
8ビット 0.2255% 2255 ppm 128:1 25 / 255
10ビット 0.0564% 564 ppm 512:1 31 / 1023
12ビット 0.0141% 141 ppm 2048:1 37 / 4095
14ビット 0.00352% 35.2 ppm 8192:1 43 / 16383
16ビット 0.00088% 8.8 ppm 32768:1 49 / 65535
18ビット 0.00022% 2.2 ppm 131072:1 55 / 262143

左は3σ単調性条件から決まる要求マッチング精度が8ビットの2255ppmから18ビットの2.2ppmまで指数的に厳しくなる様子、右はσmaxを採用したときのMSB遷移非単調率が分解能によらず設計目標0.135%に収まることの実測

左のグラフは表を対数軸で描いたもので、直線に見えるのは要求精度が $2^{-(N-1)}$ という指数則に従うからです。背景の色帯は目安で、8〜10ビットなら汎用の薄膜抵抗でも届く緑の領域にいますが、14ビットを超えると数十ppm以下、すなわちトリミングやセグメント化なしでは手が出ない赤の領域に入ります。右は「本当にこの $\sigma_{\max}$ を守れば大丈夫か」をモンテカルロで確かめた結果で、各分解能40万個体のうちMSB遷移で非単調になったのは $0.126\%$〜$0.136\%$。設計目標の $\Phi(-3) = 0.135\%$ に分解能によらず一致しており、この1本の設計式が8ビットから18ビットまで同じ精度で使えることが確認できます。

1ビット増えるごとに要求精度が倍に厳しくなります。8ビットなら0.2%で足りるので汎用の薄膜抵抗でも作れますが、16ビットでは8.8 ppm — これは温度が数度変わっただけで破綻しかねない領域で、素のR-2Rでは到底届きません。実際の16ビット以上のDACが、上位ビットのセグメント化、レーザートリミング、あるいはダイナミックエレメントマッチング(素子の役割を高速に入れ替えて誤差を時間平均でならす手法)といった技巧を総動員しているのは、この表が理由です。

正直な比較 — R-2Rは「精度要求」を緩めない

ここで誤解しやすい点を明確にしておきます。「R-2Rは2種類の抵抗しか使わないから精度が出しやすい」とよく言われますが、要求される相対精度そのものは、重み付き抵抗型とまったく同じです。

重み付き抵抗型で同じ計算をしてみましょう。重み $W_n = 2^n$(LSB単位)の抵抗に相対誤差 $\varepsilon_n$ が乗ると、電流は $1/R$ に比例するので重みは $W_n(1 – \varepsilon_n)$ になります。メジャーキャリーのステップは

$$ S = 2^{N-1}(1 – \varepsilon_{N-1}) – \sum_{n=0}^{N-2} 2^{n}(1 – \varepsilon_n) $$

ですから、DNLは $-2^{N-1}\varepsilon_{N-1} + \sum_{n \le N-2} 2^n \varepsilon_n$ となり、その標準偏差は

$$ \sigma \sqrt{4^{N-1} + \sum_{n=0}^{N-2} 4^{n}} = \sigma\sqrt{4^{N-1} + \frac{4^{N-1}-1}{3}} \approx \sqrt{\frac{4}{3}}\,\sigma\,2^{N-1} $$

式 (3) と完全に同じです。後のPython節で数値的にも確認しますが、両者のDNL統計は区別がつきません。

では何が違うのか。達成可能な $\sigma$ が違うのです。R-2Rでは全抵抗が $R$ か $2R$ で、$2R$ は単位抵抗2個の直列(あるいは $R$ を単位抵抗2個の並列)として作れます。同一形状・同一向き・隣接配置の単位抵抗どうしの比は、プロセスの絶対ばらつきではなく局所ランダムミスマッチだけで決まり、面積を増やせば $1/\sqrt{\text{面積}}$ で改善します。ウェハ面内の緩やかな勾配はコモンセントロイド配置で1次までキャンセルできます。結果として 0.01% 級のマッチングが現実的に狙えます。

一方、重み付き抵抗型で 2048:1 の比を作るには、単位抵抗を4095個並べるか(面積・寄生容量が非現実的)、形状の違う抵抗を描くか(比精度が絶対精度と同程度の 0.1〜1% に落ちる)の二択です。加えて、$32.8\ \text{M}\Omega$ のような高抵抗では自己発熱による温度差、リーク電流、寄生容量による整定遅れも無視できなくなります。

つまりR-2Rの本質的な貢献は「要求精度を下げること」ではなく、「同じ要求精度を、単位抵抗の反復という製造可能な形に翻訳したこと」です。65535個を49個に減らした、という先ほどの数字がすべてを物語っています。

スイッチのオン抵抗という現実

もうひとつ実務上の落とし穴に触れておきます。各ビットのスイッチ(MOSトランジスタ)にはオン抵抗 $R_{\text{on}}$ があり、これがシャントの $2R$ に直列に入ります。つまり全ビットに一様な相対誤差 $\varepsilon = R_{\text{on}}/(2R)$ が乗るのと同じです。感度解析からわかるとおり、この誤差はMSBで最も効いて $\text{DNL}_{\text{MC}}$ を悪化させます。

対策は2つあります。ひとつは $R$ を大きくして $R_{\text{on}}/(2R)$ を相対的に小さくすること(ただしノイズと整定時間が悪化します)。もうひとつは、上位ビットほどスイッチのトランジスタ幅を2進で大きくして $R_{\text{on}}$ を小さくし、$R_{\text{on}}/(2R)$ の比を全ビットで揃えることです。後者は電流モードの反転ラダー(スイッチが常に仮想接地に倒れ、各枝の電流が一定に保たれる構成)と組み合わせるのが定番で、スイッチング時の電圧振れが小さいためグリッチも減ります。メジャーキャリーで最大のグリッチが出るのも、$2N$ 本のスイッチのうち最も多くが同時に切り替わる瞬間だからです。

理論はここまでです。以降はPythonで、これまでの主張をひとつずつ数値的に確かめていきます。

Pythonによる実装と検証

ラダーを節点解析で解く

まず、任意の抵抗誤差を入れられるラダーソルバを作ります。理想式を使わず、節点方程式を素直に解くことがポイントです。こうしておけば「誤差を入れたときに本当に何が起きるか」を近似なしで観察できます。出力ノードの行だけ取り出せば、各ビットのゲインとテブナン出力抵抗が同時に得られます。

import numpy as np

def ladder_gains(N, eps_shunt=None, eps_series=None, eps_term=0.0, R=1.0):
    """電圧モードR-2Rラダーを節点解析で解き、各ビットの出力ゲインを返す。
    ノード0がLSB側、ノードN-1がMSB側(=出力)。誤差は公称値に対する相対誤差。"""
    eps_shunt  = np.zeros(N)   if eps_shunt  is None else np.asarray(eps_shunt)
    eps_series = np.zeros(N-1) if eps_series is None else np.asarray(eps_series)
    R_term  = 2*R*(1 + eps_term)        # 末端の終端抵抗 2R
    R_shunt = 2*R*(1 + eps_shunt)       # 各ビットのシャント抵抗 2R
    R_ser   = R  *(1 + eps_series)      # ノード間の直列抵抗 R

    G = np.zeros((N, N))                # 節点コンダクタンス行列
    d = np.arange(N)
    G[d, d] += 1.0 / R_shunt            # シャント2Rの寄与
    G[0, 0] += 1.0 / R_term             # 終端2Rの寄与
    j = np.arange(N-1)
    g = 1.0 / R_ser
    G[j, j] += g; G[j+1, j+1] += g      # 直列Rの寄与
    G[j, j+1] -= g; G[j+1, j] -= g

    Ginv = np.linalg.inv(G)
    gains = Ginv[N-1, :] / R_shunt      # ビットnをVref=1にしたときの出力
    R_out = Ginv[N-1, N-1]              # 出力から見たテブナン抵抗
    return gains, R_out

# 理想ラダーの重みが 2^-(N-n) になっているか確認
for N in [4, 8, 12]:
    g, Rout = ladder_gains(N)
    ideal = 2.0 ** -(N - np.arange(N))
    print(f"N={N:2d}: 重みの最大誤差={np.max(np.abs(g-ideal)):.2e}, 出力抵抗={Rout:.6f}R")

g4, _ = ladder_gains(4)
print("4ビットの重み(LSB→MSB):", g4)
print("Vref=5V, コード1011(=11) の出力:", 5.0*(g4[0]+g4[1]+g4[3]), "V")

出力は次の通りです。

N= 4: 重みの最大誤差=0.00e+00, 出力抵抗=1.000000R
N= 8: 重みの最大誤差=0.00e+00, 出力抵抗=1.000000R
N=12: 重みの最大誤差=0.00e+00, 出力抵抗=1.000000R
4ビットの重み(LSB→MSB): [0.0625 0.125  0.25   0.5   ]
Vref=5V, コード1011(=11) の出力: 3.4375 V

3点が確認できました。第一に、節点解析で求めた各ビットの重みが理論式 $2^{-(N-n)}$ と誤差 $0$(機械精度の範囲で完全一致)です。4ビットなら $[1/16, 1/8, 1/4, 1/2]$ がそのまま出ています。第二に、出力抵抗が $N$ によらずきっかり $1.000000R$ で、再帰構造の証明どおりです。第三に、手計算で折り畳んだ $V_{\text{ref}} = 5$ V・コード1011の結果 $3.4375$ V が再現されました。テブナン折り畳みという「近似っぽく見える手続き」が、実は厳密な回路解と一致することの確認になっています。

次は、この重みを使って伝達特性そのものを描いてみましょう。

理想伝達特性

全コードに対する出力を一気に計算します。ビット行列とゲインベクトルの行列積にすれば、$2^N$ 個のコードを1行で処理できます。

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 code_matrix(N):
    """全コード 0..2^N-1 のビット行列 (2^N, N)。列0がLSB。"""
    c = np.arange(2**N)
    return ((c[:, None] >> np.arange(N)[None, :]) & 1).astype(float)

def transfer(N, **kw):
    g, _ = ladder_gains(N, **kw)
    return code_matrix(N) @ g          # Vref=1 に正規化した出力

N, Vref = 6, 5.0
V = Vref * transfer(N)
fig, ax = plt.subplots(1, 2, figsize=(12, 4.5))
ax[0].step(np.arange(2**N), V, where="post", color="#1f77b4")
ax[0].set_xlabel("入力コード D"); ax[0].set_ylabel("出力電圧 [V]")
ax[0].set_title(f"{N}ビットR-2R DACの伝達特性 (Vref={Vref}V)")
ax[0].grid(alpha=.3)
ax[1].step(np.arange(16), Vref*transfer(4), where="post", color="#d62728")
ax[1].set_xlabel("入力コード D"); ax[1].set_ylabel("出力電圧 [V]")
ax[1].set_title("4ビットの拡大図: 1LSB = Vref/16 = 0.3125V")
ax[1].grid(alpha=.3)
plt.tight_layout(); plt.show()

print("フルスケール出力 =", V[-1], "V  (= Vref*(1-2^-N) =", Vref*(1-2.0**-N), ")")
print("1LSB =", Vref/2**N, "V")
フルスケール出力 = 4.921875 V  (= Vref*(1-2^-N) = 4.921875 )
1LSB = 0.078125 V

6ビットR-2R DACの伝達特性(64段)と4ビットの拡大図(16段)。段差は全域で等間隔で、フルスケール出力は4.921875VとVref=5Vに1LSBだけ届かない

左は6ビット(64段)、右は4ビット(16段)の伝達特性です。どちらも完全に等間隔な階段になっており、コード全域で段差が揃っていることが目で確認できます。数値的にも、フルスケール出力が $V_{\text{ref}} = 5$ V ではなく $4.921875$ V=$V_{\text{ref}}(1 – 2^{-6})$ にとどまっている点が重要です。DACの出力は基準電圧に1 LSBだけ届かないのが正常で、$V_{\text{ref}}$ 自体が出てこないのは全ビット1でも $D/2^N = 63/64 < 1$ だからです。フルスケールを $V_{\text{ref}}$ に合わせたい設計では、後段のアンプでゲイン $2^N/(2^N-1)$ を掛けるか、$V_{\text{ref}}$ 側で調整します。

理想特性が出たので、いよいよ抵抗誤差を入れていきます。まずはMSB1本だけずらす実験です。

MSBの抵抗誤差とINL・DNL

式 (2) の予測 $\text{DNL}_{\text{MC}} \approx -\varepsilon 2^{N-1}$ と、INLが鋸歯状になるという主張を確かめます。12ビットで、MSBのシャント $2R$ だけを $+0.02\%$ ずらします。

def inl_dnl(V):
    """端点直線基準の INL / DNL を LSB 単位で返す。"""
    lsb = (V[-1] - V[0]) / (len(V) - 1)
    inl = (V - V[0]) / lsb - np.arange(len(V))
    dnl = np.diff(V) / lsb - 1.0
    return inl, dnl

N = 12
eps = 2e-4                       # MSBのシャント2Rだけ +0.02% ずれている
e = np.zeros(N); e[N-1] = eps
V = transfer(N, eps_shunt=e)
inl, dnl = inl_dnl(V)
k = 2**(N-1) - 1                 # 011...1 -> 100...0 の遷移

print(f"MSB遷移のDNL = {dnl[k]:+.4f} LSB (理論値 -eps*2^(N-1) = {-eps*2**(N-1):+.4f})")
print(f"それ以外のDNL最大 = {np.max(np.abs(np.delete(dnl,k))):.5f} LSB")
print(f"INLのピーク = {inl[k]:+.4f} / {inl[k+1]:+.4f} LSB (理論値 ±eps*2^(N-2) = ±{eps*2**(N-2):.4f})")

fig, ax = plt.subplots(1, 2, figsize=(12, 4.2))
ax[0].plot(inl, color="#1f77b4"); ax[0].set_title("MSBの2Rが+0.02%ずれたときのINL")
ax[0].set_xlabel("入力コード"); ax[0].set_ylabel("INL [LSB]"); ax[0].grid(alpha=.3)
ax[1].plot(dnl, color="#d62728"); ax[1].set_title("同じくDNL: MSB遷移にだけ現れる")
ax[1].set_xlabel("入力コード"); ax[1].set_ylabel("DNL [LSB]"); ax[1].grid(alpha=.3)
plt.tight_layout(); plt.show()
MSB遷移のDNL = -0.4095 LSB (理論値 -eps*2^(N-1) = -0.4096)
それ以外のDNL最大 = 0.00010 LSB
INLのピーク = +0.2047 / -0.2047 LSB (理論値 ±eps*2^(N-2) = ±0.2048)

理論と数値が4桁一致しました。読み取れることは3つあります。第一に、わずか0.02%の抵抗誤差が0.41 LSBのDNLに化けている — 増幅率は $2^{11} = 2048$ 倍です。第二に、DNLはメジャーキャリーの1点にほぼ完全に集中しており、他のコードでのDNLは $0.0001$ LSB とほぼゼロです。MSBの誤差は「全域を少しずつ歪ませる」のではなく「1点だけを激しく壊す」性質をもちます。第三に、INLはコード2047で $+0.2047$、2048で $-0.2047$ と、中央で符号が反転する鋸歯状になっており、ピーク値はDNLのちょうど半分です。予測どおりの形が出ています。

MSB1本の効き方がわかったので、次はすべての抵抗の感度を比べてみます。

感度係数を数える

$\partial \text{DNL}_{\text{MC}} / \partial \varepsilon_i$ を数値微分で求め、$-1, 1/4, 1/16, \dots$ および $1/2, 1/8, \dots$ という構造と、$\sqrt{4/3}$ を確かめます。

def sensitivity(N):
    """MSB遷移のDNLに対する各抵抗の感度 dDNL/deps を数値微分で求める。"""
    h, k = 1e-6, 2**(N-1) - 1
    def dnl_mc(**kw):
        Vv = transfer(N, **kw); _, d = inl_dnl(Vv); return d[k]
    base = dnl_mc()
    s_sh = []
    for n in range(N):
        e = np.zeros(N); e[n] = h
        s_sh.append((dnl_mc(eps_shunt=e) - base) / h)
    s_se = []
    for j in range(N-1):
        e = np.zeros(N-1); e[j] = h
        s_se.append((dnl_mc(eps_series=e) - base) / h)
    return np.array(s_sh), np.array(s_se)

N = 12
s_sh, s_se = sensitivity(N)
scale = 2.0**(N-1)
print("シャント2Rの感度/2^(N-1) (MSBから4本):", np.round(s_sh[::-1][:4]/scale, 5))
print("直列Rの感度/2^(N-1)   (MSB側から3本):", np.round(s_se[::-1][:3]/scale, 5))
tot = (s_sh**2).sum() + (s_se**2).sum()
print(f"分散寄与: MSBのシャント2R = {100*s_sh[-1]**2/tot:.2f}%")
print(f"分散寄与: MSB直前の直列R  = {100*s_se[-1]**2/tot:.2f}%")
print(f"分散寄与: 上位2本の合計    = {100*(s_sh[-1]**2+s_se[-1]**2)/tot:.2f}%")
print(f"sqrt(全感度の二乗和)/2^(N-1) = {np.sqrt(tot)/scale:.5f}  (理論値 sqrt(4/3)={np.sqrt(4/3):.5f})")

fig, ax = plt.subplots(figsize=(10, 4.5))
x = np.arange(N)
ax.bar(x-0.2, np.abs(s_sh)/scale, 0.4, label="シャント抵抗 2R")
ax.bar(x[:-1]+0.2, np.abs(s_se)/scale, 0.4, label="直列抵抗 R")
ax.set_yscale("log"); ax.set_xlabel("ビット位置 (0=LSB, 11=MSB)")
ax.set_ylabel("|MSB遷移DNLへの感度| / $2^{N-1}$")
ax.set_title("MSB近傍の抵抗だけが効く (1ビット下がるごとに1/4)")
ax.legend(); ax.grid(alpha=.3, which="both")
plt.tight_layout(); plt.show()
シャント2Rの感度/2^(N-1) (MSBから4本): [-0.99976  0.25018  0.06267  0.01579]
直列Rの感度/2^(N-1)   (MSB側から3本): [0.49988 0.12485 0.03109]
分散寄与: MSBのシャント2R = 74.99%
分散寄与: MSB直前の直列R  = 18.75%
分散寄与: 上位2本の合計    = 93.74%
sqrt(全感度の二乗和)/2^(N-1) = 1.15447  (理論値 sqrt(4/3)=1.15470)

理論で予言した構造がそのまま現れました。シャント抵抗の感度は MSBから $-1,\ 1/4,\ 1/16,\ 1/64$ ときれいに $1/4$ ずつ減衰(数値は $-0.99976,\ 0.25018,\ 0.06267,\ 0.01579$)、直列抵抗は $1/2,\ 1/8,\ 1/32$($0.49988,\ 0.12485,\ 0.03109$)です。対数軸の棒グラフでは、右端(MSB側)から左へ向かって一直線に落ちていく様子が見えます。

分散の内訳も予測どおりで、MSBのシャント $2R$ が $74.99\%$(理論値 $\frac{1}{4/3} = 75\%$)、MSB直前の直列 $R$ が $18.75\%$(理論値 $\frac{(1/2)^2}{4/3} = 18.75\%$)、この2本だけで全体の93.74%を占めます。そして全感度の二乗和の平方根は $1.15447$ で、$\sqrt{4/3} = 1.15470$ とほぼ完全に一致しました。等比級数の和が $4/3$ になるという計算が正しかったわけです。設計上の含意は明快で、上位2〜3本の抵抗にリソースを集中投下すればよいということになります。

感度がわかったので、次はすべての抵抗にランダムな誤差を与えて、実際のINL/DNL曲線がどう暴れるかを見てみます。

ランダム誤差でのINL/DNL

多数の個体(製造ばらつきの異なるDAC)をまとめてシミュレートするため、節点方程式をバッチで解く関数を用意します。

def mc_batch(N, sigma, trials, rng, R=1.0):
    """誤差付きラダーをtrials個まとめて解き、全コードの出力を返す (trials, 2^N)。"""
    ESH = rng.normal(0, sigma, (trials, N))
    ESE = rng.normal(0, sigma, (trials, N-1))
    ET  = rng.normal(0, sigma, trials)
    Rsh = 2*R*(1+ESH); Rse = R*(1+ESE); Rt = 2*R*(1+ET)
    G = np.zeros((trials, N, N)); d = np.arange(N); j = np.arange(N-1)
    G[:, d, d] += 1/Rsh; G[:, 0, 0] += 1/Rt
    g = 1/Rse
    G[:, j, j] += g; G[:, j+1, j+1] += g
    G[:, j, j+1] -= g; G[:, j+1, j] -= g
    e = np.zeros((trials, N)); e[:, N-1] = 1.0
    y = np.linalg.solve(np.swapaxes(G, 1, 2), e[..., None])[..., 0]
    A = y / Rsh                              # (trials, N) 各ビットのゲイン
    return A @ code_matrix(N).T

N, sigma = 12, 3e-4
rng = np.random.default_rng(0)
Vs = mc_batch(N, sigma, 12, rng)
fig, ax = plt.subplots(1, 2, figsize=(12, 4.2))
for v in Vs:
    i_, d_ = inl_dnl(v)
    ax[0].plot(i_, lw=.9, alpha=.8); ax[1].plot(d_, lw=.9, alpha=.8)
ax[0].set_title(f"抵抗誤差 σ={sigma*100:.2f}% のINL (12個体)")
ax[0].set_xlabel("入力コード"); ax[0].set_ylabel("INL [LSB]"); ax[0].grid(alpha=.3)
ax[1].axhline(-1, color="k", ls="--", lw=1, label="DNL=-1 (単調性の限界)")
ax[1].set_title("同じ12個体のDNL"); ax[1].set_xlabel("入力コード")
ax[1].set_ylabel("DNL [LSB]"); ax[1].legend(); ax[1].grid(alpha=.3)
plt.tight_layout(); plt.show()

Vs = mc_batch(N, sigma, 2000, np.random.default_rng(1))
lsb = (Vs[:, -1] - Vs[:, 0]) / (2**N - 1)
k = 2**(N-1) - 1
dmc = (Vs[:, k+1] - Vs[:, k]) / lsb - 1.0
print(f"MSB遷移DNLの標準偏差 = {dmc.std():.4f} LSB, 理論値 sqrt(4/3)*σ*2^(N-1) = {np.sqrt(4/3)*sigma*2**(N-1):.4f}")
print(f"MSB遷移DNLの平均     = {dmc.mean():+.4f} LSB")
MSB遷移DNLの標準偏差 = 0.7196 LSB, 理論値 sqrt(4/3)*σ*2^(N-1) = 0.7094
MSB遷移DNLの平均     = -0.0073 LSB

抵抗誤差σ=0.03%を与えた12ビットR-2R 12個体のINLとDNL。INLは全個体がコード2048で最も折れ曲がり、DNLは中央のメジャーキャリーに最大のスパイク、1/4と3/4の位置に約半分のスパイクという自己相似な列を示す

2枚のグラフから、これまでの理論がすべて視覚的に確認できます。左のINLは、個体ごとに異なる形をしていますが、どれもコード2048(中央)で最も大きく折れ曲がっています。右のDNLでは、中央のメジャーキャリーに最大のスパイクが立ち、その左右(コード1024と3072)に約半分の高さのスパイク、さらに $1/8$ 刻みの位置にその半分…という自己相似なスパイク列が見えます。これは前節で予測した $\sigma_{\text{DNL}}(m) = \sqrt{4/3}\,\sigma 2^m$ の直接的な現れで、「キャリーが深いほどDNLが大きい」という関係そのものです。個体によっては破線(DNL $= -1$)を割り込んでおり、その個体は非単調です。

統計量も理論と整合します。$\sigma = 0.03\%$ のとき $\text{DNL}_{\text{MC}}$ の標準偏差は $0.72$ LSB で、式 (3) の予測 $0.71$ LSB とよく一致しました。平均が $-0.007$ とほぼゼロなのも重要で、誤差は系統的な偏りではなく純粋なばらつきとして効くことを示しています。つまり「平均的には正しいが、個体によっては壊れている」というのが製造ばらつきの実像です。

左はキャリーの深さmとその遷移のDNL標準偏差の関係で、実測が理論式sqrt(4/3)σ2^mと対数軸で一直線に一致する図。右はMSB遷移DNLの2000個体ヒストグラムが平均ほぼ0・標準偏差0.7196LSBの正規分布に従う様子

左のグラフは、遷移 $2^m – 1 \to 2^m$ ごとにDNLの標準偏差を測り、理論式 $\sqrt{4/3}\,\sigma\,2^m$ と重ねたものです。$m = 1$ から $11$ まで、実測(青)と理論(赤破線)が対数軸上で一直線に重なり、1段浅いキャリーではDNLのばらつきがきっちり半分になることが確認できます。右はメジャーキャリーのDNLを2000個体分ヒストグラムにしたもので、平均は $-0.0073$ LSB とほぼゼロ、形も正規分布によく乗ります。黒破線(DNL $= -1$)の左側にはみ出した部分が非単調な個体で、この面積が次に求める「壊れる確率」そのものです。

最後に、その「壊れている確率」を $\sigma$ の関数として求めます。

非単調になる確率

式 (4) の正規近似と、モンテカルロによる実測を比べます。8/10/12ビットの3水準で、$\sigma$ を $0.01\%$ から $0.5\%$ まで振ります。

from math import erf, sqrt
def Phi(z): return 0.5*(1+erf(z/sqrt(2)))

sigmas = np.array([1e-4,2e-4,3e-4,5e-4,7e-4,1e-3,1.5e-3,2e-3,3e-3,5e-3])
fig, ax = plt.subplots(figsize=(9, 5.2))
for N, col in [(8,"#1f77b4"), (10,"#2ca02c"), (12,"#d62728")]:
    p_mc = []
    for sg in sigmas:
        Vs = mc_batch(N, sg, 2000, np.random.default_rng(42))
        p_mc.append(np.mean(np.any(np.diff(Vs, axis=1) <= 0, axis=1)))
    p_th = [Phi(-1.0/(sqrt(4/3)*sg*2**(N-1))) for sg in sigmas]
    ax.semilogx(sigmas*100, p_mc, "o-", color=col, label=f"{N}ビット (モンテカルロ)")
    ax.semilogx(sigmas*100, p_th, "--", color=col, alpha=.6, label=f"{N}ビット (正規近似)")
    print(f"N={N}: " + "  ".join(f"σ={s*100:.2f}%→{p:.3f}" for s, p in zip(sigmas, p_mc))[:200])
ax.set_xlabel("抵抗の相対誤差 σ [%]"); ax.set_ylabel("非単調になる確率")
ax.set_title("単調性が崩れる確率は分解能とともに急激に厳しくなる")
ax.legend(fontsize=9); ax.grid(alpha=.3, which="both")
plt.tight_layout(); plt.show()

print()
print("3σ単調性条件 σ_max = 1/(3*sqrt(4/3)*2^(N-1))")
for N in [8, 10, 12, 14, 16, 18]:
    sm = 1/(3*sqrt(4/3)*2**(N-1))
    print(f"  N={N:2d}: σ_max={sm*100:.6f}%  ({sm*1e6:7.2f} ppm)   "
          f"重み付き型の抵抗レンジ={2**(N-1):6d}:1  単位抵抗 R-2R:{3*N+1} / 重み付き:{2**N-1}")
N=8: σ=0.01%→0.000  σ=0.02%→0.000  σ=0.03%→0.000  σ=0.05%→0.000  σ=0.07%→0.000  σ=0.10%→0.000  σ=0.15%→0.000  σ=0.20%→0.001  σ=0.30%→0.013  σ=0.50%→0.088
N=10: σ=0.01%→0.000  σ=0.02%→0.000  σ=0.03%→0.000  σ=0.05%→0.001  σ=0.07%→0.009  σ=0.10%→0.058  σ=0.15%→0.148  σ=0.20%→0.253  σ=0.30%→0.395  σ=0.50%→0.591
N=12: σ=0.01%→0.000  σ=0.02%→0.018  σ=0.03%→0.084  σ=0.05%→0.235  σ=0.07%→0.369  σ=0.10%→0.513  σ=0.15%→0.655  σ=0.20%→0.735  σ=0.30%→0.814  σ=0.50%→0.889

3σ単調性条件 σ_max = 1/(3*sqrt(4/3)*2^(N-1))
  N= 8: σ_max=0.225527%  (2255.27 ppm)   重み付き型の抵抗レンジ=   128:1  単位抵抗 R-2R:25 / 重み付き:255
  N=10: σ_max=0.056382%  ( 563.82 ppm)   重み付き型の抵抗レンジ=   512:1  単位抵抗 R-2R:31 / 重み付き:1023
  N=12: σ_max=0.014095%  ( 140.95 ppm)   重み付き型の抵抗レンジ=  2048:1  単位抵抗 R-2R:37 / 重み付き:4095
  N=14: σ_max=0.003524%  (  35.24 ppm)   重み付き型の抵抗レンジ=  8192:1  単位抵抗 R-2R:43 / 重み付き:16383
  N=16: σ_max=0.000881%  (   8.81 ppm)   重み付き型の抵抗レンジ= 32768:1  単位抵抗 R-2R:49 / 重み付き:65535
  N=18: σ_max=0.000220%  (   2.20 ppm)   重み付き型の抵抗レンジ=131072:1  単位抵抗 R-2R:55 / 重み付き:262143

8/10/12ビットR-2Rが非単調になる確率を抵抗の相対誤差σに対して両対数で描いたグラフ。モンテカルロ実測と正規近似の破線を比較し、3本の曲線がσ軸上でほぼ4倍ずつ左にシフトしている

グラフと数値から、設計に直結する3つの結論が得られます。

第一に、3本の曲線が $\sigma$ 軸上でほぼ4倍ずつ左にシフトしています。8ビットで $0.3\%$ のときの非単調率 $1.3\%$ に相当する状態は、10ビットでは $0.07\%$ 前後、12ビットでは $0.02\%$ 前後で起こります。分解能が2ビット上がるごとに、要求される抵抗精度は4倍厳しくなる — 式 (5) の $2^{-(N-1)}$ 依存そのものです。

第二に、正規近似(破線)は確率が小さい領域でモンテカルロとよく一致します。12ビット・$\sigma = 0.02\%$ で実測 $0.018$ に対し予測 $0.017$、10ビット・$\sigma = 0.1\%$ で実測 $0.058$ に対し予測 $0.045$、8ビット・$\sigma = 0.5\%$ で実測 $0.088$ に対し予測 $0.088$ です。歩留まりを議論したいのはまさにこの低確率領域なので、簡便な式 (4) が設計の見積もりに十分使えることを意味します。

第三に、$\sigma$ が大きい領域では実測が予測を上回ります。これは式 (4) がメジャーキャリーだけを見ているのに対し、実際には $1/4$ や $1/8$ の位置にある下位のキャリーでも非単調が起こり始めるからです。正規近似は $\sigma \to \infty$ で $0.5$ に飽和しますが、実測は $0.8$ を超えて上昇し続けます。裏を返せば、「どこか1か所でも非単調ならNG」という厳しい判定では、メジャーキャリーだけの評価は楽観的すぎるということです。

そして表からは、12ビットで $0.014\%$、16ビットで $8.8$ ppm という要求が読み取れます。同じ表の右端に注目してください。16ビットのR-2Rが49個の単位抵抗で済むのに対し、重み付き抵抗型は65535個必要です。要求精度は同じ、しかし作れるかどうかは天と地ほど違う — これがR-2Rが選ばれ続ける理由のすべてです。

まとめ

本記事では、R-2Rラダー型DACの原理を再帰構造から導出し、抵抗誤差が静特性に与える影響を定量的に評価しました。

  • 再帰構造: 終端抵抗を $2R$ にすることで、どのノードから左を見ても等価抵抗が $R$ になります。「$R$ に直列 $R$ を足して $2R$、シャント $2R$ と並列にして $R$ に戻る」という閉じたサイクルが、$R$ と $2R$ の2値だけで正確な2進重みを生む正体です
  • テブナン折り畳み: 等しい $2R$ どうしが出会うたびに単純平均 $T_k = (T_{k-1} + V_{\text{ref}} b_k)/2$ が成立し、これを解くと $n$ 段目のビットの寄与が $2^{-(N-n)}$ になります。出力抵抗はコードによらず常に $R$ です
  • 製造上の利点: 要求される相対精度は重み付き抵抗型と同一ですが、必要な単位抵抗の個数が $2^N-1$ 個から $3N+1$ 個に激減します。16ビットで65535個対49個。R-2Rの本質は精度要求の緩和ではなく、同じ要求を製造可能な形に翻訳したことです
  • DNL最悪点: メジャーキャリー $011\dots1 \to 100\dots0$ では、$2^{N-1}$ と $2^{N-1}-1$ という大きな量の差から1 LSBを作るため、相対誤差 $\varepsilon$ が $\text{DNL} \approx -\varepsilon 2^{N-1}$ へと $2^{N-1}$ 倍に増幅されます。INLは中央に1回だけ不連続をもつ鋸歯状になります
  • 感度の階層: MSBのシャント $2R$ の感度が $-1$、MSB直前の直列 $R$ が $+1/2$、そこから1ビット下るごとに $1/4$ ずつ減衰します。分散寄与はこの上位2本で93.75%。下位ビットの抵抗はほとんど効きません
  • 単調性条件: 全抵抗に独立な誤差 $\sigma$ があるとき $\sigma_{\text{DNL,MC}} = \sqrt{4/3}\,\sigma\,2^{N-1}$ となり($4/3$ は公比 $1/16$ の等比級数の和)、$3\sigma$ 基準の要求は $\sigma < 0.2887 \times 2^{-(N-1)}$。12ビットで $0.014\%$、16ビットで $8.8$ ppm です

R-2Rラダーは、「同じ部品を繰り返して指数的な重みを作る」という発想の教科書的な成功例です。この考え方は、容量ラダー(逐次比較型ADCの内部DACで使われるC-2Rアレイ)、抵抗ストリング分圧、さらにはデジタルフィルタの多段構成にも共通して現れます。一方で、本記事で見たとおり素のR-2Rは16ビット以上では精度の壁にぶつかるため、実際の高分解能DACは上位ビットのセグメント化・トリミング・ダイナミックエレメントマッチング、あるいは原理の異なるデルタシグマ変調へと進んでいきます。

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