Skip to content

analog M4e-offset: the converter's offset is the comparator's clock-edge kickback read through the N half's extra transmission gate -- eight experiment decks, the measured offset in the converter model (Closes #10941) - #10953

Merged
gHashTag merged 2 commits into
masterfrom
claude/analog-m4e-offset-10888
Oct 19, 2026

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #10941. Part of #10888 (M4e-offset), #10818 (M4e), epic #10486.

M4e's converter matches 30 of 31 conversions only with a fitted +6.7 mV decision offset (and a fitted top-plate load Cp). M4b-psp (PR #10884) showed the golden latch is not that offset. This PR finds where it comes from with ngspice + PSP103 experiments that change one thing at a time, names it with its size, measures it on the netlist, and makes the converter model take its offset from the measurement instead of the fit.

The result in four lines

  • The offset is the comparator's clock-edge kickback read through two top plates of unequal stiffness. When clkc rises, the comparator's tail node and the input pair's drains fall and its gate capacitances push charge into the plates: by half of Vdd VDP has fallen by 22.7 mV and VDN by 30.2 mV. The 7.5 mV difference, plus the latch's regeneration margin, is the offset: +9.42 mV at the first decision, +6.66 mV (decision 9) and +6.90 mV (decision 10) at the last ones.
  • The unequal stiffness is the N half's bottom-plate drive: neg_bottom_plate_logic puts one more transmission gate (x11 idle, x15 moved) between the driver and the N plates than the P plates have. A resistor of a golden tgate's own size (2592 ohm, measured) added to each P plate takes the first decision's offset from +9.42 to -0.89 mV; the offset crosses the latch's own 0.15 mV at 2320 ohm, 10.5 percent under the tgate's.
  • Not the tracking switches (+9.19, moved by -0.23 +- 0.40), not DAC settling (under 0.1 mV from the fourth decision on), not the latch (0.153 mV).
  • The converter model's offset is now 6.776 mV, measured (the mean of the flip points of the last two decisions). With M4e's Cp unchanged that matches 29 of 31 conversions; re-fitting Cp alone, the offset fixed, gives 30 of 31 (Cp 0.634 against 0.630).

Experiments (first decision of a conversion, DC input; offset = minus the flip point of D = V(VDP) - V(VDN) read at clkc = 0.1 V, i.e. before the edge reaches the comparator; +- half the bracket the DC inputs give)

row candidate change (committed deck) offset (mV) moved by (mV) dVDP / dVDN at clkc 0.75 V (mV) Cp (units)
0 base sar_off_base.cir: the golden circuit re-wired +9.42 +- 0.20 -- -22.7 / -30.2 0.647
a tracking switches sar_off_idealsw.cir: ideal 500 ohm switches +9.19 +- 0.20 -0.23 +- 0.40 -23.0 / -30.6 0.640
b comparator kickback onto the plates sar_off_nokick.cir: ideal buffers between plates and comparator +0.03 +- 0.15 -9.38 +- 0.35 -0.06 / -0.10 0.621
d1 N half's bottom-plate drive sar_off_nplate.cir: N plates ideal -25.79 +- 0.50 -35.20 +- 0.70 -17.1 / +3.3 0.582
d2 P half's bottom-plate drive sar_off_pplate.cir: P plates ideal +43.87 +- 0.99 +34.45 +- 1.19 +11.1 / -24.9 0.676
d3 both halves' drive sar_off_plates.cir: both ideal, symmetric +0.27 +- 0.25 -9.14 +- 0.45 -6.86 / -6.88 0.582
d4 the extra tgate, given to the P half sar_off_pseries.cir: 2592 ohm between each P plate and its Bit_k -0.89 +- 0.25 -10.31 +- 0.45 -29.7 / -29.2 0.690
d4 (same) 1300 ohm / 3900 ohm +4.09 +- 0.25 / -4.19 +- 1.00 -5.33 / -13.61 -26.4 / -29.7 and -32.7 / -28.9 0.622 / 0.851
c DAC settling when clkc fires the base sine run, D read 3 ns and 10 ns earlier under 0.1 mV from the 4th decision on (0.26 mV at the 2nd and 3rd) -- -- --

sar_off_ron.cir measures the resistances the table compares with: a golden tgate conducting at VCM 2592 ohm, the inverter's pmos 1880 ohm and nmos 1427 ohm at a rail. The latch itself flips at VDP - VDN = -0.153 mV (M4b-psp), i.e. offset +0.153 mV: rows b and d3 are the latch's own offset to within their brackets, and with both plates driven ideally the plates fall by the same 6.87 mV. Cp (the DAC's first step, two directions averaged, as a parasitic on M4a's ratio) moves from 0.58 to 0.85 units with the drive: it is not a property of the DAC alone, and it is not predicted here.

