Source code for ihp.cells2.resistors

"""Resistor components for IHP PDK."""

from typing import Literal

import gdsfactory as gf

from .. import tech
from .ihp_pycell import CbResCalc, CbResCurrent, eng_string_to_float
from .ihp_pycell import rhigh as rhighIHP
from .ihp_pycell import rppd as rppdIHP
from .ihp_pycell import rsil as rsilIHP
from .utils import *


[docs] @gf.cell def rhigh( length: float = 0.96, width: float = 0.5, bends: int = 0, polySpace: float = 0.18, numberOfSegments: int = 1, segmentConnection: Literal["None", "Serial", "Parallel"] = "Serial", segmentSpacing: float = 2, guardRingType: Literal["none", "nwell", "psub"] = "none", guardRingDistance: float = 1, ) -> gf.Component: """Create a high-resistance polysilicon resistor layout. This function generates a parametric high-resistance polysilicon resistor with configurable width, length, bends, and multiple segments. Optional guard rings can be added for isolation. Args: length: Length of the resistor in micrometers. width: Width of the resistor in micrometers. bends: Number of bends in the resistor path. polySpace: Spacing between polysilicon lines in micrometers. numberOfSegments: Number of resistor segments. segmentConnection: Connection type between segments. Options: - 'None': Segments not connected. - 'Serial': Segments connected in series. - 'Parallel': Segments connected in parallel. segmentSpacing: Spacing between segments in micrometers. guardRingType: Type of guard ring to include. Options: - 'none': No guard ring. - 'nwell': N-well guard ring. - 'psub': P-substrate guard ring. guardRingDistance: Distance between the resistor and guard ring in micrometers. Returns: gdsfactory.Component: The generated high-resistance polysilicon resistor layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "Calculate": "l", # TODO check what to do "Recommendation": "No", "model": tech.techParams["rhigh_model"], "R": CbResCalc( "R", 0, length * 1e-6, width * 1e-6, bends, polySpace * 1e-6, "rhigh" ), # TODO Is this used? "w": width * 1e-6, # Length in μm "l": length * 1e-6, # Length in μm "b": bends, "ps": polySpace * 1e-6, "Imax": CbResCurrent( width * 1e-6, tech.techParams["epsilon2"], "rhighG2" ), # TODO Is this used? "bn": "sub!", "Wmin": eng_string_to_float(tech.techParams["rhigh_minW"]) * 1e-6, "Lmin": eng_string_to_float(tech.techParams["rhigh_minL"]) * 1e-6, "PSmin": eng_string_to_float(tech.techParams["rhigh_minPS"]) * 1e-6, "Rspec": tech.techParams["rhigh_rspec"], "Rkspec": tech.techParams["rhigh_rkspec"], "Rzspec": tech.techParams["rhigh_rzspec"], "tc1": -2300e-6, # hardcoded in the PCell "tc2": 2.1e-6, # hardcoded in the PCell "PWB": "No", "m": 1, # Multiplier "trise": 0, "NumberOfSegments": numberOfSegments, "SegmentConnection": segmentConnection, "SegmentSpacing": segmentSpacing * 1e-6, "guardRingType": guardRingType, "guardRingDistance": guardRingDistance * 1e-6, } c = generate_gf_from_ihp( cell_name="rhigh", cell_params=params, function_name=rhighIHP() ) # 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=False, ) return c
[docs] @gf.cell def rppd( length: float = 0.5, width: float = 0.5, bends: int = 0, polySpace: float = 0.18, numberOfSegments: int = 1, segmentConnection: Literal["None", "Serial", "Parallel"] = "Serial", segmentSpacing: float = 2, guardRingType: Literal["none", "nwell", "psub"] = "none", guardRingDistance: float = 1, ) -> gf.Component: """Create a high-resistance polysilicon resistor layout. This function generates a parametric high-resistance polysilicon resistor with configurable width, length, bends, and multiple segments. Optional guard rings can be added for isolation. Args: length: Length of the resistor in micrometers. width: Width of the resistor in micrometers. bends: Number of bends in the resistor path. polySpace: Spacing between polysilicon lines in micrometers. numberOfSegments: Number of resistor segments. segmentConnection: Connection type between segments. Options: - 'None': Segments not connected. - 'Serial': Segments connected in series. - 'Parallel': Segments connected in parallel. segmentSpacing: Spacing between segments in micrometers. guardRingType: Type of guard ring to include. Options: - 'none': No guard ring. - 'nwell': N-well guard ring. - 'psub': P-substrate guard ring. guardRingDistance: Distance between the resistor and guard ring in micrometers. Returns: gdsfactory.Component: The generated high-resistance polysilicon resistor layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "Calculate": "l", # TODO check what to do "Recommendation": "No", "model": tech.techParams["rppd_model"], "R": CbResCalc( "R", 0, length * 1e-6, width * 1e-6, bends, polySpace * 1e-6, "rppd" ), # TODO Is this used? "w": width * 1e-6, # Length in μm "l": length * 1e-6, # Length in μm "b": bends, "ps": polySpace * 1e-6, "Imax": CbResCurrent( width * 1e-6, tech.techParams["epsilon2"], "rppdG2" ), # TODO Is this used? "bn": "sub!", "Wmin": eng_string_to_float(tech.techParams["rppd_minW"]) * 1e-6, "Lmin": eng_string_to_float(tech.techParams["rppd_minL"]) * 1e-6, "PSmin": eng_string_to_float(tech.techParams["rppd_minPS"]) * 1e-6, "Rspec": tech.techParams["rppd_rspec"], "Rkspec": tech.techParams["rppd_rkspec"], "Rzspec": tech.techParams["rppd_rzspec"], "tc1": -170e-6, # hardcoded in the PCell "tc2": 0.4e-6, # hardcoded in the PCell "PWB": "No", "m": 1, # Multiplier "trise": 0, "NumberOfSegments": numberOfSegments, "SegmentConnection": segmentConnection, "SegmentSpacing": segmentSpacing * 1e-6, "guardRingType": guardRingType, "guardRingDistance": guardRingDistance * 1e-6, } c = generate_gf_from_ihp( cell_name="rppd", cell_params=params, function_name=rppdIHP() ) # 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=False, ) return c
[docs] @gf.cell def rsil( length: float = 0.5, width: float = 0.5, polySpace: float = 0.18, resistance: float = 24.9, numberOfSegments: int = 1, segmentConnection: Literal["None", "Serial", "Parallel"] = "Serial", segmentSpacing: float = 2, guardRingType: Literal["none", "nwell", "psub"] = "none", guardRingDistance: float = 1, ) -> gf.Component: """Create a high-resistance polysilicon resistor layout (RSIL type). This function generates a parametric high-resistance polysilicon resistor of RSIL type with configurable width, length, target resistance, bends, multiple segments, and optional guard rings for isolation. Args: length: Length of the resistor in micrometers. width: Width of the resistor in micrometers. polySpace: Spacing between polysilicon lines in micrometers. resistance: Target resistance value in ohms. numberOfSegments: Number of resistor segments. segmentConnection: Connection type between segments. Options: - 'None': Segments not connected. - 'Serial': Segments connected in series. - 'Parallel': Segments connected in parallel. segmentSpacing: Spacing between segments in micrometers. guardRingType: Type of guard ring to include. Options: - 'none': No guard ring. - 'nwell': N-well guard ring. - 'psub': P-substrate guard ring. guardRingDistance: Distance between the resistor and guard ring in micrometers. Returns: gdsfactory.Component: The generated RSIL polysilicon resistor layout. """ params = { "cdf_version": tech.techParams["CDFVersion"], "Display": "Selected", "Calculate": "l", # TODO check what to do "Recommendation": "No", "model": tech.techParams["rsil_model"], "R": resistance, # TODO IHP function defines it as user parameter but also calculates it "w": width * 1e-6, # Length in μm "l": length * 1e-6, # Length in μm "ps": polySpace * 1e-6, "Imax": CbResCurrent( width * 1e-6, tech.techParams["epsilon2"], "rsilG2" ), # TODO Is this used? "bn": "sub!", "Wmin": eng_string_to_float(tech.techParams["rsil_minW"]) * 1e-6, "Lmin": eng_string_to_float(tech.techParams["rsil_minL"]) * 1e-6, "PSmin": eng_string_to_float(tech.techParams["rsil_minPS"]) * 1e-6, "Rspec": tech.techParams["rsil_rspec"], "Rkspec": tech.techParams["rsil_rkspec"], "Rzspec": tech.techParams["rsil_rzspec"], "tc1": -170e-6, # hardcoded in the PCell "tc2": 0.4e-6, # hardcoded in the PCell "PWB": "No", "m": 1, # Multiplier "trise": 0, "NumberOfSegments": numberOfSegments, "SegmentConnection": segmentConnection, "SegmentSpacing": segmentSpacing * 1e-6, "guardRingType": guardRingType, "guardRingDistance": guardRingDistance * 1e-6, } c = generate_gf_from_ihp( cell_name="rsil", cell_params=params, function_name=rsilIHP() ) # 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=False, ) return c
if __name__ == "__main__": # Test the components c1 = rsil(width=1.0, length=10.0) c1.show() c2 = rppd(width=0.8, length=20.0) c2.show() c3 = rhigh(width=1.4, length=50.0) c3.show()