Extract template registries into templates.py
The two inline registries (_TEMPLATES, _ASC_TEMPLATES) plus their ~30 generator-function imports were pure data living in server.py. Move them to a dedicated templates.py as NETLIST_TEMPLATES / ASC_TEMPLATES, and add resolve_template() (netlist-first precedence) + all_template_names() to replace the '.get() or .get()' dual-lookup dance that tune_circuit used. server.py: 3257 -> 2949 lines. Registries verified byte-identical to the originals (keys, params, descriptions, func identities); netlist-first precedence for names in both registries preserved; live tune_circuit / create_from_template / generate_schematic unchanged.
This commit is contained in:
parent
7c4f09cbb3
commit
c71b3bbb4c
@ -21,51 +21,6 @@ import numpy as np
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.prompts import Message
|
||||
|
||||
from .asc_generator import (
|
||||
generate_boost_converter as generate_boost_converter_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_buck_converter as generate_buck_converter_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_colpitts_oscillator as generate_colpitts_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_common_emitter_amp as generate_ce_amp_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_current_mirror as generate_current_mirror_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_differential_amp as generate_diff_amp_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_h_bridge as generate_h_bridge_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_instrumentation_amp as generate_inamp_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_inverting_amp,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_ldo_regulator as generate_ldo_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_non_inverting_amp as generate_noninv_amp_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_rc_lowpass as generate_rc_lowpass_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_sallen_key_lowpass as generate_sallen_key_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_transimpedance_amp as generate_tia_asc,
|
||||
)
|
||||
from .asc_generator import (
|
||||
generate_voltage_divider as generate_voltage_divider_asc,
|
||||
)
|
||||
from .batch import (
|
||||
run_monte_carlo,
|
||||
run_parameter_sweep,
|
||||
@ -82,24 +37,7 @@ from .drc import run_drc as _run_drc
|
||||
from .log_parser import parse_log
|
||||
from .models import search_models as _search_models
|
||||
from .models import search_subcircuits as _search_subcircuits
|
||||
from .netlist import (
|
||||
Netlist,
|
||||
boost_converter,
|
||||
buck_converter,
|
||||
colpitts_oscillator,
|
||||
common_emitter_amplifier,
|
||||
current_mirror,
|
||||
differential_amplifier,
|
||||
h_bridge,
|
||||
instrumentation_amplifier,
|
||||
inverting_amplifier,
|
||||
ldo_regulator,
|
||||
non_inverting_amplifier,
|
||||
rc_lowpass,
|
||||
sallen_key_lowpass,
|
||||
transimpedance_amplifier,
|
||||
voltage_divider,
|
||||
)
|
||||
from .netlist import Netlist
|
||||
from .noise_analysis import (
|
||||
compute_noise_metrics,
|
||||
compute_spot_noise,
|
||||
@ -122,6 +60,12 @@ from .spicebook import (
|
||||
)
|
||||
from .stability import compute_stability_metrics
|
||||
from .svg_plot import plot_bode, plot_spectrum, plot_timeseries, plot_timeseries_multi
|
||||
from .templates import (
|
||||
ASC_TEMPLATES,
|
||||
NETLIST_TEMPLATES,
|
||||
all_template_names,
|
||||
resolve_template,
|
||||
)
|
||||
from .touchstone import parse_touchstone, s_param_to_db
|
||||
from .waveform_expr import WaveformCalculator
|
||||
from .waveform_math import (
|
||||
@ -1200,7 +1144,7 @@ async def tune_circuit(
|
||||
|
||||
Args:
|
||||
template: Template name (from list_templates). Works with both
|
||||
netlist templates (_TEMPLATES) and schematic templates (_ASC_TEMPLATES).
|
||||
netlist templates (NETLIST_TEMPLATES) and schematic templates (ASC_TEMPLATES).
|
||||
params: Component value overrides (e.g., {"r": "2.2k", "c": "47n"}).
|
||||
Use list_templates to see available parameters.
|
||||
targets: Performance targets to check against. Each key is a metric name,
|
||||
@ -1213,14 +1157,12 @@ async def tune_circuit(
|
||||
Returns:
|
||||
Dict with metrics, target comparison, and tuning suggestions.
|
||||
"""
|
||||
# --- 1. Look up template ---
|
||||
tmpl = _TEMPLATES.get(template)
|
||||
is_netlist = tmpl is not None
|
||||
if tmpl is None:
|
||||
tmpl = _ASC_TEMPLATES.get(template)
|
||||
if tmpl is None:
|
||||
names = sorted(set(list(_TEMPLATES.keys()) + list(_ASC_TEMPLATES.keys())))
|
||||
# --- 1. Look up template (netlist registry first) ---
|
||||
found = resolve_template(template)
|
||||
if found is None:
|
||||
names = all_template_names()
|
||||
return {"error": f"Unknown template '{template}'. Available: {', '.join(names)}"}
|
||||
tmpl, is_netlist = found
|
||||
|
||||
# --- 2. Build effective params ---
|
||||
effective_params: dict[str, str] = dict(tmpl["params"])
|
||||
@ -1773,103 +1715,6 @@ async def monte_carlo(
|
||||
# ============================================================================
|
||||
|
||||
|
||||
_ASC_TEMPLATES: dict[str, dict] = {
|
||||
"rc_lowpass": {
|
||||
"func": generate_rc_lowpass_asc,
|
||||
"description": "RC lowpass filter with AC analysis",
|
||||
"params": {"r": "1k", "c": "100n"},
|
||||
},
|
||||
"voltage_divider": {
|
||||
"func": generate_voltage_divider_asc,
|
||||
"description": "Resistive voltage divider with .op analysis",
|
||||
"params": {"r1": "10k", "r2": "10k", "vin": "5"},
|
||||
},
|
||||
"inverting_amp": {
|
||||
"func": generate_inverting_amp,
|
||||
"description": "Inverting op-amp amplifier (gain = -Rf/Rin)",
|
||||
"params": {"rin": "10k", "rf": "100k"},
|
||||
},
|
||||
"non_inverting_amp": {
|
||||
"func": generate_noninv_amp_asc,
|
||||
"description": "Non-inverting op-amp amplifier (gain = 1 + Rf/Rin)",
|
||||
"params": {"rin": "10k", "rf": "100k"},
|
||||
},
|
||||
"common_emitter_amp": {
|
||||
"func": generate_ce_amp_asc,
|
||||
"description": "Common-emitter BJT amplifier with voltage divider bias",
|
||||
"params": {
|
||||
"rc": "2.2k", "rb1": "56k", "rb2": "12k", "re": "1k",
|
||||
"cc_in": "10u", "cc_out": "10u", "ce": "47u",
|
||||
"vcc": "12", "bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"colpitts_oscillator": {
|
||||
"func": generate_colpitts_asc,
|
||||
"description": "Colpitts oscillator with LC tank and BJT",
|
||||
"params": {
|
||||
"ind": "1u", "c1": "100p", "c2": "100p",
|
||||
"rb": "47k", "rc": "1k", "re": "470",
|
||||
"vcc": "12", "bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"differential_amp": {
|
||||
"func": generate_diff_amp_asc,
|
||||
"description": "Differential amplifier with op-amp",
|
||||
"params": {"r1": "10k", "r2": "10k", "r3": "10k", "r4": "10k"},
|
||||
},
|
||||
"buck_converter": {
|
||||
"func": generate_buck_converter_asc,
|
||||
"description": "Buck (step-down) converter with NMOS switch",
|
||||
"params": {
|
||||
"ind": "10u", "c_out": "100u", "r_load": "10",
|
||||
"v_in": "12", "duty_cycle": "0.5", "freq": "100k",
|
||||
"mosfet_model": "IRF540N", "diode_model": "1N5819",
|
||||
},
|
||||
},
|
||||
"ldo_regulator": {
|
||||
"func": generate_ldo_asc,
|
||||
"description": "LDO voltage regulator with PMOS pass transistor",
|
||||
"params": {
|
||||
"r1": "10k", "r2": "10k", "pass_transistor": "IRF9540N",
|
||||
"v_in": "8", "v_ref": "2.5",
|
||||
},
|
||||
},
|
||||
"h_bridge": {
|
||||
"func": generate_h_bridge_asc,
|
||||
"description": "H-bridge motor driver with 4 NMOS transistors",
|
||||
"params": {"v_supply": "12", "r_load": "10", "mosfet_model": "IRF540N"},
|
||||
},
|
||||
"sallen_key_lowpass": {
|
||||
"func": generate_sallen_key_asc,
|
||||
"description": "Sallen-Key lowpass filter (unity gain, 2nd order)",
|
||||
"params": {"r1": "10k", "r2": "10k", "c1": "10n", "c2": "10n"},
|
||||
},
|
||||
"boost_converter": {
|
||||
"func": generate_boost_converter_asc,
|
||||
"description": "Boost (step-up) converter with NMOS switch",
|
||||
"params": {
|
||||
"ind": "10u", "c_out": "100u", "r_load": "50",
|
||||
"v_in": "5", "duty_cycle": "0.5", "freq": "100k",
|
||||
},
|
||||
},
|
||||
"instrumentation_amp": {
|
||||
"func": generate_inamp_asc,
|
||||
"description": "3-opamp instrumentation amplifier",
|
||||
"params": {"r1": "10k", "r2": "10k", "r3": "10k", "r_gain": "10k"},
|
||||
},
|
||||
"current_mirror": {
|
||||
"func": generate_current_mirror_asc,
|
||||
"description": "BJT current mirror with reference and load",
|
||||
"params": {"r_ref": "10k", "r_load": "1k", "vcc": "12"},
|
||||
},
|
||||
"transimpedance_amp": {
|
||||
"func": generate_tia_asc,
|
||||
"description": "Transimpedance amplifier (current to voltage)",
|
||||
"params": {"rf": "100k", "cf": "1p", "i_source": "1u"},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def generate_schematic(
|
||||
template: str,
|
||||
@ -1894,11 +1739,11 @@ def generate_schematic(
|
||||
Use list_templates to see available parameters for each template.
|
||||
output_path: Where to save the .asc file (None = auto in /tmp)
|
||||
"""
|
||||
if template not in _ASC_TEMPLATES:
|
||||
names = ", ".join(sorted(_ASC_TEMPLATES))
|
||||
if template not in ASC_TEMPLATES:
|
||||
names = ", ".join(sorted(ASC_TEMPLATES))
|
||||
return {"error": f"Unknown template '{template}'. Available: {names}"}
|
||||
|
||||
entry = _ASC_TEMPLATES[template]
|
||||
entry = ASC_TEMPLATES[template]
|
||||
call_params: dict[str, str | float] = {}
|
||||
|
||||
if params:
|
||||
@ -2143,159 +1988,6 @@ def create_netlist(
|
||||
# CIRCUIT TEMPLATE TOOLS
|
||||
# ============================================================================
|
||||
|
||||
# Registry of netlist templates with parameter metadata
|
||||
_TEMPLATES: dict[str, dict] = {
|
||||
"voltage_divider": {
|
||||
"func": voltage_divider,
|
||||
"description": "Resistive voltage divider with .op or custom analysis",
|
||||
"params": {"v_in": "5", "r1": "10k", "r2": "10k", "sim_type": "op"},
|
||||
},
|
||||
"rc_lowpass": {
|
||||
"func": rc_lowpass,
|
||||
"description": "RC lowpass filter with AC sweep",
|
||||
"params": {"r": "1k", "c": "100n", "f_start": "1", "f_stop": "1meg"},
|
||||
},
|
||||
"inverting_amplifier": {
|
||||
"func": inverting_amplifier,
|
||||
"description": "Inverting op-amp (gain = -Rf/Rin), +/-15V supply",
|
||||
"params": {"r_in": "10k", "r_f": "100k", "opamp_model": "LT1001"},
|
||||
},
|
||||
"non_inverting_amplifier": {
|
||||
"func": non_inverting_amplifier,
|
||||
"description": "Non-inverting op-amp (gain = 1 + Rf/Rin), +/-15V supply",
|
||||
"params": {"r_in": "10k", "r_f": "100k", "opamp_model": "LT1001"},
|
||||
},
|
||||
"differential_amplifier": {
|
||||
"func": differential_amplifier,
|
||||
"description": "Diff amp: Vout = (R2/R1)*(V2-V1), +/-15V supply",
|
||||
"params": {
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"r3": "10k",
|
||||
"r4": "10k",
|
||||
"opamp_model": "LT1001",
|
||||
},
|
||||
},
|
||||
"common_emitter_amplifier": {
|
||||
"func": common_emitter_amplifier,
|
||||
"description": "BJT common-emitter with voltage divider bias",
|
||||
"params": {
|
||||
"rc": "2.2k",
|
||||
"rb1": "56k",
|
||||
"rb2": "12k",
|
||||
"re": "1k",
|
||||
"cc1": "10u",
|
||||
"cc2": "10u",
|
||||
"ce": "47u",
|
||||
"vcc": "12",
|
||||
"bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"buck_converter": {
|
||||
"func": buck_converter,
|
||||
"description": "Step-down DC-DC converter with MOSFET switch",
|
||||
"params": {
|
||||
"ind": "10u",
|
||||
"c_out": "100u",
|
||||
"r_load": "10",
|
||||
"v_in": "12",
|
||||
"duty_cycle": "0.5",
|
||||
"freq": "100k",
|
||||
"mosfet_model": "IRF540N",
|
||||
"diode_model": "1N5819",
|
||||
},
|
||||
},
|
||||
"ldo_regulator": {
|
||||
"func": ldo_regulator,
|
||||
"description": "LDO regulator: Vout = Vref * (1 + R1/R2)",
|
||||
"params": {
|
||||
"opamp_model": "LT1001",
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"pass_transistor": "IRF9540N",
|
||||
"v_in": "8",
|
||||
"v_ref": "2.5",
|
||||
},
|
||||
},
|
||||
"colpitts_oscillator": {
|
||||
"func": colpitts_oscillator,
|
||||
"description": "LC oscillator: f ~ 1/(2pi*sqrt(L*Cseries))",
|
||||
"params": {
|
||||
"ind": "1u",
|
||||
"c1": "100p",
|
||||
"c2": "100p",
|
||||
"rb": "47k",
|
||||
"rc": "1k",
|
||||
"re": "470",
|
||||
"vcc": "12",
|
||||
"bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"h_bridge": {
|
||||
"func": h_bridge,
|
||||
"description": "4-MOSFET H-bridge motor driver with dead time",
|
||||
"params": {
|
||||
"v_supply": "12",
|
||||
"r_load": "10",
|
||||
"mosfet_model": "IRF540N",
|
||||
},
|
||||
},
|
||||
"sallen_key_lowpass": {
|
||||
"func": sallen_key_lowpass,
|
||||
"description": "Sallen-Key lowpass filter (unity gain, 2nd order)",
|
||||
"params": {
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"c1": "10n",
|
||||
"c2": "10n",
|
||||
"opamp_model": "LT1001",
|
||||
},
|
||||
},
|
||||
"boost_converter": {
|
||||
"func": boost_converter,
|
||||
"description": "Step-up DC-DC converter with MOSFET switch",
|
||||
"params": {
|
||||
"ind": "10u",
|
||||
"c_out": "100u",
|
||||
"r_load": "50",
|
||||
"v_in": "5",
|
||||
"duty_cycle": "0.5",
|
||||
"freq": "100k",
|
||||
"mosfet_model": "IRF540N",
|
||||
"diode_model": "1N5819",
|
||||
},
|
||||
},
|
||||
"instrumentation_amplifier": {
|
||||
"func": instrumentation_amplifier,
|
||||
"description": "3-opamp instrumentation amp: gain = 1 + 2*R1/R_gain",
|
||||
"params": {
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"r3": "10k",
|
||||
"r_gain": "10k",
|
||||
},
|
||||
},
|
||||
"current_mirror": {
|
||||
"func": current_mirror,
|
||||
"description": "BJT current mirror with reference resistor",
|
||||
"params": {
|
||||
"r_ref": "10k",
|
||||
"r_load": "1k",
|
||||
"vcc": "12",
|
||||
"bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"transimpedance_amplifier": {
|
||||
"func": transimpedance_amplifier,
|
||||
"description": "TIA: converts input current to output voltage (Vout = -Iph * Rf)",
|
||||
"params": {
|
||||
"rf": "100k",
|
||||
"cf": "1p",
|
||||
"i_source": "1u",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def create_from_template(
|
||||
@ -2329,13 +2021,13 @@ def create_from_template(
|
||||
params: Optional dict of parameter overrides (all values as strings)
|
||||
output_path: Where to save .cir file (None = auto in /tmp)
|
||||
"""
|
||||
template = _TEMPLATES.get(template_name)
|
||||
template = NETLIST_TEMPLATES.get(template_name)
|
||||
if template is None:
|
||||
return {
|
||||
"error": f"Unknown template '{template_name}'",
|
||||
"available_templates": [
|
||||
{"name": k, "description": v["description"], "params": v["params"]}
|
||||
for k, v in _TEMPLATES.items()
|
||||
for k, v in NETLIST_TEMPLATES.items()
|
||||
],
|
||||
}
|
||||
|
||||
@ -2386,9 +2078,9 @@ def list_templates() -> dict:
|
||||
"description": info["description"],
|
||||
"params": info["params"],
|
||||
}
|
||||
for name, info in _TEMPLATES.items()
|
||||
for name, info in NETLIST_TEMPLATES.items()
|
||||
],
|
||||
"total_count": len(_TEMPLATES),
|
||||
"total_count": len(NETLIST_TEMPLATES),
|
||||
}
|
||||
|
||||
|
||||
@ -2639,11 +2331,11 @@ def resource_templates() -> str:
|
||||
templates = {
|
||||
"netlist_templates": [
|
||||
{"name": name, "description": info["description"], "params": info["params"]}
|
||||
for name, info in _TEMPLATES.items()
|
||||
for name, info in NETLIST_TEMPLATES.items()
|
||||
],
|
||||
"schematic_templates": [
|
||||
{"name": name, "description": info["description"], "params": info["params"]}
|
||||
for name, info in _ASC_TEMPLATES.items()
|
||||
for name, info in ASC_TEMPLATES.items()
|
||||
],
|
||||
}
|
||||
return json.dumps(templates, indent=2)
|
||||
@ -2653,8 +2345,8 @@ def resource_templates() -> str:
|
||||
def resource_template_detail(name: str) -> str:
|
||||
"""Detailed information about a specific circuit template."""
|
||||
# Check both registries
|
||||
netlist_info = _TEMPLATES.get(name)
|
||||
asc_info = _ASC_TEMPLATES.get(name)
|
||||
netlist_info = NETLIST_TEMPLATES.get(name)
|
||||
asc_info = ASC_TEMPLATES.get(name)
|
||||
|
||||
if not netlist_info and not asc_info:
|
||||
return json.dumps({"error": f"Template '{name}' not found"})
|
||||
|
||||
315
src/mcltspice/templates.py
Normal file
315
src/mcltspice/templates.py
Normal file
@ -0,0 +1,315 @@
|
||||
"""Circuit template registries.
|
||||
|
||||
Two registries map template names to builder functions and default params:
|
||||
|
||||
- NETLIST_TEMPLATES -> .netlist builders, producing SPICE .cir netlists
|
||||
- ASC_TEMPLATES -> .asc_generator builders, producing graphical schematics
|
||||
|
||||
Some names appear in both (e.g. rc_lowpass). resolve_template() applies a
|
||||
netlist-first precedence so a name available in both resolves to its netlist
|
||||
form, matching the historical lookup order in tune_circuit.
|
||||
"""
|
||||
|
||||
from .asc_generator import (
|
||||
generate_boost_converter,
|
||||
generate_buck_converter,
|
||||
generate_colpitts_oscillator,
|
||||
generate_common_emitter_amp,
|
||||
generate_current_mirror,
|
||||
generate_differential_amp,
|
||||
generate_h_bridge,
|
||||
generate_instrumentation_amp,
|
||||
generate_inverting_amp,
|
||||
generate_ldo_regulator,
|
||||
generate_non_inverting_amp,
|
||||
generate_rc_lowpass,
|
||||
generate_sallen_key_lowpass,
|
||||
generate_transimpedance_amp,
|
||||
generate_voltage_divider,
|
||||
)
|
||||
from .netlist import (
|
||||
boost_converter,
|
||||
buck_converter,
|
||||
colpitts_oscillator,
|
||||
common_emitter_amplifier,
|
||||
current_mirror,
|
||||
differential_amplifier,
|
||||
h_bridge,
|
||||
instrumentation_amplifier,
|
||||
inverting_amplifier,
|
||||
ldo_regulator,
|
||||
non_inverting_amplifier,
|
||||
rc_lowpass,
|
||||
sallen_key_lowpass,
|
||||
transimpedance_amplifier,
|
||||
voltage_divider,
|
||||
)
|
||||
|
||||
# Graphical .asc schematic templates (generate_schematic, tune_circuit fallback)
|
||||
ASC_TEMPLATES: dict[str, dict] = {
|
||||
"rc_lowpass": {
|
||||
"func": generate_rc_lowpass,
|
||||
"description": "RC lowpass filter with AC analysis",
|
||||
"params": {"r": "1k", "c": "100n"},
|
||||
},
|
||||
"voltage_divider": {
|
||||
"func": generate_voltage_divider,
|
||||
"description": "Resistive voltage divider with .op analysis",
|
||||
"params": {"r1": "10k", "r2": "10k", "vin": "5"},
|
||||
},
|
||||
"inverting_amp": {
|
||||
"func": generate_inverting_amp,
|
||||
"description": "Inverting op-amp amplifier (gain = -Rf/Rin)",
|
||||
"params": {"rin": "10k", "rf": "100k"},
|
||||
},
|
||||
"non_inverting_amp": {
|
||||
"func": generate_non_inverting_amp,
|
||||
"description": "Non-inverting op-amp amplifier (gain = 1 + Rf/Rin)",
|
||||
"params": {"rin": "10k", "rf": "100k"},
|
||||
},
|
||||
"common_emitter_amp": {
|
||||
"func": generate_common_emitter_amp,
|
||||
"description": "Common-emitter BJT amplifier with voltage divider bias",
|
||||
"params": {
|
||||
"rc": "2.2k", "rb1": "56k", "rb2": "12k", "re": "1k",
|
||||
"cc_in": "10u", "cc_out": "10u", "ce": "47u",
|
||||
"vcc": "12", "bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"colpitts_oscillator": {
|
||||
"func": generate_colpitts_oscillator,
|
||||
"description": "Colpitts oscillator with LC tank and BJT",
|
||||
"params": {
|
||||
"ind": "1u", "c1": "100p", "c2": "100p",
|
||||
"rb": "47k", "rc": "1k", "re": "470",
|
||||
"vcc": "12", "bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"differential_amp": {
|
||||
"func": generate_differential_amp,
|
||||
"description": "Differential amplifier with op-amp",
|
||||
"params": {"r1": "10k", "r2": "10k", "r3": "10k", "r4": "10k"},
|
||||
},
|
||||
"buck_converter": {
|
||||
"func": generate_buck_converter,
|
||||
"description": "Buck (step-down) converter with NMOS switch",
|
||||
"params": {
|
||||
"ind": "10u", "c_out": "100u", "r_load": "10",
|
||||
"v_in": "12", "duty_cycle": "0.5", "freq": "100k",
|
||||
"mosfet_model": "IRF540N", "diode_model": "1N5819",
|
||||
},
|
||||
},
|
||||
"ldo_regulator": {
|
||||
"func": generate_ldo_regulator,
|
||||
"description": "LDO voltage regulator with PMOS pass transistor",
|
||||
"params": {
|
||||
"r1": "10k", "r2": "10k", "pass_transistor": "IRF9540N",
|
||||
"v_in": "8", "v_ref": "2.5",
|
||||
},
|
||||
},
|
||||
"h_bridge": {
|
||||
"func": generate_h_bridge,
|
||||
"description": "H-bridge motor driver with 4 NMOS transistors",
|
||||
"params": {"v_supply": "12", "r_load": "10", "mosfet_model": "IRF540N"},
|
||||
},
|
||||
"sallen_key_lowpass": {
|
||||
"func": generate_sallen_key_lowpass,
|
||||
"description": "Sallen-Key lowpass filter (unity gain, 2nd order)",
|
||||
"params": {"r1": "10k", "r2": "10k", "c1": "10n", "c2": "10n"},
|
||||
},
|
||||
"boost_converter": {
|
||||
"func": generate_boost_converter,
|
||||
"description": "Boost (step-up) converter with NMOS switch",
|
||||
"params": {
|
||||
"ind": "10u", "c_out": "100u", "r_load": "50",
|
||||
"v_in": "5", "duty_cycle": "0.5", "freq": "100k",
|
||||
},
|
||||
},
|
||||
"instrumentation_amp": {
|
||||
"func": generate_instrumentation_amp,
|
||||
"description": "3-opamp instrumentation amplifier",
|
||||
"params": {"r1": "10k", "r2": "10k", "r3": "10k", "r_gain": "10k"},
|
||||
},
|
||||
"current_mirror": {
|
||||
"func": generate_current_mirror,
|
||||
"description": "BJT current mirror with reference and load",
|
||||
"params": {"r_ref": "10k", "r_load": "1k", "vcc": "12"},
|
||||
},
|
||||
"transimpedance_amp": {
|
||||
"func": generate_transimpedance_amp,
|
||||
"description": "Transimpedance amplifier (current to voltage)",
|
||||
"params": {"rf": "100k", "cf": "1p", "i_source": "1u"},
|
||||
},
|
||||
}
|
||||
|
||||
# SPICE .cir netlist templates (create_from_template, list_templates, tune_circuit)
|
||||
NETLIST_TEMPLATES: dict[str, dict] = {
|
||||
"voltage_divider": {
|
||||
"func": voltage_divider,
|
||||
"description": "Resistive voltage divider with .op or custom analysis",
|
||||
"params": {"v_in": "5", "r1": "10k", "r2": "10k", "sim_type": "op"},
|
||||
},
|
||||
"rc_lowpass": {
|
||||
"func": rc_lowpass,
|
||||
"description": "RC lowpass filter with AC sweep",
|
||||
"params": {"r": "1k", "c": "100n", "f_start": "1", "f_stop": "1meg"},
|
||||
},
|
||||
"inverting_amplifier": {
|
||||
"func": inverting_amplifier,
|
||||
"description": "Inverting op-amp (gain = -Rf/Rin), +/-15V supply",
|
||||
"params": {"r_in": "10k", "r_f": "100k", "opamp_model": "LT1001"},
|
||||
},
|
||||
"non_inverting_amplifier": {
|
||||
"func": non_inverting_amplifier,
|
||||
"description": "Non-inverting op-amp (gain = 1 + Rf/Rin), +/-15V supply",
|
||||
"params": {"r_in": "10k", "r_f": "100k", "opamp_model": "LT1001"},
|
||||
},
|
||||
"differential_amplifier": {
|
||||
"func": differential_amplifier,
|
||||
"description": "Diff amp: Vout = (R2/R1)*(V2-V1), +/-15V supply",
|
||||
"params": {
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"r3": "10k",
|
||||
"r4": "10k",
|
||||
"opamp_model": "LT1001",
|
||||
},
|
||||
},
|
||||
"common_emitter_amplifier": {
|
||||
"func": common_emitter_amplifier,
|
||||
"description": "BJT common-emitter with voltage divider bias",
|
||||
"params": {
|
||||
"rc": "2.2k",
|
||||
"rb1": "56k",
|
||||
"rb2": "12k",
|
||||
"re": "1k",
|
||||
"cc1": "10u",
|
||||
"cc2": "10u",
|
||||
"ce": "47u",
|
||||
"vcc": "12",
|
||||
"bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"buck_converter": {
|
||||
"func": buck_converter,
|
||||
"description": "Step-down DC-DC converter with MOSFET switch",
|
||||
"params": {
|
||||
"ind": "10u",
|
||||
"c_out": "100u",
|
||||
"r_load": "10",
|
||||
"v_in": "12",
|
||||
"duty_cycle": "0.5",
|
||||
"freq": "100k",
|
||||
"mosfet_model": "IRF540N",
|
||||
"diode_model": "1N5819",
|
||||
},
|
||||
},
|
||||
"ldo_regulator": {
|
||||
"func": ldo_regulator,
|
||||
"description": "LDO regulator: Vout = Vref * (1 + R1/R2)",
|
||||
"params": {
|
||||
"opamp_model": "LT1001",
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"pass_transistor": "IRF9540N",
|
||||
"v_in": "8",
|
||||
"v_ref": "2.5",
|
||||
},
|
||||
},
|
||||
"colpitts_oscillator": {
|
||||
"func": colpitts_oscillator,
|
||||
"description": "LC oscillator: f ~ 1/(2pi*sqrt(L*Cseries))",
|
||||
"params": {
|
||||
"ind": "1u",
|
||||
"c1": "100p",
|
||||
"c2": "100p",
|
||||
"rb": "47k",
|
||||
"rc": "1k",
|
||||
"re": "470",
|
||||
"vcc": "12",
|
||||
"bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"h_bridge": {
|
||||
"func": h_bridge,
|
||||
"description": "4-MOSFET H-bridge motor driver with dead time",
|
||||
"params": {
|
||||
"v_supply": "12",
|
||||
"r_load": "10",
|
||||
"mosfet_model": "IRF540N",
|
||||
},
|
||||
},
|
||||
"sallen_key_lowpass": {
|
||||
"func": sallen_key_lowpass,
|
||||
"description": "Sallen-Key lowpass filter (unity gain, 2nd order)",
|
||||
"params": {
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"c1": "10n",
|
||||
"c2": "10n",
|
||||
"opamp_model": "LT1001",
|
||||
},
|
||||
},
|
||||
"boost_converter": {
|
||||
"func": boost_converter,
|
||||
"description": "Step-up DC-DC converter with MOSFET switch",
|
||||
"params": {
|
||||
"ind": "10u",
|
||||
"c_out": "100u",
|
||||
"r_load": "50",
|
||||
"v_in": "5",
|
||||
"duty_cycle": "0.5",
|
||||
"freq": "100k",
|
||||
"mosfet_model": "IRF540N",
|
||||
"diode_model": "1N5819",
|
||||
},
|
||||
},
|
||||
"instrumentation_amplifier": {
|
||||
"func": instrumentation_amplifier,
|
||||
"description": "3-opamp instrumentation amp: gain = 1 + 2*R1/R_gain",
|
||||
"params": {
|
||||
"r1": "10k",
|
||||
"r2": "10k",
|
||||
"r3": "10k",
|
||||
"r_gain": "10k",
|
||||
},
|
||||
},
|
||||
"current_mirror": {
|
||||
"func": current_mirror,
|
||||
"description": "BJT current mirror with reference resistor",
|
||||
"params": {
|
||||
"r_ref": "10k",
|
||||
"r_load": "1k",
|
||||
"vcc": "12",
|
||||
"bjt_model": "2N2222",
|
||||
},
|
||||
},
|
||||
"transimpedance_amplifier": {
|
||||
"func": transimpedance_amplifier,
|
||||
"description": "TIA: converts input current to output voltage (Vout = -Iph * Rf)",
|
||||
"params": {
|
||||
"rf": "100k",
|
||||
"cf": "1p",
|
||||
"i_source": "1u",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def resolve_template(name: str) -> tuple[dict, bool] | None:
|
||||
"""Resolve a template name to (entry, is_netlist), netlist registry first.
|
||||
|
||||
Returns None if the name is in neither registry. Netlist-first precedence
|
||||
preserves the historical lookup order: a name present in both registries
|
||||
(e.g. "rc_lowpass") resolves to its netlist form.
|
||||
"""
|
||||
if name in NETLIST_TEMPLATES:
|
||||
return NETLIST_TEMPLATES[name], True
|
||||
if name in ASC_TEMPLATES:
|
||||
return ASC_TEMPLATES[name], False
|
||||
return None
|
||||
|
||||
|
||||
def all_template_names() -> list[str]:
|
||||
"""Sorted union of every template name across both registries."""
|
||||
return sorted(set(NETLIST_TEMPLATES) | set(ASC_TEMPLATES))
|
||||
Loading…
x
Reference in New Issue
Block a user