Repository navigation
analog M4b-psp: the StrongARM comparator on PSP103 tables at 50 C against ngspice -- sign, times, flip point, imbalance sensitivity (Closes #10856) - #10884
Merged
Conversation
…inst ngspice -- sign, times, flip point, imbalance sensitivity (Closes #10856) The golden comparator, M4b's multi-node Newton solver reused with the NMOS and PMOS tables as two arguments (sc_*_np; the old names delegate, every old pin unchanged), on the tt 50 C PSP103 tables (mos_psp103_50c_data.t27, deck psp103_tab_tt50.cir). Judged against ngspice-47 + PSP103 with the golden dynamic_comparator (charge swamped by 1e6, bulk tied or as in the deck) and with the real charge, bare and as dynamic_comparator_top. 13 tests, 0 vacuous. The isolated latch has no threshold of its own: flip point 0 in the model and in ngspice; the top's NAND gives -0.153 mV; an unequal pair gives the offset, predicted within 2.1 %. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…tch (Closes #10856) M4e merged first; this branch changes sar_comparator.t27, so sar_switch's closure moved and its seal is made again on the merged tree. sar_adc does not import sar_comparator (its closure is linear + sar_cdac, unchanged). sar_comparator 20/20, sar_comparator_psp 13/13, mos_psp103_50c_data 3/3, sar_switch 14/14, sar_adc 10/10, sar_cdac 13/13, 0 vacuous each; seal --verify all MATCH; no stale closure in any analog seal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10856. Part of #10818 (M4e), #10524, epic #10486.
M4b's StrongARM latch (
sar_comparator.t27, multi-node Newton) run on the PSP103 current tables of M3b at the golden deck's 50 C, judged against ngspice-47 + PSP103 with the golden deck's owndynamic_comparatoranddynamic_comparator_top. No change to M4e's numbers.Read first: the latch does not have the threshold M4e fits
The issue asks the PSP103 latch to predict M4e's 6.7 mV decision offset. It cannot, because the isolated latch has no threshold: the circuit is mirror-symmetric (pair XM3/XM4, pull-ups XM8/XM9 and XM6/XM7, cross-coupled XM10/XM11, resets XM12/XM13, loads), so its flip point (the VDP - VDN at which dp and dn trade places) is zero. Measured:
dynamic_comparator, charge swamped or realdynamic_comparator_top(inverter on dp and dn, NAND "Valid")The top's -0.153 mV comes from the NAND's two inputs not being the same load (the inverters' gate-drain capacitance feeds it back to dp and dn); it favours dp, the golden run's reading is positive, so even the sign differs. Valid rises 897.7 ps after the clock for +2 mV and 920.6 ps for -2 mV. The converter's offset is therefore not the DC threshold of the latch. What an offset of this size IS, in this circuit, is a pair imbalance (XM4, the device whose gate is VDP, at m = 35 or 34 instead of 36; the bulk-tied deck, charge swamped):
So the threshold is predicted within 2.1 % as a function of the imbalance, and 6.7 mV is an imbalance of 4.4 % of the pair's current (m of XM4 = 34.42 of 36): a mismatch of the pair or of the input stages, plus whatever the clock edge does (M4e: kickback of 12 and 25 mV in 2 ns), not the latch.
What is in the PR
specs/analog/sar_comparator_psp.t27(moduleAnalogSarComparatorPsp, 13 tests, 0 vacuous, sealed): the unit conversion, the runs, the flip-point bisection, the pinned ngspice numbers, the tests.specs/analog/mos_psp103_50c_data.t27(moduleAnalogMosPsp10350cData, 3 tests, 0 vacuous, sealed): M3b's two tables at 50 C (data and pins;fold_arrandmonotoneareused, not copied) plus the first 200 held-out R2 points per device. M3b's file is not edited.specs/analog/sar_comparator.t27: the solver generalized in its home spec, no copy:sc_stamp_dev_np,sc_stamp_np,sc_iter_np,sc_step_np,sc_run_nptake the NMOS table and the PMOS table as two arguments;sc_stamp_dev,sc_stamp,sc_iter,sc_step,sc_runare one-line forms that pass the one table twice. The 20 tests and every pinned fold are unchanged (20/20, 0 vacuous). The real twin (sc_*_f) andsc_board_stepkeep their one table.specs/analog/decks/:psp103_tab_tt50.cir(tables at 50 C),sar_cmp_psp_r2.cir(goldendynamic_comparator, charge swamped),sar_cmp_psp_r2b.cir(the same with every bulk tied to its source, and the unequal-pair scans),sar_cmp_psp_real.cir(real charge, bare anddynamic_comparator_top). They readIHP_PDK,IHP_OSDIandSAR_GOLDEN_SUBCKTS(the variable of analog M4d: the SAR ADC logic and asynchronous clock -- gate level from the netlist, against ngspice PSP103 edges (Closes #10754) #10845) from the environment; the golden deck is fetched at run time and not committed.AnalogMosPsp10350cData,AnalogSarComparatorPsp), two renewed (AnalogSarComparator, andAnalogSarSwitch, whose closure holdssar_comparator: its spec and gen hashes are unchanged, only the closure entry and the date moved).seal --verify: all hashes MATCH for the four.sar_adc(analog M4e: the whole SAR converter -- our own ngspice + PSP103 codes of the golden deck pinned, a behavioural converter compared conversion by conversion (Closes #10818) #10854) is not on master yet; it importssar_comparatorand needs its closure entry renewed by whichever of the two lands second.git diff --numstatover cli, bootstrap, tools, scripts is empty).python3 -I tools/dupe_scan.py: no new duplicate body, no known group grew.The unit, the devices, the temperature
SC_STEP_V_PER_A). A word of the solver is exactly 4 times an M3b word (sp_scale); the largest, 4 x 1271348 = 5085392 (NMOS) and 3874764 (PMOS), is under the 2^23 the u64 interpolation allows.SC_DV_Mthe solver already applies. No narrow-width or edge effect is assumed, because no width differs..options TEMP = 50; M3b tabulated 27 C. I tabulated 50 C with M3b's recipe (preferred and cheap): the same ngspice and checkout reproduce M3b's TT_N, TT_P and TT_R2_N word for word at 27 C, so the toolchain is the same. 50 C: saturation current -5.8 % (NMOS), -4.2 % (PMOS), weak inversion x1.6 at Vgs = 0.25 V. Held-out accuracy (first 200 R2 points): 4.97e-7 A (NMOS) and 3.92e-7 A (PMOS), relative at least 100 uA 0.34 % / 0.14 % (M3b: 0.56 % / 0.41 %).References (all ngspice-47, PSP103, mos_tt, IHP-Open-PDK 21133f21, 50 C)
sar_cmp_psp_r2.cir: the goldendynamic_comparatoras it is, with M4b's lumped node capacitances times 1e6 and the step times 1e6 (the same dt / C; PSP103's own charge, a few hundred fF, is 1e-4 of the lumped one), fixed-step backward Euler on the model's grid. Compares the CURRENTS alone. Scales 1e4 / 1e5 / 1e6: the decision time moved 0.83 % then 0.09 %.sar_cmp_psp_r2b.cir: R2 with every bulk tied to its source, the one thing a 2-D table Id(Vgs, Vds) models. The golden deck ties NMOS bulks to ground and PMOS bulks to VDD, so the input pair (source net1, 0.15 .. 0.4 V above ground) and XM8/XM9 carry a body effect the tables cannot have.sar_cmp_psp_real.cir: all of PSP103's charge, an ideal 1.6 ps clock, ngspice's own steps;Xbthe bare latch (4 fF on dp, dn),Xtopdynamic_comparator_top.Sign and times (steps of 0.1 ps after the clock's 50 % point; model / R2b / R2)
Also 0.125 mV, 31 uV, 10 uV, 1 uV: decision 55.00, 55.13, 55.16, 55.17 (R2b 55.34, 55.46, 55.48, 55.49); at 0.12 uV the sign is right and the resolution is not reached in 140 steps (in ngspice neither). All 14 runs (7 inputs x 2 orientations) decide as R2 and R2b do. Named bounds (from these numbers, both sides): vs R2b decision within 0.66 %, resolution within 0.72 %; vs R2 within 6.7 % and 3.6 %. Nodes at the 8 recorded steps: within 15.9 mV of R2b (the table's error; M4b's square law had 15 mV), 150 mV of R2 (net2 after the decision), 113 mV at dp.
The errors, kept apart
SP_RES_BOUND; the square law had 2), K = 4 gives the same times (1e-3 of a step in the decision), K = 2 leaves 155 units, K = 1 leaves 20750.Negative controls (tests that pass by seeing the failure)
The decision time is what tells the right tables from the wrong ones; the sign and the flip point cannot, because the symmetric latch decides the right way and flips at zero for any pair of tables (the test asserts that for ss).
What it does not claim
Nothing about charge (98 times too fast; the real comparator's time is not predicted). Nothing beyond the measured size of the body effect (6.2 % of the decision time). It does not predict M4e's 6.7 mV (above). The converter's offset (kickback, input stages, delay-cell clock, DAC settling) is not here, and the flip point of the isolated latch says nothing about it. The top's -0.15 mV is measured, not modelled. Other corner or temperature than tt 50 C, other W, L or supply, noise, Monte Carlo mismatch (the imbalance is a deterministic m). The arithmetic error against a real twin. A board, power, or speed against SPICE. The rest value of net1 (0.401 V) is an initial condition shared by the decks and the model, not PSP103's own (an operating point puts floating net1 at 0.71 V on gmin). The ngspice numbers are one run's (ngspice-47 Homebrew, SPARSE 1.3, run on this Mac, 2026-10-19).
Checks
t27c test-report:sar_comparator_psp13 of 13, vacuous passes 0 of 13;mos_psp103_50c_data3 of 3, 0 of 3;sar_comparator20 of 20, 0 of 20 (unchanged tests).t27c seal --savethen--verifyon the four specs: all hashes MATCH.t27c check: 0 errors.gen/,docs/reports/t27b_expectations.json(the two new specs are unlisted; the steward lists them),.claude/,mos_table.t27,mos_psp103*.t27(no change was needed there;hold_statsisused frommos_psp103, which couples this file to its signature).Heads-up for #10845 (M4d)
The
SAR_GOLDEN_SUBCKTSline in itssar_logic.t27header,grep -v -i -E '^.(end|global)', also drops the.endslines (.is any character, so.endsmatches.end). The extracted file then has 16.subcktand 0.ends, and ngspice stops with "Mismatch of .subckt ... .ends". The line I use in the decks isgrep -v -i -E '^\.(end|global)([[:space:]]|$)'.Reproduce
curl -sfL -o top.spice https://gitlab.symbioticeda.com/Juan_25/uberwave/-/raw/main/wp2-parser/golden/top.spice;sed -n '/^.subckt tracking_switch/,$p' top.spice | grep -v -i -E '^\.(end|global)([[:space:]]|$)' > $SAR_GOLDEN_SUBCKTS; thenIHP_PDK=... IHP_OSDI=... SAR_GOLDEN_SUBCKTS=... ngspice -b specs/analog/decks/sar_cmp_psp_r2.cir(and_r2b,_real,psp103_tab_tt50).🤖 Generated with Claude Code