constraints module#

Design constraints and effects#

This module provides classes for defining design rule constraints and their effects on routing, spacing, and via placement.

class TraceWidth(width)[source]#

A constraint effect specifying the exact trace width to be used in routing.

See trace_width() for usage.

Parameters:

width (float)

width: float#

The trace width in millimeters

class Clearance(clearance)[source]#

A constraint effect specifying the clearance between two objects.

See clearance() for usage.

Parameters:

clearance (float)

clearance: float#

The clearance in millimeters

class ViaStitchPattern(pitch, inset)[source]#

Base class for via stitch patterns used in StitchVia constraints.

Via stitch patterns arrange vias within copper regions.

Parameters:
pitch: float#

The spacing between via centers in millimeters

inset: float#

Minimum distance from the stitched region’s boundary to the outermost via centers in millimeters

class SquareViaStitchGrid(pitch, inset)[source]#

Bases: ViaStitchPattern

A square grid pattern for via stitching.

Places vias in a regular square grid pattern within the target area. Used in the StitchVia design rule constraint.

>>> pattern = SquareViaStitchGrid(pitch=2.0, inset=0.5)
Parameters:
class TriangularViaStitchGrid(pitch, inset)[source]#

Bases: ViaStitchPattern

A triangular grid pattern for via stitching.

Places vias in a triangular (hexagonal close-packed) pattern within the target area. Used in the StitchVia design rule constraint.

>>> pattern = TriangularViaStitchGrid(pitch=1.5, inset=1.0)
Parameters:
class StitchVia(definition, pattern)[source]#

A constraint effect specifying that vias should be arranged within copper areas in a pattern.

See stitch_via() for usage.

Parameters:
definition: type[Via]#

The Via class to use for stitching

pattern: SquareViaStitchGrid | TriangularViaStitchGrid#

The geometric pattern for via placement

class ViaFencePattern(pitch, offset, num_rows=None, min_pitch=None, max_pitch=None, initial_offset=None, input_shape_only=None)[source]#

A pattern configuration for via fencing around routes or copper features.

Via fencing places vias around the perimeter of routes or copper areas. The pattern controls how these vias are arranged. Used in the FenceVia design rule constraint.

See fence_via() for usage.

>>> fence_pattern = ViaFencePattern(
...     pitch=1.0,
...     offset=0.5,
...     num_rows=2,
...     min_pitch=0.5,
...     max_pitch=2.0
... )
Parameters:
  • pitch (float)

  • offset (float)

  • num_rows (int | None)

  • min_pitch (float | None)

  • max_pitch (float | None)

  • initial_offset (float | None)

  • input_shape_only (bool | None)

pitch: float#

The preferred center-to-center spacing between vias in millimeters

offset: float#

The center-to-center distance between fence via rows, and the default initial offset in millimeters

Positive values indicate an outwards offset, negative values an inwards offset. The offset for routes must be positive. If initial_offset is not specified, this value serves as the default initial offset.

num_rows: int | None = None#

The number of rows of fence vias to generate, default is 1

min_pitch: float | None = None#

The minimum allowed center-to-center pitch between vias in millimeters

max_pitch: float | None = None#

The maximum allowed center-to-center pitch between vias in millimeters

initial_offset: float | None = None#

The initial offset of the first row of fence vias

The initial offset is the perpendicular distance from the boundary of the route or copper feature to the centers of the first row of fence vias. Positive values indicate an outwards offset, while negative values indicate an inwards offset (inset). The offset must be positive for routes. Defaults to the same value as offset if unspecified.

input_shape_only: bool | None = None#

For pours only, whether to fence the original pour outline

If true, the pre-isolation outline shape of the pour is used to generate the fence vias. If false, the post-isolation shape is used. Defaults to true if not specified.

class FenceVia(definition, pattern)[source]#

A constraint effect specifying that fencing vias should be generated

The vias are generated around perimeter of the copper region or route which this constraint is applied to. The vias will be given the same net as the copper region.

See fence_via() for usage. This constraint can also be given to jitx.si.RoutingStructure.Layer and jitx.si.DifferentialRoutingStructure.Layer. See there for usage.

