Source code for bag3_magnetics.layout.inductor_spiral.ind_interleave

from typing import Mapping, Any

from bag.layout.template import TemplateDB
from bag.layout.util import BBox
from bag.util.immutable import Param

from pybag.enum import Orientation
from pybag.core import Transform

from .util import IndSpiralTemplate
from .ind_spiral_core import IndSpiralCore


[docs]class IndInterleave(IndSpiralTemplate): """interleaved spiral inductors with multiple turns, 'R0' orientation""" def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: IndSpiralTemplate.__init__(self, temp_db, params, **kwargs) self._lead_lower = 0 self._lead_upper = 0 @property
[docs] def lead_lower(self) -> int: # bottom lead may extend beyond first quadrant return self._lead_lower
@property
[docs] def lead_upper(self) -> int: return self._lead_upper
@classmethod
[docs] def get_params_info(cls) -> Mapping[str, str]: return dict( n_turns='Number of turns; 1 by default', lay_id='Inductor layer ID', radius='Outermost radius', width='Width of inductor sides', spacing='Spacing between inductor turns', lead_width='Width of inductor leads', lead_spacing='Spacing between inductor leads',
) @classmethod
[docs] def get_default_param_values(cls) -> Mapping[str, Any]: return dict( n_turns=1,
)
[docs] def draw_layout(self) -> None: n_turns: int = self.params['n_turns'] lay_id: int = self.params['lay_id'] radius: int = self.params['radius'] width: int = self.params['width'] spacing: int = self.params['spacing'] lead_width: int = self.params['lead_width'] lead_spacing: int = self.params['lead_spacing'] # check feasibility outer_radius = radius + width // 2 _turns = 2 * n_turns + 1 assert outer_radius >= _turns * (width + spacing), f'Either increase radius={radius} or decrease ' \ f'width={width} or spacing={spacing} or n_turns={n_turns}' core_master: IndSpiralCore = self.new_template(IndSpiralCore, params=dict(n_turns=n_turns, lay_id=lay_id, radius=radius, width=width, spacing=spacing, lead_width=lead_width, lead_spacing=lead_spacing, interleave=True)) core0 = self.add_instance(core_master, inst_name='XCORE0') _bbox = core_master.actual_bbox transform = Transform(dx=_bbox.xh, dy=_bbox.yh, mode=Orientation.R180) core1 = self.add_instance(core_master, inst_name='XCORE1', xform=transform) # draw leads self._draw_leads(lay_id, core0.get_pin('term0'), core0.get_pin('term1'), core1.get_pin('term0'), core1.get_pin('term1')) # set size self._actual_bbox = _bbox self.set_size_from_bound_box(lay_id, _bbox, round_up=True)
[docs] def _draw_leads(self, lay_id: int, plus0: BBox, minus0: BBox, plus1: BBox, minus1: BBox) -> None: port_lay_id = lay_id - 1 lp_lead = self.grid.tech_info.get_lay_purp_list(port_lay_id)[0] # define metal resistor dimensions mres_w = plus0.w mres_l0 = mres_w // 4 # plus0 mres_l1 = mres_w // 2 # minus0 mres_l2 = mres_w # plus1 mres_l3 = mres_w * 2 # minus1 mres_sp = mres_l0 # add metal resistors plus0_rbox = BBox(plus0.xl, plus0.yl - mres_l0, plus0.xh, plus0.yl) self.add_res_metal(port_lay_id, plus0_rbox) minus1_rbox = BBox(minus1.xl, plus0.yl - mres_l3, minus1.xh, plus0.yl) self.add_res_metal(port_lay_id, minus1_rbox) plus1_rbox = BBox(plus1.xl, plus1.yh, plus1.xh, plus1.yh + mres_l2) self.add_res_metal(port_lay_id, plus1_rbox) minus0_rbox = BBox(minus0.xl, plus1.yh, minus0.xh, plus1.yh + mres_l1) self.add_res_metal(port_lay_id, minus0_rbox) # extend metal beyond metal resistors lower = plus0.yl - mres_l3 - mres_sp - mres_w self.add_rect(lp_lead, BBox(plus0.xl, lower, plus0.xh, plus0.yh)) self.add_pin_primitive('plus0', lp_lead[0], BBox(plus0.xl, lower, plus0.xh, lower + mres_w), hide=True) self.add_rect(lp_lead, BBox(minus1.xl, lower, minus1.xh, plus0.yh)) self.add_pin_primitive('minus1', lp_lead[0], BBox(minus1.xl, lower, minus1.xh, lower + mres_w), hide=True) upper = plus1.yh + mres_l3 + mres_sp + mres_w self.add_rect(lp_lead, BBox(plus1.xl, plus1.yl, plus1.xh, upper)) self.add_pin_primitive('plus1', lp_lead[0], BBox(plus1.xl, upper - mres_w, plus1.xh, upper), hide=True) self.add_rect(lp_lead, BBox(minus0.xl, minus0.yl, minus0.xh, upper)) self.add_pin_primitive('minus0', lp_lead[0], BBox(minus0.xl, upper - mres_w, minus0.xh, upper), hide=True) # set properties self._lead_lower = lower self._lead_upper = upper self.sch_params = dict( plus0=dict(w=mres_w, l=mres_l0, layer=port_lay_id), minus0=dict(w=mres_w, l=mres_l1, layer=port_lay_id), plus1=dict(w=mres_w, l=mres_l2, layer=port_lay_id), minus1=dict(w=mres_w, l=mres_l3, layer=port_lay_id),
)