Source code for ihp.cells2.via_stacks

"""Via stack components for IHP PDK. Also includes NoFillerStack."""

from typing import Literal

import gdsfactory as gf

from .. import tech
from .ihp_pycell import NoFillerStack as no_filler_stackIHP
from .ihp_pycell import via_stack as via_stackIHP
from .utils import *


[docs] @gf.cell def via_stack( bottom_layer: Literal[ "Activ", "GatPoly", "Metal1", "Metal2", "Metal3", "Metal4", "Metal5", "TopMetal1", "TopMetal2", ] = "Metal1", top_layer: Literal[ "Activ", "GatPoly", "Metal1", "Metal2", "Metal3", "Metal4", "Metal5", "TopMetal1", "TopMetal2", ] = "Metal2", vn_columns: int = 2, vn_rows: int = 2, vt1_columns: int = 1, vt1_rows: int = 1, vt2_columns: int = 1, vt2_rows: int = 1, ) -> gf.Component: """Create a via stack component. This function generates a layout for a via stack connecting a bottom layer to a top layer. The number of columns and rows for standard vias (Via1-Via4) and top vias (TopVia1, TopVia2) can be specified. Args: bottom_layer: Bottom layer name. Options: 'Activ', 'GatPoly', 'Metal1'-'Metal5', 'TopMetal1', 'TopMetal2'. top_layer: Top layer name. Options: 'Activ', 'GatPoly', 'Metal1'-'Metal5', 'TopMetal1', 'TopMetal2'. vn_columns: Number of columns for standard vias (Via1-Via4). vn_rows: Number of rows for standard vias. vt1_columns: Number of columns for TopVia1. vt1_rows: Number of rows for TopVia1. vt2_columns: Number of columns for TopVia2. vt2_rows: Number of rows for TopVia2. Returns: gdsfactory.Component: The generated via stack test layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "b_layer": bottom_layer, "t_layer": top_layer, "vn_columns": vn_columns, "vn_rows": vn_rows, "vt1_columns": vt1_columns, "vt1_rows": vt1_rows, "vt2_columns": vt2_columns, "vt2_rows": vt2_rows, } c = generate_gf_from_ihp( cell_name="via_stack", cell_params=params, function_name=via_stackIHP() ) # add ports to the component layer_map = { # necessary for mapping layer names to tech layers "Activ": tech.LAYER.Activdrawing, "GatPoly": tech.LAYER.GatPolydrawing, "Metal1": tech.LAYER.Metal1drawing, "Metal2": tech.LAYER.Metal2drawing, "Metal3": tech.LAYER.Metal3drawing, "Metal4": tech.LAYER.Metal4drawing, "Metal5": tech.LAYER.Metal5drawing, "TopMetal1": tech.LAYER.TopMetal1drawing, "TopMetal2": tech.LAYER.TopMetal2drawing, } gf.add_ports.add_ports_from_boxes( c, pin_layer=(layer_map[bottom_layer]), port_type="electrical", ports_on_short_side=False, auto_rename_ports=False, ) c.ports["e1"].name = "bottom" gf.add_ports.add_ports_from_boxes( c, pin_layer=(layer_map[top_layer]), port_type="electrical", ports_on_short_side=False, auto_rename_ports=False, ) c.ports["e1"].name = "top" return c
[docs] @gf.cell def no_filler_stack( width: int = 10, length: int = 10, noAct: Literal["Yes", "No"] = "Yes", # no active filler noGP: Literal["Yes", "No"] = "Yes", # no GatePoly filler noM1: Literal["Yes", "No"] = "Yes", # no M1 filler noM2: Literal["Yes", "No"] = "Yes", # no M2 filler noM3: Literal["Yes", "No"] = "Yes", # no M3 filler noM4: Literal["Yes", "No"] = "Yes", # no M4 filler noM5: Literal["Yes", "No"] = "Yes", # no M5 filler noTM1: Literal["Yes", "No"] = "Yes", # no TM1 filler noTM2: Literal["Yes", "No"] = "Yes", # no TM2 filler ) -> gf.Component: """Create a NoFiller via stack test component. This function generates a via stack layout without filler structures for the selected layers. Each layer can be individually excluded from filler insertion using Yes/No flags. Args: width: Device width in micrometers. length: Device length in micrometers. noAct: Exclude filler for the active layer. Options: 'Yes', 'No'. noGP: Exclude filler for the GatePoly layer. Options: 'Yes', 'No'. noM1: Exclude filler for Metal1. Options: 'Yes', 'No'. noM2: Exclude filler for Metal2. Options: 'Yes', 'No'. noM3: Exclude filler for Metal3. Options: 'Yes', 'No'. noM4: Exclude filler for Metal4. Options: 'Yes', 'No'. noM5: Exclude filler for Metal5. Options: 'Yes', 'No'. noTM1: Exclude filler for TopMetal1. Options: 'Yes', 'No'. noTM2: Exclude filler for TopMetal2. Options: 'Yes', 'No'. Returns: gdsfactory.Component: The generated NoFiller via stack layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "w": width * 1e-6, "l": length * 1e-6, "minLW": 10e-9, # hardcoded not in tech file "noAct": noAct, "noGP": noGP, "noM1": noM1, "noM2": noM2, "noM3": noM3, "noM4": noM4, "noM5": noM5, "noTM1": noTM1, "noTM2": noTM2, } c = generate_gf_from_ihp( cell_name="no_filler_stack", cell_params=params, function_name=no_filler_stackIHP(), ) # Adjust port orientations, for metal1 so every other port points in the opposite direction # for i, port in enumerate(c.ports): # port.orientation = 90 if port.name.startswith("DS_") and i % 2 == 1 else port.orientation return c
if __name__ == "__main__": # Test the components c = via_stack(bottom_layer="Metal1", top_layer="Metal5") c.show()