Skip to content

analog M4c: the SAR ADC bootstrapped sampling switch -- M4b's solver reused, square law against ngspice LEVEL=1 (Closes #10753) - #10779

Merged
gHashTag merged 2 commits into
masterfrom
claude/analog-m4c-switch-10753
Oct 19, 2026
Merged

gHashTag merged 2 commits into
masterfrom
claude/analog-m4c-switch-10753

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

What this does

M4c of #10524 (epic #10486). New spec specs/analog/sar_switch.t27 (module AnalogSarSwitch, sealed) with nine ngspice decks specs/analog/decks/sar_sw_*.cir (data).

It emulates the tracking_switch of the golden SAR deck (uberWAVE wp2-parser/golden/top.spice, GPL-2.0, read at run time, not vendored): ten MOS, the inverter, the 20 um x 20 um cap_cmim boost capacitor XC3 and the 4 fF node capacitors. The device level is the SQUARE LAW (SPICE MOSFET LEVEL=1), not PSP103 -- M3a's table as M4b reads it, 3125 devices in parallel for dt = 250 ps. Backward Euler on eight nodes (seven and one dummy, because M4b's solver is 8 x 8), M4b's pivoted Gauss in unsigned sign-magnitude words reused by use.

  • Vout is loaded with the deck's 4 fF plus the M4a DAC's top plate: M4a gives only counts, so it is derived here from M4a's own UNITS, SIDE, BRIDGE_UNITS (1023/32 units of the 9 um x 9 um cap_cmim) = 3930.2 fF, 3934.2 fF in all.
  • Capacitor values from the IHP PDK at 21133f21: cornerCAP.lib:22 (cap_carea = 1.5E-15), capacitors_mod.lib:58,72 (CJSW = 40E-18); C = CJ l w + 2 CJSW (l + w), checked in ngspice: 603.2 fF (20 x 20), 122.94 fF (9 x 9).
  • New for M4c: a floating capacitor (sw_stamp_cfloat), nodes below ground and above the supply (the word is V * 2^24 + 0.5 V), and a damped Newton that stops when settled: at the clock edges a node moves by a volt in one step and plain Newton cycles between table cells. Most steps need 0 to 3 iterations (114 of 416 need none), the worst step needs 120 (K = 128).
  • M4b is split, not copied (sc_stamp_chan, sc_clear, sc_stamp_cap, sc_apply_lim, sc_stamp_chan_f, sc_stamp_caps_f, sc_assemble_f, sc_resid_f); the analytic law mode no longer clamps to the table range. M4b's 20 tests and folds are unchanged; its seal is renewed.

The four measurements against ngspice LEVEL=1 (same grid), emulator minus ngspice

Vin OD = V(net3) - Vin TE = V(Vout) - Vin INJ (344 - 328) droop (416 - 344)
0.2 V ng 1.457888 V, -252.8 uV ng -33.9 nV, -1.93 uV ng +5.8 nV, +0.17 uV 0 (ng 6e-17)
0.75 V ng 1.447160 V, -252.6 uV ng -39.2 nV, -1.93 uV ng +6.6 nV, +0.17 uV 0
1.3 V ng 1.436432 V, -252.6 uV ng -45.3 nV, -1.92 uV ng +7.5 nV, +0.17 uV 0
sine 0 deg ng 1.447151 V, -248.9 uV ng -1266.6 uV, -36.9 uV ng +239.6 uV, -0.36 uV 0
sine 90 deg ng 1.435456 V, -250.1 uV ng -2.87 uV, -0.23 uV ng +0.468 uV, +0.009 uV 0
sine 180 deg ng 1.447169 V, -257.1 uV ng +1268.0 uV, +36.8 uV ng -239.6 uV, +0.31 uV 0
sine 270 deg ng 1.458863 V, -256.3 uV ng +2.67 uV, +0.19 uV ng -0.447 uV, -0.03 uV 0
named bound SW_B_OD_V = 0.4 mV SW_B_TE_ABS_V 3 uV + SW_B_TE_REL 5 % of ng SW_B_INJ_V = 1 uV SW_B_DROOP_V = 1 nV

Every row is asserted against its bound (and the headline deviations from both sides). OD 0.2571 mV worst (a factor 1.6 inside), TE 36.9 uV of 66.3 uV at the sine's zero crossing (the table's on-resistance is 2.85 % high), 1.93 uV at DC (the integer words' settling floor).

The injection step is not the charge injection of a real switch: MOSFET LEVEL=1 with no TOX/CGSO/CGDO has no gate capacitance, so the step is Vout still following the input until the gate collapses (step 333). The droop is zero for the same kind of reason (no leak in the square law).

The three errors, kept apart (DC 0.75 V / sine zero crossing)

  • arithmetic (fixed point vs the real run of the same table): 186.8 / 164.8 units against the same scheme; 237.2 / 247.4 units (14.1 / 14.7 uV, bound SW_B_ARITH_U = 260) against the converged real run. At the measurements: 97 nV / 4.1 uV (OD), 1.91 / 0.33 uV (TE), 0.17 / 0.015 uV (INJ).
  • table (real table vs analytic law): 653576 units = 39.0 mV (bound SW_B_TABLE_U = 660000), at step 35 on net5, the soft knee of XM8 (threshold 0.35 V inside the 62.5 mV cell). At the measurements: 0.253 mV in OD, 36.6 uV in TE (sine).
  • model (analytic law vs ngspice, same W, L, KP, VTO, capacitors, grid): 0.50 nV / 0.47 nV at 56 recorded node values per deck (bound SW_B_LAW_V = 1 nV); under 2 nV in OD, TE, INJ.
  • discretization (ngspice at 250 ps vs 50 ps, decks sar_sw_sn0, sar_sw_fine): OD 2.96 mV, TE 3.4 uV (0.27 %), INJ 11.2 uV (4.5 %). Shared with ngspice by construction at 250 ps, larger than the table's 0.25 mV in OD.

Negative controls (each a test that passes by seeing the failure)

  • Boost capacitor removed: overdrive 0.437 V, 1.01 V from the real circuit's against the 0.4 mV bound (ngspice's own no-boost deck sar_sw_nocb: 0.435 V, the emulator is within 2.85 mV of it).
  • K too small: K = 119 leaves step 333 of the sine trough unsettled; K = 4 leaves 4 steps with up to 8.3e6 units owed.
  • Wrong threshold table (Vth 0.30): overdrive 4.2 mV off. XM9 removed: sine "droop" 4.1 mV against 1 nV. XM6 at half width: tracking error 1.40 mV off against 66 uV.
  • A broken constant makes t27c seal --save refuse (exit 1, no seal written): SW_CB = 0 fails 10 of 14 tests, SW_STOP loosened to 6400 fails 6.