Parameters:
definition: type[Via]#

The Via class to use for fencing

pattern: ViaFencePattern#

The geometric pattern for fence placement

class ThermalRelief(gap_distance, spoke_width, num_spokes)[source]#

A constraint effect specifying thermal connections between pours and objects.

Thermal reliefs control how pours connect to objects with gaps and spokes.

See thermal_relief() for usage.

Parameters:
gap_distance: float#

The distance between pours and affected objects in millimeters

spoke_width: float#

The width of the connecting spokes in millimeters

num_spokes: int#

The number of thermal relief spokes (typically 2 or 4)

class Tag[source]#

Tags are the fundamental building blocks for design rules.

Tags are applied to design objects, and are then used by the rule system to determine which rules apply to which objects.

Tags form a hierarchy through class inheritance, and thus a rule applied to a tag will apply to all tags that are a subclass of that tag. The name of a tag is derived from its class name.

Tags can be combined using logical operators to create complex conditions: - & (AND): Both conditions must be true - | (OR): Either condition can be true - ~ (NOT): Inverts the condition

>>> class PowerTag(Tag):
...     "This is a power net, or some appropriate docstring for this tag"
>>> class SignalTag(Tag):
...     "This is a signal net"
>>> class HighSpeedTag(SignalTag):
...     "This is a high speed signal"
>>> # This rule applies to ALL Signal tags (including HighSpeed)
>>> signal_rule = UnaryDesignConstraint(SignalTag()).trace_width(0.2)
>>> # This rule applies only to HighSpeed signals
>>> high_speed_rule = UnaryDesignConstraint(HighSpeedTag()).trace_width(0.1)

Tags can be assigned to objects and used in rule conditions:

>>> # Assign tags to nets
>>> PowerTag().assign(power_net)
>>> GroundTag().assign(ground_net)
>>>
>>> # Create rules using tag combinations
>>> rule1 = UnaryDesignConstraint(PowerTag()).trace_width(0.5)
>>> rule2 = UnaryDesignConstraint(PowerTag() & HighSpeedTag()).clearance(0.3)
>>> rule3 = UnaryDesignConstraint(PowerTag() | SignalTag()).stitch_via(MyVia, pattern)
>>> rule4 = UnaryDesignConstraint(~HighSpeedTag()).trace_width(0.2)
assign(*other)[source]#

Assign this tag to an object.

Parameters:

other – The object to assign this tag to

Returns:

The tag instance for method chaining

>>> ports = [Port(), Port()]
>>> net = Net(ports)
>>> PowerTag().assign(net)
static any(*tgs)[source]#

Construct a new tag that is the logical OR of all the passed tags.

Parameters:

tgs (Tag)

static all(*tgs)[source]#

Construct a new tag that is the logical AND of all the passed tags.

Parameters:

tgs (Tag)

class BuiltinTag(*values)[source]#

Bases: Tag, Enum

IsCopper = 'IsCopper'#
IsTrace = 'IsTrace'#
IsPour = 'IsPour'#
IsVia = 'IsVia'#
IsPad = 'IsPad'#
IsBoardEdge = 'IsBoardEdge'#
IsThroughHole = 'IsThroughHole'#
IsNeckdown = 'IsNeckdown'#
IsHole = 'IsHole'#
class OnLayer(index)[source]#

Bases: Tag

Tag for specifying layer-specific rules.

Parameters:

index (int)

index: int#
static external()[source]#

Retrieve a tag that matches to the top and bottom external copper layers of a board.

static internal()[source]#

Retrieve a tag that matches any of non-external layers (ie, inner layers) of the board. This is effectively the inverse of OnLayer.external().

class Tags(tags, *more)[source]#

Bases: Property

A collection of tags assigned to an object, as a property.

Tags are markers on design objects that are then used by the rule system to determine which rules apply to which objects.

Parameters:
  • tags (Tag | Iterable[Tag]) – A single Tag or sequence of Tags to assign

  • *more (Tag) – Additional tags to assign

