A DAC: the R-2R ladder and its linearity
Build a 6-bit R-2R DAC from SKY130 poly resistors, measure DNL and INL from its transfer curve, and see how resistor mismatch, resistor area, layout and switches decide whether it stays monotonic.
- Lesson
- E8.3
- Time
- 30 min
- Runs on
- ngspice
- Check
- 5 questions
A 10-bit DAC passed every simulation, yet on some chips the output went down when the code went from 511 to 512. At that code every lower bit switches off and the top bit switches on, so the top bit's weight must equal all the others plus one step. Resistor mismatch broke that balance, which a schematic simulated without mismatch models cannot show.
- die 3
- die 1
- Code 511die 3 = 903.3 mV · die 1 = 897.3 mV
Code 511: bits 0 to 8 on, bit 9 off.
- Code 512die 3 = 895 mV · die 1 = 900.9 mV
Code 512: die 3 falls by 4.70 LSB, a DNL of −5.70 LSB. Die 1 jumps by 2.04 LSB and skips a level. Neither ladder has a design error.
Read the plot as a table
| Code | die 3 | die 1 |
|---|---|---|
| 504 | 891 mV | 885.1 mV |
| 506 | 894.5 mV | 888.6 mV |
| 508 | 898 mV | 892.1 mV |
| 510 | 901.5 mV | 895.6 mV |
| 511 | 903.3 mV | 897.3 mV |
| 512 | 895 mV | 900.9 mV |
| 514 | 898.5 mV | 904.4 mV |
| 516 | 902 mV | 907.9 mV |
| 518 | 905.5 mV | 911.4 mV |
Measured on ngspice 42: 20 dies, seed 5. Nine of the 20 step down at 511 → 512.
A DAC is only as linear as its resistors match, and the worst code is the one where most of them change state.
Two resistor values make a binary divider
A DAC (digital-to-analog converter) turns an N-bit code into a voltage. The R-2R ladder does it with one resistor value, R, used alone or as 2R. Each bit drives a 2R leg from a source that is either Vref or 0 V. A chain of R joins the legs, and the output is the top tap.
- Every tap sees R to its left
At tap n0 the termination 2R and the b0 leg 2R are in parallel: R. Add the series R and tap n1 sees 2R to its left, in parallel with its own 2R leg: R again. The same holds at every tap.
- Each bit halves on its way
Switch one source at a time. b3 drives its 2R leg against the 2R the rest of the ladder presents at the output tap, so it adds Vref/2. The ladder makes each lower bit's share half of the one above: b2 adds Vref/4, b1 Vref/8 and b0 Vref/16.
- The major carry: 0111 to 1000
Three legs fall to 0 V and the MSB leg rises to Vref. The output moves by one LSB only if the MSB's weight equals the other three weights plus one LSB, and that depends on every resistor.
MSB on · b2 off
Read the circuit as text
- 2R resistor (termination): pin 1 →
n0, pin 2 →0 - 2R resistor: pin 1 →
n0, pin 2 →n1 - 2R resistor: pin 1 →
n2, pin 2 →n3 - 2R resistor: pin 1 →
n4, pin 2 →n5 - 2R resistor: pin 1 →
n3, pin 2 →n6 - R resistor: pin 1 →
n2, pin 2 →n0 - R resistor: pin 1 →
n4, pin 2 →n2 - R resistor: pin 1 →
n3, pin 2 →n4 - b0 voltage source (LSB): + →
n1, − →0 - b1 voltage source: + →
n3, − →0 - b2 voltage source: + →
n5, − →0 - b3 voltage source (MSB): + →
n6, − →0 - out port: terminal →
n3
The lab is the 6-bit version. Every R is one SKY130 poly unit; every 2R is two units in series.
So the output is Vout = Vref·code/2N, and one LSB (least significant bit) is the step Vref/2N. The output resistance is R at every code, which matters for E8.4's buffer.
- v(out)
- end-point line
- Code 63v(out) = 1.772 V · end-point line = 1.772 V
Code 63: one LSB below Vref. The 64 points sit within 0.044 LSB of the line, invisible at this scale.
Read the plot as a table
| Code | v(out) | end-point line |
|---|---|---|
| 0 | 0 V | 0 V |
| 10 | 280.3 mV | 281.2 mV |
| 20 | 563.5 mV | 562.4 mV |
| 30 | 843.8 mV | 843.6 mV |
| 40 | 1.124 V | 1.125 V |
| 50 | 1.407 V | 1.406 V |
| 60 | 1.687 V | 1.687 V |
| 63 | 1.772 V | 1.772 V |
The lab netlist on ngspice 42 (seed 5).
DNL and INL
Two numbers describe how far a real ladder strays, both in LSB and both measured from the end-point line through the outputs at code 0 and the top code.
DNL, differential nonlinearity
Each step minus one LSB. DNL = 0 is a perfect step. DNL below −1 means the output went down: the DAC is non-monotonic. DNL above +1 means a level was skipped.
INL, integral nonlinearity
How far each output sits from the end-point line. It is the running sum of the DNL.
- DNL
- INL
- Code 26DNL = 0.07123 · INL = 0.8799
INL peaks at +0.88 LSB at code 26.
- Code 32DNL = -1.663 · INL = -0.8317
The major carry: DNL = −1.66 LSB, so the output falls by 0.66 LSB from code 31 to 32. INL drops from one side of the line to the other.
Read the plot as a table
| Code | DNL | INL |
|---|---|---|
| 0 | 0 | 0 |
| 10 | 0.07123 | 0.4455 |
| 20 | -0.07745 | 0.4002 |
| 26 | 0.07123 | 0.8799 |
| 30 | 0.07123 | 0.8457 |
| 32 | -1.663 | -0.8317 |
| 40 | 0.3792 | -0.4435 |
| 50 | 0.07123 | -0.3401 |
| 60 | -0.07745 | -0.04326 |
Measured on ngspice 42. The INL is antisymmetric: complementary codes add up to the full scale.
The worst DNL sits at the major carry, code 31 to 32, because there the most resistors change state. The MSB leg alone must match the five lower legs together, so every weight error in the ladder lands on that one step.
Matching costs area
The SKY130 model gives each poly resistor its own random error when the mismatch switch is on. Two terms add: the body's sheet resistance varies by 2.06 % divided by √(W·L) in µm, and the contact head by 6.3 % divided by √W. A larger unit averages more material, so it matches better: this is Pelgrom's law from E7.4 Mismatch and Pelgrom's law, for resistors.
- 0.35 × 2 µm units
- 1.41 × 10 µm units
Read the plot as a table
| Die | 0.35 × 2 µm units | 1.41 × 10 µm units |
|---|---|---|
| 5 | 0.6713 | -0.1033 |
| 10 | 0.2437 | 0.04861 |
| 15 | 0.506 | 0.1296 |
| 20 | -1.525 | 0.1415 |
Measured on ngspice 42, seed 5. Lines only join neighbouring dies.
| Unit resistor | Area | σ of the carry DNL | Worst |DNL|, any code | Non-monotonic dies |
|---|---|---|---|---|
| 0.35 × 2 µm | 0.7 µm² | 0.99 LSB | 1.82 LSB | 5 of 20 |
| 1.41 × 10 µm | 14.1 µm² | 0.17 LSB | 0.40 LSB | 0 of 20 |
From the run above. Twenty times the area gives about a sixth of the spread.
Pelgrom's √area predicts a factor of 4.5. The head term, a larger share of a short resistor, raises it to about 4.7; twenty dies per size leave each σ uncertain by about 16 %. The same units at 10 bits give a carry σ of 3.3 LSB, as the hook showed: each extra bit doubles the weight the MSB must match.
What spoils the ratio without any mismatch
With mismatch off, the lab ladder is exact: every R is one unit and every 2R is two, so even the contact heads scale by two. Two common shortcuts break that ratio without any mismatch at all.
Each 2R as two units
XA5 n5 m5 0 sky130_fd_pr__res_high_po w={wu} l={lu}
XB5 m5 b5 0 sky130_fd_pr__res_high_po w={wu} l={lu}
dnl_a = 5.329071e-14: exact.
Each 2R as one long resistor
XL5 n5 b5 0 sky130_fd_pr__res_high_po w={wu} l={2*lu}
carry_p = 1.063757e+00: one contact head and one end correction instead of two, so each 2R comes out short. Code 32 skips a level.
Both from the run below, mismatch off.
Real switches add their on-resistance to each 2R leg. The figure drives the legs from CMOS inverters: a PMOS to Vref for a 1, an NMOS to ground for a 0.
- one-piece 2R
- switches 4/8 µm
- switches 32/64 µm
- Code 32one-piece 2R = 0.5319 · switches 4/8 µm = -0.971 · switches 32/64 µm = -0.1219
At code 32: INL +0.53 LSB for the one-piece 2R, −0.97 LSB for 4/8 µm switches and −0.12 LSB for 32/64 µm switches. Eight times the width, about an eighth of the error.
Read the plot as a table
| Code | one-piece 2R | switches 4/8 µm | switches 32/64 µm |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 10 | -0.2749 | -0.05217 | -0.005956 |
| 20 | -0.1885 | -0.3067 | -0.03811 |
| 30 | -0.4634 | 0.01554 | 627.2 µ |
| 32 | 0.5319 | -0.971 | -0.1219 |
| 40 | 0.3673 | -0.8578 | -0.1083 |
| 50 | 0.3867 | -0.7372 | -0.09325 |
| 60 | 0.1788 | -0.2912 | -0.03671 |
Measured on ngspice 42; widths are NMOS/PMOS, L = 0.15 µm. The worst DNL is at the carry: +1.06, −1.08 and −0.13 LSB.
So designers size the switches until Ron is negligible against 2R.
Current steering, the fast alternative
Fast DACs steer currents instead of dividing a voltage: equal unit current sources switch between the output and a dummy line. The top bits are thermometer coded, so a code of 3 turns on three identical units, while the lower bits stay binary. This split is called segmentation.
- R-2R
One resistor value and a voltage output of resistance R, which needs a buffer.
- Segmented current steering
At the major carry a thermometer DAC only adds one more equal unit, so its DNL stays small. Fewer sources switch at once, so the glitch at the carry shrinks too.
Read the diagram as text
- Code, 6 bits
- R-2R ladder: 2R legs switched to V_ref or 0 V
- Thermometer decoder: top 2 bits → 3 unit currents
- Binary cells: lower 4 bits: I, 2I, 4I, 8I
- Buffer: drives the load (E8.4)
- Summing node: currents into a load resistor
- Code, 6 bits → R-2R ladder: all bits
- Code, 6 bits → Thermometer decoder: bits 5-4
- Code, 6 bits → Binary cells: bits 3-0
- R-2R ladder → Buffer: voltage
- Thermometer decoder → Summing node: current
- Binary cells → Summing node: current
What the digital side sees
A mixed-signal bench often models a DAC as vout = vref*code/64. That model has no DNL, so a non-monotonic step never reaches the digital checks. A better model adds the measured INL of each code, taken from a run like the lab.
// A 6-bit DAC model with the measured error of each code, in LSB, from this lesson's run.
module dac6_model #(
parameter real VREF = 1.8,
// INL of each code against the end-point line (64 entries, filled from the run)
parameter real INL [64] = '{default: 0.0}
) (
input logic [5:0] code,
output real vout
);
localparam real LSB = VREF / 64.0;
always_comb vout = LSB * (code + INL[code]); // the ideal line, then the code's own error
endmoduleAsked in interviews
How does an R-2R DAC work?
Each bit switches a 2R leg between the reference and ground. Every tap of the ladder looks like R, so each bit's contribution halves on its way to the output: Vout = Vref·code/2N. It needs only one resistor value.
Define DNL and INL.
DNL is each step minus one LSB; below −1 LSB the DAC is non-monotonic. INL is each output's distance from the end-point (or best-fit) line, the running sum of the DNL. Both are in LSB.
Why segment a current-steering DAC?
Thermometer coding the top bits turns the major carry into one more unit source, so the DNL and the glitch there stay small. The lower bits stay binary to keep the number of sources down.
Try it
Run the netlist. lsb_v is one step of this die, dnl_32 its major-carry DNL, and the MIN and MAX lines give the worst DNL and INL and the codes where they occur.
Predict, then run. Change the seed: the numbers move, but stay near ±0.05 LSB. Set wu=0.35 lu=2 and the errors grow about sixfold. Raise the size to wu=5.73 lu=20 and they shrink. Last, make every 2R one resistor with l={2*lu} and watch code 32.
Run the netlist to draw its plots here.
lsb_v = 2.811978e-02 out_40 = 1.123559e+00 dnl_32 = -1.708603e-02Check yourself
Remember
- An R-2R ladder divides Vref into binary weights with one resistor value: Vout = Vref·code/2N, with output resistance R.
- DNL is each step minus one LSB (below −1: non-monotonic); INL is the distance from the end-point line, the running sum of the DNL.
- The worst DNL sits at the major carry, where the MSB leg must match all the lower legs together; each extra bit doubles that demand.
- Resistor matching improves with area: 20 times the area cut the carry-DNL spread from 0.99 to 0.17 LSB here.
- Build 2R from two units and size the switches until Ron is negligible; a one-piece 2R or narrow switches break the ratio with no mismatch at all.