Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SKiDL Feature Request] LLM Analysis tool #240

Open
shanemmattner opened this issue Jan 5, 2025 · 1 comment
Open

[SKiDL Feature Request] LLM Analysis tool #240

shanemmattner opened this issue Jan 5, 2025 · 1 comment

Comments

@shanemmattner
Copy link
Contributor

I opened up this draft PR but I'm posting here for visibility.

I've been using LLM's to check my circuit theory and help with circuit design and PCB design in general. I thought SKiDL's python based circuit descriptions would work great with LLM's. So far the results seem to be promising, but it's clear that I need to include more information on each subcircuit, part, and connections for the LLM to give better analysis.

@devbisme if you think it's worth adding to SKiDL it'll keep working on it. I just made a basic example that I only tested with Claude so far.

Here's an example output analysis file:
subcircuits_analysis.txt
From running this code:

from skidl import *
import os

@subcircuit
def rc_filter(inp, outp, gnd):
    """RC low-pass filter"""
    r = Part("Device", 'R', footprint='Resistor_SMD.pretty:R_0805_2012Metric', value='10K')
    c = Part("Device", 'C', footprint='Capacitor_SMD:C_0805_2012Metric', value='0.1uF')
    inp += r[1]
    r[2] += c[1]
    c[2] += gnd
    outp += r[2]

@subcircuit
def input_protection(inp, outp, gnd):
    """Input protection and bulk capacitance"""
    d_protect = Part("Device", 'D',
                    footprint='Diode_SMD:D_SOD-123',
                    value='1N4148W')
    c_bulk = Part("Device", 'C',
                  footprint='Capacitor_THT:CP_Radial_D10.0mm_P5.00mm',
                  value='100uF')
    
    inp += d_protect['A']
    outp += d_protect['K']
    inp += c_bulk[1]
    gnd += c_bulk[2]

@subcircuit
def voltage_regulator(inp, outp, gnd):
    """5V voltage regulator with decoupling caps"""
    reg = Part("Regulator_Linear", "LM7805_TO220",
               footprint="Package_TO_SOT_THT:TO-220-3_Vertical")
    cin = Part("Device", 'C', footprint='Capacitor_SMD:C_0805_2012Metric', value='10uF')
    cout = Part("Device", 'C', footprint='Capacitor_SMD:C_0805_2012Metric', value='10uF')
    inp += cin[1], reg['VI']
    cin[2] += gnd
    reg['GND'] += gnd
    reg['VO'] += cout[1], outp
    cout[2] += gnd

@subcircuit
def voltage_divider(inp, outp, gnd):
    """Basic voltage divider subcircuit"""
    r1 = Part("Device", 'R', footprint='Resistor_SMD.pretty:R_0805_2012Metric', value='1K')
    r2 = Part("Device", 'R', footprint='Resistor_SMD.pretty:R_0805_2012Metric', value='500')
    inp += r1[1]
    r1[2] += r2[1]
    r2[2] += gnd
    outp += r1[2]

@subcircuit
def output_termination(inp, gnd):
    """Output termination resistor"""
    r_term = Part("Device", 'R',
                  footprint='Resistor_SMD.pretty:R_0805_2012Metric',
                  value='100K')
    inp += r_term[1]
    gnd += r_term[2]

@subcircuit
def power_section(raw_in, reg_out, filt_out, gnd):
    """Power section with regulation and filtering"""
    protected_in = Net()
    input_protection(raw_in, protected_in, gnd)
    voltage_regulator(protected_in, reg_out, gnd)
    rc_filter(reg_out, filt_out, gnd)

@subcircuit
def double_divider(inp, outp, gnd):
    """Two voltage dividers in series with termination"""
    mid = Net()
    voltage_divider(inp, mid, gnd)
    voltage_divider(mid, outp, gnd)
    output_termination(outp, gnd)

@subcircuit
def complete_circuit():
    """Top level circuit connecting all subcircuits"""
    vin = Net()
    vreg = Net()
    vfilt = Net()
    vout = Net()
    gnd = Net()

    power_section(vin, vreg, vfilt, gnd)
    double_divider(vfilt, vout, gnd)

# Create the complete circuit
complete_circuit()

# Analyze each subcircuit separately using the new function
results = default_circuit.analyze_subcircuits_with_llm(
    api_key=os.getenv("ANTHROPIC_API_KEY"),
    output_file="subcircuits_analysis.txt"
)

# Print analysis results
if results["success"]:
    print("\nAnalysis Results:")
    for hier, analysis in results["subcircuits"].items():
        print(f"\nSubcircuit: {hier}")
        if analysis["success"]:
            print(f"Analysis completed in {analysis['request_time_seconds']:.2f} seconds")
            print(f"Tokens used: {analysis['prompt_tokens'] + analysis['response_tokens']}")
        else:
            print(f"Analysis failed: {analysis['error']}")
            
    print(f"\nTotal analysis time: {results['total_time_seconds']:.2f} seconds")
    print(f"Total tokens used: {results['total_tokens']}")
else:
    print(f"\nOverall analysis failed: {results.get('error', 'Unknown error')}")
@devbisme
Copy link
Owner

devbisme commented Jan 5, 2025

For increased visibility to others that might help with this, I think you should open up a thread on discussions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants