Compensation Compatibility¶
Compensation inversion-parity compatibility filter for
enumerate_circuits().
Every compensation variant in the library is Miller-family: it couples
its in port to its out port through a capacitor (directly, through a
nulling resistor, or via an internal series node). Wired across a stage
chain, that coupling is negative feedback – pole splitting – only when
the wrapped chain is inverting. Around a non-inverting chain with gain the
same capacitor is positive feedback: the AC response develops a
right-half-plane character and gain/GBW/PM become unmeasurable (issue #114:
differential_ota_second_stage, two cascaded common-source stages, PM
measured 270-281 deg with every compensation variant).
The parity of a chain is the number of common-source inversions along its
in -> out device path:
a common-source hop (signal enters a gate, exits the drain) inverts;
a follower hop (signal enters a gate, exits the source) does not invert – and contributes no gain, so a Miller capacitor around a pure follower chain is bootstrapped to
C*(1-A) ~ 0: useless but benign, NOT positive feedback. Followers are therefore deliberately allowed (a strict odd-parity rule would ban them and undo issue #110).
The reject condition is a chain whose total inversion count is a positive
even number – non-inverting with gain. This also covers composite
chains: in the nested-Miller 3-stage topologies comp1 wraps the
second+third stage cascade (net_mid1 -> out), where two common-source
stages compose to the same positive-feedback structure (standard NMC
requires a non-inverting second stage and an inverting output stage).
The check is structural (actual device terminal references, no YAML
tags, same approach as second_stage):
a stage variant’s inversion count is computed by walking gate-to-drain /
gate-to-source hops from its in port, and chains are composed by
following second_stage-category slots’ in/out nets between the
compensation slot’s in and out nets. Anything unclassifiable (a
compensation variant that does not couple in to out, a chain the
walk cannot follow, a stage with no device gating in) imposes no
constraint.
- circuitgenome.synthesizer.compatibility.compensation.stage_inversions(variant)[source]¶
Return the number of common-source inversions along variant’s
in -> outdevice chain, orNoneif the chain cannot be followed (no device gatesin, a dangling hop, or a cycle).Each hop enters a MOSFET gate; leaving through the drain counts one inversion (common source), leaving through the source counts none (follower). A diode-connected device (
d == g == net) is skipped at a fork – it terminates a branch (e.g. a current-mirror master) rather than carrying the signal forward – so the walk follows the mirror-output device instead.common_source_nmos/common_source_pmos-> 1,common_drain_pmos/common_drain_nmos-> 0,differential_ota_second_stage-> 2,noninverting_stage_nmos/noninverting_stage_pmos-> 2 (CS inversion + current-mirror inversion).- Parameters:
variant (ModuleVariant)
- Return type:
int | None
- circuitgenome.synthesizer.compatibility.compensation.is_compensation_compatible(topology, variant_map)[source]¶
Return
Falseif anycompensationslot that couples itsinandoutnets wraps a stage chain whose total inversion count is a positive even number – non-inverting with gain, i.e. positive feedback through the compensation network (see the module docstring for the electrical rationale).- Parameters:
topology (TopologyTemplate)
variant_map (dict[str, ModuleVariant])
- Return type: