Source code for gdsfactory.components.via_chain

"""Via chain."""

from __future__ import annotations

import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.components.via import via1
from gdsfactory.components.via_stack import via_stack_m2_m3
from gdsfactory.typings import ComponentSpec, LayerSpecs


[docs] @gf.cell def via_chain( num_vias: int = 100, cols: int = 10, via: ComponentSpec = via1, contact: ComponentSpec = via_stack_m2_m3, layers_bot: LayerSpecs = ("M1",), layers_top: LayerSpecs = ("M2",), offsets_top: tuple[float, ...] = (0,), offsets_bot: tuple[float, ...] = (0,), via_min_enclosure: float = 1.0, min_metal_spacing: float = 1.0, via_xoffset: float = 0.0, via_yoffset: float = 0.0, ) -> Component: """Via chain to extract via resistance. Args: num_vias: number of vias. cols: number of column pairs. via: via component. contact: contact component. layers_bot: list of bottom layers. layers_top: list of top layers. offsets_top: list of top layer offsets. offsets_bot: list of bottom layer offsets. via_min_enclosure: via_min_enclosure. min_metal_spacing: min_metal_spacing. via_xoffset: horizontal offset of the vias. via_yoffset: vertical offset of the vias. .. code:: side view: min_metal_spacing ┌────────────────────────────────────┐ ┌────────────────────────────────────┐ │ layers_top │ │ │ │ │◄───────────► │ │ └─────────────┬─────┬────────────────┘ └───────────────┬─────┬──────────────┘ │ │ via_enclosure │ │ │ │◄───────────────► │ │ │ │ │ │ │ │ │ │ │width│ │ │ ◄─────► │ │ │ │ │ │ ┌─────────────┴─────┴───────────────────────────────────────────────┴─────┴───────────────┐ │ layers_bot │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ ◄─────────────────────────────────────────────────────────────────────────────────────────► 2*e + w + min_metal_spacing + 2*e + w """ if cols % 2 != 0: raise ValueError(f"{cols=} must be even") c = gf.Component() rows = num_vias / cols if int(rows) != rows: raise ValueError(f"{num_vias=} must be a multiple of {cols=}") if rows <= 1: raise ValueError( f"rows must be at least 2. Got {rows=}. You can increase the number vias {num_vias=}." ) if rows % 2 != 0: raise ValueError( f"{rows=} must be even. Number of vias needs to be a multiple of {2*cols=}." ) via = gf.get_component(via) contact = gf.get_component(contact) wire_length = 2 * (2 * via_min_enclosure + via.size_info.width) + min_metal_spacing via_width = via.size_info.width wire_width = via_width + 2 * via_min_enclosure wire_size = (wire_length, wire_width) via_spacing = ( 2 * via_min_enclosure + min_metal_spacing + via.size_info.width, wire_width + min_metal_spacing, ) vias = c.add_array( component=via, columns=cols, rows=rows, spacing=via_spacing, ) top_wire = gf.c.rectangles(size=wire_size, layers=layers_top, offsets=offsets_top) top_wires = c.add_array( component=top_wire, columns=cols // 2, rows=rows, spacing=(wire_length + min_metal_spacing, wire_width + min_metal_spacing), ) bot_wire = gf.c.rectangles(size=wire_size, layers=layers_bot, offsets=offsets_bot) bot_wires = c.add_array( component=bot_wire, columns=cols // 2, rows=rows, spacing=(wire_length + min_metal_spacing, wire_width + min_metal_spacing), ) top_wires.x = 0 bot_wires.xmin = ( top_wires.xmin + wire_length / 2 + min_metal_spacing / 2 - via_xoffset ) bot_wires.y = 0 top_wires.y = 0 vias.xmin = top_wires.xmin + via_min_enclosure + via_spacing[0] vias.ymin = top_wires.ymin + via_min_enclosure + via_yoffset vertical_wire_left = gf.c.rectangle( size=(2 * via_min_enclosure + via_width, 2 * wire_width + min_metal_spacing), layer=layers_top[0], ) right_wires = c.add_array( component=vertical_wire_left, columns=1, rows=rows // 2, spacing=(wire_width + min_metal_spacing, 2 * (wire_width + min_metal_spacing)), ) right_wires.xmax = vias.xmax + via_min_enclosure right_wires.y = 0 left_wires = c.add_array( component=vertical_wire_left, columns=1, rows=rows // 2 - 1, spacing=(wire_width + min_metal_spacing, 2 * (wire_width + min_metal_spacing)), ) left_wires.xmin = top_wires.xmin left_wires.y = 0 contact1 = c << contact contact2 = c << contact contact1.xmax = top_wires.xmin contact2.xmax = top_wires.xmin contact1.ymax = top_wires.ymin + wire_width contact2.ymin = top_wires.ymax - wire_width c.add_port(name="e1", port=contact1.ports["e1"]) c.add_port(name="e2", port=contact2.ports["e1"]) return c
if __name__ == "__main__": c = via_chain(num_vias=40) c.show(show_ports=True)