Some checks are pending
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
Add intelligent analysis and recommendation tools for KiCad designs: ## New AI Tools (kicad_mcp/tools/ai_tools.py) - suggest_components_for_circuit: Smart component suggestions based on circuit analysis - recommend_design_rules: Automated design rule recommendations for different technologies - optimize_pcb_layout: PCB layout optimization for signal integrity, thermal, and cost - analyze_design_completeness: Comprehensive design completeness analysis ## Enhanced Utilities - component_utils.py: Add ComponentType enum and component classification functions - pattern_recognition.py: Enhanced circuit pattern analysis and recommendations - netlist_parser.py: Implement missing parse_netlist_file function for AI tools ## Key Features - Circuit pattern recognition for power supplies, amplifiers, microcontrollers - Technology-specific design rules (standard, HDI, RF, automotive) - Layout optimization suggestions with implementation steps - Component suggestion system with standard values and examples - Design completeness scoring with actionable recommendations ## Server Integration - Register AI tools in FastMCP server - Integrate with existing KiCad utilities and file parsers - Error handling and graceful fallbacks for missing data Fixes ImportError that prevented server startup and enables advanced AI-powered design assistance for KiCad projects. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
701 lines
26 KiB
Python
701 lines
26 KiB
Python
"""
|
|
AI/LLM Integration Tools for KiCad MCP Server.
|
|
|
|
Provides intelligent analysis and recommendations for KiCad designs including
|
|
smart component suggestions, automated design rule recommendations, and layout optimization.
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from fastmcp import FastMCP
|
|
|
|
from kicad_mcp.utils.component_utils import ComponentType, get_component_type
|
|
from kicad_mcp.utils.file_utils import get_project_files
|
|
from kicad_mcp.utils.netlist_parser import parse_netlist_file
|
|
from kicad_mcp.utils.pattern_recognition import analyze_circuit_patterns
|
|
|
|
|
|
def register_ai_tools(mcp: FastMCP) -> None:
|
|
"""Register AI/LLM integration tools with the MCP server."""
|
|
|
|
@mcp.tool()
|
|
def suggest_components_for_circuit(project_path: str, circuit_function: str = None) -> dict[str, Any]:
|
|
"""
|
|
Analyze circuit patterns and suggest appropriate components.
|
|
|
|
Uses circuit analysis to identify incomplete circuits and suggest
|
|
missing components based on common design patterns and best practices.
|
|
|
|
Args:
|
|
project_path: Path to the KiCad project file (.kicad_pro)
|
|
circuit_function: Optional description of intended circuit function
|
|
|
|
Returns:
|
|
Dictionary with component suggestions categorized by circuit type
|
|
|
|
Examples:
|
|
suggest_components_for_circuit("/path/to/project.kicad_pro")
|
|
suggest_components_for_circuit("/path/to/project.kicad_pro", "audio amplifier")
|
|
"""
|
|
try:
|
|
# Get project files
|
|
files = get_project_files(project_path)
|
|
if "schematic" not in files:
|
|
return {
|
|
"success": False,
|
|
"error": "Schematic file not found in project"
|
|
}
|
|
|
|
schematic_file = files["schematic"]
|
|
|
|
# Analyze existing circuit patterns
|
|
patterns = analyze_circuit_patterns(schematic_file)
|
|
|
|
# Parse netlist for component analysis
|
|
try:
|
|
netlist_data = parse_netlist_file(schematic_file)
|
|
components = netlist_data.get("components", [])
|
|
except:
|
|
components = []
|
|
|
|
# Generate suggestions based on patterns
|
|
suggestions = _generate_component_suggestions(patterns, components, circuit_function)
|
|
|
|
return {
|
|
"success": True,
|
|
"project_path": project_path,
|
|
"circuit_analysis": {
|
|
"identified_patterns": list(patterns.keys()),
|
|
"component_count": len(components),
|
|
"missing_patterns": _identify_missing_patterns(patterns, components)
|
|
},
|
|
"component_suggestions": suggestions,
|
|
"design_recommendations": _generate_design_recommendations(patterns, components),
|
|
"implementation_notes": [
|
|
"Review suggested components for compatibility with existing design",
|
|
"Verify component ratings match circuit requirements",
|
|
"Consider thermal management for power components",
|
|
"Check component availability and cost before finalizing"
|
|
]
|
|
}
|
|
|
|
except Exception as e:
|
|
return {
|
|
"success": False,
|
|
"error": str(e),
|
|
"project_path": project_path
|
|
}
|
|
|
|
@mcp.tool()
|
|
def recommend_design_rules(project_path: str, target_technology: str = "standard") -> dict[str, Any]:
|
|
"""
|
|
Generate automated design rule recommendations based on circuit analysis.
|
|
|
|
Analyzes the circuit topology, component types, and signal characteristics
|
|
to recommend appropriate design rules for the specific application.
|
|
|
|
Args:
|
|
project_path: Path to the KiCad project file (.kicad_pro)
|
|
target_technology: Target technology ("standard", "hdi", "rf", "automotive")
|
|
|
|
Returns:
|
|
Dictionary with customized design rule recommendations
|
|
|
|
Examples:
|
|
recommend_design_rules("/path/to/project.kicad_pro")
|
|
recommend_design_rules("/path/to/project.kicad_pro", "rf")
|
|
"""
|
|
try:
|
|
# Get project files
|
|
files = get_project_files(project_path)
|
|
|
|
analysis_data = {}
|
|
|
|
# Analyze schematic if available
|
|
if "schematic" in files:
|
|
patterns = analyze_circuit_patterns(files["schematic"])
|
|
analysis_data["patterns"] = patterns
|
|
|
|
try:
|
|
netlist_data = parse_netlist_file(files["schematic"])
|
|
analysis_data["components"] = netlist_data.get("components", [])
|
|
except:
|
|
analysis_data["components"] = []
|
|
|
|
# Analyze PCB if available
|
|
if "pcb" in files:
|
|
pcb_analysis = _analyze_pcb_characteristics(files["pcb"])
|
|
analysis_data["pcb"] = pcb_analysis
|
|
|
|
# Generate design rules based on analysis
|
|
design_rules = _generate_design_rules(analysis_data, target_technology)
|
|
|
|
return {
|
|
"success": True,
|
|
"project_path": project_path,
|
|
"target_technology": target_technology,
|
|
"circuit_analysis": {
|
|
"identified_patterns": list(analysis_data.get("patterns", {}).keys()),
|
|
"component_types": _categorize_components(analysis_data.get("components", [])),
|
|
"signal_types": _identify_signal_types(analysis_data.get("patterns", {}))
|
|
},
|
|
"recommended_rules": design_rules,
|
|
"rule_justifications": _generate_rule_justifications(design_rules, analysis_data),
|
|
"implementation_priority": _prioritize_rules(design_rules)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {
|
|
"success": False,
|
|
"error": str(e),
|
|
"project_path": project_path
|
|
}
|
|
|
|
@mcp.tool()
|
|
def optimize_pcb_layout(project_path: str, optimization_goals: list[str] = None) -> dict[str, Any]:
|
|
"""
|
|
Analyze PCB layout and provide optimization suggestions.
|
|
|
|
Reviews component placement, routing, and design practices to suggest
|
|
improvements for signal integrity, thermal management, and manufacturability.
|
|
|
|
Args:
|
|
project_path: Path to the KiCad project file (.kicad_pro)
|
|
optimization_goals: List of optimization priorities (e.g., ["signal_integrity", "thermal", "cost"])
|
|
|
|
Returns:
|
|
Dictionary with layout optimization recommendations
|
|
|
|
Examples:
|
|
optimize_pcb_layout("/path/to/project.kicad_pro")
|
|
optimize_pcb_layout("/path/to/project.kicad_pro", ["signal_integrity", "cost"])
|
|
"""
|
|
try:
|
|
if not optimization_goals:
|
|
optimization_goals = ["signal_integrity", "thermal", "manufacturability"]
|
|
|
|
# Get project files
|
|
files = get_project_files(project_path)
|
|
|
|
if "pcb" not in files:
|
|
return {
|
|
"success": False,
|
|
"error": "PCB file not found in project"
|
|
}
|
|
|
|
pcb_file = files["pcb"]
|
|
|
|
# Analyze current layout
|
|
layout_analysis = _analyze_pcb_layout(pcb_file)
|
|
|
|
# Get circuit context from schematic if available
|
|
circuit_context = {}
|
|
if "schematic" in files:
|
|
patterns = analyze_circuit_patterns(files["schematic"])
|
|
circuit_context = {"patterns": patterns}
|
|
|
|
# Generate optimization suggestions
|
|
optimizations = _generate_layout_optimizations(
|
|
layout_analysis, circuit_context, optimization_goals
|
|
)
|
|
|
|
return {
|
|
"success": True,
|
|
"project_path": project_path,
|
|
"optimization_goals": optimization_goals,
|
|
"layout_analysis": {
|
|
"component_density": layout_analysis.get("component_density", 0),
|
|
"routing_utilization": layout_analysis.get("routing_utilization", {}),
|
|
"thermal_zones": layout_analysis.get("thermal_zones", []),
|
|
"critical_signals": layout_analysis.get("critical_signals", [])
|
|
},
|
|
"optimization_suggestions": optimizations,
|
|
"implementation_steps": _generate_implementation_steps(optimizations),
|
|
"expected_benefits": _calculate_optimization_benefits(optimizations)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {
|
|
"success": False,
|
|
"error": str(e),
|
|
"project_path": project_path
|
|
}
|
|
|
|
@mcp.tool()
|
|
def analyze_design_completeness(project_path: str) -> dict[str, Any]:
|
|
"""
|
|
Analyze design completeness and suggest missing elements.
|
|
|
|
Performs comprehensive analysis to identify missing components,
|
|
incomplete circuits, and design gaps that should be addressed.
|
|
|
|
Args:
|
|
project_path: Path to the KiCad project file (.kicad_pro)
|
|
|
|
Returns:
|
|
Dictionary with completeness analysis and improvement suggestions
|
|
"""
|
|
try:
|
|
files = get_project_files(project_path)
|
|
|
|
completeness_analysis = {
|
|
"schematic_completeness": 0,
|
|
"pcb_completeness": 0,
|
|
"design_gaps": [],
|
|
"missing_elements": [],
|
|
"verification_status": {}
|
|
}
|
|
|
|
# Analyze schematic completeness
|
|
if "schematic" in files:
|
|
schematic_analysis = _analyze_schematic_completeness(files["schematic"])
|
|
completeness_analysis.update(schematic_analysis)
|
|
|
|
# Analyze PCB completeness
|
|
if "pcb" in files:
|
|
pcb_analysis = _analyze_pcb_completeness(files["pcb"])
|
|
completeness_analysis["pcb_completeness"] = pcb_analysis["completeness_score"]
|
|
completeness_analysis["design_gaps"].extend(pcb_analysis["gaps"])
|
|
|
|
# Overall completeness score
|
|
overall_score = (
|
|
completeness_analysis["schematic_completeness"] * 0.6 +
|
|
completeness_analysis["pcb_completeness"] * 0.4
|
|
)
|
|
|
|
return {
|
|
"success": True,
|
|
"project_path": project_path,
|
|
"completeness_score": round(overall_score, 1),
|
|
"analysis_details": completeness_analysis,
|
|
"priority_actions": _prioritize_completeness_actions(completeness_analysis),
|
|
"design_checklist": _generate_design_checklist(completeness_analysis),
|
|
"recommendations": _generate_completeness_recommendations(completeness_analysis)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {
|
|
"success": False,
|
|
"error": str(e),
|
|
"project_path": project_path
|
|
}
|
|
|
|
|
|
# Helper functions for component suggestions
|
|
def _generate_component_suggestions(patterns: dict, components: list, circuit_function: str = None) -> dict[str, list]:
|
|
"""Generate component suggestions based on circuit analysis."""
|
|
suggestions = {
|
|
"power_management": [],
|
|
"signal_conditioning": [],
|
|
"protection": [],
|
|
"filtering": [],
|
|
"interface": [],
|
|
"passive_components": []
|
|
}
|
|
|
|
# Analyze existing components
|
|
component_types = [get_component_type(comp.get("value", "")) for comp in components]
|
|
|
|
# Power management suggestions
|
|
if "power_supply" in patterns:
|
|
if ComponentType.VOLTAGE_REGULATOR not in component_types:
|
|
suggestions["power_management"].append({
|
|
"component": "Voltage Regulator",
|
|
"suggestion": "Add voltage regulator for stable power supply",
|
|
"examples": ["LM7805", "AMS1117-3.3", "LM2596"]
|
|
})
|
|
|
|
if ComponentType.CAPACITOR not in component_types:
|
|
suggestions["power_management"].append({
|
|
"component": "Decoupling Capacitors",
|
|
"suggestion": "Add decoupling capacitors near power pins",
|
|
"examples": ["100nF ceramic", "10uF tantalum", "1000uF electrolytic"]
|
|
})
|
|
|
|
# Signal conditioning suggestions
|
|
if "amplifier" in patterns:
|
|
if not any("op" in comp.get("value", "").lower() for comp in components):
|
|
suggestions["signal_conditioning"].append({
|
|
"component": "Operational Amplifier",
|
|
"suggestion": "Consider op-amp for signal amplification",
|
|
"examples": ["LM358", "TL072", "OPA2134"]
|
|
})
|
|
|
|
# Protection suggestions
|
|
if "microcontroller" in patterns or "processor" in patterns:
|
|
if ComponentType.FUSE not in component_types:
|
|
suggestions["protection"].append({
|
|
"component": "Fuse or PTC Resettable Fuse",
|
|
"suggestion": "Add overcurrent protection",
|
|
"examples": ["1A fuse", "PPTC 0.5A", "Polyfuse 1A"]
|
|
})
|
|
|
|
if not any("esd" in comp.get("value", "").lower() for comp in components):
|
|
suggestions["protection"].append({
|
|
"component": "ESD Protection",
|
|
"suggestion": "Add ESD protection for I/O pins",
|
|
"examples": ["TVS diode", "ESD suppressors", "Varistors"]
|
|
})
|
|
|
|
# Filtering suggestions
|
|
if any(pattern in patterns for pattern in ["switching_converter", "motor_driver"]):
|
|
suggestions["filtering"].append({
|
|
"component": "EMI Filter",
|
|
"suggestion": "Add EMI filtering for switching circuits",
|
|
"examples": ["Common mode choke", "Ferrite beads", "Pi filter"]
|
|
})
|
|
|
|
# Interface suggestions based on circuit function
|
|
if circuit_function:
|
|
function_lower = circuit_function.lower()
|
|
if "audio" in function_lower:
|
|
suggestions["interface"].extend([
|
|
{
|
|
"component": "Audio Jack",
|
|
"suggestion": "Add audio input/output connector",
|
|
"examples": ["3.5mm jack", "RCA connector", "XLR"]
|
|
},
|
|
{
|
|
"component": "Audio Coupling Capacitor",
|
|
"suggestion": "AC coupling for audio signals",
|
|
"examples": ["10uF", "47uF", "100uF"]
|
|
}
|
|
])
|
|
|
|
if "usb" in function_lower or "communication" in function_lower:
|
|
suggestions["interface"].append({
|
|
"component": "USB Connector",
|
|
"suggestion": "Add USB interface for communication",
|
|
"examples": ["USB-A", "USB-C", "Micro-USB"]
|
|
})
|
|
|
|
return suggestions
|
|
|
|
|
|
def _identify_missing_patterns(patterns: dict, components: list) -> list[str]:
|
|
"""Identify common circuit patterns that might be missing."""
|
|
missing_patterns = []
|
|
|
|
has_digital_components = any(
|
|
comp.get("value", "").lower() in ["microcontroller", "processor", "mcu"]
|
|
for comp in components
|
|
)
|
|
|
|
if has_digital_components:
|
|
if "crystal_oscillator" not in patterns:
|
|
missing_patterns.append("crystal_oscillator")
|
|
if "reset_circuit" not in patterns:
|
|
missing_patterns.append("reset_circuit")
|
|
if "power_supply" not in patterns:
|
|
missing_patterns.append("power_supply")
|
|
|
|
return missing_patterns
|
|
|
|
|
|
def _generate_design_recommendations(patterns: dict, components: list) -> list[str]:
|
|
"""Generate general design recommendations."""
|
|
recommendations = []
|
|
|
|
if "power_supply" not in patterns and len(components) > 5:
|
|
recommendations.append("Consider adding dedicated power supply regulation")
|
|
|
|
if len(components) > 20 and "decoupling" not in patterns:
|
|
recommendations.append("Add decoupling capacitors for noise reduction")
|
|
|
|
if any("high_freq" in str(pattern) for pattern in patterns):
|
|
recommendations.append("Consider transmission line effects for high-frequency signals")
|
|
|
|
return recommendations
|
|
|
|
|
|
# Helper functions for design rules
|
|
def _analyze_pcb_characteristics(pcb_file: str) -> dict[str, Any]:
|
|
"""Analyze PCB file for design rule recommendations."""
|
|
# This is a simplified analysis - in practice would parse the PCB file
|
|
return {
|
|
"layer_count": 2, # Default assumption
|
|
"min_trace_width": 0.1,
|
|
"min_via_size": 0.2,
|
|
"component_density": "medium"
|
|
}
|
|
|
|
|
|
def _generate_design_rules(analysis_data: dict, target_technology: str) -> dict[str, dict]:
|
|
"""Generate design rules based on analysis and technology target."""
|
|
base_rules = {
|
|
"trace_width": {"min": 0.1, "preferred": 0.15, "unit": "mm"},
|
|
"via_size": {"min": 0.2, "preferred": 0.3, "unit": "mm"},
|
|
"clearance": {"min": 0.1, "preferred": 0.15, "unit": "mm"},
|
|
"annular_ring": {"min": 0.05, "preferred": 0.1, "unit": "mm"}
|
|
}
|
|
|
|
# Adjust rules based on technology
|
|
if target_technology == "hdi":
|
|
base_rules["trace_width"]["min"] = 0.075
|
|
base_rules["via_size"]["min"] = 0.1
|
|
base_rules["clearance"]["min"] = 0.075
|
|
elif target_technology == "rf":
|
|
base_rules["trace_width"]["preferred"] = 0.2
|
|
base_rules["clearance"]["preferred"] = 0.2
|
|
elif target_technology == "automotive":
|
|
base_rules["trace_width"]["min"] = 0.15
|
|
base_rules["clearance"]["min"] = 0.15
|
|
|
|
# Adjust based on patterns
|
|
patterns = analysis_data.get("patterns", {})
|
|
if "power_supply" in patterns:
|
|
base_rules["power_trace_width"] = {"min": 0.3, "preferred": 0.5, "unit": "mm"}
|
|
|
|
if "high_speed" in patterns:
|
|
base_rules["differential_impedance"] = {"target": 100, "tolerance": 10, "unit": "ohm"}
|
|
base_rules["single_ended_impedance"] = {"target": 50, "tolerance": 5, "unit": "ohm"}
|
|
|
|
return base_rules
|
|
|
|
|
|
def _categorize_components(components: list) -> dict[str, int]:
|
|
"""Categorize components by type."""
|
|
categories = {}
|
|
for comp in components:
|
|
comp_type = get_component_type(comp.get("value", ""))
|
|
category_name = comp_type.name.lower() if comp_type != ComponentType.UNKNOWN else "other"
|
|
categories[category_name] = categories.get(category_name, 0) + 1
|
|
|
|
return categories
|
|
|
|
|
|
def _identify_signal_types(patterns: dict) -> list[str]:
|
|
"""Identify signal types based on circuit patterns."""
|
|
signal_types = []
|
|
|
|
if "power_supply" in patterns:
|
|
signal_types.append("power")
|
|
if "amplifier" in patterns:
|
|
signal_types.append("analog")
|
|
if "microcontroller" in patterns:
|
|
signal_types.extend(["digital", "clock"])
|
|
if "crystal_oscillator" in patterns:
|
|
signal_types.append("high_frequency")
|
|
|
|
return list(set(signal_types))
|
|
|
|
|
|
def _generate_rule_justifications(design_rules: dict, analysis_data: dict) -> dict[str, str]:
|
|
"""Generate justifications for recommended design rules."""
|
|
justifications = {}
|
|
|
|
patterns = analysis_data.get("patterns", {})
|
|
|
|
if "trace_width" in design_rules:
|
|
justifications["trace_width"] = "Based on current carrying capacity and manufacturing constraints"
|
|
|
|
if "power_supply" in patterns and "power_trace_width" in design_rules:
|
|
justifications["power_trace_width"] = "Wider traces for power distribution to reduce voltage drop"
|
|
|
|
if "high_speed" in patterns and "differential_impedance" in design_rules:
|
|
justifications["differential_impedance"] = "Controlled impedance required for high-speed signals"
|
|
|
|
return justifications
|
|
|
|
|
|
def _prioritize_rules(design_rules: dict) -> list[str]:
|
|
"""Prioritize design rules by implementation importance."""
|
|
priority_order = []
|
|
|
|
if "clearance" in design_rules:
|
|
priority_order.append("clearance")
|
|
if "trace_width" in design_rules:
|
|
priority_order.append("trace_width")
|
|
if "via_size" in design_rules:
|
|
priority_order.append("via_size")
|
|
if "power_trace_width" in design_rules:
|
|
priority_order.append("power_trace_width")
|
|
if "differential_impedance" in design_rules:
|
|
priority_order.append("differential_impedance")
|
|
|
|
return priority_order
|
|
|
|
|
|
# Helper functions for layout optimization
|
|
def _analyze_pcb_layout(pcb_file: str) -> dict[str, Any]:
|
|
"""Analyze PCB layout for optimization opportunities."""
|
|
# Simplified analysis - would parse actual PCB file
|
|
return {
|
|
"component_density": 0.6,
|
|
"routing_utilization": {"top": 0.4, "bottom": 0.3},
|
|
"thermal_zones": ["high_power_area"],
|
|
"critical_signals": ["clock", "reset", "power"]
|
|
}
|
|
|
|
|
|
def _generate_layout_optimizations(layout_analysis: dict, circuit_context: dict, goals: list[str]) -> dict[str, list]:
|
|
"""Generate layout optimization suggestions."""
|
|
optimizations = {
|
|
"placement": [],
|
|
"routing": [],
|
|
"thermal": [],
|
|
"signal_integrity": [],
|
|
"manufacturability": []
|
|
}
|
|
|
|
if "signal_integrity" in goals:
|
|
optimizations["signal_integrity"].extend([
|
|
"Keep high-speed traces short and direct",
|
|
"Minimize via count on critical signals",
|
|
"Use ground planes for return current paths"
|
|
])
|
|
|
|
if "thermal" in goals:
|
|
optimizations["thermal"].extend([
|
|
"Spread heat-generating components across the board",
|
|
"Add thermal vias under power components",
|
|
"Consider copper pour for heat dissipation"
|
|
])
|
|
|
|
if "cost" in goals or "manufacturability" in goals:
|
|
optimizations["manufacturability"].extend([
|
|
"Use standard via sizes and trace widths",
|
|
"Minimize layer count where possible",
|
|
"Avoid blind/buried vias unless necessary"
|
|
])
|
|
|
|
return optimizations
|
|
|
|
|
|
def _generate_implementation_steps(optimizations: dict) -> list[str]:
|
|
"""Generate step-by-step implementation guide."""
|
|
steps = []
|
|
|
|
if optimizations.get("placement"):
|
|
steps.append("1. Review component placement for optimal positioning")
|
|
|
|
if optimizations.get("routing"):
|
|
steps.append("2. Re-route critical signals following guidelines")
|
|
|
|
if optimizations.get("thermal"):
|
|
steps.append("3. Implement thermal management improvements")
|
|
|
|
if optimizations.get("signal_integrity"):
|
|
steps.append("4. Optimize signal integrity aspects")
|
|
|
|
steps.append("5. Run DRC and electrical rules check")
|
|
steps.append("6. Verify design meets all requirements")
|
|
|
|
return steps
|
|
|
|
|
|
def _calculate_optimization_benefits(optimizations: dict) -> dict[str, str]:
|
|
"""Calculate expected benefits from optimizations."""
|
|
benefits = {}
|
|
|
|
if optimizations.get("signal_integrity"):
|
|
benefits["signal_integrity"] = "Improved noise margin and reduced EMI"
|
|
|
|
if optimizations.get("thermal"):
|
|
benefits["thermal"] = "Better thermal performance and component reliability"
|
|
|
|
if optimizations.get("manufacturability"):
|
|
benefits["manufacturability"] = "Reduced manufacturing cost and higher yield"
|
|
|
|
return benefits
|
|
|
|
|
|
# Helper functions for design completeness
|
|
def _analyze_schematic_completeness(schematic_file: str) -> dict[str, Any]:
|
|
"""Analyze schematic completeness."""
|
|
try:
|
|
patterns = analyze_circuit_patterns(schematic_file)
|
|
netlist_data = parse_netlist_file(schematic_file)
|
|
components = netlist_data.get("components", [])
|
|
|
|
completeness_score = 70 # Base score
|
|
missing_elements = []
|
|
|
|
# Check for essential patterns
|
|
if "power_supply" in patterns:
|
|
completeness_score += 10
|
|
else:
|
|
missing_elements.append("power_supply_regulation")
|
|
|
|
if len(components) > 5:
|
|
if "decoupling" not in patterns:
|
|
missing_elements.append("decoupling_capacitors")
|
|
else:
|
|
completeness_score += 10
|
|
|
|
return {
|
|
"schematic_completeness": min(completeness_score, 100),
|
|
"missing_elements": missing_elements,
|
|
"design_gaps": [],
|
|
"verification_status": {"nets": "checked", "components": "verified"}
|
|
}
|
|
|
|
except Exception:
|
|
return {
|
|
"schematic_completeness": 50,
|
|
"missing_elements": ["analysis_failed"],
|
|
"design_gaps": [],
|
|
"verification_status": {"status": "error"}
|
|
}
|
|
|
|
|
|
def _analyze_pcb_completeness(pcb_file: str) -> dict[str, Any]:
|
|
"""Analyze PCB completeness."""
|
|
# Simplified analysis
|
|
return {
|
|
"completeness_score": 80,
|
|
"gaps": ["silkscreen_labels", "test_points"]
|
|
}
|
|
|
|
|
|
def _prioritize_completeness_actions(analysis: dict) -> list[str]:
|
|
"""Prioritize actions for improving design completeness."""
|
|
actions = []
|
|
|
|
if "power_supply_regulation" in analysis.get("missing_elements", []):
|
|
actions.append("Add power supply regulation circuit")
|
|
|
|
if "decoupling_capacitors" in analysis.get("missing_elements", []):
|
|
actions.append("Add decoupling capacitors near ICs")
|
|
|
|
if analysis.get("schematic_completeness", 0) < 80:
|
|
actions.append("Complete schematic design")
|
|
|
|
if analysis.get("pcb_completeness", 0) < 80:
|
|
actions.append("Finish PCB layout")
|
|
|
|
return actions
|
|
|
|
|
|
def _generate_design_checklist(analysis: dict) -> list[dict[str, Any]]:
|
|
"""Generate design verification checklist."""
|
|
checklist = [
|
|
{"item": "Schematic review complete", "status": "complete" if analysis.get("schematic_completeness", 0) > 90 else "pending"},
|
|
{"item": "Component values verified", "status": "complete" if "components" in analysis.get("verification_status", {}) else "pending"},
|
|
{"item": "Power supply design", "status": "complete" if "power_supply_regulation" not in analysis.get("missing_elements", []) else "pending"},
|
|
{"item": "Signal integrity considerations", "status": "pending"},
|
|
{"item": "Thermal management", "status": "pending"},
|
|
{"item": "Manufacturing readiness", "status": "pending"}
|
|
]
|
|
|
|
return checklist
|
|
|
|
|
|
def _generate_completeness_recommendations(analysis: dict) -> list[str]:
|
|
"""Generate recommendations for improving completeness."""
|
|
recommendations = []
|
|
|
|
completeness = analysis.get("schematic_completeness", 0)
|
|
|
|
if completeness < 70:
|
|
recommendations.append("Focus on completing core circuit functionality")
|
|
elif completeness < 85:
|
|
recommendations.append("Add protective and filtering components")
|
|
else:
|
|
recommendations.append("Review design for optimization opportunities")
|
|
|
|
if analysis.get("missing_elements"):
|
|
recommendations.append(f"Address missing elements: {', '.join(analysis['missing_elements'])}")
|
|
|
|
return recommendations
|