The late decisions (the ones that decide the codes) are bracketed by 26 DC conversions of the base deck (480 ns each, the input chosen so that decision 7, 8, 9 or 10 sees D within a few mV of its flip): decision 10 flips at -6.895 mV +- 5 uV, decision 9 at -6.658 mV +- 0.043, decision 8 at -7.10 +- 0.50, decision 7 at -6.98 +- 0.50. They depend on the decision and on the bit path at the 0.2 mV level (one threshold for decisions 9 and 10 together leaves three decisions on the wrong side, a test). The golden sine's first two conversions in the other decks give the same story on the late decisions: 6.95 +- 0.42 mV with ideal switches, +0.09 +- 0.60 with the kickback removed, -0.10 +- 0.31 with ideal plates.

The converter, 31 conversions (Cp as in M4e unless said)

row model matches
2 Cp 0.63 and offset 6.7 mV, both fitted (M4e) 30
4 Cp 0.63 (M4e's), offset 6.776 mV measured, nothing fitted for the offset 29 (misses: conversion 16, +1 code, and 25, -1 code)
5 offset 6.776 mV measured, Cp re-fitted alone on M4e's grid 30 (Cp 0.634)
  • The fitted 6.7 mV was 0.08 mV from the measured offset.
  • Conversions 2 to 30 never entered the offset's measurement: 27 of those 29 match.
  • Over the measured spread of the offset (Cp 0.63): 6.6 mV 29, 6.655 29, 6.7 30, 6.9 30, 7.0 25, 7.1 21. The 29 against 30 is inside the path dependence of the flip point (decision 10: between -7.06 and -6.85 mV).
  • The first four decisions are never within 3 mV of their thresholds in the 31 conversions (the closest is 3.01 mV), so the first decision's 2.6 mV larger offset cannot change a code (a test).
  • Negative controls (tests that see the failure): the latch alone (+0.153 mV), the first decision's 9.42 mV for every decision, no offset, and the measured offset with the wrong sign each match 0 of 31.

Cp is still a fit (and one fitted number plus a measured one is what rows 4 and 5 are). The experiments show why it is not predicted here: the first plate step gives 0.58 to 0.85 units depending on how the plates are driven.

Corrections to earlier statements

  • analog M4e-offset: the +6.7 mV the converter needs is not the comparator -- find and model its source #10888 said the golden run's reading (+2.5 .. +3.1 mV) has the opposite sign of dynamic_comparator_top's -0.153 mV. It does not: both are in the converter's convention ("above" when VDP - VDN + off > 0), 0.153 mV against about 3, the same sign. The +2.5 .. +3.1 mV was read 1 ns before half of Vdd, inside the kickback (which has already moved VDP - VDN by 3.9 mV there); read before the edge the flip is at -6.7 .. -6.9 mV, the fitted 6.7.
  • The golden deck's own run gives code 1006 for conversion 0 (pinned in sar_adc.t27); the wrapper decks give 1007. That conversion's last decision sits 0.006 mV from its flip (D = -6.889 mV, flip -6.895 mV), so a 0.01 mV difference between two simulations of the same circuit decides it. Conversion 1's code (841) agrees with the pinned one.

What is in the PR

  • specs/analog/sar_kick.t27 (module AnalogSarKick, 10 tests, 0 vacuous, sealed): the pinned measurements with provenance (six first-decision brackets and their kicks, the series-resistor sweep, the tgate and inverter resistances, 112 late-decision records, the 22 decisions of the base sine run with their settling and kick, the other decks' sine brackets), the estimators (late_thr: the threshold with the fewest decisions on the wrong side; off_late_v; rs_zero_ohm) and the tests. It runs no solver.
  • specs/analog/sar_adc.t27: uses off_late_v, adds fit_cp (Cp alone) and five tests (rows 4 and 5, the spread, the first four decisions, the controls) and a header section. (The generic Range struct that broke the types ratchet was renamed ErrRange by ledger: the five rows master lacks -- sar_adc, sar_comparator_psp, mos_psp103_50c_data, worktrees/reap pass, ngram_hslm blocked; cap equals reality at 129 (Closes #10887) #10889, already on master; this branch is rebased on it.)
  • Decks specs/analog/decks/sar_off_{base,idealsw,nokick,nplate,pplate,plates,pseries,ron}.cir: the golden top level re-wired (so the ngspice netlist is ours), its 16 subcircuits .included from the run-time file named by SAR_GOLDEN_SUBCKTS (the GPL-2.0 deck is never committed; the sed recipe in each header keeps the .ends, which the recipe in sar_logic.t27 drops). sar_off_base.cir holds the table. They read IHP_PDK, IHP_OSDI, SAR_GOLDEN_SUBCKTS, sar_dmv, sar_amp, sar_tstop from the environment.
  • Two seals (AnalogSarKick new, AnalogSarAdc renewed with the new closure entry). Nothing else imports sar_adc.
  • Hand-written foreign lines: +0 / -0. The throwaway readers I used (a binary RAW parser, the decision and flip analysis, the sweep runners, a float replica of the converter used only to choose DC inputs) live under $TMPDIR and are not committed.

Checks

  • t27c test-report specs/analog/sar_kick.t27: 10 tests, 10 pass, FAIL 0, vacuous passes 0 of 10.
  • t27c test-report specs/analog/sar_adc.t27: 15 tests, 15 pass, FAIL 0, vacuous passes 0 of 15.
  • t27c seal --verify MATCH for both; ./target/release/tri types ratchet: RATCHET: CLEAN; python3 -I tools/dupe_scan.py: no new duplicate body, no known group grew. A mutant of the base bracket in sar_kick fails 3 tests.
  • Not touched: sar_logic.t27, sar_comparator*.t27, mos_*.t27, gen/, docs/reports/t27b_expectations.json, .claude/. A new spec is UNLISTED in the t27b ledger until the steward lists it (t27b ledger steward: the rules and the job card, so spec PRs stop editing the ledger (Closes #8654) #8656).

What is left

🤖 Generated with Claude Code

…dge kickback read through the N half's extra transmission gate -- eight experiment decks, the measured offset in the converter model (Closes #10941)

Part of #10888 (M4e-offset), #10818, epic #10486.

One-change ngspice + PSP103 experiments on the golden SAR ADC (first decision, DC input, offset = minus the flip point of VDP - VDN read at clkc = 0.1 V):
base +9.42 mV; ideal tracking switches +9.19 (not it); the comparator's kickback removed +0.03 (it IS the offset, the latch's own 0.153 mV is left);
N half's bottom plates ideal -25.79; P half's ideal +43.87; both ideal and symmetric +0.27; a golden tgate's resistance (2592 ohm, measured by
sar_off_ron.cir) added to each P plate -0.89 (+4.09 at 1300 ohm, -4.19 at 3900; zero at 2320 ohm). At the clock edge VDP falls 22.7 mV and VDN 30.2 mV:
neg_bottom_plate_logic's x11 / x15 put one transmission gate more between the driver and the N plates, so the N plates are softer.
At the last two decisions the offset is 6.66 and 6.90 mV (26 DC conversions bracket them to 0.05 and 0.005 mV).

specs/analog/sar_kick.t27 (new, 10 tests, 0 vacuous, sealed): the pinned measurements, the threshold estimators, the tests. specs/analog/sar_adc.t27 takes its
offset from it (6.776 mV, measured): 29 of 31 conversions match with M4e's Cp, 30 of 31 with Cp re-fitted alone; the fitted 6.7 mV was 0.08 mV from it.
Cp stays a fit. Follow-up: #10942 (derive the kick from the plates' drive).

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

@tri-claw tri-claw Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TRI CLAW formatting suggestions: 1 posted, 0 left out (outside this diff, over the caps, or unreadable). Whitespace only: every comment and token is kept.

Comment thread specs/analog/sar_kick.t27
assert fabs64(DEC_D[18] - LD_D[4]) < 0.00000001;
assert fabs64(DEC_D[21] - LD_D[7]) < 0.00000001;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 08:32:20 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 46
PRs with All Checks Green 4
READY 1
FAILING 46
PENDING 0
NO CHECKS YET 0

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

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=509db03c8f4d != 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).

This was referenced Oct 19, 2026
…10486)

Gates run on this tree with t27c built from master d8458f5: sar_adc 15/15, sar_kick 10/10,
sar_adc_ax7203 13/13; seal --verify MATCH for all eight sar and board specs (no seal moved after the
gen-verilog change in #8844); tri types ratchet CLEAN. tools/dupe_scan.py is red on master itself
(bytes_eq, ws_len_at and thirteen more copied bodies, none in analog specs); this branch adds no copied body.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@gHashTag
gHashTag marked this pull request as ready for review October 19, 2026 13:46
@gHashTag
gHashTag enabled auto-merge (squash) October 19, 2026 13:46

@tri-claw tri-claw Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TRI CLAW formatting suggestions: 1 posted, 0 left out (outside this diff, over the caps, or unreadable). Whitespace only: every comment and token is kept.

Comment thread specs/analog/sar_kick.t27
assert fabs64(DEC_D[18] - LD_D[4]) < 0.00000001;
assert fabs64(DEC_D[21] - LD_D[7]) < 0.00000001;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 13:46:42 UTC

Summary

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

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

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=57b91bb96334 != 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 76eb8f4 into master Oct 19, 2026
46 of 49 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 M4e-offset-a: name the offset's source with one-change experiments and take the converter's offset from the netlist, not the fit (Part of #10888)

2 participants