pin_series_array module#
Channel choice through a pass-through part, with both sides in one mapping.
Use this pattern when signals pass through a part whose channels are interchangeable, and choosing a channel fixes a pin on each side of the part. Here a 4-bit bus runs from a driver to a receiver through a 4-channel series termination array; any channel may carry any bit, but a bit enters and leaves on the same channel. Four pieces compose:
A bundle over both sides.
ArrayChannelhas a driver-side portaand a receiver-side portb. Each offered mapping sets both, so one choice moves both ends of the channel together. Two separate offers, one per side, could pick different channels for the two ends of a bit.The provider.
SeriesTerminationoffersArrayChannelwith@provide(all_of): one option per channel, each usable once, all usable together. The consumer takes four withrequire(ArrayChannel, count=4)and keeps them local.The pin model. Each channel carries a
BridgingPinModelfroma[i]tob[i]; without one the path stops at the array.The constraints, on fixed physical ends either side of the assigned part:
Constrain(Topology(drv.d[i], rcv.d[i]))per bit, andConstrainReferenceDifferencefor bus skew with bit 0 as the single-pin guide. While the assignment is unresolved, a bit reportsNo path for signal constraint.
The shipping design, SeriesArrayDesign, has no placement and no routes.
The verification designs place the parts and close every bit with code
Routes that end on the array’s physical pins:
SwappedChannelsProof: bits 0 and 1 swap channels (bit 0 on channel 1, bit 1 on channel 0), the same on both sides. Offered, so every bit measures.SidesDisagreeIllegal: the driver side as in the swapped proof, the receiver side straight. Bits 0 and 1 enter on one channel and leave on another, which no option offers, so two of their four routes are dropped and both bits have no path; bits 2 and 3 still measure.
Every part is fictional, not a real product. The array’s 5 ps and 0.05 dB per channel, the 1 ns delay budget and the 10 ps bus skew window are illustrative values; take real ones from the part’s datasheet and the interface’s timing budget.
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_series_array import SwappedChannelsProof
def main() -> None:
with jitx.runtime as rt:
report = rt.submit(SwappedChannelsProof).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 two verification designs):
SeriesArrayDesign:
NOT MET No path for signal constraint from drv.d[0] to rcv.d[0]
NOT MET No path for signal constraint from drv.d[1] to rcv.d[1]
NOT MET No path for signal constraint from drv.d[2] to rcv.d[2]
NOT MET No path for signal constraint from drv.d[3] to rcv.d[3]
met Satisfied
SwappedChannelsProof:
met Time: 74.729ps - Target: 500ps ± 500ps from dut.drv.d[0] to dut.rcv.d[0]
met Time: 97.061ps - Target: 500ps ± 500ps from dut.drv.d[1] to dut.rcv.d[1]
met Time: 73.144ps - Target: 500ps ± 500ps from dut.drv.d[2] to dut.rcv.d[2]
met Time: 73.144ps - Target: 500ps ± 500ps from dut.drv.d[3] to dut.rcv.d[3]
NOT MET Skew: 22.332ps - Target: ± 10ps (longer from dut.drv.d[1] to dut.rcv.d[1], shorter from dut.drv.d[0] to dut.rcv.d[0])
met Skew: 1.585ps - Target: ± 10ps (longer from dut.drv.d[0] to dut.rcv.d[0], shorter from dut.drv.d[2] to dut.rcv.d[2])
met Skew: 1.585ps - Target: ± 10ps (longer from dut.drv.d[0] to dut.rcv.d[0], shorter from dut.drv.d[3] to dut.rcv.d[3])
met Satisfied
SidesDisagreeIllegal:
met Time: 73.144ps - Target: 500ps ± 500ps from dut.drv.d[2] to dut.rcv.d[2]
met Time: 73.144ps - Target: 500ps ± 500ps from dut.drv.d[3] to dut.rcv.d[3]
NOT MET No path for signal constraint from dut.drv.d[0] to dut.rcv.d[0]
NOT MET No path for signal constraint from dut.drv.d[1] to dut.rcv.d[1]
NOT MET 2 issues: Code route dropped: it conflicts with other connections
Code route dropped: it conflicts with other connections
Code route dropped: it conflicts with other connections
Bit 1’s skew against bit 0 misses its window because the swapped routes
cross on one layer and come out unequal: the constraint bound, and this
routing fails it; read group.satisfied, not the text. In the illegal
design bits 0 and 1 have no path, so the bus skew, guided by bit 0, has
no line at all.
- BITS = 4#
Bus width, and the array’s channel count.
- ARRAY_DELAY = 5e-12#
5 ps through each array channel.
- Type:
Illustrative
- ARRAY_LOSS = 0.05#
0.05 dB through each array channel.
- Type:
Illustrative
- BIT_DELAY_BUDGET = 1e-09#
1 ns from driver to receiver.
- Type:
Illustrative
- BUS_SKEW = Toleranced(0, 1e-11, 1e-11)#
each bit within 10 ps of bit 0.
- Type:
Illustrative
- STRAIGHT: tuple[int, ...] = (0, 1, 2, 3)#
bit
ion channeli.- Type:
Array channel for each bit, bit 0 first
- class BusDriver[source]#
Bases:
ComponentFictional 4-bit bus driver. Not a real part.
- d = [Port(), Port(), Port(), Port()]#
- gnd = Port()#
- class BusReceiver[source]#
Bases:
ComponentFictional 4-bit bus receiver. Not a real part.
- d = [Port(), Port(), Port(), Port()]#
- gnd = Port()#
- class SeriesArray4[source]#
Bases:
ComponentFictional 4-channel series termination array: channel
iruns froma[i]tob[i], and the channels are identical. Not a real part; its pin-model values are illustrative.- a = [Port(), Port(), Port(), Port()]#
- b = [Port(), Port(), Port(), Port()]#
- class ArrayChannel[source]#
Bases:
PortOne array channel, both sides:
afaces the driver,bthe receiver.- a = Port()#
- b = Port()#
- class SeriesTermination[source]#
Bases:
CircuitThe provider: every channel of the array, each offered once.
- channel = PrePostInit#
- class SeriesArrayBus[source]#
Bases:
CircuitDriver to receiver through the array, every bit constrained. Unplaced and route-free, so the channel choice stays open.
- class SeriesArrayDesign(*args, **kwargs)[source]#
Bases:
SampleDesignThe shipping design: no placement, no routes.
- class SeriesArrayProof(drv_side, rcv_side)[source]#
Bases:
CircuitSeriesArrayBusplaced, with code routes on chosen array channels: bitienters ondrv_side[i]and leaves onrcv_side[i].
- class SwappedChannelsProof[source]#
Bases:
SampleDesignBits 0 and 1 on each other’s channel, both sides: offered, so every bit measures.
- class SidesDisagreeIllegal[source]#
Bases:
SampleDesignDriver side swapped, receiver side straight: bits 0 and 1 change channel inside the part, which is not offered, so their routes drop.