Move guided-workflow prompts into prompts.py
The 7 narrative prompts (design_filter, debug_circuit, etc.) are pure Message builders with no tool dependencies -- relocate them to prompts.py, registered on the shared mcp instance. server.py: 1876 -> 1568 lines.
This commit is contained in:
parent
ca6e15e751
commit
dfb94bfcb9
309
src/mcltspice/prompts.py
Normal file
309
src/mcltspice/prompts.py
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
"""Guided-workflow prompts. Each returns a Message list and registers on the
|
||||||
|
shared mcp instance. Pure narrative -- no tool calls.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastmcp.prompts import Message
|
||||||
|
|
||||||
|
from ._app import mcp
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def design_filter(
|
||||||
|
filter_type: str = "lowpass",
|
||||||
|
topology: str = "rc",
|
||||||
|
cutoff_freq: str = "1kHz",
|
||||||
|
) -> list:
|
||||||
|
"""Guide through designing and simulating a filter circuit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filter_type: lowpass, highpass, bandpass, or notch
|
||||||
|
topology: rc (1st order), rlc (2nd order), or sallen-key (active)
|
||||||
|
cutoff_freq: Target cutoff frequency with units
|
||||||
|
"""
|
||||||
|
return [Message(role="user", content=f"""Design a {filter_type} filter with these requirements:
|
||||||
|
- Topology: {topology}
|
||||||
|
- Cutoff frequency: {cutoff_freq}
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
1. Use create_netlist to build the circuit
|
||||||
|
2. Add .ac analysis directive for frequency sweep
|
||||||
|
3. Add .meas directive for -3dB bandwidth
|
||||||
|
4. Simulate with simulate_netlist
|
||||||
|
5. Use measure_bandwidth to verify cutoff frequency
|
||||||
|
6. Use get_waveform to inspect the frequency response
|
||||||
|
7. Adjust component values with create_netlist if needed
|
||||||
|
|
||||||
|
Tips:
|
||||||
|
- For RC lowpass: f_c = 1/(2*pi*R*C)
|
||||||
|
- For 2nd order: Q controls peaking, Butterworth Q=0.707
|
||||||
|
- Use search_spice_models to find op-amp models for active filters
|
||||||
|
""")]
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def analyze_power_supply(schematic_path: str = "") -> list:
|
||||||
|
"""Guide through analyzing a power supply circuit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
schematic_path: Path to the power supply schematic
|
||||||
|
"""
|
||||||
|
path_instruction = (
|
||||||
|
f"The schematic is at: {schematic_path}"
|
||||||
|
if schematic_path
|
||||||
|
else "First, identify or create the power supply schematic."
|
||||||
|
)
|
||||||
|
|
||||||
|
return [Message(role="user", content=f"""Analyze a power supply circuit for key performance metrics.
|
||||||
|
|
||||||
|
{path_instruction}
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
1. Use read_schematic to understand the circuit topology
|
||||||
|
2. Use run_drc to check for design issues
|
||||||
|
3. Simulate with .tran analysis (include load step if applicable)
|
||||||
|
4. Use analyze_waveform with these analyses:
|
||||||
|
- "peak_to_peak" on output for ripple measurement
|
||||||
|
- "settling_time" for transient response
|
||||||
|
- "fft" on output to identify noise frequencies
|
||||||
|
5. If AC analysis available, use measure_bandwidth for loop gain
|
||||||
|
|
||||||
|
Key metrics to extract:
|
||||||
|
- Output voltage regulation (DC accuracy)
|
||||||
|
- Ripple voltage (peak-to-peak on output)
|
||||||
|
- Load transient response (settling time after step)
|
||||||
|
- Efficiency (input power vs output power)
|
||||||
|
""")]
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def debug_circuit(schematic_path: str = "") -> list:
|
||||||
|
"""Guide through debugging a circuit that isn't working.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
schematic_path: Path to the problematic schematic
|
||||||
|
"""
|
||||||
|
path_instruction = (
|
||||||
|
f"The schematic is at: {schematic_path}"
|
||||||
|
if schematic_path
|
||||||
|
else "First, identify the schematic file."
|
||||||
|
)
|
||||||
|
|
||||||
|
return [Message(role="user", content=f"""Systematic approach to debugging a circuit.
|
||||||
|
|
||||||
|
{path_instruction}
|
||||||
|
|
||||||
|
Step 1 - Validate the schematic:
|
||||||
|
- Use run_drc to catch obvious issues (missing ground, floating nodes)
|
||||||
|
- Use read_schematic to review component values and connections
|
||||||
|
|
||||||
|
Step 2 - Check simulation setup:
|
||||||
|
- Verify simulation directives are correct
|
||||||
|
- Check that models/subcircuits are available (search_spice_models)
|
||||||
|
|
||||||
|
Step 3 - Run and analyze:
|
||||||
|
- Simulate the circuit
|
||||||
|
- Use get_waveform to inspect key node voltages
|
||||||
|
- Compare expected vs actual values at each stage
|
||||||
|
|
||||||
|
Step 4 - Isolate the problem:
|
||||||
|
- Use edit_component to simplify (replace active devices with ideal)
|
||||||
|
- Use diff_schematics to track what changes fixed the issue
|
||||||
|
- Re-simulate after each change
|
||||||
|
|
||||||
|
Common issues:
|
||||||
|
- Wrong node connections (check wire endpoints)
|
||||||
|
- Missing bias voltages or ground
|
||||||
|
- Component values off by orders of magnitude
|
||||||
|
- Wrong model (check with search_spice_models)
|
||||||
|
""")]
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def optimize_design(
|
||||||
|
circuit_type: str = "filter",
|
||||||
|
target_spec: str = "1kHz bandwidth",
|
||||||
|
) -> list:
|
||||||
|
"""Guide through optimizing a circuit to meet target specifications.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
circuit_type: Type of circuit (filter, amplifier, regulator, oscillator)
|
||||||
|
target_spec: Target specification to achieve
|
||||||
|
"""
|
||||||
|
return [Message(role="user", content=f"""Optimize a {circuit_type} circuit to achieve: {target_spec}
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
1. Start with a template: use list_templates to see available circuits
|
||||||
|
2. Create the initial circuit with create_from_template
|
||||||
|
3. Simulate and measure the current performance
|
||||||
|
4. Use optimize_circuit to automatically tune component values:
|
||||||
|
- Define target metrics (bandwidth, gain, settling time, etc.)
|
||||||
|
- Specify component ranges with preferred E-series values
|
||||||
|
- Let the optimizer iterate (typically 10-20 simulations)
|
||||||
|
5. Verify the optimized design with a full simulation
|
||||||
|
6. Run Monte Carlo (monte_carlo tool) to check yield with tolerances
|
||||||
|
|
||||||
|
Tips:
|
||||||
|
- Start with reasonable initial values from the template
|
||||||
|
- Use E24 or E96 series for resistors/capacitors
|
||||||
|
- For filters: target bandwidth_hz metric
|
||||||
|
- For amplifiers: target gain_db and phase_margin_deg
|
||||||
|
- For regulators: target settling_time and peak_to_peak (ripple)
|
||||||
|
""")]
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def monte_carlo_analysis(
|
||||||
|
circuit_description: str = "RC filter",
|
||||||
|
n_runs: str = "100",
|
||||||
|
) -> list:
|
||||||
|
"""Guide through Monte Carlo tolerance analysis.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
circuit_description: What circuit to analyze
|
||||||
|
n_runs: Number of Monte Carlo iterations
|
||||||
|
"""
|
||||||
|
return [Message(role="user", content=f"""Run Monte Carlo tolerance analysis on: {circuit_description}
|
||||||
|
Number of runs: {n_runs}
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
1. Create or identify the netlist for your circuit
|
||||||
|
2. Use monte_carlo tool with component tolerances:
|
||||||
|
- Resistors: typically 1% (0.01) or 5% (0.05)
|
||||||
|
- Capacitors: typically 10% (0.1) or 20% (0.2)
|
||||||
|
- Inductors: typically 10% (0.1)
|
||||||
|
3. For each completed run, extract key metrics:
|
||||||
|
- Use get_waveform on each raw file
|
||||||
|
- Use analyze_waveform for RMS, peak-to-peak, etc.
|
||||||
|
- Use measure_bandwidth for filter circuits
|
||||||
|
4. Compute statistics across all runs:
|
||||||
|
- Mean and standard deviation of each metric
|
||||||
|
- Min/max (worst case)
|
||||||
|
- Yield: what percentage meet spec?
|
||||||
|
|
||||||
|
Tips:
|
||||||
|
- Use list_simulation_runs to understand stepped data
|
||||||
|
- For stepped simulations, use get_waveform with run parameter
|
||||||
|
- Start with fewer runs (10-20) to verify setup, then scale up
|
||||||
|
- Set seed for reproducible results during development
|
||||||
|
- Typical component tolerances:
|
||||||
|
- Metal film resistors: 1%
|
||||||
|
- Ceramic capacitors: 10-20%
|
||||||
|
- Electrolytic capacitors: 20%
|
||||||
|
- Inductors: 10-20%
|
||||||
|
""")]
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def circuit_from_scratch(
|
||||||
|
description: str = "audio amplifier",
|
||||||
|
) -> list:
|
||||||
|
"""Guide through creating a complete circuit from scratch.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
description: What circuit to build
|
||||||
|
"""
|
||||||
|
return [Message(role="user", content=f"""Build a complete circuit from scratch: {description}
|
||||||
|
|
||||||
|
Approach 1 - Use a template (recommended for common circuits):
|
||||||
|
1. Use list_templates to see available circuit templates
|
||||||
|
2. Use create_from_template with custom parameters
|
||||||
|
3. Simulate with simulate_netlist
|
||||||
|
4. Analyze results with get_waveform and analyze_waveform
|
||||||
|
|
||||||
|
Approach 2 - Build from components:
|
||||||
|
1. Use create_netlist to define components and connections
|
||||||
|
2. Use search_spice_models to find transistor/diode models
|
||||||
|
3. Use search_spice_subcircuits to find op-amp/IC models
|
||||||
|
4. Add simulation directives (.tran, .ac, .dc, .op, .tf)
|
||||||
|
5. Simulate and analyze
|
||||||
|
|
||||||
|
Approach 3 - Graphical schematic (.asc file):
|
||||||
|
1. Use generate_schematic for any of 10 topologies: rc_lowpass,
|
||||||
|
voltage_divider, inverting_amp, non_inverting_amp, common_emitter_amp,
|
||||||
|
colpitts_oscillator, differential_amp, buck_converter, ldo_regulator,
|
||||||
|
h_bridge
|
||||||
|
2. The .asc file can be opened in LTspice GUI for editing
|
||||||
|
3. Simulate with the simulate tool
|
||||||
|
|
||||||
|
Verification workflow:
|
||||||
|
1. Run run_drc to check for design issues before simulating
|
||||||
|
2. Start with .op analysis to verify DC bias point
|
||||||
|
3. Run .tf analysis for gain and impedance
|
||||||
|
4. Run .ac analysis for frequency response
|
||||||
|
5. Run .tran analysis for time-domain behavior
|
||||||
|
6. Use diff_schematics to compare design iterations
|
||||||
|
""")]
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def troubleshoot_simulation(
|
||||||
|
error_description: str = "",
|
||||||
|
schematic_path: str = "",
|
||||||
|
) -> list:
|
||||||
|
"""Systematic checklist for diagnosing simulation failures.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error_description: What went wrong (error message, unexpected results, etc.)
|
||||||
|
schematic_path: Path to the problematic schematic or netlist
|
||||||
|
"""
|
||||||
|
path_note = (
|
||||||
|
f"Schematic/netlist: {schematic_path}"
|
||||||
|
if schematic_path
|
||||||
|
else "First, identify the schematic or netlist file."
|
||||||
|
)
|
||||||
|
error_note = (
|
||||||
|
f"Reported issue: {error_description}"
|
||||||
|
if error_description
|
||||||
|
else "No specific error described -- run full diagnostic."
|
||||||
|
)
|
||||||
|
|
||||||
|
return [Message(role="user", content=f"""Troubleshoot a simulation that isn't working correctly.
|
||||||
|
|
||||||
|
{path_note}
|
||||||
|
{error_note}
|
||||||
|
|
||||||
|
Diagnostic checklist (work through in order):
|
||||||
|
|
||||||
|
1. **Design Rule Check**
|
||||||
|
- Run run_drc on the schematic
|
||||||
|
- Fix any: missing ground, floating nodes, duplicate names, missing sim directive
|
||||||
|
|
||||||
|
2. **Installation & Setup**
|
||||||
|
- Run check_installation to verify Wine + LTspice
|
||||||
|
- Check that required .lib files exist
|
||||||
|
|
||||||
|
3. **Model Availability**
|
||||||
|
- Use search_spice_models to verify all transistor/diode models exist
|
||||||
|
- Use search_spice_subcircuits to verify op-amp models
|
||||||
|
- Common issue: model name in schematic doesn't match library
|
||||||
|
|
||||||
|
4. **Simulation Directive**
|
||||||
|
- Use read_schematic to check the directive
|
||||||
|
- Verify analysis type matches what you want (.tran, .ac, .dc, .op, .tf)
|
||||||
|
- For .tran: is the stop time long enough?
|
||||||
|
- For .ac: are start/stop frequencies reasonable?
|
||||||
|
|
||||||
|
5. **Node Connections**
|
||||||
|
- Use read_schematic to list all components and nets
|
||||||
|
- Check for disconnected nodes (components not wired)
|
||||||
|
- Verify ground connections on all return paths
|
||||||
|
|
||||||
|
6. **Run & Inspect**
|
||||||
|
- Simulate the circuit
|
||||||
|
- Check the log file for convergence warnings
|
||||||
|
- Use get_waveform to inspect node voltages
|
||||||
|
- Compare expected vs actual at each circuit stage
|
||||||
|
|
||||||
|
7. **Simplify & Isolate**
|
||||||
|
- Use edit_component to replace active devices with ideal ones
|
||||||
|
- Remove non-essential subcircuits
|
||||||
|
- Test each stage independently
|
||||||
|
- Add .ic directives if oscillators won't start
|
||||||
|
|
||||||
|
Common failure modes:
|
||||||
|
- Convergence failure: reduce timestep, add initial conditions
|
||||||
|
- All zeros: check ground connections and source polarity
|
||||||
|
- Unexpected clipping: check supply voltages and headroom
|
||||||
|
- Oscillation in DC circuit: add small capacitors on feedback
|
||||||
|
- Model not found: verify .lib/.include paths
|
||||||
|
""")]
|
||||||
@ -16,11 +16,10 @@ import tempfile
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from fastmcp.prompts import Message
|
|
||||||
|
|
||||||
# Domain modules register their tools/resources/prompts on the shared mcp
|
# Domain modules register their tools/resources/prompts on the shared mcp
|
||||||
# instance at import time. Imported for that side effect only.
|
# instance at import time. Imported for that side effect only.
|
||||||
from . import library_tools, resources, spicebook_tools # noqa: F401,E402
|
from . import library_tools, prompts, resources, spicebook_tools # noqa: F401,E402
|
||||||
from ._app import mcp
|
from ._app import mcp
|
||||||
from .batch import (
|
from .batch import (
|
||||||
run_monte_carlo,
|
run_monte_carlo,
|
||||||
@ -1555,313 +1554,6 @@ def list_templates() -> dict:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# PROMPTS
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def design_filter(
|
|
||||||
filter_type: str = "lowpass",
|
|
||||||
topology: str = "rc",
|
|
||||||
cutoff_freq: str = "1kHz",
|
|
||||||
) -> list:
|
|
||||||
"""Guide through designing and simulating a filter circuit.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filter_type: lowpass, highpass, bandpass, or notch
|
|
||||||
topology: rc (1st order), rlc (2nd order), or sallen-key (active)
|
|
||||||
cutoff_freq: Target cutoff frequency with units
|
|
||||||
"""
|
|
||||||
return [Message(role="user", content=f"""Design a {filter_type} filter with these requirements:
|
|
||||||
- Topology: {topology}
|
|
||||||
- Cutoff frequency: {cutoff_freq}
|
|
||||||
|
|
||||||
Workflow:
|
|
||||||
1. Use create_netlist to build the circuit
|
|
||||||
2. Add .ac analysis directive for frequency sweep
|
|
||||||
3. Add .meas directive for -3dB bandwidth
|
|
||||||
4. Simulate with simulate_netlist
|
|
||||||
5. Use measure_bandwidth to verify cutoff frequency
|
|
||||||
6. Use get_waveform to inspect the frequency response
|
|
||||||
7. Adjust component values with create_netlist if needed
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
- For RC lowpass: f_c = 1/(2*pi*R*C)
|
|
||||||
- For 2nd order: Q controls peaking, Butterworth Q=0.707
|
|
||||||
- Use search_spice_models to find op-amp models for active filters
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def analyze_power_supply(schematic_path: str = "") -> list:
|
|
||||||
"""Guide through analyzing a power supply circuit.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schematic_path: Path to the power supply schematic
|
|
||||||
"""
|
|
||||||
path_instruction = (
|
|
||||||
f"The schematic is at: {schematic_path}"
|
|
||||||
if schematic_path
|
|
||||||
else "First, identify or create the power supply schematic."
|
|
||||||
)
|
|
||||||
|
|
||||||
return [Message(role="user", content=f"""Analyze a power supply circuit for key performance metrics.
|
|
||||||
|
|
||||||
{path_instruction}
|
|
||||||
|
|
||||||
Workflow:
|
|
||||||
1. Use read_schematic to understand the circuit topology
|
|
||||||
2. Use run_drc to check for design issues
|
|
||||||
3. Simulate with .tran analysis (include load step if applicable)
|
|
||||||
4. Use analyze_waveform with these analyses:
|
|
||||||
- "peak_to_peak" on output for ripple measurement
|
|
||||||
- "settling_time" for transient response
|
|
||||||
- "fft" on output to identify noise frequencies
|
|
||||||
5. If AC analysis available, use measure_bandwidth for loop gain
|
|
||||||
|
|
||||||
Key metrics to extract:
|
|
||||||
- Output voltage regulation (DC accuracy)
|
|
||||||
- Ripple voltage (peak-to-peak on output)
|
|
||||||
- Load transient response (settling time after step)
|
|
||||||
- Efficiency (input power vs output power)
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def debug_circuit(schematic_path: str = "") -> list:
|
|
||||||
"""Guide through debugging a circuit that isn't working.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schematic_path: Path to the problematic schematic
|
|
||||||
"""
|
|
||||||
path_instruction = (
|
|
||||||
f"The schematic is at: {schematic_path}"
|
|
||||||
if schematic_path
|
|
||||||
else "First, identify the schematic file."
|
|
||||||
)
|
|
||||||
|
|
||||||
return [Message(role="user", content=f"""Systematic approach to debugging a circuit.
|
|
||||||
|
|
||||||
{path_instruction}
|
|
||||||
|
|
||||||
Step 1 - Validate the schematic:
|
|
||||||
- Use run_drc to catch obvious issues (missing ground, floating nodes)
|
|
||||||
- Use read_schematic to review component values and connections
|
|
||||||
|
|
||||||
Step 2 - Check simulation setup:
|
|
||||||
- Verify simulation directives are correct
|
|
||||||
- Check that models/subcircuits are available (search_spice_models)
|
|
||||||
|
|
||||||
Step 3 - Run and analyze:
|
|
||||||
- Simulate the circuit
|
|
||||||
- Use get_waveform to inspect key node voltages
|
|
||||||
- Compare expected vs actual values at each stage
|
|
||||||
|
|
||||||
Step 4 - Isolate the problem:
|
|
||||||
- Use edit_component to simplify (replace active devices with ideal)
|
|
||||||
- Use diff_schematics to track what changes fixed the issue
|
|
||||||
- Re-simulate after each change
|
|
||||||
|
|
||||||
Common issues:
|
|
||||||
- Wrong node connections (check wire endpoints)
|
|
||||||
- Missing bias voltages or ground
|
|
||||||
- Component values off by orders of magnitude
|
|
||||||
- Wrong model (check with search_spice_models)
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def optimize_design(
|
|
||||||
circuit_type: str = "filter",
|
|
||||||
target_spec: str = "1kHz bandwidth",
|
|
||||||
) -> list:
|
|
||||||
"""Guide through optimizing a circuit to meet target specifications.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
circuit_type: Type of circuit (filter, amplifier, regulator, oscillator)
|
|
||||||
target_spec: Target specification to achieve
|
|
||||||
"""
|
|
||||||
return [Message(role="user", content=f"""Optimize a {circuit_type} circuit to achieve: {target_spec}
|
|
||||||
|
|
||||||
Workflow:
|
|
||||||
1. Start with a template: use list_templates to see available circuits
|
|
||||||
2. Create the initial circuit with create_from_template
|
|
||||||
3. Simulate and measure the current performance
|
|
||||||
4. Use optimize_circuit to automatically tune component values:
|
|
||||||
- Define target metrics (bandwidth, gain, settling time, etc.)
|
|
||||||
- Specify component ranges with preferred E-series values
|
|
||||||
- Let the optimizer iterate (typically 10-20 simulations)
|
|
||||||
5. Verify the optimized design with a full simulation
|
|
||||||
6. Run Monte Carlo (monte_carlo tool) to check yield with tolerances
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
- Start with reasonable initial values from the template
|
|
||||||
- Use E24 or E96 series for resistors/capacitors
|
|
||||||
- For filters: target bandwidth_hz metric
|
|
||||||
- For amplifiers: target gain_db and phase_margin_deg
|
|
||||||
- For regulators: target settling_time and peak_to_peak (ripple)
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def monte_carlo_analysis(
|
|
||||||
circuit_description: str = "RC filter",
|
|
||||||
n_runs: str = "100",
|
|
||||||
) -> list:
|
|
||||||
"""Guide through Monte Carlo tolerance analysis.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
circuit_description: What circuit to analyze
|
|
||||||
n_runs: Number of Monte Carlo iterations
|
|
||||||
"""
|
|
||||||
return [Message(role="user", content=f"""Run Monte Carlo tolerance analysis on: {circuit_description}
|
|
||||||
Number of runs: {n_runs}
|
|
||||||
|
|
||||||
Workflow:
|
|
||||||
1. Create or identify the netlist for your circuit
|
|
||||||
2. Use monte_carlo tool with component tolerances:
|
|
||||||
- Resistors: typically 1% (0.01) or 5% (0.05)
|
|
||||||
- Capacitors: typically 10% (0.1) or 20% (0.2)
|
|
||||||
- Inductors: typically 10% (0.1)
|
|
||||||
3. For each completed run, extract key metrics:
|
|
||||||
- Use get_waveform on each raw file
|
|
||||||
- Use analyze_waveform for RMS, peak-to-peak, etc.
|
|
||||||
- Use measure_bandwidth for filter circuits
|
|
||||||
4. Compute statistics across all runs:
|
|
||||||
- Mean and standard deviation of each metric
|
|
||||||
- Min/max (worst case)
|
|
||||||
- Yield: what percentage meet spec?
|
|
||||||
|
|
||||||
Tips:
|
|
||||||
- Use list_simulation_runs to understand stepped data
|
|
||||||
- For stepped simulations, use get_waveform with run parameter
|
|
||||||
- Start with fewer runs (10-20) to verify setup, then scale up
|
|
||||||
- Set seed for reproducible results during development
|
|
||||||
- Typical component tolerances:
|
|
||||||
- Metal film resistors: 1%
|
|
||||||
- Ceramic capacitors: 10-20%
|
|
||||||
- Electrolytic capacitors: 20%
|
|
||||||
- Inductors: 10-20%
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def circuit_from_scratch(
|
|
||||||
description: str = "audio amplifier",
|
|
||||||
) -> list:
|
|
||||||
"""Guide through creating a complete circuit from scratch.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
description: What circuit to build
|
|
||||||
"""
|
|
||||||
return [Message(role="user", content=f"""Build a complete circuit from scratch: {description}
|
|
||||||
|
|
||||||
Approach 1 - Use a template (recommended for common circuits):
|
|
||||||
1. Use list_templates to see available circuit templates
|
|
||||||
2. Use create_from_template with custom parameters
|
|
||||||
3. Simulate with simulate_netlist
|
|
||||||
4. Analyze results with get_waveform and analyze_waveform
|
|
||||||
|
|
||||||
Approach 2 - Build from components:
|
|
||||||
1. Use create_netlist to define components and connections
|
|
||||||
2. Use search_spice_models to find transistor/diode models
|
|
||||||
3. Use search_spice_subcircuits to find op-amp/IC models
|
|
||||||
4. Add simulation directives (.tran, .ac, .dc, .op, .tf)
|
|
||||||
5. Simulate and analyze
|
|
||||||
|
|
||||||
Approach 3 - Graphical schematic (.asc file):
|
|
||||||
1. Use generate_schematic for any of 10 topologies: rc_lowpass,
|
|
||||||
voltage_divider, inverting_amp, non_inverting_amp, common_emitter_amp,
|
|
||||||
colpitts_oscillator, differential_amp, buck_converter, ldo_regulator,
|
|
||||||
h_bridge
|
|
||||||
2. The .asc file can be opened in LTspice GUI for editing
|
|
||||||
3. Simulate with the simulate tool
|
|
||||||
|
|
||||||
Verification workflow:
|
|
||||||
1. Run run_drc to check for design issues before simulating
|
|
||||||
2. Start with .op analysis to verify DC bias point
|
|
||||||
3. Run .tf analysis for gain and impedance
|
|
||||||
4. Run .ac analysis for frequency response
|
|
||||||
5. Run .tran analysis for time-domain behavior
|
|
||||||
6. Use diff_schematics to compare design iterations
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.prompt()
|
|
||||||
def troubleshoot_simulation(
|
|
||||||
error_description: str = "",
|
|
||||||
schematic_path: str = "",
|
|
||||||
) -> list:
|
|
||||||
"""Systematic checklist for diagnosing simulation failures.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
error_description: What went wrong (error message, unexpected results, etc.)
|
|
||||||
schematic_path: Path to the problematic schematic or netlist
|
|
||||||
"""
|
|
||||||
path_note = (
|
|
||||||
f"Schematic/netlist: {schematic_path}"
|
|
||||||
if schematic_path
|
|
||||||
else "First, identify the schematic or netlist file."
|
|
||||||
)
|
|
||||||
error_note = (
|
|
||||||
f"Reported issue: {error_description}"
|
|
||||||
if error_description
|
|
||||||
else "No specific error described -- run full diagnostic."
|
|
||||||
)
|
|
||||||
|
|
||||||
return [Message(role="user", content=f"""Troubleshoot a simulation that isn't working correctly.
|
|
||||||
|
|
||||||
{path_note}
|
|
||||||
{error_note}
|
|
||||||
|
|
||||||
Diagnostic checklist (work through in order):
|
|
||||||
|
|
||||||
1. **Design Rule Check**
|
|
||||||
- Run run_drc on the schematic
|
|
||||||
- Fix any: missing ground, floating nodes, duplicate names, missing sim directive
|
|
||||||
|
|
||||||
2. **Installation & Setup**
|
|
||||||
- Run check_installation to verify Wine + LTspice
|
|
||||||
- Check that required .lib files exist
|
|
||||||
|
|
||||||
3. **Model Availability**
|
|
||||||
- Use search_spice_models to verify all transistor/diode models exist
|
|
||||||
- Use search_spice_subcircuits to verify op-amp models
|
|
||||||
- Common issue: model name in schematic doesn't match library
|
|
||||||
|
|
||||||
4. **Simulation Directive**
|
|
||||||
- Use read_schematic to check the directive
|
|
||||||
- Verify analysis type matches what you want (.tran, .ac, .dc, .op, .tf)
|
|
||||||
- For .tran: is the stop time long enough?
|
|
||||||
- For .ac: are start/stop frequencies reasonable?
|
|
||||||
|
|
||||||
5. **Node Connections**
|
|
||||||
- Use read_schematic to list all components and nets
|
|
||||||
- Check for disconnected nodes (components not wired)
|
|
||||||
- Verify ground connections on all return paths
|
|
||||||
|
|
||||||
6. **Run & Inspect**
|
|
||||||
- Simulate the circuit
|
|
||||||
- Check the log file for convergence warnings
|
|
||||||
- Use get_waveform to inspect node voltages
|
|
||||||
- Compare expected vs actual at each circuit stage
|
|
||||||
|
|
||||||
7. **Simplify & Isolate**
|
|
||||||
- Use edit_component to replace active devices with ideal ones
|
|
||||||
- Remove non-essential subcircuits
|
|
||||||
- Test each stage independently
|
|
||||||
- Add .ic directives if oscillators won't start
|
|
||||||
|
|
||||||
Common failure modes:
|
|
||||||
- Convergence failure: reduce timestep, add initial conditions
|
|
||||||
- All zeros: check ground connections and source polarity
|
|
||||||
- Unexpected clipping: check supply voltages and headroom
|
|
||||||
- Oscillation in DC circuit: add small capacitors on feedback
|
|
||||||
- Model not found: verify .lib/.include paths
|
|
||||||
""")]
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# ENTRY POINT
|
# ENTRY POINT
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user