Source code for ihp.cells2.capacitors

"""Capacitor components for IHP PDK."""

from typing import Literal

import gdsfactory as gf

from .. import tech
from .ihp_pycell import CbCapCalc, eng_string
from .ihp_pycell import SVaricap as SVaricapIHP
from .ihp_pycell import cmim as cmimIHP
from .ihp_pycell import rfcmim as rfcmimIHP
from .utils import *


[docs] @gf.cell def cmim( width: float = 6.99, length: float = 6.99, guardRingType: Literal["none", "psub", "nwell"] = "none", guardRingDistance: float = 1, ) -> gf.Component: """Create a MIM (Metal-Insulator-Metal) capacitor. This function generates a layout cell for a MIM capacitor with optional guard rings. The capacitor dimensions and the spacing to the guard ring can be customized. Args: width: Width of the capacitor in micrometers. length: Length of the capacitor in micrometers. guardRingType: Type of guard ring to include. Options: - 'none': No guard ring. - 'psub': P-substrate guard ring surrounding the capacitor. - 'nwell': N-well guard ring surrounding the capacitor. guardRingDistance: Spacing between the capacitor body and the guard ring, in micrometers. Returns: gdsfactory.Component: The generated MIM capacitor layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "Calculate": "w&l", "model": tech.techParams["cmim_model"], "C": CbCapCalc( "C", 0, width * 1e-6, length * 1e-6, "cmim" ), # TODO Is this used? "w": eng_string(width * 1e-6), # Width as engineering string "l": eng_string(length * 1e-6), # Length as engineering string "Cspec": tech.techParams["cmim_caspec"], "Wmin": tech.techParams["cmim_minLW"], "Lmin": tech.techParams["cmim_minLW"], "Cmax": tech.techParams["cmim_maxC"], "ic": "", "m": "1", # Multiplier as string "trise": "", "guardRingType": guardRingType, "guardRingDistance": eng_string(guardRingDistance * 1e-6), } c = generate_gf_from_ihp( cell_name="cmim", cell_params=params, function_name=cmimIHP() ) # add ports to the component # no pin layers for cmim, so we use drawing layers gf.add_ports.add_ports_from_boxes( c, pin_layer=(tech.LAYER.Metal5drawing), port_type="electrical", ports_on_short_side=True, ) c.ports["e1"].name = "B" gf.add_ports.add_ports_from_boxes( c, pin_layer=(tech.LAYER.TopMetal1drawing), port_type="electrical", ports_on_short_side=True, auto_rename_ports=False, ) c.ports["e1"].name = "T" c.ports["B"].orientation = 0 c.ports["T"].orientation = 180 return c
[docs] @gf.cell def rfcmim( width: float = 6.99, length: float = 6.99, feed_width: float = 3, ) -> gf.Component: """Create an RF MIM (Metal-Insulator-Metal) capacitor with optimized layout. This function generates a layout for an RF MIM capacitor with a feed line. The capacitor dimensions and feed width can be customized. Args: width: Width of the capacitor in micrometers. length: Length of the capacitor in micrometers. feed_width: Width of the feed line connecting to the capacitor, in micrometers. Returns: gdsfactory.Component: The generated RF MIM capacitor layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "Calculate": "C", "model": tech.techParams["rfcmim_model"], "C": CbCapCalc( "C", 0, width * 1e-6, length * 1e-6, "rfcmim" ), # TODO Is this used? "w": eng_string(width * 1e-6), # Width as engineering string "l": eng_string(length * 1e-6), # Length as engineering string "wfeed": eng_string(feed_width * 1e-6), "Cspec": tech.techParams["rfcmim_caspec"], "Wmin": tech.techParams["rfcmim_minLW"], "Lmin": tech.techParams["rfcmim_minLW"], "Cmax": tech.techParams["rfcmim_maxC"], "ic": "", "m": "1", # Multiplier as string "trise": "", } c = generate_gf_from_ihp( cell_name="rfcmim", cell_params=params, function_name=rfcmimIHP() ) # add ports to the component gf.add_ports.add_ports_from_boxes( c, pin_layer=(tech.LAYER.Metal5pin), port_type="electrical", ports_on_short_side=False, auto_rename_ports=False, ) c.ports["e1"].name = "MINUS" gf.add_ports.add_ports_from_boxes( c, pin_layer=(tech.LAYER.TopMetal1pin), port_type="electrical", ports_on_short_side=False, auto_rename_ports=False, ) c.ports["e1"].name = "PLUS" gf.add_ports.add_ports_from_boxes( c, pin_layer=(tech.LAYER.Metal1pin), port_type="electrical", ports_on_short_side=True, auto_rename_ports=False, ) c.ports["e1"].name = "TIE" return c
[docs] @gf.cell def svaricap( width: Literal["3.74u", "9.74u"] = "9.74u", length: Literal["0.3u", "0.8u"] = "0.8u", Nx: int = 1, guardRingType: Literal["none", "nwell"] = "none", guardRingDistance: float = 1, ) -> gf.Component: """Create a MOS varicap (variable capacitor) layout. This function generates a parametric MOS varicap with optional n-well guard rings. The device geometry and number of fingers can be customized. Args: width: Width of the varicap. Must be one of: '3.74u', '9.74u'. length: Length of the varicap. Must be one of: '0.3u', '0.8u'. Nx: Number of fingers for the varicap. guardRingType: Type of guard ring to include. Options: - 'none': No guard ring. - 'nwell': N-well guard ring. guardRingDistance: Spacing between the varicap body and the guard ring, in micrometers. Returns: gdsfactory.Component: The generated varicap layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "model": tech.techParams["SVaricap_model"], "w": width, # Width already as string like "3.74u" "l": length, # Length already as string like "0.3u" "Nx": Nx, "bn": "sub!", "trise": "", "guardRingType": guardRingType, "guardRingDistance": eng_string(guardRingDistance * 1e-6), } c = generate_gf_from_ihp( cell_name="svaricap", cell_params=params, function_name=SVaricapIHP() ) # add ports to the component gf.add_ports.add_ports_from_boxes( c, pin_layer=(tech.LAYER.Metal1pin), port_type="electrical", ports_on_short_side=True, ) c.ports["e1"].orientation = 90 c.ports["e2"].orientation = 270 c.ports["e3"].orientation = 180 return c
if __name__ == "__main__": # Test the components c1 = cmim(width=10, length=10) c1.show() c2 = rfcmim(width=20, length=20) c2.show()