si_via_model module#

A single-ended path that changes layer through a via with models.

The driver sits on the top side and the receiver on the bottom side of the two-layer sample board. The signal leaves the driver on layer 0, drops through a through via and reaches the receiver on layer 1. ExampleSignalVia subclasses the substrate’s THVia and adds models = {(0, 1): PinModel(delay=6e-12, loss=0.04)}, keyed by the layer pair the signal crosses (illustrative values). The substrate declares the via class; a design-local subclass adds the models when a constrained path goes through it.

PortAttachment(self.drv.io, self.via) puts the via on the driver’s net, and the two routes, one per layer, close the path through it. The constraint still names the driver and receiver pads.

The via adds its model to the measurement: 110.529 ps here, 6 ps more than the same span on one layer (104.529 ps in si_diff_pair). The same circuit with the substrate’s bare THVia still measured, 124.529 ps and 0.506 dB, but with a placeholder model, and each measurement group carried:

Structure model from [0] to [1] not found in "THVia". Using placeholder model for proxy of drv.io.

That group is reported NOT MET although its number is in range: the placeholder is not the via’s data.

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_via_model import ViaModelDesign


def main() -> None:
    with jitx.runtime as rt:
        report = rt.submit(ViaModelDesign).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: 110.529ps - Target: 500ps ± 500ps from drv.io to rcv.io
met Loss: 0.396db ± 0db - Target: 0.5db ± 0.5db from drv.io to rcv.io
met Satisfied

The limits are illustrative.

The last line is the Routing category’s group: every code route was made. It is not a constraint verdict.

class ExampleSignalVia(*args, **kwargs)[source]#

Bases: THVia

The sample board’s through via, with a model for a signal that crosses it from layer 0 to layer 1. The 6 ps and 0.04 dB are illustrative; a real via takes them from an EM simulation or a measurement.

models: Mapping[tuple[int, int], PinModel] = {(0, 1): <jitx.si.PinModel object>}#

Specifies delay and loss models for the via, used by signal integrity constraints.

Each entry defines a model for a pair of layers. Layers are specified as layer indices. Models are assumed to be symmetric, so the order of layer indices is arbitrary. It is an error to specify multiple models for the same pair of layers.

It is recommended to not specify models with the same start and end layer. They will currently be ignored by the constraint solver (since path does not travel through the via) but this behavior may change in a future version of JITX. The models are given in terms of the same jitx.si.PinModel object used by components.

>>> class MyVia(Via):
>>>     # Other via parameters...
>>>     models = {
>>>         # Top to bottom layer (through-hole via)
>>>         (0, -1): PinModel(5e-12, 0.05),
>>>         # Top to inner layer 1 (blind via)
>>>         (0, 1): PinModel(2e-12, 0.02),
>>>         # Inner layer 1 to inner layer 2 (buried via)
>>>         (1, 2): PinModel(2e-12, 0.02),
>>>     }

Not all layer pairs need to be specified. If you know that, for example, all usages of a via will go between the top and bottom of the board, then only that model needs to be provided.

Via models can also be generated programmatically using loops. For example, to define models for all layer pairs in a multi-layer board where delay and loss scale linearly with the number of layers traversed:

>>> class MultiModelVia(Via):
>>>     # Other via parameters...
>>>
>>>     # Generate models for all layer pairs
>>>     total_layers = 4
>>>     models = {}
>>>     for i in range(total_layers):
>>>         for j in range(i + 1, total_layers):
>>>             # Model that scales with number of layers
>>>             n_layers = j - i
>>>             models[(i, j)] = PinModel(
>>>                 2e-12 * n_layers,
>>>                 0.05 * n_layers
>>>             )

When models are not provided for a via, placeholder models are automatically inserted. When using placeholder models (models with ideal delay and loss), any timing or loss constraints involving signals through these vias will be flagged as unsatisfied. This is because the placeholder model assumes some arbitrary transmission delay and loss values, which are not set by the user. For accurate signal integrity analysis, provide calculated, measured, or simulated via models for all layer pairs used in your design.

For maximum accuracy, it is recommended to simulate or measure each specific pair of layers rather than using a simplified linear model. The loop approach is most useful for initial designs or when detailed measurements are not yet available.

class ViaModel[source]#

Bases: Circuit

A single-ended line that changes layer through one modeled via.

class ViaModelDesign(*args, **kwargs)[source]#

Bases: SampleDesign

The two-layer line on the sample board.

circuit: Circuit = ViaModel()#