si_signal_constraint module#
A reusable protocol constraint: a SignalConstraint subclass, built and
applied on ordinary nets.
ExampleLinkConstraint constrains an
ExampleSerialLink bundle (a tx and an rx pair) between
two ends. Its parameters live in a frozen dataclass,
ExampleLinkStandard, and its __init__ calls
super().__init__() first: the base initializer creates the collection
that self.add(...) extends. It looks the differential structure up on
the design’s substrate by impedance unless one is passed, and holds one
DiffPairConstraint stored on self. constrain(src, dst) applies it
across the crossover, each end’s tx to the other end’s rx.
The circuit calls self.link_cst.constrain(self.host.link, self.phy.link)
on the chips’ own bundles, the true ends, and wires the parts between them
as usual. The host’s transmit pair passes through
ExampleDualCoupler, which carries a BridgingPinModel on each
leg. The constraint does not change for the coupler; the pin models carry
the path across it.
SignalConstraint.constrain_topology(src, dst) calls constrain(src,
dst) at once and returns a context manager that yields (src, dst); it
only moves an end along a >> chain already in the circuit, so on
ordinary nets it adds nothing over constrain.
The standard’s values are illustrative, not from any specification. For
protocols with several signal groups, compose: hold one constraint per group
and call each from constrain, as
jitxexamples.protocols.memory does for DDR4 and LPDDR4.
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_signal_constraint import SerialLinkDesign
def main() -> None:
with jitx.runtime as rt:
report = rt.submit(SerialLinkDesign).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 Loss: 0.389db - Target: 1.5db ± 1.5db from host.link.tx.p to phy.link.rx.p
met Loss: 0.389db - Target: 1.5db ± 1.5db from host.link.tx.n to phy.link.rx.n
met Loss: 0.356db ± 0db - Target: 1.5db ± 1.5db from phy.link.tx.p to host.link.rx.p
met Loss: 0.356db ± 0db - Target: 1.5db ± 1.5db from phy.link.tx.n to host.link.rx.n
met Skew: 0s - Target: ± 2ps (longer from host.link.tx.p to phy.link.rx.p, shorter from host.link.tx.n to phy.link.rx.n)
met Skew: 0s - Target: ± 2ps (longer from phy.link.tx.p to host.link.rx.p, shorter from phy.link.tx.n to host.link.rx.n)
met Satisfied
The transmit legs measure more loss than the receive legs, 0.389 dB against 0.356 dB. Their path adds the coupler’s 0.06 dB per leg but carries 1.5 mm less trace, the coupler’s pad span, so the difference is 0.033 dB, not the model’s 0.06 dB.
The last line is the Routing category’s group: every code route was made. It is not a constraint verdict.
- class ExampleLinkStandard(skew=Toleranced(0, 2e-12, 2e-12), loss=3.0, impedance=100.0)[source]#
Bases:
objectLimits for the fictional serial link. The values are illustrative, not taken from any standard.
- Parameters:
skew (Toleranced)
loss (float)
impedance (float)
- skew: Toleranced = Toleranced(0, 2e-12, 2e-12)#
Intra-pair skew window, in seconds.
- class ExampleSerialLink[source]#
Bases:
PortA full-duplex serial link: one transmit pair and one receive pair.
- tx = DiffPair()#
- rx = DiffPair()#
- class ExampleLinkConstraint(standard, structure=None)[source]#
Bases:
SignalConstraint[ExampleSerialLink]Constrain a serial link between two ends: each end’s
txto the other end’srx, with the standard’s skew, loss and structure.- Parameters:
standard (ExampleLinkStandard)
structure (DifferentialRoutingStructure | None)
- constrain(src, dst)[source]#
Called to apply implementation specific constraints. Note that all constraints should be added to the container by calling
add()on self. It is valid to just set member attributes as well, as with everything in JITX, but be aware that your constraint may be used multiple times with different topologies, and thus be careful with overwriting values (e.g. some constraints may use a singleDiffPairConstraintto constrain all its diff pairs).- Return type:
- Parameters:
src (ExampleSerialLink)
dst (ExampleSerialLink)
- class ExampleLinkChip(rx_first=False)[source]#
Bases:
ComponentFictional chip with one serial link. Not a real product, and it has no pin models.
rx_firstputs the receive pair on the lower two pads, so two chips facing each other line their crossing pairs up.- Parameters:
rx_first (bool)
- reference_designator_prefix: str | None = 'U'#
Reference designator prefix for this component. This will be used to generate a unique reference designator for each component of the same type.
Note
This field is a required data point for matching components between builds. If this value changes (including changing from unset to set), it will be treated as a new component, even if nothing else changes.
- link = ExampleSerialLink()#
- class CouplerPads[source]#
Bases:
LandpatternTwo columns of two square pads, 1.5 mm apart:
aleft,bright.
- class ExampleDualCoupler[source]#
Bases:
ComponentFictional two-channel AC coupling part for one differential pair. Not a real product.
The signal passes through it from
atobon each leg, so each leg carries aBridgingPinModel: 3 ps and 0.06 dB, values that are illustrative.- reference_designator_prefix: str | None = 'C'#
Reference designator prefix for this component. This will be used to generate a unique reference designator for each component of the same type.
Note
This field is a required data point for matching components between builds. If this value changes (including changing from unset to set), it will be treated as a new component, even if nothing else changes.
- a = DiffPair()#
- b = DiffPair()#
- through = [BridgingPinModel(DiffPair().p, DiffPair().p, delay=3e-12, loss=0.06), BridgingPinModel(DiffPair().n, DiffPair().n, delay=3e-12, loss=0.06)]#
- class SerialLink[source]#
Bases:
CircuitTwo chips joined by a serial link, constrained by one
ExampleLinkConstraint; the transmit pair fromhostpasses through a coupler.
- class SerialLinkDesign(*args, **kwargs)[source]#
Bases:
SampleDesignThe serial link on the sample board.