"""Capacitor components for IHP PDK."""
import gdsfactory as gf
from gdsfactory import Component
from gdsfactory.typings import LayerSpec
from numpy import floor
from ihp import tech
from ihp.cells.passives import guard_ring
from ihp.cells.via_stacks import via_array, via_stack
from ihp.cells2.ihp_pycell.utility_functions import CbCapCalc
def snap_to_grid(p, grid: float = 0.005):
return round(p / grid) * grid
# TODO: snap dims to grid
def cmom_extractor(
nfingers: int = 1,
length: float = 2.0,
spacing: float = 0.26,
min_width: float = 0.2,
mom_metals: list[LayerSpec] | None = None,
**kwargs,
) -> float:
if mom_metals is None:
mom_metals = []
layer_thickness = {
"Metal1": tech.LAYER_STACK["metal1"].thickness,
"Metal2": tech.LAYER_STACK["metal2"].thickness,
"Metal3": tech.LAYER_STACK["metal3"].thickness,
"Metal4": tech.LAYER_STACK["metal4"].thickness,
"Metal5": tech.LAYER_STACK["metal5"].thickness,
}
total_cap: float = 0.0
fringe_field_factor = kwargs.get("fringe_field_factor", 0.2)
permitivity = kwargs.get("interlayer_dielectric", 3.8)
eps0 = 8.8541878188e-3 #
for metal in mom_metals:
th = layer_thickness[metal]
min_finger_width = min_width
total_cap += (
permitivity
* eps0
* (th / spacing)
* (
(nfingers * 2) * (length + spacing)
+ min_finger_width * (nfingers * 2 + 1)
)
)
return total_cap * (1 + fringe_field_factor)
[docs]
@gf.cell
def cmom(
nfingers: int = 1,
length: float = 4.0,
spacing: float = 0.26,
botmetal: LayerSpec = "Metal1",
topmetal: LayerSpec = "Metal3",
layer_metal1: LayerSpec = "Metal1drawing",
layer_metal2: LayerSpec = "Metal2drawing",
layer_metal3: LayerSpec = "Metal3drawing",
layer_metal4: LayerSpec = "Metal4drawing",
layer_metal5: LayerSpec = "Metal5drawing",
layer_metal1pin: LayerSpec = "Metal1pin",
layer_metal2pin: LayerSpec = "Metal2pin",
layer_metal3pin: LayerSpec = "Metal3pin",
layer_metal4pin: LayerSpec = "Metal4pin",
layer_metal5pin: LayerSpec = "Metal5pin",
layer_metal1label: LayerSpec = "Metal1label",
layer_metal2label: LayerSpec = "Metal2label",
layer_metal3label: LayerSpec = "Metal3label",
layer_metal4label: LayerSpec = "Metal4label",
layer_metal5label: LayerSpec = "Metal5label",
layer_metal1nofill: LayerSpec = "Metal1nofill",
layer_metal2nofill: LayerSpec = "Metal2nofill",
layer_metal3nofill: LayerSpec = "Metal3nofill",
layer_metal4nofill: LayerSpec = "Metal4nofill",
layer_metal5nofill: LayerSpec = "Metal5nofill",
layer_cap_mark: LayerSpec = "MemCapdrawing",
layer_text: LayerSpec = "TEXTdrawing",
model: str = "cmom",
**kwargs,
) -> Component:
"""Create a MOM (Metal-Over-Metal) interdigitated capacitor.
Args:
nfingers: Number of inside fingers.
length: Length of the capacitor in micrometers.
spacing: Spacing between top and bottom electrodes.
Higher spacing, lower capacitance.
botmetal: Bottom Metal layer for the capacitor stack.
topmetal: Top Metal layer for the capacitor stack.
--- Layers
layer_metal1: Metal1 drawing layer.
layer_metal2: Metal2 drawing layer.
layer_metal3: Metal3 drawing layer.
layer_metal4: Metal4 drawing layer.
layer_metal5: Metal5 drawing layer.
layer_metal1pin: Metal1 pin logic layer.
layer_metal2pin: Metal2 pin logic layer.
layer_metal3pin: Metal3 pin logic layer.
layer_metal4pin: Metal4 pin logic layer.
layer_metal5pin: Metal5 pin logic layer.
layer_metal1label: Metal1 label logic layer.
layer_metal2label: Metal2 label logic layer.
layer_metal3label: Metal3 label logic layer.
layer_metal4label: Metal4 label logic layer.
layer_metal5label: Metal5 label logic layer.
layer_metal1nofill: Metal1 nofill logic layer.
layer_metal2nofill: Metal2 nofill logic layer.
layer_metal3nofill: Metal3 nofill logic layer.
layer_metal4nofill: Metal4 nofill logic layer.
layer_metal5nofill: Metal5 nofill logic layer.
layer_cap_mark: MemCapdrawing logic layer.
layer_text: TEXT drawing layer
model: Device model name.
Returns:
Component with MOM capacitor layout.
Raises:
"""
metals = {
"Metal1": layer_metal1,
"Metal2": layer_metal2,
"Metal3": layer_metal3,
"Metal4": layer_metal4,
"Metal5": layer_metal5,
}
labels = {
"Metal1": layer_metal1label,
"Metal2": layer_metal2label,
"Metal3": layer_metal3label,
"Metal4": layer_metal4label,
"Metal5": layer_metal5label,
}
pins = {
"Metal1": layer_metal1pin,
"Metal2": layer_metal2pin,
"Metal3": layer_metal3pin,
"Metal4": layer_metal4pin,
"Metal5": layer_metal5pin,
}
nofills = {
"Metal1": layer_metal1nofill,
"Metal2": layer_metal2nofill,
"Metal3": layer_metal3nofill,
"Metal4": layer_metal4nofill,
"Metal5": layer_metal5nofill,
}
pdk_design_rules = {
"Metal1": {
"min_width": tech.TECH.metal1_width,
"min_spacing": tech.TECH.metal1_spacing,
},
"Metal2": {
"min_width": tech.TECH.metal2_width,
"min_spacing": tech.TECH.metal2_spacing,
},
"Metal3": {
"min_width": tech.TECH.metal3_width,
"min_spacing": tech.TECH.metal3_spacing,
},
"Metal4": {
"min_width": tech.TECH.metal4_width,
"min_spacing": tech.TECH.metal4_spacing,
},
"Metal5": {
"min_width": tech.TECH.metal5_width,
"min_spacing": tech.TECH.metal5_spacing,
},
}
min_width_global = min([v["min_width"] for v in pdk_design_rules.values()])
min_spacing_global = min([v["min_spacing"] for v in pdk_design_rules.values()])
min_length = 3 * min_width_global # to comply with minimum metal area DRC
assert length > min_length, (
f"Minimum Area for all metals > {min_length * min_width_global}"
)
assert spacing > min_spacing_global, (
f"Minimum metal spacing for all metals > {min_spacing_global}"
)
ordered_metals = list(metals.keys())
# ordered_vias = [lay for lay in ordered_layers if "via" in lay]
assert botmetal in ordered_metals, (
"{botmetal} not it available layers: {_ordered_metals}"
)
assert topmetal in ordered_metals, (
"{topmetal} not it available layers: {_ordered_metals}"
)
mom_metals = ordered_metals[
ordered_metals.index(botmetal) : ordered_metals.index(topmetal) + 1
]
c = gf.Component()
total_length = 0.0
top_pad_ref = None
bot_pad_ref = None
for metal_layer in mom_metals:
min_width = min_width_global
layer = metals[metal_layer]
top_finger = gf.components.rectangle(size=(min_width, length), layer=layer)
top_finger_array = c.add_ref(
top_finger,
columns=nfingers + 1,
rows=1,
column_pitch=2 * (spacing + min_width),
)
top_finger_array.ymin += spacing
bot_finger = gf.components.rectangle(size=(min_width, length), layer=layer)
bot_finger_array = c.add_ref(
bot_finger, columns=nfingers, rows=1, column_pitch=2 * (spacing + min_width)
)
bot_finger_array.xmin += min_width + spacing
total_length = (min_width + spacing) * (2 * nfingers + 1) - spacing
top_pad = gf.components.rectangle(
size=(total_length, 3 * min_width), layer=layer
)
top_pad_ref = c.add_ref(top_pad)
top_pad_ref.ymin += length + spacing
bot_pad_ref = c.add_ref(top_pad)
bot_pad_ref.ymax = 0
# add no fill and no QRC layers to the mom device region
# nofill_layer = metal_layer.capitalize()+'nofill'
nofill_layer = nofills[metal_layer.capitalize()]
c.add_ref(gf.components.bbox(c, layer=nofill_layer))
# add capacitor region marker
c.add_ref(gf.components.bbox(c, layer=layer_cap_mark))
# add ports
# pin_layer: LayerSpec = metal_layer.capitalize()+'pin'
# label_layer: LayerSpec = metal_layer.capitalize()+'label'
pin_layer = pins[metal_layer.capitalize()]
label_layer = labels[metal_layer.capitalize()]
c.add_port(
"PLUS", center=(top_pad_ref.x, top_pad_ref.y), width=min_width, layer=pin_layer
)
c.add_port(
"MINUS", center=(bot_pad_ref.x, bot_pad_ref.y), width=min_width, layer=pin_layer
)
c.add_label(text="PLUS", position=(top_pad_ref.x, top_pad_ref.y), layer=label_layer)
c.add_label(
text="MINUS", position=(bot_pad_ref.x, bot_pad_ref.y), layer=label_layer
)
c.add_label(text="PLUS", position=(top_pad_ref.x, top_pad_ref.y), layer=layer_text)
c.add_label(text="MINUS", position=(bot_pad_ref.x, bot_pad_ref.y), layer=layer_text)
c.add_label(text=model, position=(c.x, c.y + min_width), layer=layer_text)
# add a via array stack to the top and bottom pads
mom_via_stack = via_stack(
bottom_layer=botmetal.capitalize(),
top_layer=topmetal.capitalize(),
size=(total_length, 3 * min_width),
vn_columns=nfingers * 4,
vn_rows=1,
)
via_stack_bot = c.add_ref(mom_via_stack)
via_stack_bot.xmin = bot_pad_ref.xmin
via_stack_bot.ymax = bot_pad_ref.ymax
via_stack_top = c.add_ref(mom_via_stack)
via_stack_top.xmin = top_pad_ref.xmin
via_stack_top.ymin = top_pad_ref.ymin
# add place and route layers to define the device's bounding box
prboundary_layer = "prBoundarydrawing"
c.add_ref(gf.components.bbox(c, layer=prboundary_layer))
c.info["capacitance"] = cmom_extractor(
nfingers,
length,
spacing,
min_width=min_width_global,
mom_metals=mom_metals,
**kwargs,
)
c.add_label(
text=f"C = {c.info['capacitance']} fF",
position=(c.x, c.y - min_width),
layer=layer_text,
)
c.info["model"] = model
c.info["nfingers"] = nfingers
c.info["length"] = length
c.info["spacing"] = spacing
# return the component
return c
@gf.cell
def cmim(
width: float = 6.0,
length: float = 6.0,
layer_metal5: LayerSpec = "Metal5drawing",
layer_mim: LayerSpec = "MIMdrawing",
layer_vmim: LayerSpec = "Vmimdrawing",
layer_topmetal1: LayerSpec = "TopMetal1drawing",
layer_cap_mark: LayerSpec = "MemCapdrawing",
layer_m4nofill: LayerSpec = "Metal4nofill",
layer_m5nofill: LayerSpec = "Metal5nofill",
layer_tm1nofill: LayerSpec = "TopMetal1nofill",
layer_tm2nofill: LayerSpec = "TopMetal2nofill",
layer_text: LayerSpec = "TEXTdrawing",
layer_metal5label: LayerSpec = "Metal5label",
layer_topmetal1label: LayerSpec = "TopMetal1label",
layer_metal5pin: LayerSpec = "Metal5pin",
layer_topmetal1pin: LayerSpec = "TopMetal1pin",
model: str = "cmim",
**kwargs,
) -> Component:
"""Create a MIM (Metal-Insulator-Metal) capacitor.
Args:
width: Width of the capacitor in micrometers.
length: Length of the capacitor in micrometers.
bot_enclosure: Bottol Metal5 layer enclosure
top_enclosure:
layer_metal5: Metal 5 drawing layer.
layer_mim: MIM device drawing layer.
layer_vmim: Vmim (MIM-TopMetal1 Via) drawing layer.
layer_topmetal1: TopMetal1 drawing layer.
layer_cap_mark: MemCap drawing layer.
layer_m4nofill: Metal4 nofill logic layer.
layer_m5nofill: Metal5 nofill logic layer.
layer_tm1nofill: TopMetal1 nofill logic layer.
layer_tm2nofill: TopMetal2 nofill logic layer.
layer_text: TEXT drawing layer.
layer_metal5label: Metal5 label logic layer.
layer_topmetal1label: TopMetal1 label logic layer.
layer_metal5pin: Metal5 pin logic layer.
layer_topmetal1pin: TopMetal1 pin logic layer.
model: Device model name.
Returns:
Component with MIM capacitor layout.
Raises:
"""
c = Component()
mim_drc = {
# capacitor
"mim_min_size": tech.TECH.mim_min_size,
"mim_cap_density": tech.TECH.mim_cap_density,
# metals
"m5_min_width": tech.TECH.metal5_width,
"m5_min_spacing": tech.TECH.metal5_spacing,
"topmetal1_width": tech.TECH.topmetal1_width,
"topmetal1_spacing": tech.TECH.topmetal1_spacing,
# vias
"vmim_size": 0.42,
"vmim_spacing": 0.52,
"vmim_enc_metal": 0.42,
"vmim_enc": 0.6, # bot_enclosure
"mim_enc": 0.36, # top_enclosure
}
bot_enclosure = mim_drc["vmim_enc"]
top_enclosure = mim_drc["mim_enc"]
# verification
assert width > mim_drc["mim_min_size"], f"MIM width > {mim_drc['mim_min_size']}"
assert length > mim_drc["mim_min_size"], f"MIM width > {mim_drc['mim_min_size']}"
# snap to grid
grid = tech.TECH.grid
width = round(width / grid) * grid
length = round(length / grid) * grid
# build capacitor stack
# Bottom plate (Metal4)
bottom_plate_width = width + 2 * bot_enclosure + 2 * top_enclosure
bottom_plate_length = length + 2 * bot_enclosure + 2 * top_enclosure
bottom_plate = gf.components.rectangle(
size=(bottom_plate_length, bottom_plate_width),
layer=layer_metal5,
centered=True,
)
bot = c.add_ref(bottom_plate)
# MIM layer
mim_layer = gf.components.rectangle(
size=(length + 2 * top_enclosure, width + 2 * top_enclosure),
layer=layer_mim,
centered=True,
)
c.add_ref(mim_layer)
# add vmim via array
vmim_min_width = mim_drc["vmim_size"] + mim_drc["vmim_spacing"]
nrows = int(floor(width / vmim_min_width))
ncols = int(floor(length / vmim_min_width))
# Top plate (TopMetal1)
top_plate = gf.components.rectangle(
size=(length, width),
layer=layer_topmetal1,
centered=True,
)
top = c.add_ref(top_plate)
vmim_array = via_array(
via_type=layer_vmim.split("drawing")[0],
via_size=mim_drc["vmim_size"],
via_spacing=mim_drc["vmim_size"] + mim_drc["vmim_spacing"],
via_enclosure=mim_drc["vmim_enc_metal"],
columns=ncols,
rows=nrows,
)
vias = c.add_ref(vmim_array)
vias.x = top.x
vias.y = top.y
# Add no fill logic layers
logic = [
layer_cap_mark,
layer_m4nofill,
layer_m5nofill,
layer_tm1nofill,
layer_tm2nofill,
]
for layer_spec in logic:
ll = gf.components.rectangle(
size=(bottom_plate_length, bottom_plate_width),
layer=layer_spec,
centered=True,
)
c.add_ref(ll)
minus = c.add_port(
name="MINUS",
center=(bot.xmin + mim_drc["m5_min_width"] / 2, bot.y),
width=mim_drc["m5_min_width"],
orientation=180,
layer=layer_metal5label,
port_type="electrical",
)
plus = c.add_port(
name="PLUS",
center=(top.xmax - mim_drc["topmetal1_width"] / 2, top.y),
width=mim_drc["topmetal1_width"],
orientation=0,
layer=layer_topmetal1label,
port_type="electrical",
)
pin_minus = gf.components.rectangle(
size=(mim_drc["topmetal1_width"], 2 * mim_drc["topmetal1_width"]),
layer=layer_metal5pin,
centered=True,
)
pin_minus_ref = c.add_ref(pin_minus)
pin_minus_ref.xmin = bot.xmin
pin_minus_ref.y = minus.y
pin_plus = gf.components.rectangle(
size=(mim_drc["topmetal1_width"], 2 * mim_drc["topmetal1_width"]),
layer=layer_topmetal1pin,
centered=True,
)
pin_plus_ref = c.add_ref(pin_plus)
pin_plus_ref.xmax = top.xmax
pin_plus_ref.y = plus.y
c.add_label(
text="PLUS",
position=(top.xmax - mim_drc["topmetal1_width"] / 2, top.y),
layer=layer_text,
)
c.add_label(
text="MINUS",
position=(bot.xmin + mim_drc["m5_min_width"] / 2, bot.y),
layer=layer_text,
)
c.add_label(text=model, position=(c.x, c.y + width / 2), layer=layer_text)
# fringe_factor = kwargs.get("fringe_factor", 0.355)
# capacitance = width * length * mim_drc['mim_cap_density']
# capacitance *= (1+fringe_factor)
capacitance = CbCapCalc("C", 0, length * 1e-6, width * 1e-6, model) / 1e-15
c.add_label(
text=f"C = {capacitance} fF", position=(c.x, c.y - width / 2), layer=layer_text
)
c.info["model"] = model
c.info["width"] = width
c.info["length"] = length
c.info["capacitance_fF"] = capacitance
c.info["area_um2"] = width * length
# VLSIR simulation metadata
c.info["vlsir"] = {
"model": "cap_cmim",
"spice_type": "SUBCKT",
"spice_lib": "capacitors_mod.lib",
"port_order": ["PLUS", "MINUS"],
"params": {"w": width * 1e-6, "l": length * 1e-6},
}
return c
@gf.cell
def rfcmim(
width: float = 6.0,
length: float = 6.0,
layer_pwellblock: LayerSpec = "PWellblock",
layer_metal5: LayerSpec = "Metal5drawing",
layer_mim: LayerSpec = "MIMdrawing",
layer_vmim: LayerSpec = "Vmimdrawing",
layer_topmetal1: LayerSpec = "TopMetal1drawing",
layer_cap_mark: LayerSpec = "MemCapdrawing",
layer_m4nofill: LayerSpec = "Metal4nofill",
layer_m5nofill: LayerSpec = "Metal5nofill",
layer_tm1nofill: LayerSpec = "TopMetal1nofill",
layer_tm2nofill: LayerSpec = "TopMetal2nofill",
layer_activ: LayerSpec = "Activdrawing",
layer_cont: LayerSpec = "Contdrawing",
layer_metal1: LayerSpec = "Metal1drawing",
layer_psd: LayerSpec = "pSDdrawing",
# layer_rfpad: LayerSpec = "RFPaddrawing",
layer_activnoqrc: LayerSpec = "Activnoqrc",
layer_metal1noqrc: LayerSpec = "Metal1noqrc",
layer_metal2noqrc: LayerSpec = "Metal2noqrc",
layer_metal3noqrc: LayerSpec = "Metal3noqrc",
layer_metal4noqrc: LayerSpec = "Metal4noqrc",
layer_metal5noqrc: LayerSpec = "Metal5noqrc",
layer_topmetal1noqrc: LayerSpec = "TopMetal1noqrc",
layer_text: LayerSpec = "TEXTdrawing",
layer_metal1pin: LayerSpec = "Metal1pin",
layer_metal5pin: LayerSpec = "Metal5pin",
layer_topmetal1pin: LayerSpec = "TopMetal1pin",
layer_metal5label: LayerSpec = "Metal5label",
layer_topmetal1label: LayerSpec = "TopMetal1label",
layer_metal1label: LayerSpec = "Metal1label",
model: str = "rfcmim",
) -> Component:
"""Create a MIM (Metal-Insulator-Metal) capacitor isolated by a
bulk charge-drift encapsulation P-Plus guard-ring.
Args:
width: Width of the capacitor in micrometers.
length: Length of the capacitor in micrometers.
layer_metal5: Metal 5 drawing layer.
layer_mim: MIM device drawing layer.
layer_vmim: Vmim (MIM-TopMetal1 Via) drawing layer.
layer_topmetal1: TopMetal1 drawing layer.
layer_cap_mark: MemCap drawing layer.
layer_m4nofill: Metal4 nofill logic layer.
layer_m5nofill: Metal5 nofill logic layer.
layer_tm1nofill: TopMetal1 nofill logic layer.
layer_tm2nofill: TopMetal2 nofill logic layer.
layer_text: TEXT drawing layer.
layer_metal5label: Metal5 label logic layer.
layer_topmetal1label: TopMetal1 label logic layer.
layer_metal5pin: Metal5 pin logic layer.
layer_topmetal1pin: TopMetal1 pin logic layer.
model: Device model name.
Returns:
Component with MIM capacitor layout.
Raises:
"""
c = Component()
cap = cmim(
width=width,
length=length,
layer_metal5=layer_metal5,
layer_mim=layer_mim,
layer_vmim=layer_vmim,
layer_topmetal1=layer_topmetal1,
layer_cap_mark=layer_cap_mark,
layer_m4nofill=layer_m4nofill,
layer_m5nofill=layer_m5nofill,
layer_tm1nofill=layer_tm1nofill,
layer_tm2nofill=layer_tm2nofill,
layer_text=layer_text,
layer_metal5pin=layer_metal5pin,
layer_topmetal1pin=layer_topmetal1pin,
layer_metal5label=layer_metal5label,
layer_topmetal1label=layer_topmetal1label,
model=model,
)
c.info = cap.info
c.add_ref(cap)
c.ports = cap.ports
# add pwell block
size = c.bbox_np()
size = size[1] - size[0]
pwellblock_enc = 2.4
pwell = gf.components.rectangle(
size=(size[0] + 2 * pwellblock_enc, size[1] + 2 * pwellblock_enc),
layer=layer_pwellblock,
centered=True,
)
ccenter = (c.x, c.y)
pwell_ref = c.add_ref(pwell)
pwell_ref.x = ccenter[0]
pwell_ref.y = ccenter[1]
# add p guard ring
pguardring_seq = 0.6
pguardring_width = 2.0
c.add_ref(
guard_ring(
width=pguardring_width,
guardRingSpacing=pguardring_seq,
guardRingType="psub",
bbox=tuple(tuple(p) for p in c.bbox_np()),
path=None,
layer_activ=layer_activ,
layer_cont=layer_cont,
layer_metal1=layer_metal1,
layer_psd=layer_psd,
)
)
logic_layers = [
layer_activnoqrc,
layer_metal1noqrc,
layer_metal2noqrc,
layer_metal3noqrc,
layer_metal4noqrc,
layer_metal5noqrc,
layer_topmetal1noqrc,
]
size = c.bbox_np()
size = size[1] - size[0]
ccenter = (c.x, c.y)
for layer_spec in logic_layers:
ll = gf.components.rectangle(
size=(size[0], size[1]),
layer=layer_spec,
centered=True,
)
ref = c.add_ref(ll)
ref.x = ccenter[0]
ref.y = ccenter[1]
gr_drc = {
"active_min_enclose_pp": 0.14,
}
# add TIE LOW pin
tie_low = gf.components.rectangle(
size=(size[0] - 2 * gr_drc["active_min_enclose_pp"], pguardring_width),
layer=layer_metal1pin,
centered=True,
)
xmin, ymin = c.xmin, c.ymin
tie_low_ref = c.add_ref(tie_low)
tie_low_ref.xmin = xmin + gr_drc["active_min_enclose_pp"]
tie_low_ref.ymin = ymin + gr_drc["active_min_enclose_pp"]
tie = c.add_port(
name="TIE_LOW",
center=(tie_low_ref.x, tie_low_ref.y),
width=pguardring_width,
orientation=0,
layer=layer_metal1,
port_type="electrical",
)
c.add_label(text="TIE_LOW", position=(tie.x, tie.y), layer=layer_metal1label)
c.add_label(text="TIE_LOW", position=(tie.x, tie.y), layer=layer_text)
# VLSIR simulation metadata
c.info["vlsir"] = {
"model": "cap_rfcmim",
"spice_type": "SUBCKT",
"spice_lib": "capacitors_mod.lib",
"port_order": ["PLUS", "MINUS", "bn"],
"port_map": {"PLUS": "PLUS", "MINUS": "MINUS"},
"params": {"l": length * 1e-6, "w": width * 1e-6},
}
return c
if __name__ == "__main__":
from math import isclose
# capacitance in femto farad
c = cmom(nfingers=2)
assert isclose(c.info["capacitance"], 3.8016)
c.show()
c2 = cmom(nfingers=4)
assert c2.info["capacitance"] >= 2 * c.info["capacitance"]
assert isclose(c2.info["capacitance"], 7.5733)
c2.show()
if __name__ == "__main__":
from gdsfactory.difftest import xor
from ihp import PDK, cells2
PDK.activate()
# Test the components
c0 = cells2.cmim() # original
c1 = cmim() # New
# c = gf.grid([c0, c1], spacing=100)
c = xor(c0, c1)
c.show()
# c0 = fixed.rfcmim() # original
# c1 = rfcmim() # New
# # c = gf.grid([c0, c1], spacing=100)
# c = xor(c0, c1)
# c.show()