Understanding JITX Object Relationships#

This guide explains the relationships between key JITX objects that often confuse newcomers: Port, Pin, Pad, Component, Circuit, Net, and TopologyNet.

The Three Layers#

JITX models electronics at three distinct layers:

Layer

Purpose

Key Objects

Logical

Electrical connectivity

Port, Net, TopologyNet

Schematic

Visual representation

Symbol, Pin

Physical

PCB layout

Landpattern, Pad

Port vs Pin vs Pad#

These three objects represent the same electrical connection point at different abstraction levels:

Port (Logical Layer)#

A Port is the fundamental connectivity element. It represents an electrical signal that can be connected to other ports.

from jitx import Port

class MyComponent(Component):
    VCC = Port()      # Single signal port
    GND = Port()
    DATA = Port()

Ports can be grouped into bundles for related signals:

class I2C(Port):
    """Bundle of related signals"""
    sda = Port()
    scl = Port()

class MyComponent(Component):
    i2c = I2C()  # Bundle port containing sda and scl

Pin (Schematic Layer)#

A Pin is a connection point on a schematic Symbol. Pins define where wires connect visually in the schematic.

from jitx import Symbol, Pin, Direction

class MySymbol(Symbol):
    vcc_pin = Pin.up((0, 2), length=1)      # Pin extending upward
    gnd_pin = Pin.down((0, -2), length=1)   # Pin extending downward
    data_pin = Pin.right((2, 0), length=2)  # Pin extending right

Pad (Physical Layer)#

A Pad is a copper area on a Landpattern (footprint) where a component lead is soldered.

from jitx import Landpattern, Pad
from jitx.shapes import Circle, rectangle

class MyPad(Pad):
    shape = Circle(diameter=1.0)  # 1mm circular pad

class MyLandpattern(Landpattern):
    p1 = MyPad().at(-1.27, 0)  # Pad at position (-1.27, 0)
    p2 = MyPad().at(1.27, 0)   # Pad at position (1.27, 0)

How They Connect#

A Component links all three layers together:

Component
├── Ports (logical connections)
├── Symbol (schematic representation)
│   └── Pins (visual connection points)
├── Landpattern (physical footprint)
│   └── Pads (solder points)
├── SymbolMapping (Port ↔ Pin)
└── PadMapping (Port ↔ Pad)
class Resistor(Component):
    # Logical layer: Ports
    p = Port(), Port()

    # Schematic layer: Symbol
    symbol = ResistorSymbol()

    # Physical layer: Landpattern
    landpattern = SMD0402()

    # Mappings are automatic by declaration order,
    # or explicit with PadMapping/SymbolMapping

Circuit vs Component#

Both are containers, but serve different purposes:

Component#

A Component represents a physical part that will be placed on the PCB:

  • Has a landpattern (footprint)

  • Has a symbol for schematics

  • Appears in the Bill of Materials (BOM)

  • Examples: resistor, capacitor, IC, connector

class LED(Component):
    anode = Port()
    cathode = Port()
    landpattern = SMD0603LED()
    symbol = LEDSymbol()

Circuit#

A Circuit is a logical grouping of components and sub-circuits:

  • No physical footprint of its own

  • Used for hierarchy and organization

  • Can contain other Circuits (sub-circuits)

  • Examples: power supply module, filter block, interface circuit

class PowerSupply(Circuit):
    vin = Power()   # Input port
    vout = Power()  # Output port

    regulator = VoltageRegulator()
    input_cap = Capacitor()
    output_cap = Capacitor()

    def __init__(self):
        self.nets = [
            self.vin.Vp + self.input_cap.p[1] + self.regulator.vin,
            # ... more connections
        ]

Net vs TopologyNet#

Both represent electrical connections, but with different constraints:

Net (Simple Connection)#

A Net is an unordered electrical connection. Use it for:

  • Power and ground connections

  • Simple signals without timing constraints

  • Connections where routing order doesn’t matter

# Using the + operator creates a Net
vcc_net = power.Vp + regulator.vin + capacitor.p[1]
gnd_net = power.Vn + regulator.gnd + capacitor.p[2]

TopologyNet (Ordered Connection)#

A TopologyNet is an ordered connection for signal integrity. Use it for:

  • High-speed signals (USB, Ethernet, DDR)

  • Signals requiring length matching

  • Connections where routing order matters

# Using the >> operator creates a TopologyNet
# Signal flows: transmitter → series_resistor, series_resistor → receiver
# the delay and loss through the resistor can be set using a BridgingPinModel
data_topology1 = tx.data >> resistor.p[1]
data_topology2 = resistor.p[2] >> rx.data

When to Use Each#

Scenario

Use

Power rails

Net (+)

Ground connections

Net (+)

Simple GPIO

Net (+)

USB data lines

TopologyNet (>>)

Ethernet pairs

TopologyNet (>>)

High-speed clocks

TopologyNet (>>)

DDR memory bus

TopologyNet (>>)

Visual Summary#

Design
├── Board (physical outline)
├── Substrate (PCB stackup)
└── Circuit (root)
    ├── Ports (external interface)
    ├── Components
    │   ├── Ports
    │   ├── Symbol → Pins
    │   └── Landpattern → Pads
    ├── Sub-Circuits
    │   └── (recursive structure)
    └── Nets / TopologyNets (connections)

Common Patterns#

Accessing Component Pads#

# Via landpattern
component.landpattern.p[1]  # First pad
component.landpattern.p[2]  # Second pad

# For generators like SOIC
soic_component.landpattern.p[1]   # Pad 1
soic_component.landpattern.p[14]  # Pad 14

Connecting Bundles#

class MyCircuit(Circuit):
    mcu = MCU()
    sensor = Sensor()

    def __init__(self):
        # Connect entire I2C bundle at once
        i2c = self.mcu.require(I2C)
        self.i2c_bus = i2c + self.sensor.i2c

Mapping Multiple Pads to One Port#

class PowerIC(Component):
    VCC = Port()
    GND = Port()

    landpattern = QFN32()

    # Map GND port to multiple pads (thermal pad + pin)
    mapping = PadMapping({
        GND: [landpattern.p[9], landpattern.thermal_pad],
        VCC: landpattern.p[1],
    })

See Also#