Rules

The following example shows to create a clearance rule, add it to the technology of a library, and save it.

def creating_a_clearance_rule(library: de.Library) -> None:
    # Clearance rules specify the minimum clearance between two objects

    # NOTE: You cannot create a rule that already exists
    assert not library.tech.clearance_rules.find("Example Clearance Rule")

    # Create a clearance rule with a default clearance of 10.0
    rule = tech.rule.ClearanceRule(library, "Example Clearance Rule", 10.0)

    # Set the priority of the rule, higher priority rules will take precedence over lower priority rules
    # The numerical value of the priority must be greater than or equal to zero and is relative to other
    # rule priorities; the higher the number, the higher the priority
    rule.priority = 10

    # By default, a new rule is enabled
    assert rule.enabled

    # Rules apply to a pair of objects, the first object must match the first scope and the second object,
    # the second scope.
    # By default, the both the first and second scope are set to tech.rule.ScopeType.Default
    assert rule.first_scope == rule.second_scope == tech.rule.DefaultScope()
    # The same as
    assert rule.first_scope.scope_type == rule.second_scope.scope_type == tech.rule.ScopeType.DEFAULT

    # For this example, the first scope will refer to the my_net Net
    rule.first_scope = tech.rule.NetClassScope(["my_net"])

    # The second scope will refer to any net that is not the my_net Net
    rule.second_scope = tech.rule.DifferentNetScope()

    # By default, the rule will apply to all layers, but for this example,
    # We'll specify a few different layers and show how to set different clearances for
    # different object types

    # when viewing the result inside ADS
    # Let's apply this rule to the M3, 9, and M12 layers
    rule.layers = ["M3", "M9", "M12"]

    # The rule values are a 2D matrix of the clearance values between the object types
    # The object types are:
    # Trace
    # Pad
    # Via
    # Plane
    rule.rule_values[("Plane", "Trace")] = 25.0
    rule.rule_values[("Plane", "Pad")] = 40.0
    rule.rule_values[("Plane", "Via")] = 55.0

    # The values for the object types that are not explicitly set use the default_clearance,
    # whose initial value is set when the rule is created
    assert rule.default_clearance == 10.0

    # NOTE: The order of the object types in the tuple doesn't matter
    assert rule.rule_values[("Plane", "Trace")] == rule.rule_values[("Trace", "Plane")] == 25.0

    # Add the clearance rule to the technology and save it
    library.tech.clearance_rules.add(rule)
    library.tech.save_rules()

The following image shows how the clearance rule created above appears inside the constraints manager of ADS.

../../../_images/clearance_rule.png

The following example shows how to delete a clearance rule from the technology of a library.

def deleting_a_clearance_rule(library: de.Library) -> None:
    # Ensure the clearance rule exists before trying to delete it
    if not library.tech.clearance_rules.find("Example Clearance Rule"):
        creating_a_clearance_rule(library)

    assert library.tech.clearance_rules.find("Example Clearance Rule")

    # Deleting a clearance rule is straightforward
    del library.tech.clearance_rules["Example Clearance Rule"]
    assert not library.tech.clearance_rules.find("Example Clearance Rule")
    library.tech.save_rules()

The following examples shows how to create a via rule.

