Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions .trinity/seals/analog_AnalogSarAdc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,30 @@
{
"spec": "specs/analog/sar_cdac.t27",
"spec_hash": "sha256:a7c45039214a8b2e92333a88befc95af33ff482ce08af3be97e2c5b8be3eacd3"
},
{
"spec": "specs/analog/sar_kick.t27",
"spec_hash": "sha256:ccea2477f8ea8f09a40c15a4881c9003111866a176565d60102b6f9550a7d94c"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:c8621c9cb85a4f0990075a906c901964df0b4c48d37206057ec1d4265ccdea30",
"gen_hash_rust": "sha256:f63529e07003b67b4d34a5a999c0095daae6732a8c3e56093dcb17fcf9573947",
"gen_hash_verilog": "sha256:3281bec146dd8f240de65ffc8a867647645c8a6af1c56303eba2e7fe35289005",
"gen_hash_zig": "sha256:9fa3aa4789bcb6d02177add93c6613f6720c4f7c59b2e6b3e65b3accf66b7048",
"gen_hash_c": "sha256:c7975a48e25986b2272d521ab304e55bd417bcf7cf7d4ab3cb7aa65d96cd7150",
"gen_hash_rust": "sha256:ae7e4c0b49b85a469c57b69f3c625ce500cf1c6a00181b10f27856dbcddf592a",
"gen_hash_verilog": "sha256:a4c327a14579be4a4e3f863b98a605adf06f0d7b23808fdbaf643d74d52cf7fd",
"gen_hash_zig": "sha256:b925acb2621b537ebcb0f0b0f126ec15015820ddcb4530819bfcf91f31f88a92",
"module": "AnalogSarAdc",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-19T05:44:03Z",
"sealed_at": "2026-10-19T08:20:17Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:48e8825a4a6a7fc24ce23472bcba5499dcafbd399ac45a14fb153a0a020018e2",
"spec_hash": "sha256:208a64705a1d07ff14d3131d999135a3d5da6c7cb9bc2e919430d7e60b34db68",
"spec_path": "specs/analog/sar_adc.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 10,
"total": 10,
"passed": 15,
"total": 15,
"vacuous": 0
},
"toolchain": {
Expand Down
33 changes: 33 additions & 0 deletions .trinity/seals/analog_AnalogSarKick.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"built_by": "t27c-bootstrap@0.5.2+ea35d9b72",
"closure": [
{
"spec": "specs/analog/linear.t27",
"spec_hash": "sha256:3ddef7be183aba583ed285334ee389b48a65b41335e98914514235db7c4e5d62"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:eadf7a5711ab26d9ccc62014db5742e9384ce4f4b435056d1491aeaf4401c8eb",
"gen_hash_rust": "sha256:5516883b9db0b8b604aafaa502a79c08d8680e7be9b7a4aa05fcf61666eeea4f",
"gen_hash_verilog": "sha256:4fcae5993b32996b83ceafc7794fcb6ce084b37c79d413c5412ca602c9b8da90",
"gen_hash_zig": "sha256:fb3ac67bc0ab4942a221bf1c76792d28c313975f4e99694563d6ab56192353c9",
"module": "AnalogSarKick",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-19T08:09:24Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:ccea2477f8ea8f09a40c15a4881c9003111866a176565d60102b6f9550a7d94c",
"spec_path": "specs/analog/sar_kick.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 10,
"total": 10,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
155 changes: 155 additions & 0 deletions specs/analog/decks/sar_off_base.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
The golden SAR ADC with the sine or a DC input: the control of the M4e-offset experiments (#10888)
* specs/analog/decks/sar_off_base.cir -- the golden SAR ADC deck of uberWAVE (wp2-parser/golden/top.spice, GPL-2.0: fetched at run time, never vendored), its top level wired as the
* golden top wires it and its 16 subcircuits from the run-time file SAR_GOLDEN_SUBCKTS. Nothing in the circuit is changed: this is the control the other sar_off_*.cir decks (idealsw, nokick, nplate, pplate, plates, pseries) each differ from by
* ONE thing, named in their headers. It runs the golden sine (the first two conversions) or a DC input.
* Paths and the run are NOT in this file: ngspice reads IHP_PDK (the IHP-Open-PDK checkout, commit 21133f21), IHP_OSDI (the directory with the compiled psp103.osdi, psp103_nqs.osdi,
* r3_cmc.osdi, mosvar.osdi, cap_cmomi.osdi, cap_cmomf.osdi), SAR_GOLDEN_SUBCKTS (the subcircuit section of the golden deck, made at run time:
* sed -n '/^.subckt tracking_switch/,$p' top.spice | grep -v -i -E '^\.(end|global)([[:space:]]|$)' > $SAR_GOLDEN_SUBCKTS
* the older recipe in sar_logic.t27 drops every line that BEGINS with .end, which loses each .ends), and, lower case because ngspice lower-cases the control lines it substitutes
* into: sar_dmv (the DC differential input in mV, or 0 for the sine), sar_amp (the sine's amplitude, 0.6 for the golden sine, 0 for a DC input) and sar_tstop (150n for the first
* decision, 480n for one conversion, 1.1u for the sine's first two conversions). The deck writes sar_off.raw (binary) in the current directory and prints the measures below.
* Run: sar_dmv=-12 sar_amp=0 sar_tstop=150n IHP_PDK=<checkout> IHP_OSDI=<osdi dir> SAR_GOLDEN_SUBCKTS=<file> ngspice -b <deck> (ngspice-47, about a minute)
* The measures: D = V(VDP) - V(VDN) is read at the instant clkc crosses 0.1 V going up (vp1 - vn1, vp2 - vn2 for the first and second clock: before the clock edge has reached the
* comparator, so before its kickback); the first decision is the level the bottom plate Bit_10 settles to (b10 below 0.75 V = VDP above VDN, the latch's dp won); the flip point is the
* vp1 - vn1 at which b10 changes; vp050 - vn050 .. vp125 - vn125 are the plates at later clkc levels (the kickback); the first plate step is (vp2 - vn2) - (vp1 - vn1), +-2 x 0.75 V x K10
* with K10 = 512 / (1023 + 32 Cp) of M4a. The golden sine's first two conversions are read from the raw file: D at each clkc rise through 0.1 V, the bit from vocn against vocp.
* THE EXPERIMENTS (#10888; the first decision of a conversion, DC input; flip point = the D between the two inputs that bracket it, offset = minus its middle, +- half the bracket;
* data, estimators and tests in specs/analog/sar_kick.t27; Cp is the first plate step, two directions averaged, in units of the 9 um cap_cmim):
* deck candidate and change offset (mV) moved by (mV) dVDP / dVDN at clkc 0.75 V (mV) Cp
* sar_off_base the golden circuit +9.42 +- 0.20 -- -22.7 / -30.2 0.647
* sar_off_idealsw (a) tracking switches ideal +9.19 +- 0.20 -0.23 +- 0.40 -23.0 / -30.6 0.640
* sar_off_nokick (b) comparator kickback onto the plates removed (buffers) +0.03 +- 0.15 -9.38 +- 0.35 -0.06 / -0.10 0.621
* sar_off_nplate (d1) N half's bottom plates ideal -25.79 +- 0.50 -35.20 +- 0.70 -17.1 / +3.3 0.582
* sar_off_pplate (d2) P half's bottom plates ideal +43.87 +- 0.99 +34.45 +- 1.19 +11.1 / -24.9 0.676
* sar_off_plates (d3) both halves' bottom plates ideal and symmetric +0.27 +- 0.25 -9.14 +- 0.45 -6.86 / -6.88 0.582
* sar_off_pseries (d4) P plates behind 2592 ohm (a golden tgate's, sar_off_ron) -0.89 +- 0.25 -10.31 +- 0.45 -29.7 / -29.2 0.690
* (the same with 1300 ohm: +4.09 +- 0.25; with 3900 ohm: -4.19 +- 1.00; it crosses the latch's own +0.15 mV at 2320 ohm, 10.5 percent under the tgate's 2592)
* (c) DAC settling when clkc fires: read D 3 ns and 10 ns before clkc = 0.1 V in the base sine run: under 0.1 mV and 0.31 mV from the fourth / fifth decision on.
* The latch itself flips at VDP - VDN = -0.153 mV (M4b-psp), so rows (b) and (d3) are the latch's own offset to within their brackets: the kickback IS the offset, and what makes it a
* difference between the two plates is the N half's bottom-plate drive (neg_bottom_plate_logic's tgate x11 idle, x15 moved: one transmission gate more than the P half's); row d4 shows the
* tgate is the asymmetry: a resistor of its size on the P half's plates takes the first decision's offset from +9.42 to -0.89 mV.
* The late decisions (index 9 and 10 of a conversion): 6.66 and 6.90 mV in this deck, from 26 DC conversions (sar_amp 0, sar_tstop 480n, sar_dmv in sar_kick.t27's header).
.param dmv=0
.param amp=0.6
.lib $IHP_PDK/ihp-sg13g2/libs.tech/ngspice/models/cornerMOSlv.lib mos_tt
.lib $IHP_PDK/ihp-sg13g2/libs.tech/ngspice/models/cornerCAP.lib cap_typ
.include $SAR_GOLDEN_SUBCKTS
* supplies, trim code A B C = 0 0 0, the common mode, the sampling clock and the differential sine input
VDD4 vdda 0 1.5
VDD6 vdd 0 1.5
VDD7 vcm 0 0.75
V2 c 0 0
V5 b 0 0
V6 a 0 0
VDD1 vss 0 0
VCMS net2 0 0.75
VCLKS clks 0 PULSE(0 1.5 0n 2n 2n 80n 500n)
VSP net2 vinp sin({-dmv*0.5e-3} {amp} 62.5k)
VSN vinn net2 sin({-dmv*0.5e-3} {amp} 62.5k)
* the two tracking switches, the comparator, the SAR logic and the clock generator
x1 vdda 0 vinn vdn clks tracking_switch
x2 vdda 0 vinp vdp clks tracking_switch
x3 vocp vocn valid vdp vdn clkc vdd 0 dynamic_comparator_top
x7 ck3 ck11 ck7 ck2 ck6 ck10 ck1 ck9 ck5 ck8 ck4 vdd 0 vdd valid 0 clks SAR_logic
x4 vdd clkc 0 clks valid ck1 a b c clock_gen
* the 4 fF loads the golden top hangs on the top plates and on the control nets
C3 vdp 0 4f
C4 vdn 0 4f
C5 vdp 0 4f
C6 vdn 0 4f
C7 vinp 0 4f
C8 vinn 0 4f
C9 clkc 0 4f
C10 vocp 0 4f
C11 valid 0 4f
C12 vocn 0 4f
C13 clkc 0 4f
C14 clks 0 4f
C15 valid 0 4f
C16 ck1 0 4f
C17 a 0 4f
C18 b 0 4f
C19 c 0 4f
C20 clks 0 4f
C21 valid 0 4f
C22 vdd 0 4f
* the bottom-plate drivers (every stage decides on vocn), then the negated copy of each bit for the N half
x5 vdd bit_10 vocn 0 ck11 vcm out_11 0 0 clks bit_9 vocn ck10 out_10 bit_8 vocn ck9 out_9 bit_7 vocn ck8 out_8 bit_6 vocn
+ ck7 out_7 bit_5 vocn ck6 out_6 bit_4 vocn ck5 out_5 bit_3 vocn ck4 out_4 bit_2 vocn ck3 out_3 bit_1 vocn ck2 out_2 bit_0 vocn ck1
+ out_1 DAC_control_top
x6 vdd vss ck11 bit_10 bit_10_n neg_bottom_plate_logic
x8 vdd vss ck6 bit_5 bit_5_n neg_bottom_plate_logic
x9 vdd vss ck10 bit_9 bit_9_n neg_bottom_plate_logic
x10 vdd vss ck5 bit_4 bit_4_n neg_bottom_plate_logic
x11 vdd vss ck9 bit_8 bit_8_n neg_bottom_plate_logic
x12 vdd vss ck4 bit_3 bit_3_n neg_bottom_plate_logic
x13 vdd vss ck8 bit_7 bit_7_n neg_bottom_plate_logic
x14 vdd vss ck3 bit_2 bit_2_n neg_bottom_plate_logic
x15 vdd vss ck7 bit_6 bit_6_n neg_bottom_plate_logic
x16 vdd vss ck2 bit_1 bit_1_n neg_bottom_plate_logic
* the deck's own output adder: V(out) = 1.5 V code / 2048 with the bits at 0 / 1.5 V
E1 out net12 out_11 0 0.5
E2 net12 net11 out_10 0 0.25
E3 net11 net10 out_9 0 0.125
E4 net10 net9 out_8 0 0.0625
E5 net9 net8 out_7 0 0.03125
E6 net8 net7 out_6 0 0.015625
E7 net7 net6 out_5 0 0.0078125
E8 net6 net5 out_4 0 0.00390625
E9 net5 net4 out_3 0 0.001953125
E10 net4 net3 out_2 0 0.0009765625
E11 net3 0 out_1 0 0.00048828125
* the two capacitive DAC halves: the N half on VDN with the negated bits, the P half on VDP
x17 vdn bit_3_n bit_8_n bit_5_n bit_6_n bit_7_n bit_4_n bit_9_n bit_10_n bit_2_n bit_1_n Diff_cap_DAC
x18 vdp bit_3 bit_8 bit_5 bit_6 bit_7 bit_4 bit_9 bit_10 bit_2 bit_1 Diff_cap_DAC
.ic v(x1.net1)=0
.ic v(x1.net2)=0
.nodeset v(x1.net2)=0
.ic v(x1.net3)=0
.ic v(x2.net1)=0
.ic v(x2.net2)=0
.ic v(x2.net3)=0
.ic v(x17.net1)=0
.ic v(x18.net1)=0
.ic v(vdp)=0
.ic v(vdn)=0
.options temp=50
.options klu
.save v(vdp) v(vdn) v(vinp) v(vinn) v(clks) v(clkc) v(vocp) v(vocn) v(valid) v(out)
.save v(ck1) v(ck2) v(ck3) v(ck4) v(ck5) v(ck6) v(ck7) v(ck8) v(ck9) v(ck10) v(ck11)
.save v(bit_1) v(bit_2) v(bit_3) v(bit_4) v(bit_5) v(bit_6) v(bit_7) v(bit_8) v(bit_9) v(bit_10)
.save v(bit_1_n) v(bit_2_n) v(bit_3_n) v(bit_4_n) v(bit_5_n) v(bit_6_n) v(bit_7_n) v(bit_8_n) v(bit_9_n) v(bit_10_n)
.save v(out_1) v(out_2) v(out_3) v(out_4) v(out_5) v(out_6) v(out_7) v(out_8) v(out_9) v(out_10) v(out_11)
.save v(x3.dp) v(x3.dn) v(x3.x1.an) v(x3.x1.ap) v(x3.x1.net1) v(x17.net1) v(x18.net1) v(x1.net3) v(x2.net3)
.control
pre_osdi $IHP_OSDI/psp103.osdi
pre_osdi $IHP_OSDI/psp103_nqs.osdi
pre_osdi $IHP_OSDI/r3_cmc.osdi
pre_osdi $IHP_OSDI/mosvar.osdi
pre_osdi $IHP_OSDI/cap_cmomi.osdi
pre_osdi $IHP_OSDI/cap_cmomf.osdi
set num_threads=4
alterparam dmv = $sar_dmv
alterparam amp = $sar_amp
reset
tran 0.1n $sar_tstop
meas tran tc1 when v(clkc)=0.75 rise=1
meas tran tc2 when v(clkc)=0.75 rise=2
meas tran vp1 find v(vdp) when v(clkc)=0.1 rise=1
meas tran vn1 find v(vdn) when v(clkc)=0.1 rise=1
meas tran vp2 find v(vdp) when v(clkc)=0.1 rise=2
meas tran vn2 find v(vdn) when v(clkc)=0.1 rise=2
meas tran vp050 find v(vdp) when v(clkc)=0.5 rise=1
meas tran vn050 find v(vdn) when v(clkc)=0.5 rise=1
meas tran vp075 find v(vdp) when v(clkc)=0.75 rise=1
meas tran vn075 find v(vdn) when v(clkc)=0.75 rise=1
meas tran vp100 find v(vdp) when v(clkc)=1.0 rise=1
meas tran vn100 find v(vdn) when v(clkc)=1.0 rise=1
meas tran vp125 find v(vdp) when v(clkc)=1.25 rise=1
meas tran vn125 find v(vdn) when v(clkc)=1.25 rise=1
meas tran b10 find v(bit_10) at=136n
meas tran b10n find v(bit_10_n) at=136n
set filetype=binary
write sar_off.raw
.endc
.end
Loading
Loading