>>> # Assign a single tag
>>> Tags(PowerTag()).assign(power_net)
>>>
>>> # Assign multiple tags
>>> Tags([PowerTag(), HighSpeedTag()]).assign(signal_net)
>>>
>>> # Assign using multiple arguments
>>> Tags(PowerTag(), HighSpeedTag(), CriticalTag()).assign(clock_net)
tags: list[Tag]#
class BoolExpr[source]#

Base class for boolean expressions used in design rule conditions.

Boolean expressions are created by combining Tags using logical operators. They form the condition part of design rules that determine when the rule should be applied.

Boolean expressions support the same logical operators as Tags: - & (AND): Both expressions must be true - | (OR): Either expression can be true - ~ (NOT): Inverts the expression

>>> expr1 = PowerTag() & HighSpeedTag()
>>> expr2 = GroundTag() | SignalTag()
>>> complex_expr = expr1 | (expr2 & ~CriticalTag())
class TrueExpr[source]#

Bases: BoolExpr

Always true boolean expression.

This expression always evaluates to true and can be used to create rules that apply to all objects regardless of their tags.

>>> # Rule that applies to everything
>>> rule = design_constraint(TrueExpr()).trace_width(0.2)
AnyObject: TrueExpr = TrueExpr()#

A convenience constant alias for TrueExpr, representing a boolean expression that is always true, thus applying to any object.

class AtomExpr(atom)[source]#

Bases: BoolExpr

Atomic boolean expression containing a single tag.

This is the simplest form of boolean expression, containing just a single tag. It’s created automatically when a Tag is used in a rule condition.

Parameters:

atom (Tag) – The Tag this expression represents

atom: Tag#
class NotExpr(expr)[source]#

Bases: BoolExpr

Negation of a boolean expression.

Represents the logical NOT of another boolean expression.

Parameters:

expr (BoolExpr) – The boolean expression to negate

>>> not_power = NotExpr(AtomExpr(PowerTag()))
>>> # Or more commonly: ~PowerTag()
expr: BoolExpr#
class OrExpr(left, right)[source]#

Bases: BoolExpr

Logical OR of two boolean expressions.

Represents a condition where either the left OR right expression (or both) must be true.

Parameters:
  • left (BoolExpr) – Left side of the OR operation

  • right (BoolExpr) – Right side of the OR operation

>>> power_or_ground = OrExpr(AtomExpr(PowerTag()), AtomExpr(GroundTag()))
>>> # Or more commonly:
>>> power_or_ground = PowerTag() | GroundTag()
left: BoolExpr#
right: BoolExpr#
class AndExpr(left, right)[source]#

Bases: BoolExpr

Logical AND of two boolean expressions.

Represents a condition where both the left AND right expressions must be true.

Parameters:
  • left (BoolExpr) – Left side of the AND operation

  • right (BoolExpr) – Right side of the AND operation

>>> power_and_critical = AndExpr(AtomExpr(PowerTag()), AtomExpr(CriticalTag()))
>>> # Or more commonly:
>>> power_and_critical = PowerTag() & CriticalTag()
left: BoolExpr#
right: BoolExpr#
design_constraint(condition1, condition2=None, /, *, priority=0, name=None)[source]#

Syntactic helper function for creating the correct type of class. The overloads will generate UnaryDesignConstraint or BinaryDesignConstraint depending on the number of conditions, and should provide correct method completion in the editor.

Parameters:
class DesignConstraint(*, priority=0, name=None)[source]#

Bases: ABC

Top-level design constraint that defines manufacturing and electrical rules.

A DesignConstraint combines conditional logic (based on Tags) with constraint effects controlling the physical layout. Rules can specify trace widths, clearances, via stitches, via fences, and thermal reliefs.

Rules are prioritized - higher priority numbers take precedence when multiple rules could apply to the same object. Rules can have single conditions or pairs of conditions (for rules that apply between two different objects).

Single condition rules (apply to objects matching the condition):

>>> # Basic trace width rule for power nets
>>> power_rule = design_constraint(PowerTag()).trace_width(0.5)
>>> # Complex condition with priority
>>> critical_rule = design_constraint(PowerTag() & CriticalTag(), priority=10).trace_width(1.0)
>>> # Via stitching for ground planes
>>> stitch_pattern = SquareViaStitchGrid(pitch=2.0, inset=0.5)
>>> ground_rule = design_constraint(GroundTag()).stitch_via(GroundVia, stitch_pattern)

