Functional Block Recognizer

Layer 2 — Functional Block Recognizer (FBR).

Two modes:

  • Topology mode (assign_slots()): requires a TopologyTemplate. Assigns each slot to its best-matching SR candidate using expected net connectivity (_connectivity_score). Handles repeated-category slots (e.g. two compensation slots in a fully-differential topology).

  • Topology-free mode (group_by_category()): no topology needed. Groups SR structures by circuit_block (outer) and category (inner) using a three-pass algorithm: (1) filter pass for single-category gain_stage_* blocks — three classes of spurious candidates are dropped: (A) in pin on an external port (bias nmos re-matched as a gain stage); (B) bias pin on an external port (bias mirror pmos re-matched); (C) any nmos device whose source is not gnd! (cascode load devices); (2) multi-category gain_stage_* pass (gain_stage_1) — re-sorts input_pair candidates by the count of distinct external ports among {in1, in2} (real differential pairs have both signal inputs on distinct external ports; bias mirrors and spurious stage-device pairs do not), then uses the top input_pair result to guide load and tail_current via signal-chain following (load.in1/in2 matched against input_pair.out1/out2; tail_current.out matched against input_pair.tail), with external-port exclusion filters applied to each category first; (3) split pass — single-category gain_stage_* blocks with more than one remaining candidate are split into consecutive gain_stage_N groups ordered by ascending external-port adjacency, enabling disambiguation of three-stage opamp stages without a topology.

circuitgenome.recognizer.functional_block_recognizer.group_by_category(sr_result, netlist)[source]

Group SR structures by circuit block and category without a topology.

Produces a CategoryGroupResult whose groups dict is keyed first by circuit_block (e.g. "gain_stage_1", "gain_stage_2", "bias") then by category (e.g. "input_pair", "load"). Structures with circuit_block=None (primitives, structural composites) are excluded.

Two-pass algorithm:

  1. Filter pass — for every gain_stage_* candidate that has an in pin, check whether that pin’s net is an external port. Real gain stages receive their input from an internal intermediate net (the previous stage’s output); spurious matches arise when an input-pair nmos or a bias device is re-matched by a gain-stage pattern, putting in1/ in2 or ibias on the in pin. Removing those candidates eliminates the majority of SR noise before the split pass.

  2. Split passgain_stage_* blocks that have exactly one remaining category and more than one remaining candidate are split into consecutive gain_stage_N groups ordered by ascending _external_port_score(). The instance whose out pin connects to the external output port scores highest and is promoted to the highest-numbered stage. Blocks with multiple categories (e.g. gain_stage_1 which holds input_pair, load, and tail_current) are never split; their candidates are simply sorted descending and the top-1 is the best topology-free guess.

Parameters:
Returns:

CategoryGroupResult with grouped, ranked candidates and unrecognized_devices passed through unchanged.

Return type:

CategoryGroupResult

circuitgenome.recognizer.functional_block_recognizer.assign_slots(sr_result, topology)[source]

Assign each Slot in topology.slots to its best-matching SR candidate.

For each slot, candidates are filtered by category == category, then ranked by _connectivity_score() against slot_connections() for that slot. The highest-scoring candidate is assigned (design doc section 6.3, steps 2-3). A slot with no candidates of its category is silently omitted from slot_assignments.

Connectivity scoring is applied even when a category has only one slot: SR’s patterns can structurally overlap (e.g. current_mirror_tail_nmos also matches the bias-generation reference’s diode-connected pair), so a category can have multiple candidates regardless of how many slots need it. Once a candidate is assigned to a slot its id is added to assigned_ids so it cannot be double-assigned to a second slot of the same category (e.g. comp_p/comp_n in two_stage_opamp_fully_differential).

Parameters:
Returns:

A FunctionalBlockRecognitionResult with one SlotAssignment per filled slot (slot_assignments), every unassigned candidate structure in unassigned_structures, and unrecognized_devices passed through unchanged from sr_result.

Return type:

FunctionalBlockRecognitionResult