Source code for gdsfactory.components.via_cutback

"""Via cutback."""

from __future__ import annotations

import warnings

import gdsfactory as gf
from gdsfactory.add_pins import LayerSpec
from gdsfactory.component import Component
from gdsfactory.components.compass import compass
from gdsfactory.components.via_stack import via_stack_heater_m3
from gdsfactory.typings import ComponentSpec, Float2


@gf.cell
def _via_iterable(
    via_spacing: float,
    wire_width: float,
    layer1: LayerSpec,
    layer2: LayerSpec,
    via_layer: LayerSpec,
    via_width: float,
) -> Component:
    """Via chain.

    Args:
        via_spacing: via_spacing (um).
        wire_width: width of wire.
        layer1: top wiring.
        layer2: bottom wiring.
        via_layer: via.
        via_width: width of via.
    """
    c = gf.Component()
    wire1 = c.add_ref(compass(size=(via_spacing, wire_width), layer=layer1))
    wire2 = c.add_ref(compass(size=(via_spacing, wire_width), layer=layer2))
    viac = c.add_ref(compass(size=(via_width, via_width), layer=via_layer))
    via1 = c.add_ref(compass(size=(via_width, via_width), layer=via_layer))
    wire1.connect(
        port="e3",
        destination=wire2.ports["e1"],
        overlap=wire_width,
        allow_layer_mismatch=True,
    )
    viac.connect(
        port="e1",
        destination=wire1.ports["e3"],
        overlap=(wire_width + via_width) / 2,
        allow_layer_mismatch=True,
    )
    via1.connect(
        port="e1",
        destination=wire2.ports["e3"],
        overlap=(wire_width + via_width) / 2,
        allow_layer_mismatch=True,
    )
    c.add_port(name="e1", port=wire1.ports["e1"], port_type="electrical", layer=layer1)
    c.add_port(name="e3", port=wire2.ports["e3"], port_type="electrical", layer=layer2)
    c.add_port(
        name="e4",
        center=((1 * wire_width) + wire_width / 2, -wire_width / 2),
        width=wire_width,
        orientation=-90,
        port_type="electrical",
        layer=layer2,
    )
    c.add_port(
        name="e2",
        center=((1 * wire_width) + wire_width / 2, wire_width / 2),
        width=wire_width,
        orientation=90,
        port_type="electrical",
        layer=layer2,
    )

    return c


[docs] @gf.cell def via_cutback( num_vias: float = 200.0, wire_width: float = 10.0, via_width: float = 5.0, via_spacing: float = 30.0, min_pad_spacing: float = 10.0, pad: ComponentSpec = via_stack_heater_m3, pad_size: Float2 = (100, 100), layer1: LayerSpec = "HEATER", layer2: LayerSpec = "M1", via_layer: LayerSpec = "VIAC", wire_pad_inclusion: float = 2.0, ) -> Component: """Via cutback to extract via resistance. based on phidl.geometry Args: num_vias: total requested vias needs to be even. wire_width: width of wire. via_width: width of via. via_spacing: via_spacing. pad_size: (width, height). min_pad_spacing. pad_layer. layer1: top wiring. layer2: bottom wiring. via_layer: via. wire_pad_inclusion: in um. """ warnings.warn("via_cutback is deprecated. Use via_chain instead") c = gf.Component() pad_component = pad(size=pad_size) pad1 = c.add_ref(pad_component) pad2 = c.add_ref(pad_component) nub = c.add_ref(pad(size=(3 * wire_width, wire_width))) head = c.add_ref(pad(size=(wire_width, wire_width))) nub.ymax = pad1.ymax - 5 nub.xmin = pad1.xmax - wire_pad_inclusion head.connect(port="e1", destination=nub.ports["e3"]) old_port = head.ports["e4"] count = 0 width_via_iter = 2 * via_spacing - 2 * wire_width pad2.xmin = pad1.xmax + min_pad_spacing up = False down = True edge = True current_width = 3 * wire_width + wire_width # width of nub and 1 overlap obj_old = head obj = head via_iterable = _via_iterable( via_spacing=via_spacing, wire_width=wire_width, layer1=layer1, layer2=layer2, via_layer=via_layer, via_width=via_width, ) overlap = wire_width while (count + 2) <= num_vias: obj = c.add_ref(via_iterable) obj.connect( port="e1", destination=old_port, overlap=overlap, allow_layer_mismatch=True ) old_port = obj.ports["e3"] edge = False if obj.ymax > pad1.ymax: obj.connect( port="e1", destination=obj_old.ports["e4"], overlap=overlap, allow_layer_mismatch=True, ) old_port = obj.ports["e4"] current_width += width_via_iter down = True up = False edge = True elif obj.ymin < pad1.ymin: obj.connect( port="e1", destination=obj_old.ports["e2"], overlap=overlap, allow_layer_mismatch=True, ) old_port = obj.ports["e2"] current_width += width_via_iter up = True down = False edge = True count += 2 obj_old = obj if ( current_width < min_pad_spacing and (min_pad_spacing - current_width) > 3 * wire_width ): tail = c.add_ref( pad( size=(min_pad_spacing - current_width + wire_width, wire_width), ) ) else: tail = c.add_ref(pad(size=(3 * wire_width, wire_width))) if up and not edge: tail.connect( port="e1", destination=obj.ports["e4"], overlap=wire_width, allow_layer_mismatch=True, ) elif down and not edge: tail.connect( port="e1", destination=obj.ports["e2"], overlap=wire_width, allow_layer_mismatch=True, ) else: tail.connect( port="e1", destination=obj.ports["e3"], overlap=wire_width, allow_layer_mismatch=True, ) pad2.xmin = tail.xmax - wire_pad_inclusion c.add_ports(pad1.ports, prefix="p1_") c.add_ports(pad2.ports, prefix="p2_") return c
if __name__ == "__main__": c = via_cutback() c.show(show_ports=True)