Repository navigation
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
Merged
Conversation
… of the golden deck pinned, a behavioural converter compared conversion by conversion (Closes #10818) specs/analog/sar_adc.t27 (AnalogSarAdc), first slice of M4e of #10524 (epic #10486). Reference: the unmodified golden deck of uberWAVE (wp2-parser/golden/top.spice, GPL-2.0, fetched at run time, never committed) run in ngspice-47 with the IHP PSP103 models (IHP-Open-PDK 21133f21, mos_tt, cap_typ, TEMP 50, tran 0.1n 16u), 3894.9 s wall. The output code of each of the 31 conversions (V(out) = 1.5 V code / 2048, read after the clks rise that latches it) and the held top plates VDP, VDN of each are pinned with the deck sha256, the uberWAVE commit and the command. 30 of 31 codes equal uberWAVE's own published run; the 31st is the .ic start-up conversion. Converter: MSB first, Bit_10 after the first decision, a sign comparator with a stated offset, the M4a split capacitive DAC (exact charge redistribution) and M1's step, on the held samples. - the merged blocks as they are match 0 of 31 (-21 .. +12 codes): a straight line, gain 1.02 and offset +4.6 codes, the first wrong decision 0.11 .. 21.4 mV from its threshold - plus one top-plate parasitic (0.63 units, 77 fF) and one comparator offset (6.7 mV), fitted on a stated grid: 30 of 31 match, the miss is one code off at 0.133 mV from a threshold; the fit made on the even conversions scores the odd ones 14 of 15, on the odd the even ones 15 of 16 - an ideal-sampling input instead of the held plates: 4 of 31 (the PSP103 switch's lag is LSBs) - negative controls: 2-unit bridge 0 of 31, Bit_8 with 3 units 0, no parasitic 2, no offset 0, LSB-first plate order fails 8 of 10 tests, CP_FIT 0.70 fails 4 of 10 Levels: reference PSP103 (whole deck); sampling PSP103 (from the run); DAC, comparator and SAR sequence behavioural (M4b square law and M4c are not called; M4d replaces the sequence). Also: sar_cdac.t27 gains derive_k_top (a parasitic from the top plate to ground; derive_k delegates, no caller changes) and one test; its seal and sar_switch's closure entry are renewed. 10 tests, 0 vacuous, sealed (all hashes MATCH). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
This was referenced Oct 19, 2026
gHashTag
pushed a commit
that referenced
this pull request
Oct 19, 2026
…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>
This was referenced Oct 19, 2026
Merged
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 #10818. Part of #10524 (epic #10486). M4e, first slice: the whole SAR converter of the golden deck, conversion by conversion.
What is in the PR
specs/analog/sar_adc.t27(moduleAnalogSarAdc, 10 tests, 0 vacuous, sealed): (1) the output code of every conversion of our own ngspice + PSP103 run of the unmodified golden deck, with the held input of each, pinned with provenance; (2) a behavioural converter built from the merged blocks (M4a split capacitive DAC and M1's step called by name, a sign comparator with a stated offset, the SAR sequence read from the deck); (3) the comparison, conversion by conversion.specs/analog/sar_cdac.t27: one function added in its home spec instead of copied,derive_k_top(a parasitic from the top plate to ground joins the Vout corner of C;derive_kdelegates to it, no caller changes) and one test (every Vout ratio becomes 2^j / (1023 + 32 Cp), the staircase stays straight). Its seal is renewed, and so is thesar_cdacclosure entry in thesar_switchseal (seal --verifyMATCH onsar_adc,sar_cdac,sar_switch,sar_comparator).$TMPDIRand are not committed; the spec's own tests assert every pinned table element by element and re-run the grid fit.The reference run (FR-002: the unmodified deck, paths substituted only)
https://gitlab.symbioticeda.com/Juan_25/uberwave/-/raw/main/wp2-parser/golden/top.spice, sha256c5ad548a3e1a181f1b8e81e92ead2f630e14861a36b796169f4fec6b95746e23c75a89c8fae0eecdf18a3b31c4f2b55af56b1ae2(read 2026-10-19); the deck last changed in8e015311a43eee436b25734865de68b7e0617ee0(2026-04-01).libpaths/usr/local/share/OpenPDKs/IHP-Open-PDKto a checkout of IHP-Open-PDK at21133f219b1a6da10d803e345761e77415ceff40; sixpre_osdilines (psp103, psp103_nqs, r3_cmc, mosvar, cap_cmomi, cap_cmomf, compiled from the PDK at that commit, #10516) at the top of the deck's own.controlblock, where uberWAVE's Dockerfile loads them from spinit. Nothing else:tran 0.1n 16u,.options TEMP = 50,.ic,.saveandwriteare the deck's; itsplotis ignored in batch modengspice -b run_full.spiceunder/usr/bin/time -pmos_tt,cap_typ, PSP103 through OSDI, TEMP 50 C (TNOM 27 C)ngbehavior=hsa): 30 of 31 codes identical (conversion 0, the.icstart-up, is 1006 here and 1007 there); at the pinned instants from conversion 1 on VDP and VDN agree to 0.007 and 0.012 mV.set ngbehavior=hsachanges nothing: a 0.5 us run with and without it differs by 0 V in all five saved vectorsThe deck's own output
V(out)is the weighted sum of the eleven latched bits (E1..E11, weights 0.5 .. 2^-11), socode = round(V(out) * 2048 / 1.5 V), read 10 ns after theclksrise that latches it; a test checks every one is within 0.03 LSB of an integer. 16 us at 2 MHz is 32 conversions, but the 32nd latches at 16 us exactly where the run ends: 31 conversions. The held samplesS_VP,S_VNareV(VDP),V(VDN)at 500 k + 98 ns (the track phase has ended at 83 ns,clkcstarts to rise at about 99 ns and passes half of Vdd 20.1 ns afterclksfalls, read in a 1.1 us run of the same deck with every node saved, which is identical to the long run to 0 V).Result (exact code match, 31 conversions)
Held-out: the same grid search on the 16 even conversions alone (16 of 16, Cp 0.626, 6.7 mV) scores the 15 odd ones it never saw 14 of 15; on the 15 odd alone (15 of 15, Cp 0.630, 6.9 mV) the 16 even 15 of 16. Row 2 is a description of this run (30 codes of one sine, two fitted numbers), not a prediction; only the held-out numbers are predictions.
What the two numbers are: Cp is everything on the top plate that M4a does not have (the explicit 4 fF capacitors, 12 fF in all, plus the device capacitance of the comparator's 36-unit input device and of the switch, not decomposed). The offset is not the comparator's alone: reading the 22 decisions of two conversions in the all-nodes run directly puts the latch's decision point at +2.5 .. +3.1 mV of the real VDP - VDN 1 ns before
clkcpasses half of Vdd (+3.3 .. +4.0 mV at 2 ns; the kickback at the clock edge moves VDP and VDN by 12 and 25 mV in 2 ns); the fitted 6.7 mV also absorbs what else the model lacks. Neither is claimed beyond "with these two, a behavioural converter reproduces this run's codes".The code table, all 31 conversions (the spec pins
BASE_CODEandFIT_CODEand asserts them element by element)Levels of every block (FR-001)
Negative controls (tests that pass by seeing the failure)
CP_FIT = 0.70fails 4 of 10 tests; the plate order reversed (LSB first) fails 8 of 10Gates run
t27c test-report specs/analog/sar_adc.t27: tests 10, pass 10, FAIL 0, vacuous passes 0 of 10;sar_cdac.t27: 13 of 13;sar_switch.t27: 14 of 14 (seal run)t27c seal --savethen--verify: all hashes MATCH forsar_adc,sar_cdac,sar_switch,sar_comparator; no home path and no "blocked" in the sealspython3 -I tools/dupe_scan.py: no entry forsar_adcorsar_cdac(it reportsbytes_containandsaturating_addcopies that are on this branch's base in t27o files this PR does not touch)ZIG_GLOBAL_CACHE_DIRset for every seal; the compiler is the existing release binary, not rebuiltWhat it does not claim
No speed claim (no timing is modelled; the reference took 65 minutes and the behavioural converter takes a fraction of a second for 31 conversions, which is not a comparison of the same thing). Nothing about power, noise, mismatch, supply, temperature or another corner: one run, TEMP 50 C,
mos_tt,cap_typ. The comparator is behavioural (a sign and a fitted offset), not M4b's latch, and the offset's cause is not found; the switch is the run's, not M4c's; the SAR logic is a sequence, not gates (M4d). Conversion 0 is the.ictransient (its held common mode is 13.8 mV off). Not a board: no bitstream, clock, LUT, DSP or BRAM.🤖 Generated with Claude Code