diff --git a/crates/applications/stacked_cores/scripts/stacked_cores_52xx.py b/crates/applications/stacked_cores/scripts/stacked_cores_52xx.py index 2b88267..ebb82a6 100755 --- a/crates/applications/stacked_cores/scripts/stacked_cores_52xx.py +++ b/crates/applications/stacked_cores/scripts/stacked_cores_52xx.py @@ -11,7 +11,7 @@ from stacked_cores_52xx_db import DB ## CONSTANTS/CONFIGURATION # list of sims to extract details for -PREFIXES = { "52", "53", "54", "55", "56", "57", "58", "59", "60" } +PREFIXES = { "52", "53", "54", "55", "56", "57", "58", "59", "60", "61" } def times_of_interest(sim_name: str) -> list: # could be more intelligent, extracting e.g. the clock duration from the name @@ -35,6 +35,8 @@ def times_of_interest(sim_name: str) -> list: return [4e-9, 6e-9] if sim_name.startswith("60-"): return [4e-9, 6e-9] + if sim_name.startswith("61-"): + return [4e-9, 6e-9] ## USER-FACING FUNCTIONS diff --git a/crates/applications/stacked_cores/scripts/stacked_cores_52xx_db.py b/crates/applications/stacked_cores/scripts/stacked_cores_52xx_db.py index 8bf8223..9fce01e 100644 --- a/crates/applications/stacked_cores/scripts/stacked_cores_52xx_db.py +++ b/crates/applications/stacked_cores/scripts/stacked_cores_52xx_db.py @@ -3764,4 +3764,102 @@ DB = { MeasRow(6e-09, [-29635, 15487, -11297, 11974]), ], }), + '61-buf-neg_out-2_1windings_in-1_1windings_out-1windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-8coupling-2e10-drive-': ParameterizedMeas({ + ( 0.000, 0.000,): [ + MeasRow(4e-09, [-17903, -18968, 10689, 10693, -18970, -17901]), + MeasRow(6e-09, [-16920, 2138, -30867, -30869, 2133, -16920]), + ], + ( 0.100, -0.100,): [ + MeasRow(4e-09, [-17702, -18439, 16456, -18815, -19513, -17953]), + MeasRow(6e-09, [-16914, 7305, -30870, -30877, -13825, -16837]), + ], + ( 0.200, -0.200,): [ + MeasRow(4e-09, [-17677, -18320, 16707, -19009, -19586, -17968]), + MeasRow(6e-09, [-16914, 7518, -30870, -30877, -14004, -16836]), + ], + ( 1.000, -1.000,): [ + MeasRow(4e-09, [-17640, -18069, 17240, -19454, -19801, -18007]), + MeasRow(6e-09, [-16914, 7960, -30870, -30876, -14449, -16835]), + ], + }), + '61-buf-neg_out-2_1windings_in-2_1windings_out-2windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-6coupling-2e10-drive-': ParameterizedMeas({ + (-1.000, 1.000,): [ + MeasRow(4e-09, [-17712, -20248, -18458, 16667, -18884, -17397]), + MeasRow(6e-09, [-16797, -16215, -30295, -30287, -2598, -16887]), + ], + ( 0.000, 0.000,): [ + MeasRow(4e-09, [-17598, -19619, 10712, 10717, -19619, -17596]), + MeasRow(6e-09, [-16873, -6765, -30283, -30283, -6787, -16872]), + ], + ( 0.200, -0.200,): [ + MeasRow(4e-09, [-17448, -19132, 16323, -18147, -20033, -17662]), + MeasRow(6e-09, [-16889, -2913, -30286, -30293, -15978, -16796]), + ], + ( 1.000, -1.000,): [ + MeasRow(4e-09, [-17397, -18883, 16669, -18456, -20247, -17710]), + MeasRow(6e-09, [-16888, -2580, -30286, -30295, -16234, -16799]), + ], + }), + '61-buf-pos_out-2_1windings_in-0_0windings_out-1windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-8coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16863, -16729, 17385, -19143, -18169, 16866]), + MeasRow(6e-09, [ 13832, 16789, -30869, -30886, -14705, 14109]), + ], + }), + '61-buf-pos_out-2_1windings_in-0_0windings_out-2windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-8coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16864, -17281, 17418, -19440, -18751, 16864]), + MeasRow(6e-09, [ 14383, 13495, -30870, -30877, -16556, 14548]), + ], + }), + '61-buf-pos_out-2_1windings_in-1_1windings_out-1windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-8coupling-2e10-drive-': ParameterizedMeas({ + ( 0.000, 0.000,): [ + MeasRow(4e-09, [ 16354, -17564, 11558, 11572, -17568, 16342]), + MeasRow(6e-09, [ -1324, 6443, -30869, -30870, 6425, -1318]), + ], + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16544, -16772, 17539, -19164, -18620, 16333]), + MeasRow(6e-09, [ -6945, 14172, -30871, -30877, -12582, 10629]), + ], + }), + '61-buf-pos_out-2_1windings_in-1_2windings_out-1windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-7coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 17330, -16156, 17283, -18651, -17792, 17061]), + MeasRow(6e-09, [ 2782, 15481, -30707, -30714, -12134, 13898]), + ], + }), + '61-buf-pos_out-2_1windings_in-1_2windings_out-1windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-8coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 17689, -16694, 17701, -19387, -18319, 17617]), + MeasRow(6e-09, [ 11997, 2393, -30871, -30872, -13275, 15689]), + ], + }), + '61-buf-pos_out-2_1windings_in-2_1windings_out-2windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-6coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16187, -17741, 16913, -18248, -19226, 16098]), + MeasRow(6e-09, [ -2905, 1055, -30287, -30296, -14558, 10198]), + ], + }), + '61-buf-pos_out-4_1windings_in-0_0windings_out-1windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-6coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16866, -16456, 17771, -19027, -17659, 16868]), + MeasRow(6e-09, [ 13711, 16773, -30281, -30297, -13352, 13914]), + ], + }), + '61-buf-pos_out-4_1windings_in-0_0windings_out-2windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-5coupling-2e10-drive-': ParameterizedMeas({ + ( 0.000, 0.000,): [ + MeasRow(4e-09, [ 16872, -17018, 8560, 8555, -17019, 16870]), + MeasRow(6e-09, [ 13357, 2370, -30113, -30110, 2354, 13486]), + ], + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16873, -16809, 17401, -18429, -17508, 16870]), + MeasRow(6e-09, [ 13109, 15769, -30113, -30142, -16332, 13296]), + ], + }), + '61-buf-pos_out-6_1windings_in-0_0windings_out-2windings_couple-0.0004rad-2000ctl_cond-20000coupling_cond-2000ps-100ps-4coupling-2e10-drive-': ParameterizedMeas({ + ( 1.000, -1.000,): [ + MeasRow(4e-09, [ 16857, -16663, 17505, -18247, -17239, 16857]), + MeasRow(6e-09, [ 13464, 10716, -27951, -27983, -15026, 13941]), + ], + }), } \ No newline at end of file diff --git a/crates/applications/stacked_cores/src/main.rs b/crates/applications/stacked_cores/src/main.rs index 79d95fd..4063ac2 100644 --- a/crates/applications/stacked_cores/src/main.rs +++ b/crates/applications/stacked_cores/src/main.rs @@ -1378,6 +1378,20 @@ fn drive_map_complementary_buf_edge_inputs_59(amp0: f32, amp1: f32) -> [[ClockSt ] } +#[allow(unused)] +fn drive_map_complementary_buf_center_inputs_61(amp0: f32, amp1: f32, amp_load: f32) -> [[ClockState; 6]; 3] { + use ClockState as C; + // amplitudes are inverted from what you would expect. + // hold(-1) puts the core into a positive M + [ + // init S0, S5 as load, S2 pos, S3 pos/inp; charge S1 neg, S4 neg + [C::hold(-amp_load), C::hold_high(), C::hold(-amp0), C::hold(-amp1), C::hold_high(), C::hold(-amp_load), ], + [C::release(-amp_load), C::release_high(), C::release(-amp0), C::release(-amp1), C::release_high(), C::release(-amp_load),], + // clear S2 -> S1, S3 -> S4 + [C::float(), C::float(), C::hold_high(), C::hold_high(), C::float(), C::float(), ], + ] +} + #[allow(unused)] fn drive_map_split_54(amp: f32) -> [[ClockState; 3]; 4] { use ClockState as C; @@ -1593,6 +1607,21 @@ fn asymmetric_binary_gate_name_v2(p: &Params, sim_id: &str, ctl_loops: u32, coup format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{ctl_loops}ctl-{coupling_loops}coupling-{windings_a}_1_{windings_b}_1_winding-{input_str}-drive-{init_level_a}-{init_level_b}") } +fn gate_name_custom_2_input(p: &Params, sim_id: &str, init_flt0: f32, init_flt1: f32) -> String { + let init_level0 = init_float_str(init_flt0); + let init_level1 = init_float_str(init_flt1); + + let s_major = p.s_major; + let ctl_cond = p.ctl_conductivity as u64; + let coupling_cond = p.coupling_conductivity as u64; + let clock_length = (p.clock_phase_duration * 1e12 + 0.5) as u64; + let clock_decay = (p.clock_decay * 1e12 + 0.5) as u64; + let coupling_loops = p.coupling_loops; + + let input_str = exp_format(p.input_magnitude); + format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{coupling_loops}coupling-{input_str}-drive-{init_level0}-{init_level1}") +} + /// couple `sender` to the `sender+1` core by using `loops` loops, including a crossover so that /// when the sender goes high -> low, the receiver *also* goes high -> low ("inverting"). /// `loops` must be >= 1. @@ -7057,6 +7086,198 @@ fn main() { } } } + + if true { + for init_set in [ + // M2, M3 are treated as X and -X, respectively. + // because it's differential, testing (-1, 1) is sort of extraneous with (1, -1). + // generally only need to test the X > 0 region, if X == -X. + // but also test some cases where X != -X, due to error + &[ + // establish rough domain/range + ( 1.00, -1.00), + ][..], + &[ + ( 0.00, 0.00), + // (-1.00, 1.00), // technically extraneous + ( 0.20, -0.20), + ( 0.10, -0.10), + // (-1.00, -1.00), // uninitialized case + ][..], + // &[ + // // negative side + // (-0.10, 0.10), + // (-0.20, 0.20), + // (-0.25, 0.25), + // (-0.05, 0.05), + // (-0.15, 0.15), + // (-0.02, 0.02), + // (-0.07, 0.07), + // (-0.12, 0.12), + // (-0.17, 0.17), + // (-0.22, 0.22), + // ][..], + &[ + // more detailed sweep + ( 0.30, -0.30), + ( 0.05, -0.05), + ( 0.15, -0.15), + ( 0.25, -0.25), + ][..], + &[ + // even more verbosity + ( 0.02, -0.02), + ( 0.07, -0.07), + ( 0.12, -0.12), + ( 0.17, -0.17), + ( 0.22, -0.22), + ][..], + &[ + // bias M2 to be 0.15 lower what we expect + (-0.20, 0.05), + (-0.10, -0.05), + (-0.25, 0.10), + (-0.05, -0.10), + ( 0.00, -0.15), + (-0.15, 0.00), + ( 0.10, -0.25), + ( 0.20, -0.35), + ], + &[ + // test some asymmetries -- specifically where A1 is higher than expected + ( 0.20, 0.00), + ( 0.20, -0.10), + ( 0.20, 0.10), + ( 0.30, 0.00), + ( 0.30, -0.20), + ( 0.30, -0.10), + ( 0.10, 0.00), + + ( 0.00, -0.10), + (-0.10, -0.30), + (-0.05, -0.20), + ][..], + &[ + // unexpected scenarios + (-0.20, -0.20), + (-0.10, -0.10), + ( 0.10, 0.10), + ][..], + ] { + for (init_out, ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, out_couple_slots, inp_slots, inp_recv_slots, out_slots, out_recv_slots, s_major, cur_flt) in [ + // total slot use is L*(A + Yc + Yl + 1), + // where L is the "coupling loops" and A is the inp_slots (half "asymmetric loops"), + // Yc is out_couple_slots, Yl is out_slots + // e.g. L= 6, Yc=2, A=2, Yl=2 gives 6*7 = 42 + // e.g. L= 7, Yc=1, A=2, Yl=2 gives 7*6 = 42 + // e.g. L= 8, Yc=1, A=2, Yl=1 gives 8*5 = 40 + // special case of A=0 is L*(2 + 1) + + // areas of focus (annotated further below) + ("pos", 2e3, 2e4, ps(2000), ps(100), 5, 2, 4, 1, 0, 0, um(400), 2e10), + ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 0, 0, um(400), 2e10), + + // // (16700, -18500) -> (-2600, -16200) + // // ("neg", 2e3, 2e4, ps(2000), ps(100), 6, 2, 2, 1, 2, 1, um(400), 2e10), // asym load + + // // (17200, -19500) -> (8000, -14400) + // ("neg", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 1, 1, um(400), 2e10), // sym load, min + // // (16900, -18200) -> (1100, -14600) + // // ("pos", 2e3, 2e4, ps(2000), ps(100), 6, 2, 2, 1, 2, 1, um(400), 2e10), // asym load + + // // (17500, -19200) -> (14200, -12600) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 1, 1, um(400), 2e10), // sym load, min + // // SUS: too many slots (48) + // // (17700, -19400) -> (2400, -13300) + // // ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 1, 2, um(400), 2e10), + // // (17300, -18700) -> (15500, -12100) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 7, 1, 2, 1, 1, 2, um(400), 2e10), + + // // recreating 53-xx + // // (17400, -19400) -> (13500, -16600) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 2, 2, 1, 0, 0, um(400), 2e10), + + // // 53-xx with less out-core coupling + // // (17400, -19100) -> (16800, -14700) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 0, 0, um(400), 2e10), + // // (17800, -19000) -> (16800, -13400) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 6, 1, 4, 1, 0, 0, um(400), 2e10), + // // **SELECT: (17400, -18400) -> (15800, -16300) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 5, 2, 4, 1, 0, 0, um(400), 2e10), + // // (17500, -18200) -> (10700, -15000) + // ("pos", 2e3, 2e4, ps(2000), ps(100), 4, 2, 6, 1, 0, 0, um(400), 2e10), + ] { + for &(init_flt_a, init_flt_b) in init_set { + // each core is coupled to 1, 2, or 3 others + control slots + // M2 -> M1 & M3 -> M4 are asymmetric (tx input -> output) + // M1 <-> M4 is symmetrics (outputs) + // M1 -> M0, M4 -> M5 may be asym or not + let slots_into_out = inp_slots.max(inp_recv_slots); + let slots_out_of_out = out_slots.max(out_recv_slots); + let slots_between_out = out_couple_slots; + let net_slots = slots_into_out + slots_out_of_out + slots_between_out + 1; + let mut params = params_v2 + .with_clock_phase_duration(clock_duration) + .with_clock_decay(clock_decay) + .with_ctl_conductivity(ctl_cond) + .with_coupling_conductivity(coupling_cond) + .with_s_major(s_major) + .with_coupling_loops(coupling_loops) + .with_input_magnitude(cur_flt) + // control loops + .with_coupling(0, 0, 0, net_slots, CouplingMethod::Control) + .with_coupling(1, 1, 0, net_slots, CouplingMethod::Control) + .with_coupling(2, 2, 0, net_slots, CouplingMethod::Control) + .with_coupling(3, 3, 0, net_slots, CouplingMethod::Control) + .with_coupling(4, 4, 0, net_slots, CouplingMethod::Control) + .with_coupling(5, 5, 0, net_slots, CouplingMethod::Control) + ; + if inp_slots != inp_recv_slots { + // couple input M2 -> output M1 + params = couple_asymmetric_buffer_bi(¶ms, 1 /* low core */, inp_recv_slots/2, inp_slots/2, 1 /* slot offset */, net_slots); + // couple input M3 -> output M4 + params = couple_asymmetric_buffer_bi(¶ms, 3 /* low core */, inp_slots/2, inp_recv_slots/2, 1 /* slot offset */, net_slots); + } else { + for i in 0..inp_slots { + params = params.with_coupling(1, 2, 1+i, net_slots, CouplingMethod::Direct); + params = params.with_coupling(3, 4, 1+i, net_slots, CouplingMethod::Direct); + } + } + if out_slots != out_recv_slots { + // couple output M1 -> load M0 + params = couple_asymmetric_buffer_bi(¶ms, 0 /* low core */, out_recv_slots/2, out_slots/2, 1 + slots_into_out /* slot offset */, net_slots); + // couple output M4 -> load M5 + params = couple_asymmetric_buffer_bi(¶ms, 4 /* low core */, out_slots/2, out_recv_slots/2, 1 + slots_into_out /* slot offset */, net_slots); + } else { + for i in 0..out_slots { + params = params.with_coupling(0, 1, 1+slots_into_out+i, net_slots, CouplingMethod::Direct); + params = params.with_coupling(4, 5, 1+slots_into_out+i, net_slots, CouplingMethod::Direct); + } + } + for i in 0..slots_between_out { + // couple output M1 to output M4 + params = params.with_coupling(1, 4, 1+slots_into_out+slots_out_of_out+i, net_slots, CouplingMethod::Outside); + } + let name = gate_name_custom_2_input( + ¶ms, + &format!("61-buf-{init_out}_out-{inp_slots}_{inp_recv_slots}windings_in-{out_slots}_{out_recv_slots}windings_out-{slots_between_out}windings_couple"), + init_flt_a, + init_flt_b, + ); + let init_flt_out = match init_out { + "pos" => 1.0, + "neg" => -1.0, + _ => panic!(), + }; + run_sim( + &name, + drive_map_complementary_buf_center_inputs_61(init_flt_a, init_flt_b, init_flt_out), + params, + ); + } + } + } + } }