gm/Id — Bias Levels

Tune the constructed bias generator’s level devices (gm/Id pipeline).

The demand-driven bias generator (synthesizer bias_construction.py + config/bias_legs.yaml) contains two kinds of devices whose operating point is a level choice, not a mirror ratio, so the intent-table geometry pass cannot size them:

  • Cascode-leg level diodes (cascode_gnd/cascode_vdd legs): the rail must sit at the consumer cascode’s V_GS plus its stack’s saturation floor. The leg’s diode covers the V_GS part (re-sized here to match the consumers’ planned V_GS, so the rail tracks Vth over process/temperature) and the floor resistor under it covers the small Vdsat floor (R = floor / I_leg).

  • The pref branch’s wide-swing cascode level (ncasc): the branch’s NMOS mirror is cascoded to pin its Vds near the master reference’s (uncascoded it runs at vdd - |V_GSP| – the ~4% extra-mirror-hop error of issue #103’s A/B). The ncasc diode is sized narrow (high V_GS) to push the pinned Vds as close to the master’s V_GS as the LUT range and the pref node’s headroom allow; the cascode itself is re-sized to the weak-inversion end (low V_GS and Vdsat) to maximize that reach.

Both detections are structural (actual device terminals – a diode riding a resistor to a supply, a mirror-drain cascode topped by a diode), so external netlists without these shapes pass through untouched. Runs after geometry and the DC operating-point check; its resistor values override the generic fallback size_resistors() assigns to nets it cannot derive.

circuitgenome.sizer.gmid.bias_levels.tune_bias_levels(blocks, ids_map, sizing, model, spec, tech)[source]

Return (sizing, level_resistors) with the bias levels tuned.

The input mapping is never mutated. level_resistors carries the cascode legs’ floor-resistor values; merge it over the generic values from size_resistors() (which cannot derive a level for a mid net and falls back to its representative value).

Parameters:
Return type:

tuple[dict[str, TransistorSizing], dict[str, float]]