def creating_a_via_rule(library: de.Library) -> None:
    lib_name = library.name
    # Create a new via rule for cond to m2 from the Example Padstack
    # NOTE: The padstack name is in the form of "library_name:padstack_name"
    via_cond_m2_rule = tech.rule.ViaRule("via_cond_m2", f"{lib_name}:Example Padstack", "cond", "M2")

    # Set the priority of the rule, higher priority rules will take precedence over lower priority rules
    # The numerical value of the priority must be greater than or equal to zero and is relative to other
    # rule priorities; the higher the number, the higher the priority
    via_cond_m2_rule.priority = 10

    # Rules are enabled by default, but no harm in being explicit
    via_cond_m2_rule.enabled = True

    assert via_cond_m2_rule.name == "via_cond_m2"
    assert via_cond_m2_rule.padstack_name == f"{lib_name}:Example Padstack"
    assert via_cond_m2_rule.has_layer_constraints
    assert via_cond_m2_rule.top_layer == "cond"
    assert via_cond_m2_rule.bottom_layer == "M2"

    # Create another rule. You don't need to specify the layers up front if you don't want to
    via_m2_m3_rule = tech.rule.ViaRule("via_m2_m3", f"{lib_name}:Example Padstack")

    # There are no constraints set
    assert not via_m2_m3_rule.has_layer_constraints
    assert via_m2_m3_rule.top_layer == ""
    assert via_m2_m3_rule.bottom_layer == ""
    # Set them here
    via_m2_m3_rule.set_layer_constraints("M2", "M3")
    assert via_m2_m3_rule.has_layer_constraints
    assert via_m2_m3_rule.top_layer == "M2"
    assert via_m2_m3_rule.bottom_layer == "M3"

    via_m2_m3_rule.priority = 10
    via_m2_m3_rule.enabled = True

    # Add the rules to the library and save them
    library.tech.via_rules.add(via_cond_m2_rule)
    library.tech.via_rules.add(via_m2_m3_rule)
    library.tech.save_rules()

The following image shows how the via rule created above appears inside the constraints manager of ADS.

../../../_images/creating_via_rules.png

The following example shows how to create a stacked via rule.

def creating_a_stacked_via_rule(library: de.Library) -> None:
    libname = library.name
    # Ensure we have the via rules we need
    if library.tech.via_rules.find("via_cond_m2"):
        del library.tech.via_rules["via_cond_m2"]
    if library.tech.via_rules.find("via_m2_m3"):
        del library.tech.via_rules["via_m2_m3"]

    creating_a_via_rule(library)

    via_cond_m2_rule = library.tech.via_rules["via_cond_m2"]
    via_m2_m3_rule = library.tech.via_rules["via_m2_m3"]

    # Make the via rules stackable
    via_cond_m2_rule.is_stackable = True
    via_m2_m3_rule.is_stackable = True

    # Create a stacked via rule using the two via rules, via_cond_m2 and via_m2_m3
    # Rule names are in the form of "libname:rule_name"
    stacked_rule = tech.rule.StackedViaRule(
        "stacked_cond_m3", "cond", "M3", [f"{libname}:via_cond_m2", f"{libname}:via_m2_m3"]
    )
    stacked_rule.enabled = True
    library.tech.stacked_via_rules.add(stacked_rule)
    library.tech.save_rules()

The following image shows how the padstack rule created above appears inside the constraints manager of ADS.

../../../_images/stacked_via_rule.png

The following example shows how to place the vias constrained by the rules defined above.

def placing_constrained_vias(design: db_uu.Design, library: de.Library) -> None:
    libname = library.name

    if not library.tech.padstacks.find("Example Padstack"):
        # See ex_padstack.py for the padstack template used in this example
        # NOTE: If you've copied/pasted this code into the ADS Python console,
        # you may need to execute building_up_a_padstack from ex_padstack.py
        # first to create "Example Padstack".
        from . import ex_padstack

        ex_padstack.building_up_a_padstack(library)

    if not library.tech.stacked_via_rules.find("stacked_cond_m3"):
        creating_a_stacked_via_rule(library)

    cond_layer = db_uu.LayerId.create_layer_id_from_library(library, "cond")
    m2_layer = db_uu.LayerId.create_layer_id_from_library(library, "M2")
    m3_layer = db_uu.LayerId.create_layer_id_from_library(library, "M3")

    design.add_trace(cond_layer, [(0, -200), (200, -200)], 25)
    design.add_constrained_via(f"{libname}:via_cond_m2", (200, -200))
    design.add_trace(m2_layer, [(200, -200), (200, -400)], 25)
    design.add_constrained_via(f"{libname}:via_m2_m3", (200, -400))
    design.add_trace(m3_layer, [(200, -400), (0, -400)], 25)
    design.add_stacked_via(f"{libname}:stacked_cond_m3", (0, -400))

The following image shows the vias placed using the rules defined above.

../../../_images/placing_constrained_vias.png
On this page