Skip to main content

logicaffeine_compile/codegen_ana/
dims.rs

1//! The ADL dimension census — every numeric field of the characterized descriptors
2//! ([`AnalogTarget`](super::target::AnalogTarget), [`NonIdealityModel`](super::nonideal::NonIdealityModel))
3//! declares its physical dimension, ONCE, here.
4//!
5//! Dimensionless is a CLAIM, not a default: counts, ratios, and exponents say so explicitly.
6//! `analog_dimension_lock` holds full struct literals of both descriptors, so ADDING a field
7//! breaks the lock at compile time until it is consciously censused — and pins the naming
8//! convention (`*_v` ⇒ voltage, `*_ns` ⇒ time, `*_k_range` ⇒ frequency) so a field cannot
9//! lie about its unit in its name.
10
11use logicaffeine_base::dimension::Dimension;
12
13/// Every numeric field of the ADL, with its declared dimension. Names are
14/// `Type::field` — exactly one row per field, no field left out (the lock cross-checks
15/// against compile-guarded struct literals).
16pub fn adl_dimensions() -> Vec<(&'static str, Dimension)> {
17    let d = Dimension::DIMENSIONLESS;
18    vec![
19        // ── AnalogTarget: array geometry and resources (counts) ──
20        ("AnalogTarget::rows", d),
21        ("AnalogTarget::cols", d),
22        ("AnalogTarget::mul_tiles", d),
23        ("AnalogTarget::sum_fanin", d),
24        ("AnalogTarget::weight_bits", d),
25        ("AnalogTarget::dac_bits", d),
26        ("AnalogTarget::adc_bits", d),
27        ("AnalogTarget::n_dac", d),
28        ("AnalogTarget::n_adc", d),
29        // ── AnalogTarget: physical figures ──
30        ("AnalogTarget::rails_v", Dimension::voltage()),
31        ("AnalogTarget::headroom", d),
32        ("AnalogTarget::weight_range", d),
33        ("AnalogTarget::mul_vref_options_v", Dimension::voltage()),
34        ("AnalogTarget::scale_log2_range", d),
35        ("AnalogTarget::integrator_k_range", Dimension::frequency()),
36        ("AnalogTarget::settle_ns", Dimension::time()),
37        // ── NonIdealityModel ──
38        ("NonIdealityModel::weight_gain_sigma", d),
39        ("NonIdealityModel::gm_distance_sigma_per_pitch", d),
40        ("NonIdealityModel::offset_sigma_v", Dimension::voltage()),
41        ("NonIdealityModel::noise_floor_v", Dimension::voltage()),
42        ("NonIdealityModel::cross_tier_gain_sigma", d),
43        (
44            "NonIdealityModel::gain_tempco_per_k",
45            Dimension::temperature().recip(),
46        ),
47        (
48            "NonIdealityModel::offset_tempco_v_per_k",
49            Dimension::voltage().div(Dimension::temperature()),
50        ),
51        ("NonIdealityModel::chop_residual_v", Dimension::voltage()),
52    ]
53}