Gates run

  • t27c test-report specs/analog/sar_switch.t27: 14 pass, 0 FAIL, vacuous passes 0 of 14 (about 10 s). t27b test: 14 pass (native). t27c test-report specs/analog/sar_comparator.t27: 20 pass, 0 vacuous (unchanged asserts).
  • t27c seal --save then --verify: all MATCH, for both seals; no home path or blocked verdict in either.
  • python3 -I tools/dupe_scan.py: ok (682 of 13564 bodies in 195 groups, as before).
  • The words have headroom: widest word 7.2e16 = 2^56 (u64 limit 2^63).

What this does NOT claim

  • Not PSP103: the devices are the square law; no PDK corner, no gate charge, no leakage, so the injection step and the droop are not those of the real switch.
  • Not the continuous circuit: the 250 ps grid moves the overdrive by 3.0 mV and the injection step by 4.5 %.
  • One 104 ns window of the 500 ns period (one pulse, 20 ns of the 416 ns hold), the sine sampled at four phases each from a cold start; the load is the DAC's top plate as one linear capacitor; the held "slow ramp" of the brief is three DC levels.
  • n_clks has a 1 fF the deck does not have (a node with no capacitor and two saturated devices has no Newton slope); the 55 mOhm of cap_cmim is left out.
  • No board: no bitstream, no LUT/DSP/BRAM, no UART line; the iteration count is a model count (up to 120 per step). No power claim and no speed claim against SPICE.

Closes #10753

🤖 Generated with Claude Code

…reused, square law against ngspice LEVEL=1 (Closes #10753)

specs/analog/sar_switch.t27 (AnalogSarSwitch): the tracking_switch of the golden SAR deck (ten MOS, the
inverter, the 603.2 fF boost capacitor XC3 and the 4 fF node capacitors; Vout loaded with 4 fF plus the M4a
DAC's top plate, 3930.2 fF from M4a's own counts and the IHP cap_cmim density). THE DEVICE LEVEL IS THE
SQUARE LAW (MOSFET LEVEL=1), NOT PSP103: devices are M3a's table as M4b reads it, 3125 in parallel for
dt = 250 ps. Backward Euler on eight nodes (seven and a dummy) by M4b's pivoted Gauss in unsigned words,
with a damped Newton that stops when every node is settled (the clock edges need up to 120 iterations).

Measured against ngspice LEVEL=1 on the same grid, each with a named bound: gate overdrive within 0.26 mV
(bound 0.4 mV) at Vin 0.2, 0.75, 1.3 V and four sine phases; tracking error within 36.9 uV of a 1.27 mV lag
(bound 3 uV + 5 %); injection step within 0.36 uV (1 uV); droop 0 (1 nV). The three errors apart: arithmetic
247 units, table 39 mV (the knee), model 0.5 nV; discretization from a 50 ps ngspice deck. Negative controls:
no boost capacitor, K too small, Vth 0.30, XM9 removed, XM6 halved; a broken constant makes seal --save refuse.

M4b (specs/analog/sar_comparator.t27) is split, not copied: sc_stamp_chan, sc_clear, sc_stamp_cap,
sc_apply_lim, sc_stamp_chan_f, sc_stamp_caps_f, sc_assemble_f, sc_resid_f; the law mode no longer clamps to
the table range. Its 20 tests and folds are unchanged; its seal is renewed. Nine decks under
specs/analog/decks/ (data). dupe_scan ok.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 02:35:02 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 43
PRs with All Checks Green 7
READY 2
FAILING 43
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 43 + 0 + 0 = 45, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=fad12492937a != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag enabled auto-merge (squash) October 19, 2026 02:37
… and sar_switch (Closes #10753)

M3b changed mos_table.t27 (two tables) and renewed sar_comparator's seal for its closure; this branch
changed sar_comparator.t27 itself. The only conflict was that seal: both seals are made again on the
merged tree. mos_table 14/14, sar_comparator 20/20, sar_switch 14/14, mos_psp103 11/11,
mos_psp103_data 4/4, 0 vacuous each; seal --verify all MATCH; every closure hash current; dupe_scan ok.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 03:00:15 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 44
PRs with All Checks Green 6
READY 2
FAILING 44
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 44 + 0 + 0 = 46, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=fad12492937a != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit 1ae0c4a into master Oct 19, 2026
32 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

analog M4c: the SAR ADC bootstrapped sampling switch -- M4b solver reused, square law first, against ngspice LEVEL=1

2 participants