Source code for jitxexamples.patterns.si_diff_pair
"""Intra-pair skew on differential pairs, in the two forms ``jitx.si`` offers.
Two lanes run straight between two fictional chips. ``self.tx.lane0 +
self.rx.lane0`` is one bundle net: it joins ``p`` to ``p`` and ``n`` to
``n``. Each leg gets its own code ``Route``.
``lane0`` is constrained with ``ConstrainDiffPair(Topology(tx.lane0,
rx.lane0))``: ``timing_difference(2e-12)`` is the P-to-N skew window,
``timing`` and ``insertion_loss`` apply to each leg, and
``.structure(SampleSubstrate.DRS_100)`` takes a ``DifferentialRoutingStructure``
(``Constrain.structure`` takes only a single-ended one).
``lane1`` uses ``DiffPairConstraint``, a reusable ``SignalConstraint`` that
holds a skew window, a loss limit and a structure and applies them each time
``constrain(src, dst)`` is called. It sets no delay limit, so its lane gets
``Loss`` and ``Skew`` lines and no ``Time``. Store the helper on ``self``
before calling ``constrain``; an unstored helper is lost during
instantiation.
The limits are illustrative.
Checked with the design-issues query, run as a script from a project
root with that project's runtime running
(jitx 4.6.0rc10, runtime 4.6.0-rc.16)::
import jitx
from jitxexamples.patterns.si_diff_pair import DiffPairsDesign
def main() -> None:
with jitx.runtime as rt:
report = rt.submit(DiffPairsDesign).issues(satisfied=True, wait=30)
if not report.complete:
print("report incomplete: raise wait and run again")
for group in report.groups():
print("met" if group.satisfied else "NOT MET", group.text)
if len(group.issues) > 1:
for issue in group:
print(" ", issue.text)
if __name__ == "__main__":
main()
It printed::
met Time: 104.529ps - Target: 500ps ± 500ps from tx.lane0.p to rx.lane0.p
met Time: 104.529ps - Target: 500ps ± 500ps from tx.lane0.n to rx.lane0.n
met Loss: 0.356db - Target: 0.5db ± 0.5db from tx.lane0.p to rx.lane0.p
met Loss: 0.356db - Target: 0.5db ± 0.5db from tx.lane0.n to rx.lane0.n
met Loss: 0.356db - Target: 0.5db ± 0.5db from tx.lane1.p to rx.lane1.p
met Loss: 0.356db - Target: 0.5db ± 0.5db from tx.lane1.n to rx.lane1.n
met Skew: 0s - Target: ± 2ps (longer from tx.lane0.p to rx.lane0.p, shorter from tx.lane0.n to rx.lane0.n)
met Skew: 0s - Target: ± 2ps (longer from tx.lane1.p to rx.lane1.p, shorter from tx.lane1.n to rx.lane1.n)
met Satisfied
Timing and loss give one line per leg; the skew gives one ``Skew`` line per
pair, naming the longer and the shorter leg. Equal straight routes measure
``0s``.
The last line is the Routing category's group: every code route was made.
It is not a constraint verdict.
"""
from __future__ import annotations
from jitx.circuit import Circuit, Route
from jitx.net import Topology
from jitx.sample import SampleDesign, SampleSubstrate
from jitx.si import ConstrainDiffPair, DiffPairConstraint
from jitx.toleranced import Toleranced
from jitxexamples.patterns.si_parts import ExampleTwoLaneChip
[docs]
class DiffPairs(Circuit):
"""Two differential lanes between two chips: one constrained with
``ConstrainDiffPair``, one with the reusable ``DiffPairConstraint``."""
def __init__(self) -> None:
self.tx = ExampleTwoLaneChip().at(-10, 0)
self.rx = ExampleTwoLaneChip().at(10, 0)
# A bundle net joins each leg: lane0.p to lane0.p, lane0.n to lane0.n.
self.lanes = [self.tx.lane0 + self.rx.lane0, self.tx.lane1 + self.rx.lane1]
self.routes = [
Route(src, dst, layer=0)
for src, dst in (
(self.tx.lane0.p, self.rx.lane0.p),
(self.tx.lane0.n, self.rx.lane0.n),
(self.tx.lane1.p, self.rx.lane1.p),
(self.tx.lane1.n, self.rx.lane1.n),
)
]
self.lane0_cst = (
ConstrainDiffPair(Topology(self.tx.lane0, self.rx.lane0))
.timing_difference(2e-12)
.timing(1e-9)
.insertion_loss(1.0)
.structure(SampleSubstrate.DRS_100)
)
self.lane1_cst = DiffPairConstraint(
skew=Toleranced(0, 2e-12), loss=1.0, structure=SampleSubstrate.DRS_100
)
self.lane1_cst.constrain(self.tx.lane1, self.rx.lane1)
[docs]
class DiffPairsDesign(SampleDesign):
"""The two lanes on the sample board."""
circuit = DiffPairs()