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
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.primitive import Circle
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
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. Use it for a daisy chain whose order is part of the design, such as a DDR flyby clock or address bus that visits each memory in turn:
# Using the >> operator creates a TopologyNet
# The address line visits dram0, then dram1
a0_chain = ctrl.a0 >> dram0.a0 >> dram1.a0
High-speed signals that run from one end to the other, such as USB, Ethernet or PCIe pairs, use ordinary nets. Their timing, loss and skew constraints name the two ends of the path; see Signal Integrity Constraints.
When to Use Each#
Scenario |
Use |
|---|---|
Power rails |
Net ( |
Ground connections |
Net ( |
Simple GPIO |
Net ( |
USB data lines |
Net ( |
Ethernet pairs |
Net ( |
Point-to-point high-speed clocks |
Net ( |
DDR flyby clock and address 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