AgentSkillsCN

jitx-component-modeler

为电子元器件生成 JITX Python 组件代码。当用户要求创建组件、建模元器件、生成组件、添加组件,或制作 JITX 组件时——即使手中没有元器件数据手册——也务必调用此技能。该技能会根据元器件型号(如 NE555、LM1117、RP2040 等)与封装类型(如 SOIC、QFN、BGA、SON、SOT)进行精准匹配。同时,它支持多单元符号、热焊盘,以及复杂的引脚映射。

SKILL.md
--- frontmatter
name: jitx-component-modeler
description: Create JITX Python component code for electronic parts. ALWAYS use this skill when user asks to create a component, model a part, generate a component, add a component, or make a JITX component - even without a datasheet. Triggers on part numbers (NE555, LM1117, RP2040, etc.) and package types (SOIC, QFN, BGA, SON, SOT). Supports multi-unit symbols, thermal pads, and complex pin mappings.

JITX Component Generation Skill

Generate JITX Python component code from datasheets and specifications.

Environment

Environment setup is handled by the base jitx skill. Ensure it has been invoked first.

Datasheet Handling

ALWAYS save datasheets locally before reading.

When user provides a URL or asks to download a datasheet:

  1. Download the PDF using WebFetch
  2. Save to datasheets/<mpn>.pdf in the project (create folder if needed)
  3. Then use the extraction process in Step 0

This ensures:

  • Datasheet is available for future reference
  • Consistent file paths for extraction scripts
  • No repeated downloads

AVOID REDUNDANT WEB SEARCHES

Once you have the datasheet PDF, extract pinout, package dimensions, and pin descriptions from it using Step 0. Do NOT search for info that's already in the datasheet.

