SI Usage Patterns#

The objects and methods discussed in Topologies and Constraints are often considered the “primitives” of the JITX Signal Integrity (SI) system. These primitives must be strung together in a particular way to achieve the desired results. To make this process easier, we’ve developed various higher level constructs to support differential pairs and other more complex protocols.

Signal Constraint Base Class#

The SignalConstraint object is a base class for defining a modular set of constraints that apply to a particular protocol. This base class has a type parameter that defines the bundle type that a particular signal constraint applies to. This type parameter allows the language server to confirm that you, the user, are using this constraint correctly.

The easiest example to look at is the DiffPairConstraint. Here is an excerpt:

class DiffPairConstraint(SignalConstraint[DiffPair]):
    """Basic signal constraint for a differential pair signal topology.
       ...
    """

    def __init__(
        self,
        skew: Toleranced,
        loss: float,
        structure: DifferentialRoutingStructure | None = None,
    ):
    ...

Notice that the parent class for DiffPairConstraint is SignalConstraint[DiffPair]. This is indicating that this type only applies to topologies of the type DiffPair.

The DiffPairConstraint object is a helpful abstraction for applying all of the necessary constraints for a typical differential pair. This includes:

  1. skew - Constrains the time delay between the p and n signals of the DiffPair bundle.

  2. loss - Maximum acceptable loss from endpoint to endpoint.

  3. structure - Applies a medium constraint for this diff pair.

This constraint doesn’t handle any inter-topology constraints - it only handles the constraints that apply to a differential pair. Deriving for this class would allow us to add additional constraints - such as a timing delay constraint - for custom applications.

Here is a simple example:


  def __init__(self):
    ...
    
    diff_rs = current.substrate.differential_routing_structure(100.0)
    
    self.ck_cst = DiffPairConstraint(
      skew=Toleranced(0, 1e-12), # Seconds
      loss=12.0, # dB
      structure=diff_rs
    )

    self += src.CK >> dst.CK
    
    self.ck_cst.constrain(src.CK, dst.CK)

The main pieces are:

  1. Create the DiffPairConstraint object and attach it to the circuit via self.ck_cst = ...

  2. Create the topology with the >> operator.

  3. Apply the self.ck_cst constraint by defining the endpoints of the topology.

    1. Notice that src.CK and dst.CK must be the same port type, DiffPair.

More Complex Protocols#

This model extends to more complex protocols. For example, consider the RGMII Protocol Constraint. This constraint type is defined as an internal type to the RGMII bundle type. The RGMII.Standard.Constraint encapsulates the constraints for an RGMII interface and makes constraint application a single method call. This allows for highly re-usable constraints.

Signal Ends#

Often times when constructing a sub-circuit, the actual endpoint of a topology is buried inside that sub-circuit (or recursively within a sub-sub-circuit). This makes it difficult to apply the routing structure to the terminal endpoints. This manifests in a section of a trace or differential pair that lacks a routing structure assignment. For example, consider the following:

TODO