Load Branch Compatibility

Untapped-load-branch compatibility filter for enumerate_circuits().

In every single_ended topology only one of the first stage’s two branch nodes is tapped: load.out/out2 land on the stage-output net (inside the feedback loop, or at least observed by the next stage), while load.in1/out1 (net_diff1) is untapped – nothing outside the first stage senses or drives it. That node’s DC voltage must therefore be defined by the load itself. A load branch that is a plain, rail-referenced current source (issue #112: current_source_load_* – gate on a bias rail, no diode connection) leaves the untapped node high-impedance between two series current sources: the load device on one side, the input-pair half plus tail on the other. Any mismatch between the two currents – and there is always some – collapses the node until one device leaves saturation; no sizing can fix it, because there is no mechanism (diode, resistor, CMFB, or feedback) to absorb the difference. This is the textbook reason plain current-source loads are only used with common-mode control.

The check is structural (actual device terminal references, no YAML tags, same approach as second_stage): the untapped branch node (port in1) counts as DC-defined when the load contains

  • a diode-connected MOSFET on it (g == d == in1 – the mirror loads’ reference side, active_load_*),

  • a resistor touching it (resistor_load_*), or

  • a MOSFET source terminal on it (the cascode loads’ folding/cascode devices: the device’s gate rail pins the node one V_GS away).

Loads whose devices never put a MOSFET drain on in1 are not constrained (no current is forced into the node, so nothing needs to absorb a mismatch). fully_differential topologies tap both branches (net_loadout1/ net_loadout2) and are out of scope here – there the common-mode definition is the CMFB loop’s job (see cmfb).

To extend: nothing to tag – a new load variant is classified by what its devices connect to in1, and a new topology is covered by its output_type (single_ended templates leave in1’s net untapped by the wiring convention documented in config/opamp_topologies.yaml).

circuitgenome.synthesizer.compatibility.load_branch.untapped_branch_is_dc_defined(load)[source]

Return True if load defines the DC voltage of its untapped branch node (port in1), or forces no current into it at all – see the module docstring for the electrical rationale.

Parameters:

load (ModuleVariant)

Return type:

bool

circuitgenome.synthesizer.compatibility.load_branch.is_load_branch_compatible(topology, variant_map)[source]

Return False if topology leaves the load’s in1 branch node untapped (output_type: single_ended) and the load doesn’t define its DC voltage (see the module docstring for the electrical rationale).

Parameters:
Return type:

bool