When additional searches ARE appropriate:

  • Datasheet lacks package mechanical drawings (common for simple parts)
  • Complex packages (200+ pins) where cross-referencing helps catch errors
  • Need separate package drawing document (e.g., TI's MPDS files)

When searching:

  • Use manufacturer sites: ti.com, analog.com, st.com, nxp.com, microchip.com, infineon.com, onsemi.com
  • Search pattern: "<MPN> datasheet" site:<manufacturer>.com
  • Avoid distributor sites, random aggregators, or unverified PDFs

Output Location

ALWAYS place components in a components/ folder, even for single components.

Standard Structure

code
project/
└── src/<namespace>/
    └── components/
        ├── __init__.py
        ├── <category>/
        │   ├── __init__.py
        │   └── <manufacturer>_<mpn>.py
        └── <category>/
            └── ...

If src/<namespace>/ doesn't exist, use:

code
project/
└── components/
    ├── __init__.py
    └── <manufacturer>_<mpn>.py

Category examples: mcus, connectors, power_linear_regulators, opamp, flash, crystals, leds, logic, timers, buttons, transceivers, diodes_tvs, isolators, power_switchmode

File naming: <manufacturer>_<mpn>.py - lowercase, underscores for spaces/special chars

  • texas_instruments_NE555.py
  • raspberry_pi_RP2040.py
  • renesas_DA14705.py

Instructions

When generating a JITX component from a datasheet or specification, follow this structured approach:

Step 0: Handle Datasheets (CRITICAL)

NEVER read a full datasheet PDF directly. Even 50-page PDFs consume excessive context.

Always extract relevant pages first using scripts/extract_pages.py:

bash
# Find pages containing keywords
python scripts/extract_pages.py datasheet.pdf --find "pinout" "pin description" "dimension" "package" "ball map" "mechanical"

# Extract matched pages to a smaller PDF
python scripts/extract_pages.py datasheet.pdf --pages 10 11 12 -o datasheet_extract.pdf

Then read only the extracted PDF.

Key pages to find:

  • Pin assignment / ball map (usually pages 10-20)
  • Pin description table
  • Package mechanical drawing (usually near end)
  • Ordering information

If pymupdf not available, ask user to provide:

  • Pin count and package type
  • Screenshot of pinout/ball map
  • Package dimensions (body size, pitch, ball/lead size)

Do NOT just read the PDF and hope for the best - this will exhaust context.

Step 1: Extract Key Information

IMPORTANT: Multiple Packages/Variants

If the datasheet covers multiple package options or component variants, use AskUserQuestion to ask the user which one to model:

code
Example: "The datasheet shows 3 package options for this part:
- SOIC-8 (NE555DR)
- PDIP-8 (NE555P)
- VSSOP-8 (NE555DGKR)

Which package would you like me to model?"

Do NOT assume or pick one arbitrarily. Ask first.

From the datasheet (or extracted pages), extract:

  1. Component identification: Manufacturer, MPN, description
  2. Package type: SOIC, SOT, QFN, BGA, SON, etc.
  3. Pin count: Total number of pins
  4. Pin functions: Pin names and functions from pinout table (see Pin Naming below)
  5. Package dimensions:
    • Body width/length (D, E dimensions)
    • Body height (A dimension)
    • Lead span (E1/D1 or terminal span)
    • Lead pitch (e dimension)
    • Lead width (b dimension)
    • Lead length (L dimension)

Step 2: Select Package Generator

Use this decision tree to select the appropriate generator:

code
Is it a 2-sided package?
├── Yes, ≤6 pins → SOT23_3, SOT23_5, or SOT23_6
├── Yes, >6 pins with gull-wing leads → SOIC
├── Yes, >6 pins with flat leads (no-lead) → SON
└── No (4-sided or array)
    ├── 4-sided gull-wing leads → QFP
    ├── 4-sided flat/no-lead → QFN
    ├── Bottom ball array → BGA
    └── Custom/unusual → Manual Landpattern

Step 3: Generate Component Code

Use this template structure:

python
"""
{Manufacturer} {MPN} - {Description}

Component definition for the {full description}.
"""

import jitx
from jitx import PadMapping
from jitx.net import Port
from jitx.toleranced import Toleranced
from jitxlib.symbols.box import BoxSymbol, PinGroup, Row, Column
# Import appropriate landpattern generator:
# from jitxlib.landpatterns.generators.soic import SOIC, SOIC_DEFAULT_LEAD_PROFILE
# from jitxlib.landpatterns.generators.sot import SOT23_3, SOT23_5, SOT23_6, SOTLeadProfile
# from jitxlib.landpatterns.generators.qfn import QFN, QFNLead
# from jitxlib.landpatterns.generators.son import SON, SONLead
# from jitxlib.landpatterns.generators.bga import BGA
from jitxlib.landpatterns.leads import LeadProfile
from jitxlib.landpatterns.package import RectanglePackage


class {ComponentClassName}(jitx.Component):
    """Brief description of the component."""

    mpn = "{MPN}"
    manufacturer = "{Manufacturer}"
    reference_designator_prefix = "U"  # or "Q" for transistors, etc.
    datasheet = "{datasheet_url}"

    # Define ports for each pin
    # Single pins:
    VCC = Port()
    GND = Port()

    # Pin arrays (for many similar pins):
    GPIO = [Port() for _ in range(N)]

    # Landpattern definition
    landpattern = (
        {Generator}(num_leads=N)
        .lead_profile(...)
        .package_body(...)
        # Optional: .thermal_pad(...)
    )

    # Symbol definition
    symbol = BoxSymbol(
        rows=Row(
            left=PinGroup(...),
            right=PinGroup(...),
        ),
        columns=Column(
            up=PinGroup(...),    # Power pins typically go up
            down=PinGroup(...),  # Ground pins typically go down
        ),
    )

    # For non-standard pin ordering, add explicit mapping in __init__:
    def __init__(self):
        lp = self.landpattern
        self.mappings = [PadMapping({
            self.PIN1: [lp.p[1]],
            self.PIN2: [lp.p[2]],
            # ...
        })]


Device: type[{ComponentClassName}] = {ComponentClassName}

Package-Specific Examples

For complete examples of each package type (SOIC, SON, QFN, BGA), including thermal pads, port arrays, inactive positions, and non-uniform BGA grids, see references/package-examples.md.

Dimension Mapping Reference

Datasheet SymbolDescriptionJITX Parameter
DPackage lengthRectanglePackage.length
EPackage widthRectanglePackage.width
APackage heightRectanglePackage.height
E1 / D1Lead spanLeadProfile.span
eLead pitchLeadProfile.pitch
bLead widthSMDLead.width / QFNLead.width
LLead lengthSMDLead.length / QFNLead.length
D2 / E2Thermal pad size.thermal_pad(rectangle(D2, E2))

Common Patterns

Toleranced Values

python
Toleranced.min_max(3.8, 4.0)           # Min-max range (most common)
Toleranced(5.0, 0.1)                    # Nominal ± tolerance
Toleranced.min_typ_max(0.13, 0.18, 0.23)  # Asymmetric
Toleranced.exact(7.0)                   # BSC = Basic

Thermal Pad with Paste Subdivision

python
from jitx.shapes.composites import rectangle
from jitxlib.landpatterns.pads import SMDPadConfig, WindowSubdivide

.thermal_pad(
    shape=rectangle(3.0, 3.0),
    config=SMDPadConfig(paste=WindowSubdivide(padding=0.25)),
)

Reference Designator Prefixes

  • U - Integrated circuits
  • Q - Transistors (MOSFETs, BJTs)
  • D - Diodes
  • R - Resistors
  • C - Capacitors
  • L - Inductors
  • J - Connectors
  • Y - Crystals/oscillators

Multi-Unit Symbols

Multiple BoxSymbol attributes = separate visual boxes:

python
def __init__(self):
    self.symbol_a = BoxSymbol(rows=Row(
        left=PinGroup(self.INp[0], self.INn[0]),
        right=PinGroup(self.OUT[0]),
    ))
    self.symbol_b = BoxSymbol(rows=Row(
        left=PinGroup(self.INp[1], self.INn[1]),
        right=PinGroup(self.OUT[1]),
    ))
    # Power unit: use horizontal layout (left=supplies, right=grounds)
    self.symbol_power = BoxSymbol(
        rows=Row(
            left=PinGroup(self.VCC, self.VBAT),
            right=PinGroup(self.VSS, self.GND),
        ),
    )

Pin Naming Best Practices

Use real functional names from the datasheet, not generic placeholders:

python
# GOOD - from datasheet
OQSPIF_D0 = Port()   # Octal QSPI Flash data bit 0
eMMC_CMD = Port()    # eMMC command line
V18F = Port()        # 1.8V flash supply

# BAD - generic
P0 = Port()          # What does P0 do?
VDD1 = Port()        # Which power domain?

PadMapping Requirements

  • Automatic mapping (no PadMapping needed): Ports mapped to pads in declaration order.
  • Explicit PadMapping required when:
    • Thermal pad exists (map to lp.thermal_pads[0])
    • Ports declared out of pin order
    • Multiple ports map to same pad
    • Pin 1 is not the first declared port

Verification Process

Test Harness

python
import jitx
from jitx.container import inline
from jitx.sample import SampleDesign

from .component import Device


class TestDesign(SampleDesign):
    @inline
    class circuit(jitx.Circuit):
        dut = Device()

Build Command

bash
python -m jitx build <module>.TestDesign

Success: status: ok Failure: Python traceback or status: error

Output files (in designs/<design_name>/):

  • cache/netlist.json - Verify net connections
  • design-info/stable.design - Design snapshot

Common Build Errors

ErrorFix
port X not mapped to symbol pinAdd port to BoxSymbol
port X not mapped to padCheck port count = pad count
No pad configuration specifiedBGA needs .pad_config(SMDPadConfig())

Verification Report

After generating code, provide:

code
## Verification Report

### Pin Count
- Datasheet: N pins
- Generated: N ports
- Status: ✓ MATCH / ✗ MISMATCH

### Pad Count
- Landpattern: N pads + M thermal
- Ports requiring pads: N + M
- Status: ✓ MATCH / ✗ MISMATCH

### Dimensions
| Parameter | Datasheet | Generated | Status |
|-----------|-----------|-----------|--------|
| Width     | 3.8-4.0mm | min_max(3.8, 4.0) | ✓ |

### Issues Found
- [List any discrepancies or assumptions made]

Step 6: Capture Application Circuit (Optional)

After generating component code, check the datasheet for "Typical Application", "Reference Design", or "Application Circuit" sections. These provide valuable circuit templates.

When to offer:

  • Datasheet includes a schematic with the component
  • User is creating a power IC, amplifier, or other circuit-centric component
  • Application circuit shows passive values and connections

Process:

  1. Ask user if they want to capture the application circuit:

    code
    "The datasheet includes a Typical Application circuit (Figure X).
    Would you like me to also generate the application circuit code?"
    
  2. If yes, invoke the jitx-circuit-builder skill to generate circuit code

  3. Pass context to circuit-builder:

    • Component class name and import path
    • Datasheet figure reference
    • Component values from schematic (cap values, resistor values, inductor specs)
    • Pin connections shown in the schematic

Example application circuit output:

python
"""
Texas Instruments TPS62933DRLR Application Circuit
From datasheet Figure 23 - Typical Application

3.8-V to 30-V input, 3.3V 3A output buck converter.
"""

from jitx import Circuit, Net
from jitx.common import Power
from jitxlib.parts import Capacitor, CapacitorQuery, Resistor, Inductor, ResistorQuery
from jitxlib.voltage_divider import VoltageDividerConstraints, voltage_divider_from_constraints

from .texas_instruments_TPS62933DRLR import TPS62933DRLR


class TPS62933DRLRCircuit(Circuit):
    """Buck converter application circuit per datasheet Figure 23."""

    vin = Power()   # Input power (3.8V-30V)
    vout = Power()  # Output power (3.3V)

    def __init__(self, output_voltage=3.3):
        self.GND = Net(name="GND")
        self.VOUT = Net(name="VOUT")
        self.VIN = Net(name="VIN")

        # Main IC
        self.buck = TPS62933DRLR()

        # Power connections
        self.VIN += self.vin.Vp + self.buck.VIN
        self.GND += self.buck.GND + self.vin.Vn + self.vout.Vn

        # Input capacitors (C1, C2 - 10µF each per schematic)
        with CapacitorQuery.refine(type="ceramic", case="0805"):
            for _ in range(2):
                Capacitor(capacitance=10e-6, rated_voltage=50.0).insert(
                    self.buck.VIN, self.GND, short_trace=True
                )

        # Feedback voltage divider
        vdiv_cons = VoltageDividerConstraints(
            v_in=output_voltage, v_out=0.8, current=0.8/10e3,
            base_query=ResistorQuery(case=["0402"])
        )
        self.fb_div = voltage_divider_from_constraints(vdiv_cons)
        self.VOUT += self.fb_div.hi + self.vout.Vp
        self.GND += self.fb_div.lo
        self.nets = [self.fb_div.out + self.buck.FB]

        # Output inductor and capacitors
        self.L = Inductor(inductance=4.7e-6, current_rating=3.9)
        # ... complete circuit per datasheet

File location: Save application circuits alongside the component:

code
components/
├── power_switchmode/
│   ├── texas_instruments_TPS62933DRLR.py      # Component
│   └── texas_instruments_TPS62933DRLR_circuit.py  # Application circuit

Output Format

When generating a component, provide:

  1. Complete Python source code in a code block
  2. Verification report (using format above)
  3. Any assumptions or decisions made
  4. Known limitations or items requiring manual review
  5. Offer to capture application circuit if datasheet includes one