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#
Design Hierarchy - Circuit structure and instantiation
Pin Assignment - The provide/require system
Building the Design - Top-level Design structure