Skip to content

analog: mos_table.t27 -- CMOS inverter with a tabulated square-law MOS, backward Euler and fixed Newton, against cpphdl (Closes #10515) - #10518

Merged
gHashTag merged 1 commit into
masterfrom
claude/analog-m3a-mos-table-10515
Oct 18, 2026
Merged

gHashTag merged 1 commit into
masterfrom
claude/analog-m3a-mos-table-10515

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #10515

M3a of the analog emulation epic (#10486): specs/analog/mos_table.t27, a CMOS inverter whose MOS currents are read from an Id(Vgs, Vds) table by bilinear interpolation, integrated by backward Euler with a fixed number of Newton iterations, checked against cpphdl's analytic square-law inverter (analog/examples/cmos_inverter: Vdd 1.2 V, input 0 -> 1.2 V at 2 us, 10 pF, dt 10 ns, stop 4 us).

Result (13 tests, vacuous passes 0 of 13; tri test exit 0; seal MATCH)

  • K = 3 Newton iterations per step, fixed. inv_step takes k so the tests can run K = 1 and 2; board_step has a static trip count.
  • Grid: 25 x 25 nodes, 0.05 V a cell. 0.05 V divides both 1.2 V and 0.35 V, so Vdd and Vth are grid lines. One 2^20-unit cell is 0.05 V (unit 47.68 nV), so cell index, fraction and the interpolation divisor are shifts; the only division is Newton's. One table serves both transistors (PMOS reads it mirrored).
  • Three errors, each bounded from both sides:
    • arithmetic (fixed point vs f64 of the same iteration): 0.61 unit (29 nV), bound 0.7
    • table (f64 table model vs analytic law solved to convergence): 0.428 mV, bound 0.45 mV (Newton at K = 3 equals K = 12 to 1e-3 unit, so this is the table, not the iteration)
    • discretization (analytic dt vs dt/2): 27.2 mV, bound 27.5 mV (the largest of the three; the scheme at dt = 10 ns on a ~12 ns node)
  • |Y(4 us)| = 0 V in the fixed-point run (cpphdl requires <= 1 mV; analytic run 8e-54 V). Y(2 us) = 1.2 V exactly, 1e-6 V bound against the analytic run (measured 2e-16).
  • Last residual |g(y_K)| <= 1 unit (47.68 nV) at all 400 steps, bound 2, asserted at every step and from both sides.
  • Table vs law at all 576 cell midpoints: absolute error 3.13e-7 A (bound 3.2e-7). Relative error with the 1e-9 A floor: 1.0 over all midpoints, because in the first cell above Vth a chord reads exactly twice a square law; 0.2000 from the second cell above Vth on (bound 0.2002). gm and gds differ from the analytic derivatives by 0.0125 of dt/C (bound 0.0126).
  • Negative controls (tests that pass by seeing the failure): K = 1 gives a residual of 1199464 units (57 mV) against the bound of 2 (K = 2: 29760); a table built with Vth = 0.30 is 917504 units off at a node, 4.3e-5 A off at a midpoint, and the inverter run is 46.6 mV from the law. Also proven by hand on copies: K_NEWTON = 1, the law's Vth = 0.30, and a truncating table builder each make 4, 11 and 7 of the 13 tests FAIL.
  • Mirror symmetry: the run with A -> Vdd - A from Y = Vdd gives Vdd - Y at every step, bit for bit.

Hardware check

t27b verilog specs/analog/mos_table.t27: exit 0, but the module is empty (nothing in the file is a clocked top, and its f64 test locals do not lower). With a scratch top outside the repo: the scalar arithmetic (blend, blend1, newton_move, frac_of, cell_of, mag_diff, gate_at) lowers (exit 0, division included); board_step itself exits 2 on two constructs: a slice parameter ("call of a fn with a parameter that is no integer or bool") and array indexing (ExprIndex). The table read (node_at) is the single access point M3b needs as a ROM. A while needs a static trip bound, which board_step has.

Reuse

fold and fabs64 come from analog/linear (M1, #10511) by use. use brings in all of that module's public names, so step, residual and STEPS here are board_step, g_resid and RUN_STEPS. The dupe ratchet prints ok.

Not claimed

Nothing about a transistor (the table is the square law, not PSP103; that is M3b), a board, power, a second nonlinear node, or cpphdl's own 11.5 nV (quoted from its README, not re-run).

🤖 Generated with Claude Code

…S, backward Euler and fixed Newton, against cpphdl (Closes #10515)

M3a of the analog emulation epic (#10486). The device is a 25 x 25 Id(Vgs, Vds)
table on a 0.05 V grid (Vdd and Vth are grid lines), read by exact-integer
bilinear interpolation; gm and gds are the slopes of the same interpolant. The
output node is integrated by backward Euler with K = 3 Newton iterations, fixed.
One 2^20-unit cell is 0.05 V, so cell index, fraction and the interpolation
divisor are shifts; the only division is Newton's.

Tests (13, 0 vacuous): table against the law at the nodes and at all 576 cell
midpoints; the fixed-point inverter run against cpphdl's requirement; the three
errors kept apart and bounded from both sides (arithmetic 0.61 unit, table
0.428 mV, discretization 27.2 mV); the last residual at most 1 unit at every
step; negative controls K = 1 and Vth = 0.30; bit-exact mirror symmetry.

fold and fabs64 come from analog/linear (M1) by use; no board top, no PDK.

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

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-18 16:10:11 UTC

Summary

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

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 ffaec39 into master Oct 18, 2026
32 of 35 checks passed
gHashTag added a commit that referenced this pull request Oct 18, 2026
…nXC7 path in the analog skill (Closes #10521) (#10523)

The M3a seal (#10518) was written without ZIG_GLOBAL_CACHE_DIR, so its test
run recorded a false "blocked" verdict carrying /Users/playom/.cache/zig;
re-sealed it records 13 passed, 13 total, 0 vacuous and all hashes MATCH.
The skill (#10520) named /Users/playom/t27/build/fpga/openxc7; it now uses
"$(git rev-parse --git-common-dir)/../build/fpga/openxc7", which resolves to
the main checkout from any worktree, and records the seal trap. Both made
`scan` (tools/check_devhome_paths.py) red on master.

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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 M3a: nonlinear table-device cell -- CMOS inverter with a tabulated square-law MOS, backward Euler and a fixed Newton count, against cpphdl

2 participants