Dual condition rules (apply between objects matching different conditions):

>>> # Clearance between power and signal nets
>>> clearance_rule = design_constraint(PowerTag(), SignalTag()).clearance(0.3)
>>> # Clearance between any ground and non-critical nets
>>> ground_clearance = design_constraint(GroundTag(), ~CriticalTag()).clearance(0.2)

Method chaining for complex rules:

>>> complex_rule = (
...     design_constraint(PowerTag(), priority=5)
...     .trace_width(0.8)
...     .stitch_via(PowerVia, SquareViaStitchGrid(pitch=1.5, inset=0.3))
...     .thermal_relief(gap_distance=0.15, spoke_width=0.1, num_spokes=4)
... )

Via fencing example:

>>> fence_pattern = ViaFencePattern(
...     pitch=1.0,
...     offset=0.5,
...     num_rows=2,
...     min_pitch=0.5,
...     max_pitch=2.0
... )
>>> shield_rule = design_constraint(HighSpeedTag()).fence_via(ShieldVia, fence_pattern)

Universal rules using a true (or TrueExpr) condition:

>>> # Default trace width for all nets
>>> default_rule = design_constraint(true).trace_width(0.2)
Parameters:
  • priority (int)

  • name (str | None)

priority: int = 0#

Priority level - higher numbers take precedence if multiple rules apply

name: str | None = None#

Name of this rule to identify it at runtime

class UnaryDesignConstraint(condition, *, priority=0, name=None)[source]#

Bases: DesignConstraint

Parameters:
trace_width_constraint: TraceWidth | None = None#
stitch_via_constraint: StitchVia | None = None#
fence_via_constraint: FenceVia | None = None#
thermal_relief_constraint: ThermalRelief | None = None#
condition: BoolExpr#
trace_width(width)[source]#

Set the trace width constraint for this rule.

Parameters:

width (float) – Trace width in millimeters

Return type:

Self

Returns:

Self for method chaining

>>> rule = UnaryDesignConstraint(PowerTag()).trace_width(0.5)
stitch_via(definition, pattern)[source]#

Set the via stitching constraint for this rule.

Parameters:
Return type:

Self

Returns:

Self for method chaining

>>> pattern = SquareViaStitchGrid(pitch=2.0, inset=0.5)
>>> rule = design_constraint(GroundTag()).stitch_via(GroundVia, pattern)
fence_via(definition, pattern)[source]#

Set the via fencing constraint for this rule.

Parameters:
  • definition (type[Via]) – The Via class to use in the fence

  • pattern (ViaFencePattern) – The geometric pattern for arranging the vias

Return type:

Self

Returns:

Self for method chaining

>>> fence_pattern = ViaFencePattern(pitch=1.0, offset=0.5, num_rows=2)
>>> rule = design_constraint(HighSpeedTag()).fence_via(ShieldVia, fence_pattern)
thermal_relief(gap_distance, spoke_width, num_spokes)[source]#

Set the thermal relief constraint for this rule.

Parameters:
  • gap_distance (float) – The distance between pours and affected objects in millimeters

  • spoke_width (float) – Width of the connecting spokes in millimeters

  • num_spokes (int) – Number of thermal relief spokes (typically 2 or 4)

Return type:

Self

Returns:

Self for method chaining

>>> rule = design_constraint(ComponentPadTag()).thermal_relief(
...     gap_distance=0.2, spoke_width=0.15, num_spokes=4
... )
class BinaryDesignConstraint(first, second, *, priority=0, name=None)[source]#

Bases: DesignConstraint

Parameters:
clearance_constraint: Clearance | None = None#
first: BoolExpr#
second: BoolExpr#
clearance(clearance)[source]#

Set the clearance constraint for this rule.

Parameters:

clearance (float) – Clearance in millimeters

Return type:

Self

Returns:

Self for method chaining

>>> rule = design_constraint(PowerTag(), SignalTag()).clearance(0.3)