pin_lane_polarity module#
Lane choice and P/N inversion on a provider that is one end of the path.
Use this pattern when a part may drive a differential link from any of several lanes, either way round, and an SI constraint covers the link. The provider is the driving part itself, so the constrained path begins on the required port. Four pieces compose:
The provider.
SerializerLanesoffers oneDiffPairwith@provide.one_of: lane 0 or lane 1, each straight or inverted (OFFERED).one_ofbecause the receiver takes a single lane. Offer inversion only where both ends of the link tolerate it, as the fictional parts here do.The consumer.
LanePolarityLinkrequires the pair, keeps it in a local variable (a required port stored onselffails the build), and nets it with plain+nets through a common-mode choke to the connector.The pin model. The choke is a pass-through part, so each winding carries a
BridgingPinModel; without one the path stops at the choke.The constraint.
ConstrainDiffPair(Topology(lane, conn.rx))begins on the required pair. Until routes resolve the assignment the report saysUnassigned Pin on Path. Once they do, the measured line names the serializer pin the routes chose, inverted lanes included.
The shipping design, LanePolarityDesign, has no placement and no routes,
so the assignment stays open for whoever routes the board. The verification
designs place the parts and close the path with code Routes that end
on the serializer’s physical pins (a route cannot end on a required port):
LaneZeroProof: lane 0, straight. Offered, so it measures.LaneOneInvertedProof: lane 1, inverted (tx[1].nto connectorrx.p). Offered, so it measures fromtx[1].n.SplitLanesIllegal:rx.pfrom lane 0,rx.nfrom lane 1. No offered mapping splits a lane, so a route is dropped.
Every part is fictional, not a real product. The choke’s 2 ps and 0.02 dB per winding, the 1 ns delay budget and the 5 ps skew limit are illustrative values; take real ones from the part’s datasheet and the protocol’s specification.
To check it, save this as a script in the project root and run it with the project’s runtime running:
import jitx
from jitxexamples.patterns.pin_lane_polarity import LaneOneInvertedProof
def main() -> None:
with jitx.runtime as rt:
report = rt.submit(LaneOneInvertedProof).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()
The real output for each design, on jitx 4.6.0rc10 against runtime 4.6.0-rc.16 (the shipping design and the three verification designs):
LanePolarityDesign:
NOT MET 2 issues: Unassigned Pin on Path: TX_P.p
Unassigned Pin on Path: TX_P.p
Unconnected Topology on Path: choke.a_out, conn.rx.p
NOT MET 2 issues: Unassigned Pin on Path: TX_P.n
Unassigned Pin on Path: TX_P.n
Unconnected Topology on Path: choke.b_out, conn.rx.n
NOT MET 4 issues: Unassigned Pin on Path: TX_P.p
Unassigned Pin on Path: TX_P.p
Unconnected Topology on Path: choke.a_out, conn.rx.p
Unassigned Pin on Path: TX_P.n
Unconnected Topology on Path: choke.b_out, conn.rx.n
met Satisfied
LaneZeroProof:
met Time: 70.937ps - Target: 500ps ± 500ps from dut.ser.serializer.tx[0].p to dut.conn.rx.p
met Time: 70.937ps - Target: 500ps ± 500ps from dut.ser.serializer.tx[0].n to dut.conn.rx.n
met Skew: 0s - Target: ± 5ps (longer from dut.ser.serializer.tx[0].p to dut.conn.rx.p, shorter from dut.ser.serializer.tx[0].n to dut.conn.rx.n)
met Satisfied
LaneOneInvertedProof:
met Time: 70.937ps - Target: 500ps ± 500ps from dut.ser.serializer.tx[1].n to dut.conn.rx.p
met Time: 81.924ps - Target: 500ps ± 500ps from dut.ser.serializer.tx[1].p to dut.conn.rx.n
NOT MET Skew: 10.987ps - Target: ± 5ps (longer from dut.ser.serializer.tx[1].p to dut.conn.rx.n, shorter from dut.ser.serializer.tx[1].n to dut.conn.rx.p)
met Satisfied
SplitLanesIllegal:
NOT MET Unassigned Pin on Path: dut.TX_P.p
NOT MET Unassigned Pin on Path: dut.TX_P.p
met Time: 70.144ps - Target: 500ps ± 500ps from dut.ser.serializer.tx[1].n to dut.conn.rx.n
NOT MET Code route dropped: it conflicts with other connections
Lane 1 inverted measures from tx[1].n: the routes resolved the inverted
mapping. Its skew misses the window because its two routes cross on one
layer and come out unequal: the constraint bound, and this routing fails it.
A measurement means the constraint applied; whether it is met is
group.satisfied. In the illegal design the dropped route leaves rx.p
with no assignment, and rx.n still measures from the lane its route
fits.
- CHOKE_DELAY = 2e-12#
2 ps through each choke winding.
- Type:
Illustrative
- CHOKE_LOSS = 0.02#
0.02 dB through each choke winding.
- Type:
Illustrative
- LINK_DELAY_BUDGET = 1e-09#
1 ns from serializer to connector.
- Type:
Illustrative
- LINK_SKEW = Toleranced(0, 5e-12, 5e-12)#
5 ps intra-pair skew.
- Type:
Illustrative
- OFFERED: tuple[tuple[int, bool], ...] = ((0, False), (0, True), (1, False), (1, True))#
either lane, either way round.
- Type:
Every option the provider offers
- class Serializer[source]#
Bases:
ComponentFictional two-lane serializer. Either lane may carry the link, and its link partner corrects P/N polarity. Not a real part.
- tx = (DiffPair(), DiffPair())#
Transmit lanes 0 and 1.
- gnd = Port()#
- class CommonModeChoke[source]#
Bases:
ComponentFictional common-mode choke: winding A from
a_intoa_out, winding B fromb_intob_out. Not a real part; its pin-model values are illustrative.- a_in = Port()#
- b_in = Port()#
- a_out = Port()#
- b_out = Port()#
- class LinkConnector[source]#
Bases:
ComponentFictional one-lane connector. Not a real part.
- rx = DiffPair()#
- gnd = Port()#
- class SerializerLanes[source]#
Bases:
CircuitThe provider: the serializer, offering one lane either way round.
- gnd = Port()#
- lane = PrePostInit#
- class LanePolarityLink[source]#
Bases:
CircuitSerializer lane to connector through the choke, constrained end to end. Unplaced and route-free, so the assignment stays open.
- class LanePolarityDesign(*args, **kwargs)[source]#
Bases:
SampleDesignThe shipping design: no placement, no routes.
- class LanePolarityProof(p_lane, n_lane, inverted)[source]#
Bases:
CircuitLanePolarityLinkplaced, with code routes from the serializer to the choke:rx.p’s winding from lanep_lane,rx.n’s from lanen_lane, each lane’s legs crossed wheninverted.
- class LaneZeroProof[source]#
Bases:
SampleDesignLane 0, straight: offered, so the constraint measures.
- class LaneOneInvertedProof[source]#
Bases:
SampleDesignLane 1, inverted: offered, so the constraint measures from
tx[1].n.
- class SplitLanesIllegal[source]#
Bases:
SampleDesignrx.pfrom lane 0 andrx.nfrom lane 1: not offered, so a route is dropped.