Source code for jitx.controlpoint

from __future__ import annotations
from typing import overload

from .placement import Positionable
from .shapes import Shape
from .net import Port, DiffPair


[docs] class ControlPoint(Positionable): """Base class for control points. Do not subclass or use this directly, use one of :py:class:`RoutePoint`, :py:class:`PairInsertion` or :py:class:`PairPoint` instead.""" layer: int """The layer on which the control point should be placed.""" def __init__( self, *, layer: int, ): self.layer = layer
[docs] class RoutePoint[T: Port](ControlPoint): shape: Shape | None """The geometric shape of the control point.""" port: T """The port associated to this control point, used for routing.""" @overload def __init__(self, *, layer: int, shape: Shape | None = None, bundle: type[T]): ... @overload def __init__(self: RoutePoint[Port], *, layer: int, shape: Shape | None = None): ... def __init__(self, *, layer: int, shape: Shape | None = None, bundle: type = Port): super().__init__(layer=layer) self.shape = shape self.port = bundle()
[docs] class PairInsertion[T: DiffPair](ControlPoint): """Differential pair insertion point. Transitions two individual, uncoupled traces into a differential pair. When used with :py:attr:`~jitx.net.PortAttachment`, it needs an ordered pair of ports. The first port is connected to the left side (looking from the uncoupled side of the pair insertion point), and the second to the right side. Currently it cannot be used in a :py:attr:`~jitx.net.Net` or :py:attr:`~jitx.net.TopologyNet` directly. Currently, the left port is accessed using ``uncoupled.n``, and the right port using ``uncoupled.p``, where :py:attr:`~.uncoupled` is a member attribute of type :py:attr:`~jitx.net.DiffPair`. This is only relevant when making code routes, since in that case the physical route ends need to be referenced, and you may need to unintuitively connect ``n`` and ``p`` in order to make the geometry work. This a limitation in the current implementation. This will be addressed to be more consistent with logical netting in future releases. The ``coupled`` side is always routed as a diffpair so ``coupled.p`` and ``coupled.n`` never need to be accessed individually. See the PortAttachment example below for how to set up two insertion control points with correct geometry. .. code-block:: text uncoupled.n -- \\ == coupled / uncoupled.p -- >>> class MyCircuit(Circuit): ... c1 = MyComponent1() ... c2 = MyComponent2() ... def __init__(self): ... self.insertion1 = PairInsertion(layer=0).at(-2, 0) ... self.insertion2 = PairInsertion(layer=0).at(2, 0, rotate=180) ... self.nets = [ ... Net([self.c1.p1, self.c2.p1]), ... Net([self.c1.p2, self.c2.p2]), ... ] ... self.attachments = [ ... PortAttachment([self.c1.p1, self.c1.p2], self.insertion1), ... PortAttachment([self.c2.p2, self.c2.p1], self.insertion2), # note the flipped order for achieving opposite chirality ... ] ... self.routes = [ ... Route(self.insertion1, self.insertion2, 0) ... ] """ coupled: T "Coupled side of the differential insertion point." uncoupled: T "Uncoupled side of the differential insertion point." @overload def __init__(self, *, layer: int, bundle: type[T]): ... @overload def __init__(self: PairInsertion[DiffPair], *, layer: int): ... def __init__(self, *, layer: int, bundle: type = DiffPair): super().__init__(layer=layer) self.coupled = bundle() self.uncoupled = bundle()
[docs] class PairPoint[T: DiffPair](ControlPoint): """A differential pair control point connects two segments of a differential pair, while still paired, allowing for each segment to be configured independently.""" pair: T """The differential pair port associated to this control point, used for routing.""" @overload def __init__(self, *, layer: int, bundle: type[T]): ... @overload def __init__(self: PairPoint[DiffPair], *, layer: int): ... def __init__(self, *, layer: int, bundle: type = DiffPair): super().__init__(layer=layer) self.pair = bundle()