Repository navigation
analog M4d: the SAR ADC logic and asynchronous clock -- gate level from the netlist, against ngspice PSP103 edges (Closes #10754) - #10845
Merged
Conversation
…om the netlist, against ngspice PSP103 edges (Closes #10754) specs/tools/t27o/spice_convert.t27 (M2a/M2b's one SPICE front end, extended): emit_gates reads the hierarchy of a named subcircuit down to its gates (inverter, nand, nor, nor3, tgate, delay_cell) and lists each with the nets on its pins, resolved through the port maps to the root's net names (ports first, internal nets as <instance path>.<name>, 0 is ground). 5 tests, incl. refusals with their line. gen/rust regenerated, compiles with rustc. specs/analog/sar_logic.t27: a gate / switch-level event model of SAR_logic + clock_gen built from that table (113 gates, 100 nets): inertial delays d0 + k * fanout per arc, a tgate as a switch with a stored node and drive strengths, the delay cell tabulated per trim code. 12 tests: CK11 .. CK1 rise once each in ngspice's order, within 17 % / 92 ps of its Valid-to-CK delays; the 8 trim codes within 4.3 % of the clks-to-clkc delays; the negative control (one dff with Set and Reset swapped) fails the order check and shows CK7 and CK6 as ngspice does. Reference decks (specs/analog/decks/sar_gate_arcs.cir, sar_delay_cell.cir, sar_logic_ref.cir, sar_logic_swap.cir): IHP PSP103 tt at 50 C (the golden deck's temperature) instead of LEVEL=1, the golden subcircuits read at run time through IHP_PDK, IHP_OSDI and SAR_GOLDEN_SUBCKTS. Gate level for the logic; the transistors are only in the decks. The repeated clkc falling edges are 83 to 127 % late in the model (the delay cell is history dependent) and say so in the header. No speed claim. tri t27o --emit-gates is a follow-up (cmd_t27o is being edited by #10765). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
October 19, 2026 04:41
1 task
This was referenced Oct 19, 2026
16 of 21 tasks
Contributor
This was referenced Oct 19, 2026
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 #10754
M4d of #10524 (epic #10486): the digital half of the golden SAR deck, SAR_logic and clock_gen, as a GATE-LEVEL model built from the netlist and judged against ngspice. Gate level for the logic, device level only in the reference decks. No speed claim.
Deviations from the issue text (read first)
.options TEMP). All numbers below are ngspice-47 + IHP SG13G2 PSP103mos_ttat 50 C.tri t27o --emit-gatesis not wired (spec functions and tests only). The Zig front end (t27o: Zig front end step 1 -- zig_convert.t27 converts tier-1 leaf fns and translates the file own tests as the oracle (step 1 of #10597) #10765) is editingcmd_t27oright now; the flag is a few lines of glue for a follow-up. Hand-written foreign lines in this PR: +0 / -0 (git diff --numstatover cli, bootstrap/src, tools, scripts is empty). To see the extraction on the real deck I ran the generated Rust of the spec (the codetrilinks) through a scratch harness, see below.1. Extraction from the netlist (FR-002)
specs/tools/t27o/spice_convert.t27(the one SPICE front end; no second parser) gainsemit_gates(src, top, w, out, st, gt): the hierarchy of a named subcircuit is walked down to the gate subcircuits (inverter, nand, nor, nor3, tgate, delay_cell), each gate is listed with the nets on its pins found by the gate's port NAMES (so port order does not matter), nets numbered ports-of-the-root first, internal nets named<instance path>.<name>,0ground. Refusals withline N: reason+ card: subcircuit not defined, an element that is not an X card (a resistor, a transistor outside a gate), a gate missing a pin,mother than 1, self-instantiation, table overflow. 5 new tests (44 total in the spec).gen/rust/tools/t27o/spice_convert.rsregenerated witht27c gen-rust(additions only plus the NOT LOWERED count; compiles withrustc --edition 2021 --crate-type lib).Instances found, by kind:
SAR_logicclock_gensar_clk(SAR_logic + clock_gen as the top wires them; the model's root)Receipt, once, by a scratch harness (not committed): the generated Rust run on the whole 783-line fetched
top.spicegives the SAR_logic and clock_gen rows; the 113-gate table ofsar_clkmade from the golden subcircuits WITH their transistors is identical (100 net names, 113 gates: kind, 7 pins, instance name) to the table the spec's embedded netlist gives. The embedded text holds the wiring of SAR_logic, dff, clock_gen and the top's two lines (facts of the circuit) and the gates' ports only; the model is built from what the converter returns for it, no instance table is typed.2. The gate model (
specs/analog/sar_logic.t27, 12 tests)tgateis a switch: PMOS on at CLK = 0, NMOS on at nCLK = 1, strong/weak drive (an NMOS passes a strong 0 and a weak 1), a node nobody drives HOLDS its value (dynamic storage), In -> Out only (checked by a test). A tgate that only changes strength takes 1 ps (without it the slave's keeper goes unknown).Delays and where they come from (all measured, PSP103 tt 50 C, input 50 % to output 50 %):
sar_gate_arcs.cirSL_ARC(least-squares fit),SL_NG_ARC(the 60 points); a test holds the fit to the points within 25 ps (worst 17 ps)sar_delay_cell.cirSL_DC_FALL/RISE,SL_NG_TOT_R/Fsar_logic_ref.cirSL_NG_TV .. SL_NG_TCFsar_logic_swap.cirSL_NG_SW_*The decks hold only my bench text plus
.include $SAR_GOLDEN_SUBCKTS; paths come fromIHP_PDK,IHP_OSDI,SAR_GOLDEN_SUBCKTS(the subcircuit section of the fetched deck, made with the sed line in the spec header). Every pinned number was re-checked against the ngspice output by a script.Delay-cell delays, falling output (the trimmable one) and rising output, ns: code 000 8.09 / 10.48; one bit 5.75 / 10.55; two bits 4.11 / 10.58; 111 1.73 / 10.58 (1, 2 and 4 give the same time).
3. Edge order and times against ngspice
Order: CK11 .. CK1 rise once each, in ngspice's order, and stay up (test). Times, delay from each Valid edge (ps), bounds 20 % and 100 ps (
SL_CK_BOUND_PM,SL_CK_ABS_PS):The CK edges are ABOUT 17 % EARLY: the model has no contention slowdown in the clock-skew window and no input-slope term. Said in the header.
Delay cell, 8 trim codes (clks -> clkc end to end through nor3, delay cell, inverter; bound 6 %): the model is within -4.3 % .. -0.3 % of ngspice for all 8 codes, rising and falling clkc (worst: code 111 rising, 9256 vs 9669 ps).
clkc in the sequencer run: 11 rises and 11 falls in both, as ngspice. First rise (from clks falling) 15610 vs 16232 ps (-3.8 %); first fall (from Valid rising) 13163 vs 11996 ps (+9.7 %), bound 15 %. The repeated clkc edges are NOT right and the header says so: the repeated rises are 6.0 .. 11.0 % late (bound 15 %), the repeated falls 83 .. 127 % late (13163 ps against 7207 .. 5807 ps; bound 130 %). The delay cell is history dependent: at the second Valid rise ngspice has its input at 1.05 V and its output still at 0.39 V (first cycle 1.35 V and 0.08 V), and the output then rises in 6.1 ns, not 10.5 ns. A table of settled delays can not follow that; closing the loop is M4e.
4. Negative control
one_dff_with_set_and_reset_swapped_fails_the_order_check_that_the_right_netlist_passes: the right netlist passessl_order_ok, the one with the fifth dff's Set and Reset swapped fails it, and the model reproduces ngspice's picture (sar_logic_swap.cir): CK7 is set during the reset, falls at the first Valid edge, rises at its own turn (two rises, one fall; ngspice 0.5 ns, 80.64 ns, 240.65 ns), CK6 rises a stage early at the first edge (80.65 ns), falls at the second, rises at its sixth. CK falls come about 22 % early in the model (bound 25 %).5. Gates
t27c test-report specs/analog/sar_logic.t27: tests 12, pass 12, FAIL 0,vacuous passes 0 of 12.t27c test-report specs/tools/t27o/spice_convert.t27: tests 44, pass 44, FAIL 0,vacuous passes 0 of 44.t27c seal --savethen--verifyfor both: all hashes MATCH; no home path, no "blocked" in the seal JSON.python3 -I tools/dupe_scan.py: my additions add no duplicate body (726 duplicate bodies in 205 groups before and after; the two complaints it prints,bytes_containandsaturating_add, are about rust_std.t27 and panel.t27, which this PR does not touch, and are identical on a clean copy of HEAD).t27b teston both: 12/12 and 44/44.What it does not claim
Not transistor level for the logic (the transistors are only in the decks), no speed claim, nothing about power. The CK edges are the sequencer's own: no CK net carries the DAC's load and the Valid is ideal (the comparator closes the loop in M4e). The delay cell input load and the 4 / 8 fF equivalents are fitted, not derived. Weak levels are not degraded, a stored node does not leak. A missing flag:
tri t27o --emit-gatesis the follow-up.🤖 Generated with Claude Code