Source code for circuitgenome.sizer.gmid.gmid_sizer

"""Orchestrator for the block-based gm/Id sizing pipeline.

``size_gmid`` runs the gm/Id path end-to-end, separate from the Level-1 CP-SAT
sizer, as five phases with explicit hand-offs:

1. **Analyze** (:mod:`.analyze`) — structural view: slots, blocks, cascodes,
   topology-mismatch warnings → :class:`~.analyze.CircuitView`.
2. **Bias currents** (:mod:`.plan`) — per-device IDS from KCL + ``spec.ibias``
   and the rail-referenced load resistors → :class:`~.plan.CurrentPlan`.
3. **Plan** (:mod:`.plan`) — per-stage gm requirements and compensation caps
   from the spec, per-device design intent from the functional-block registry
   → :class:`~.plan.SizingPlan`.
4. **Size** — deterministic geometry from the LUT (:mod:`.geometry`), the DC
   operating-point check and tail repair (:mod:`.bias`), the stage-interface
   window check and repair (:mod:`.stage_interface`), the non-load
   resistor network (:mod:`.resistors`), and the constructed-bias level
   tuning (:mod:`.bias_levels`).
5. **Evaluate** (:mod:`.evaluate`) — cascode-aware analytical metrics.

The model-independent topology math is reused from the
``circuitgenome.sizer.shared`` package rather than duplicated.
"""
from __future__ import annotations

from circuitgenome.recognizer.models import (
    FunctionalBlockRecognitionResult,
    ParsedNetlist,
    SubcircuitRecognitionResult,
)
from circuitgenome.synthesizer.models import TopologyTemplate

from ..shared.models import SizingResult, SizingSpec, TechParams
from .analyze import analyze_circuit
from .bias import check_dc_operating_point
from .bias_levels import tune_bias_levels
from .evaluate import evaluate_circuit
from .geometry import assign_geometry_gmid
from .intent import DEFAULT_INTENT, GmIdIntent
from .plan import assign_currents, plan_devices
from .resistors import size_resistors
from .stage_interface import check_stage_interface


[docs] def size_gmid( parsed: ParsedNetlist, sr_result: SubcircuitRecognitionResult, fbr_result: FunctionalBlockRecognitionResult, topology: TopologyTemplate, tech: TechParams, spec: SizingSpec, intent: GmIdIntent = DEFAULT_INTENT, ) -> SizingResult: """Size a circuit via the gm/Id pipeline. Requires ``tech.gmid_lut``.""" # Phase 1 — Analyze: structural view of the recognised circuit. view = analyze_circuit(fbr_result, topology) # Phase 2 — Bias currents: IDS from KCL, rail-referenced load resistors. currents = assign_currents(view, spec, tech) # Phase 3 — Plan: gm requirements + compensation caps + per-device intent. plan = plan_devices(view, currents, spec, tech, intent) # Phase 4 — Size: LUT geometry, DC bias check/repair, resistor network. sizing, geom_warnings, geom_feasible = assign_geometry_gmid( plan.model, view.all_transistors, view.slot_transistors, currents.ids_map, plan.tintents, plan.gm_req_map, tech, vod_max_map=plan.vod_max_map) sizing, dc_warnings, bias_feasible = check_dc_operating_point( plan.model, view.blocks, view.slot_transistors, view.all_transistors, currents.ids_map, sizing, spec, tech) sizing, si_warnings, si_feasible = check_stage_interface( plan.model, view.blocks, sizing, plan.gm_req_map, spec, tech) bias_feasible = bias_feasible and si_feasible and geom_feasible extra_r, modifiers = size_resistors( view.blocks, view.slot_resistors, currents.ids_map, sizing, plan.model, spec, tech, intent, cc_pf=plan.cc_pf, cc2_pf=plan.cc2_pf) sizing, level_r = tune_bias_levels( view.blocks, currents.ids_map, sizing, plan.model, spec, tech) extra_r = {**extra_r, **level_r} # Phase 5 — Evaluate: analytical (ngspice-free) metrics from the sizing. metrics, margins, eval_notes = evaluate_circuit( view, currents, plan, sizing, modifiers, spec, tech) return SizingResult( transistors=sizing, cc_pf=plan.cc_pf, metrics=metrics, margins=margins, solver_status="GMID", cc2_pf=plan.cc2_pf, warnings=(view.warnings + plan.warnings + geom_warnings + dc_warnings + si_warnings + eval_notes), resistors={**currents.load_resistors, **extra_r}, bias_feasible=bias_feasible, transistor_intents=plan.tintents, )