diff --git a/OA/bag3_analog/drv_shunt_peak/data.dm b/OA/bag3_analog/drv_shunt_peak/data.dm new file mode 100644 index 0000000..e22fd18 Binary files /dev/null and b/OA/bag3_analog/drv_shunt_peak/data.dm differ diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/data.dm b/OA/bag3_analog/drv_shunt_peak/schematic/data.dm new file mode 100644 index 0000000..53786e6 Binary files /dev/null and b/OA/bag3_analog/drv_shunt_peak/schematic/data.dm differ diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/master.tag b/OA/bag3_analog/drv_shunt_peak/schematic/master.tag new file mode 100644 index 0000000..26be1be --- /dev/null +++ b/OA/bag3_analog/drv_shunt_peak/schematic/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +sch.oa diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/sch.oa b/OA/bag3_analog/drv_shunt_peak/schematic/sch.oa new file mode 100644 index 0000000..ca2a5ad Binary files /dev/null and b/OA/bag3_analog/drv_shunt_peak/schematic/sch.oa differ diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/thumbnail_128x128.png b/OA/bag3_analog/drv_shunt_peak/schematic/thumbnail_128x128.png new file mode 100644 index 0000000..861c679 Binary files /dev/null and b/OA/bag3_analog/drv_shunt_peak/schematic/thumbnail_128x128.png differ diff --git a/OA/bag3_analog/drv_shunt_peak/symbol/master.tag b/OA/bag3_analog/drv_shunt_peak/symbol/master.tag new file mode 100644 index 0000000..e1024da --- /dev/null +++ b/OA/bag3_analog/drv_shunt_peak/symbol/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +symbol.oa diff --git a/OA/bag3_analog/drv_shunt_peak/symbol/symbol.oa b/OA/bag3_analog/drv_shunt_peak/symbol/symbol.oa new file mode 100644 index 0000000..7566982 Binary files /dev/null and b/OA/bag3_analog/drv_shunt_peak/symbol/symbol.oa differ diff --git a/OA/bag3_analog/drv_shunt_peak/symbol/thumbnail_128x128.png b/OA/bag3_analog/drv_shunt_peak/symbol/thumbnail_128x128.png new file mode 100644 index 0000000..d61facb Binary files /dev/null and b/OA/bag3_analog/drv_shunt_peak/symbol/thumbnail_128x128.png differ diff --git a/OA/bag3_analog/gm_stage/data.dm b/OA/bag3_analog/gm_stage/data.dm new file mode 100644 index 0000000..d3715f9 Binary files /dev/null and b/OA/bag3_analog/gm_stage/data.dm differ diff --git a/OA/bag3_analog/gm_stage/schematic/data.dm b/OA/bag3_analog/gm_stage/schematic/data.dm new file mode 100644 index 0000000..8cc33e9 Binary files /dev/null and b/OA/bag3_analog/gm_stage/schematic/data.dm differ diff --git a/OA/bag3_analog/gm_stage/schematic/master.tag b/OA/bag3_analog/gm_stage/schematic/master.tag new file mode 100644 index 0000000..26be1be --- /dev/null +++ b/OA/bag3_analog/gm_stage/schematic/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +sch.oa diff --git a/OA/bag3_analog/gm_stage/schematic/sch.oa b/OA/bag3_analog/gm_stage/schematic/sch.oa new file mode 100644 index 0000000..4151c2d Binary files /dev/null and b/OA/bag3_analog/gm_stage/schematic/sch.oa differ diff --git a/OA/bag3_analog/gm_stage/schematic/thumbnail_128x128.png b/OA/bag3_analog/gm_stage/schematic/thumbnail_128x128.png new file mode 100644 index 0000000..f49d429 Binary files /dev/null and b/OA/bag3_analog/gm_stage/schematic/thumbnail_128x128.png differ diff --git a/OA/bag3_analog/gm_stage/symbol/master.tag b/OA/bag3_analog/gm_stage/symbol/master.tag new file mode 100644 index 0000000..e1024da --- /dev/null +++ b/OA/bag3_analog/gm_stage/symbol/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +symbol.oa diff --git a/OA/bag3_analog/gm_stage/symbol/symbol.oa b/OA/bag3_analog/gm_stage/symbol/symbol.oa new file mode 100644 index 0000000..3a65adf Binary files /dev/null and b/OA/bag3_analog/gm_stage/symbol/symbol.oa differ diff --git a/OA/bag3_analog/gm_stage/symbol/thumbnail_128x128.png b/OA/bag3_analog/gm_stage/symbol/thumbnail_128x128.png new file mode 100644 index 0000000..f7257a7 Binary files /dev/null and b/OA/bag3_analog/gm_stage/symbol/thumbnail_128x128.png differ diff --git a/OA/bag3_analog/res_diff/data.dm b/OA/bag3_analog/res_diff/data.dm new file mode 100644 index 0000000..abe90be Binary files /dev/null and b/OA/bag3_analog/res_diff/data.dm differ diff --git a/OA/bag3_analog/res_diff/schematic/data.dm b/OA/bag3_analog/res_diff/schematic/data.dm new file mode 100644 index 0000000..2563929 Binary files /dev/null and b/OA/bag3_analog/res_diff/schematic/data.dm differ diff --git a/OA/bag3_analog/res_diff/schematic/master.tag b/OA/bag3_analog/res_diff/schematic/master.tag new file mode 100644 index 0000000..26be1be --- /dev/null +++ b/OA/bag3_analog/res_diff/schematic/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +sch.oa diff --git a/OA/bag3_analog/res_diff/schematic/sch.oa b/OA/bag3_analog/res_diff/schematic/sch.oa new file mode 100644 index 0000000..0f08c7e Binary files /dev/null and b/OA/bag3_analog/res_diff/schematic/sch.oa differ diff --git a/OA/bag3_analog/res_diff/schematic/thumbnail_128x128.png b/OA/bag3_analog/res_diff/schematic/thumbnail_128x128.png new file mode 100644 index 0000000..473fb3f Binary files /dev/null and b/OA/bag3_analog/res_diff/schematic/thumbnail_128x128.png differ diff --git a/OA/bag3_analog/res_diff/symbol/master.tag b/OA/bag3_analog/res_diff/symbol/master.tag new file mode 100644 index 0000000..e1024da --- /dev/null +++ b/OA/bag3_analog/res_diff/symbol/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +symbol.oa diff --git a/OA/bag3_analog/res_diff/symbol/symbol.oa b/OA/bag3_analog/res_diff/symbol/symbol.oa new file mode 100644 index 0000000..a10a8b3 Binary files /dev/null and b/OA/bag3_analog/res_diff/symbol/symbol.oa differ diff --git a/OA/bag3_analog/res_diff/symbol/thumbnail_128x128.png b/OA/bag3_analog/res_diff/symbol/thumbnail_128x128.png new file mode 100644 index 0000000..5e528b9 Binary files /dev/null and b/OA/bag3_analog/res_diff/symbol/thumbnail_128x128.png differ diff --git a/src/bag3_analog/design/drv_shunt_peak.py b/src/bag3_analog/design/drv_shunt_peak.py new file mode 100644 index 0000000..cc5270a --- /dev/null +++ b/src/bag3_analog/design/drv_shunt_peak.py @@ -0,0 +1,134 @@ +from typing import Mapping, Any, Dict, Union, List, Type +import numpy as np +from copy import deepcopy + +from bag.util.immutable import Param +from bag.io.sim_data import load_sim_file, save_sim_results +from bag.concurrent.util import GatherHelper +from bag.simulation.cache import DesignInstance +from bag.simulation.measure import MeasurementManager + +from bag3_testbenches.design.optimize.base import OptDesigner, OptimizationError + +from ..measurement.drv_shunt_peak import DrvShuntPeakTranMeas + + +class DrvShuntPeakDesigner(OptDesigner): + def __init__(self, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + + @classmethod + def get_meas_var_list(cls): + return ['width', 'height', 'i_avg', 'fom'] + + async def async_design(self, **kwargs: Any) -> Mapping[str, Any]: + await self.characterize_designs() + fn_table, swp_order = self.make_models() + opt_specs = self._dsn_specs['opt_specs'] + spec_constraints = {k: tuple(v) for k, v in opt_specs['spec_constraints'].items()} + + self.log(f'Performing eye_area optimization...') + try: + opt_x, opt_y, spec_vals = self.optimize('height', fn_table, swp_order, maximize=True, reduce_fn=np.max, + spec_constraints=spec_constraints) + print('--------------------------') + print(f'opt_x = {opt_x}') + print(f'opt_y = {opt_y}') + print(f'spec_vals = {spec_vals}') + print('--------------------------') + except OptimizationError as e: + self.warn(f'Error occurred while running: {e}') + + return fn_table + + async def verify_design(self, dut: DesignInstance, dsn_params: Dict[str, Any], + sim_swp_params: Dict[str, Any]) -> Dict[str, Any]: + dsn_name = self.get_design_name(dsn_params) + + gatherer = GatherHelper() + gatherer.append(self.run_sim('tran', DrvShuntPeakTranMeas, dut, dsn_name, dsn_params, sim_swp_params)) + res_list = await gatherer.gather_err() + res = self.aggregate_results(res_list) + return res + + async def run_sim(self, meas_name: str, mm_cls: Type[MeasurementManager], dut: DesignInstance, dsn_name: str, + dsn_params: Dict[str, Any], sim_swp_params: Dict[str, Any]) -> Dict[str, Any]: + sim_dir = self.get_meas_dir(dsn_name) + out_dir = self.get_data_dir(dsn_name) + + res_fpath = out_dir / f'{meas_name}.hdf5' + run_meas = self.check_run_meas(res_fpath) + + if not run_meas: + prev_res = load_sim_file(str(res_fpath)) + self.reorder_data_swp(prev_res, self.sim_swp_order) + return prev_res + + # setup measurement specs + mm_specs = deepcopy(self._dsn_specs['meas_params']) + mm_specs['sim_envs'] = sim_swp_params['corner'] + mm_specs['v_incm_swp'] = sim_swp_params['v_incm'] + mm_specs['v_tail_g_swp'] = sim_swp_params['v_tail_g'] + mm_specs['ind_specs']['sp_file_specs']['shunt']['file_name'] = dsn_params['sp_file'] + + mm = self.make_mm(mm_cls, mm_specs) + + data = (await self._sim_db.async_simulate_mm_obj(meas_name, sim_dir / meas_name, dut, mm)).data + + res = self.postproc_tran(data, dsn_params) + res['sweep_params'] = {k: self.sim_swp_order for k in res} + res.update(sim_swp_params) + + save_sim_results(res, str(res_fpath)) + return res + + @staticmethod + def postproc_tran(data: Mapping[str, Any], dsn_params: Dict[str, Any]) -> Dict[str, Any]: + radius: int = int(dsn_params['radius']) + height: float = data['height'] + i_avg: float = data['i_avg'] + return dict( + width=data['width'], + height=height, + i_avg=i_avg, + fom=height / (np.sqrt(i_avg) * np.sqrt(radius)), + ) + + @staticmethod + def aggregate_results(res_list: List[Dict[str, Any]]) -> Dict[str, Any]: + ans = {} + for res in res_list: + for k, v in res.items(): + if k == 'sweep_params': + if k not in ans: + ans[k] = {} + ans[k].update(v) + elif k not in ans: + ans[k] = v + elif isinstance(v, np.ndarray): + assert np.all(ans[k] == v) + else: + assert ans[k] == v + return ans + + @classmethod + def get_dut_gen_specs(cls, is_lay: bool, base_gen_specs: Param, + gen_params: Mapping[str, Any]) -> Union[Param, Dict[str, Any]]: + base_gen_specs = base_gen_specs.to_yaml() + base_gen_specs['lay_mode'] = 'EXT' + base_gen_specs['gm_params']['seg_dict']['tail'] = int(gen_params['seg_tail']) + base_gen_specs['gm_params']['seg_dict']['gm'] = int(gen_params['seg_gm']) + base_gen_specs['ind_sh_params']['radius_x'] = int(gen_params['radius']) + base_gen_specs['ind_sh_params']['radius_y'] = int(gen_params['radius']) + return base_gen_specs + + @classmethod + def get_em_dut_gen_specs(cls, base_gen_specs: Param, + gen_params: Mapping[str, Any]) -> Union[Param, Dict[str, Any]]: + base_gen_specs = base_gen_specs.to_yaml() + base_gen_specs['lay_mode'] = 'EM' + base_gen_specs['gm_params']['seg_dict']['tail'] = int(gen_params['seg_tail']) + base_gen_specs['gm_params']['seg_dict']['gm'] = int(gen_params['seg_gm']) + base_gen_specs['ind_sh_params']['radius_x'] = int(gen_params['radius']) + base_gen_specs['ind_sh_params']['radius_y'] = int(gen_params['radius']) + return base_gen_specs diff --git a/src/bag3_analog/layout/drv_shunt_peak.py b/src/bag3_analog/layout/drv_shunt_peak.py new file mode 100644 index 0000000..fd8b96a --- /dev/null +++ b/src/bag3_analog/layout/drv_shunt_peak.py @@ -0,0 +1,196 @@ +from typing import Mapping, Any, Optional, Type, Union + +from bag.util.immutable import Param +from bag.design.module import Module +from bag.layout.template import TemplateDB, TemplateBase +from bag.layout.routing.base import TrackManager, WDictType, SpDictType + +from pybag.enum import RoundMode, MinLenMode, Orientation +from pybag.core import Transform, BBox + +from xbase.layout.mos.top import GenericWrapper +from xbase.layout.array.top import ArrayBaseWrapper + +from bag3_magnetics.layout.inductor.ind_diff_wrap import IndDiffWrap + +from .gm_stage import GmStageGR, GmStage +from .res_diff import ResDiff + +from ..schematic.drv_shunt_peak import bag3_analog__drv_shunt_peak, LayMode + + +class DrvShuntPeak(TemplateBase): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + TemplateBase.__init__(self, temp_db, params, **kwargs) + tr_widths: WDictType = self.params['tr_widths'] + tr_spaces: SpDictType = self.params['tr_spaces'] + self._tr_manager = TrackManager(self.grid, tr_widths, tr_spaces) + + @classmethod + def get_schematic_class(cls) -> Optional[Type[Module]]: + return bag3_analog__drv_shunt_peak + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + return dict( + tr_widths='Track width dictionary for TrackManager', + tr_spaces='Track spaces dictionary for TrackManager', + gm_params='Parameters for gm cells', + res_params='Parameters for differential resistors', + ind_sh_params='Parameters for shunt differential inductor', + ind_v_sp='Vertical spacing between resistor and inductor', + lay_mode='Layout mode, TOP by default.', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(lay_mode=LayMode.TOP, ind_v_sp=0) + + def draw_layout(self) -> None: + # make masters + gm_params: Mapping[str, Any] = self.params['gm_params'] + gm_cls = GmStageGR if self.has_guard_ring else GmStage + gm_master = self.new_template(GenericWrapper, params=dict(cls_name=gm_cls.get_qualified_name(), + params=gm_params, export_hidden=True)) + gm_bbox = gm_master.bound_box + + res_params: Mapping[str, Any] = self.params['res_params'] + res_master = self.new_template(ArrayBaseWrapper, params=dict(cls_name=ResDiff.get_qualified_name(), + params=res_params, export_hidden=True)) + res_bbox = res_master.bound_box + + ind_sh_params: Mapping[str, Any] = self.params['ind_sh_params'] + ind_sh_master: IndDiffWrap = self.new_template(IndDiffWrap, params=ind_sh_params) + ind_sh_bbox = ind_sh_master.actual_bbox + ind_layer: int = ind_sh_params['lay_id'] + + lay_mode: Union[str, LayMode] = self.params['lay_mode'] + if isinstance(lay_mode, str): + lay_mode = LayMode[lay_mode] + gen_gm = gen_res = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT + gen_ind = lay_mode is LayMode.TOP or lay_mode is LayMode.EM + + # --- Placement --- # + w_tot = max(gm_bbox.w, res_bbox.w, ind_sh_bbox.w) + + x_gm = (w_tot - gm_bbox.w) // 2 + y_gm = gm_bbox.h + gm = self.add_instance(gm_master, xform=Transform(dx=x_gm, dy=y_gm, mode=Orientation.MX), commit=gen_gm) + + x_res = (w_tot + res_bbox.w) // 2 + y_res = y_gm + res = self.add_instance(res_master, xform=Transform(dx=x_res, dy=y_res, mode=Orientation.MY), commit=gen_res) + + ind_v_sp: int = self.params['ind_v_sp'] + x_ind = (w_tot + ind_sh_bbox.w) // 2 + y_ind = y_res + res_bbox.h + ind_v_sp + ind = self.add_instance(ind_sh_master, xform=Transform(dx=x_ind, dy=y_ind, mode=Orientation.MY), commit=gen_ind) + + h_tot = ind.bound_box.yh + self.set_size_from_bound_box(ind_layer, BBox(0, 0, w_tot, h_tot), round_up=True) + + # --- Routing --- # + # gm cell + if gen_gm: + for pin in ('v_inp', 'v_inm', 'v_tail_g', 'v_tail'): + self.reexport(gm.get_port(pin)) + + self.reexport(gm.get_port('VSS'), connect=True) + if gm.has_port('VDD'): + # TODO: routing supply + self.reexport(gm.get_port('VDD'), connect=True) + + # res_diff + if gen_res: + for pin in ('VDD', 'VSS'): + if res.has_port(pin): + self.reexport(res.get_port(pin), connect=True) + + # routing from gm cell to res_diff + i_outp = gm.get_pin('i_outp') + i_outm = gm.get_pin('i_outm') + gm_top_layer = i_outp.layer_id + + p_in = res.get_pin('p_in') + p_out = res.get_pin('p_out') + m_in = res.get_pin('m_in') + m_out = res.get_pin('m_out') + + if gm_top_layer < p_in.layer_id: + raise NotImplementedError + elif gm_top_layer > p_in.layer_id: + _tidx0 = self.grid.coord_to_track(gm_top_layer, p_in.bound_box.ym, RoundMode.NEAREST) + _tidx1 = self.grid.coord_to_track(gm_top_layer, p_out.bound_box.ym, RoundMode.NEAREST) + if self._tr_manager.get_next_track(gm_top_layer, _tidx0, 'sig_hs', 'sig_hs', 2) > _tidx1: + # compute new _tidx0 and _tidx1 + _, _locs = self._tr_manager.place_wires(gm_top_layer, ['sig_hs', 'sig_hs', 'sig_hs'], + center_coord=(p_in.bound_box.ym + p_out.bound_box.ym) // 2) + _tidx0, _tidx1 = _locs[0], _locs[-1] + alternate_o = True + else: + alternate_o = False + _coord0 = self.grid.track_to_coord(gm_top_layer, _tidx0) + _coord1 = self.grid.track_to_coord(gm_top_layer, _tidx1) + p_0, p_1 = p_in.lower, p_in.upper + m_0, m_1 = m_in.lower, m_in.upper + p_in = self.connect_via_stack(self._tr_manager, p_in, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord0], alignment_o=1) + p_in = self.extend_wires(p_in, lower=p_0, upper=p_1)[0] + m_in = self.connect_via_stack(self._tr_manager, m_in, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord0], alignment_o=-1) + m_in = self.extend_wires(m_in, lower=m_0, upper=m_1)[0] + p_out = self.connect_via_stack(self._tr_manager, p_out, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord1], alternate_o=alternate_o, alignment_o=1) + p_out = self.extend_wires(p_out, lower=p_0, upper=p_1)[0] + m_out = self.connect_via_stack(self._tr_manager, m_out, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord1], alternate_o=alternate_o, alignment_o=-1) + m_out = self.extend_wires(m_out, lower=m_0, upper=m_1)[0] + + # now i_outp and p_in are on the same layer + _conn_layer = gm_top_layer + 1 + p_in = self.connect_via_stack(self._tr_manager, p_in, _conn_layer, 'sig_hs', + mlm_dict={_conn_layer: MinLenMode.LOWER}) + m_in = self.connect_via_stack(self._tr_manager, m_in, _conn_layer, 'sig_hs', + mlm_dict={_conn_layer: MinLenMode.LOWER}) + i_outp = self.connect_to_track_wires(i_outp, p_in) + i_outm = self.connect_to_track_wires(i_outm, m_in) + if gen_gm and gen_res: + self.add_pin('i_outp', i_outp) + self.add_pin('i_outm', i_outm) + + # routing from res_diff to inductors + _tidx = self.grid.coord_to_track(_conn_layer + 1, p_out.bound_box.ym, RoundMode.GREATER) + _coord = self.grid.track_to_coord(_conn_layer + 1, _tidx) + p_out = self.connect_via_stack(self._tr_manager, p_out, _conn_layer + 1, 'sig_hs', + coord_list_p_override=[_coord], mlm_dict={_conn_layer: MinLenMode.UPPER}) + m_out = self.connect_via_stack(self._tr_manager, m_out, _conn_layer + 1, 'sig_hs', + coord_list_p_override=[_coord], mlm_dict={_conn_layer: MinLenMode.UPPER}) + ind_p: BBox = ind.get_pin('P1') + ind_m: BBox = ind.get_pin('P3') + ind_lp = self.grid.tech_info.get_lay_purp_list(ind_layer)[0] + if _conn_layer + 1 == ind_layer: + self.add_rect(ind_lp, BBox(ind_p.xl, p_out.bound_box.yl, ind_p.xh, ind_p.yh)) + self.add_rect(ind_lp, BBox(ind_m.xl, m_out.bound_box.yl, ind_m.xh, ind_m.yh)) + else: + raise NotImplementedError + + # ind + if gen_res: + self.reexport(ind.get_port('P1'), net_name='ind_p') + self.reexport(ind.get_port('P3'), net_name='ind_m') + if gen_ind: + if lay_mode is LayMode.TOP: + for pin in ('P13_R', 'P2_R', 'P2'): + # TODO: routing supplies + self.reexport(ind.get_port(pin), net_name='VDD', connect=True) + else: + for pin in ('P13_R', 'P2_R', 'P2', 'P1', 'P3'): + self.reexport(ind.get_port(pin)) + + # get schematic parameters + self.sch_params = dict( + gm=gm_master.sch_params, + res=res_master.sch_params, + ind=ind_sh_master.sch_params, + lay_mode=lay_mode, + ) diff --git a/src/bag3_analog/layout/gm_stage.py b/src/bag3_analog/layout/gm_stage.py new file mode 100644 index 0000000..4cece91 --- /dev/null +++ b/src/bag3_analog/layout/gm_stage.py @@ -0,0 +1,353 @@ +"""This module contains layout generator for gm_stage.""" + +from typing import Any, Mapping, Type, Optional, Sequence + +from pybag.enum import MinLenMode, RoundMode + +from bag.util.immutable import Param +from bag.layout.template import TemplateDB +from bag.design.module import Module + +from xbase.layout.enum import MOSWireType, MOSPortType, SubPortMode +from xbase.layout.mos.base import MOSBasePlaceInfo, MOSBase +from xbase.layout.mos.guardring import GuardRing + +from ..schematic.gm_stage import bag3_analog__gm_stage + + +class GmStage(MOSBase): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + MOSBase.__init__(self, temp_db, params, **kwargs) + + @classmethod + def get_schematic_class(cls) -> Optional[Type[Module]]: + return bag3_analog__gm_stage + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + return dict( + pinfo='The MOSBasePlaceInfo object.', + seg_dict='Dictionary of transistor segments', + w='transistor width.', + ridx_tail='index for mos row with tail transistor', + ridx_gm='index for mos row with gm transistors', + export_tail='True to export tail node; False by default', + is_dum='True if the gm stage is used as dummy load; False by default', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(export_tail=False, w=0, ridx_tail=0, ridx_gm=1, is_dum=False) + + def draw_layout(self) -> None: + pinfo = MOSBasePlaceInfo.make_place_info(self.grid, self.params['pinfo']) + self.draw_base(pinfo) + + tile_tap = 0 + tile_logic = 1 + _pinfo = self.get_tile_pinfo(tile_idx=tile_logic) + + seg_dict: Mapping[str, int] = self.params['seg_dict'] + w: int = self.params['w'] + ridx_tail: int = self.params['ridx_tail'] + ridx_gm: int = self.params['ridx_gm'] + export_tail: bool = self.params['export_tail'] + is_dum: bool = self.params['is_dum'] + + # set number of columns + seg_gm = seg_dict['gm'] + seg_tail = seg_dict['tail'] + if seg_tail % 2: + raise ValueError(f'This generator requires seg_tail={seg_tail} to be even.') + if self.can_abut_mos: + seg_sep = 0 + else: + seg_sep = 4 + seg_tot = max(seg_tail, 2 * seg_gm + seg_sep) + seg_tot2 = seg_tot // 2 + seg_tail2 = seg_tail // 2 + seg_sep2 = seg_sep // 2 + + # --- Placement --- # + if seg_tail2 % 2 == 1: + sup_term, share_term = MOSPortType.S, MOSPortType.D + g_on_s = False + else: + sup_term, share_term = MOSPortType.D, MOSPortType.S + g_on_s = True + + # tail + tail_inst = self.add_mos(ridx_tail, seg_tot2 - seg_tail2, seg_tail, tile_idx=tile_logic, w=w, g_on_s=g_on_s) + _row_info = _pinfo.get_row_place_info(ridx_tail).row_info + w_tail, th_tail = _row_info.width, _row_info.threshold + + # gm cells + gm_left_inst = self.add_mos(ridx_gm, seg_tot2 - seg_sep2, seg_gm, tile_idx=tile_logic, w=w, flip_lr=True) + gm_right_inst = self.add_mos(ridx_gm, seg_tot2 + seg_sep2, seg_gm, tile_idx=tile_logic, w=w) + _row_info = _pinfo.get_row_place_info(ridx_gm).row_info + w_gm, th_gm = _row_info.width, _row_info.threshold + + # tap cells + tap_conn = self.add_substrate_contact(0, 0, tile_idx=tile_tap, seg=seg_tot, port_mode=SubPortMode.ODD) + + self.set_mos_size() + + # --- Routing --- # + tr_manager = self.tr_manager + hm_layer = self.conn_layer + 1 + vm_layer = hm_layer + 1 + xm_layer = vm_layer + 1 + ym_layer = xm_layer + 1 + xxm_layer = ym_layer + 1 + + # 1. source terminals of tail transistor go to supplies + tap_tid = self.get_track_id(0, MOSWireType.DS, 'sup', tile_idx=tile_tap) + if self.can_extend_ds_conn(g_side=True, threshold=th_tail): + tap_hm = self.connect_to_tracks([tail_inst[sup_term], tap_conn], tap_tid) + else: + raise NotImplementedError('Redo routing.') + tap_xxm = self.connect_via_stack(tr_manager, tap_hm, xxm_layer, 'sup', alternate_o=True) + self.add_pin('VSS', tap_xxm) + + # 2. source terminals of gm transistors connect to drain terminals of tail: connect on 2 hm_layer wires to + # improve connection + tail_tid0 = self.get_track_id(ridx_tail, MOSWireType.DS, 'sig_hs', tile_idx=tile_logic) + tail_tid1 = self.get_track_id(ridx_gm, MOSWireType.DS, 'sig_hs', wire_idx=-1, tile_idx=tile_logic) + tail1_vm = None + if self.can_extend_ds_conn(g_side=False, threshold=th_gm): + tail0 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid0, + wire_lower=tail_inst[share_term].lower) + tail1 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid1) + else: + tail0 = self.connect_to_tracks(tail_inst[share_term], tail_tid0, wire_lower=tail_inst[share_term].lower) + tail1 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s], tail_tid1) + # connect on vm_layer + tail1_vm = self.connect_via_stack(self.tr_manager, tail1, vm_layer, 'sig_hs', + mlm_dict={vm_layer: MinLenMode.LOWER}) + self.connect_to_track_wires(tail0, tail1_vm) + self.add_pin('v_tail', [tail0, tail1], hide=is_dum or not export_tail) + + # 3. gate terminals of tail transistor + tail_g_tid = self.get_track_id(ridx_tail, MOSWireType.G, 'sig_hs', tile_idx=tile_logic) + tail_g = self.connect_to_tracks(tail_inst.g, tail_g_tid) + tail_g_xxm = self.connect_via_stack(tr_manager, tail_g, xxm_layer, 'sig_hs', + mlm_dict={vm_layer: MinLenMode.LOWER, ym_layer: MinLenMode.LOWER}) + if is_dum: + self.connect_wires([tail_inst.g, tail_inst[sup_term]]) + else: + self.add_pin('v_tail_g', tail_g_xxm) + + # 4. get gate connections of gm transistors + gate_tid = self.get_track_id(ridx_gm, MOSWireType.G, 'sig_hs', tile_idx=tile_logic) + gate_left = self.connect_to_tracks(gm_left_inst.g, gate_tid) + gate_right = self.connect_to_tracks(gm_right_inst.g, gate_tid) + mlm_gate = {vm_layer: MinLenMode.UPPER, ym_layer: MinLenMode.UPPER} + _, ym_locs_sig = tr_manager.place_wires(ym_layer, ['sig', 'sig', 'sig'], center_coord=seg_tot2 * self.sd_pitch) + l_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig[0]) + r_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig[-1]) + gate_left_hm = self.add_wires(hm_layer, gate_tid.base_index, gate_left.lower, + min(l_coord, gate_left.upper), width=gate_tid.width) + gate_right_hm = self.add_wires(hm_layer, gate_tid.base_index, max(r_coord, gate_right.lower), gate_right.upper, + width=gate_tid.width) + gate_left_xxm = self.connect_via_stack(tr_manager, gate_left_hm, xxm_layer, 'sig', 0, -1, mlm_gate) + gate_right_xxm = self.connect_via_stack(tr_manager, gate_right_hm, xxm_layer, 'sig', 0, 1, mlm_gate) + self.add_pin('v_inp', gate_left_xxm) + self.add_pin('v_inm', gate_right_xxm) + + # 5. get drain connections of gm transistors + drain_tid = self.get_track_id(ridx_gm, MOSWireType.DS, 'sig_hs', wire_idx=0, tile_idx=tile_logic) + drain_left = self.connect_to_tracks(gm_left_inst.d, drain_tid) + drain_right = self.connect_to_tracks(gm_right_inst.d, drain_tid) + mlm_drain = {vm_layer: MinLenMode.LOWER, ym_layer: MinLenMode.LOWER} + _, ym_locs_sig_hs = self.tr_manager.place_wires(ym_layer, ['sig_hs', 'sig_hs', 'sig_hs'], + center_coord=seg_tot2 * self.sd_pitch) + l_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig_hs[0]) + r_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig_hs[-1]) + drain_left_hm = self.add_wires(hm_layer, drain_tid.base_index, drain_left.lower, + min(l_coord, drain_left.upper), width=drain_tid.width) + drain_right_hm = self.add_wires(hm_layer, drain_tid.base_index, max(r_coord, drain_right.lower), + drain_right.upper, width=drain_tid.width) + if self.can_extend_ds_conn(g_side=False, threshold=th_gm): + drain_left_xxm = self.connect_via_stack(tr_manager, drain_left_hm, xxm_layer, 'sig_hs', 0, -1, mlm_drain) + drain_right_xxm = self.connect_via_stack(tr_manager, drain_right_hm, xxm_layer, 'sig_hs', 0, 1, mlm_drain) + else: + # don't collide with vm_layer for tail connection + coords_l, coords_r = [], [] + for _widx in range((tail1_vm.track_id.num - 1) // 2): + _tidx0 = self.tr_manager.get_next_track(vm_layer, tail1_vm[_widx].track_id.base_index, + 'sig_hs', 'sig_hs', 1) + coords_l.append(self.grid.track_to_coord(vm_layer, _tidx0)) + _tidx1 = self.tr_manager.get_next_track(vm_layer, tail1_vm[-1 - _widx].track_id.base_index, + 'sig_hs', 'sig_hs', -1) + coords_r.insert(0, self.grid.track_to_coord(vm_layer, _tidx1)) + drain_left_xm = self.connect_via_stack(tr_manager, drain_left_hm, xm_layer, 'sig_hs', 0, -1, mlm_drain, + coord_list_o_override=coords_l) + drain_right_xm = self.connect_via_stack(tr_manager, drain_right_hm, xm_layer, 'sig_hs', 0, 1, mlm_drain, + coord_list_o_override=coords_r) + drain_left_xxm = self.connect_via_stack(tr_manager, drain_left_xm, xxm_layer, 'sig_hs', 0, -1, mlm_drain) + drain_right_xxm = self.connect_via_stack(tr_manager, drain_right_xm, xxm_layer, 'sig_hs', 0, 1, mlm_drain) + self.add_pin('i_outm', drain_left_xxm, hide=is_dum) + self.add_pin('i_outp', drain_right_xxm, hide=is_dum) + + # get schematic parameters + self.sch_params = dict( + lch=_pinfo.lch, + w_dict=dict(tail=w_tail, gm=w_gm), + th_dict=dict(tail=th_tail, gm=th_gm), + seg_dict=seg_dict, + export_tail=export_tail, + is_dum=is_dum, + ) + + +class GmStageGR(GuardRing): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + GuardRing.__init__(self, temp_db, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + ans = dict(**GmStage.get_params_info()) + ans.update( + pmos_gr='pmos guard ring tile name.', + nmos_gr='nmos guard ring tile name.', + edge_ncol='Number of columns on guard ring edge. Use 0 for default.', + ) + return ans + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + ans = dict(**GmStage.get_default_param_values()) + ans.update( + pmos_gr='pgr', + nmos_gr='ngr', + edge_ncol=0, + ) + return ans + + def get_layout_basename(self) -> str: + return self.__class__.__name__ + + def draw_layout(self) -> None: + params = self.params + pmos_gr: str = params['pmos_gr'] + nmos_gr: str = params['nmos_gr'] + edge_ncol: int = params['edge_ncol'] + + core_params = params.copy(remove=['pmos_gr', 'nmos_gr', 'edge_ncol']) + master = self.new_template(GmStage, params=core_params) + + sep_ncol_left = sep_ncol_right = master.gr_sub_sep_col + sep_ncol = (sep_ncol_left, sep_ncol_right) + + inst, sup_list = self.draw_guard_ring(master, pmos_gr, nmos_gr, sep_ncol, edge_ncol, export_pins=False) + + # --- Routing --- # + hm_layer = self.conn_layer + 1 + vm_layer = hm_layer + 1 + xm_layer = vm_layer + 1 + ym_layer = xm_layer + 1 + xxm_layer = ym_layer + 1 + yym_layer = xxm_layer + 1 + x3m_layer = yym_layer + 1 + + # guard ring supply connections + vdd_hm_list = [] + for (_, vdd_list) in sup_list: + if vdd_list: + vdd_hm_list.extend(vdd_list) + vdd_dict0, vdd_dict1 = {}, {} + mlm_dict0 = {vm_layer: MinLenMode.LOWER, ym_layer: MinLenMode.LOWER} + mlm_dict1 = {vm_layer: MinLenMode.UPPER, ym_layer: MinLenMode.UPPER} + vdd_xxm0 = self.connect_via_stack(self.tr_manager, vdd_hm_list[0], xxm_layer, 'guard', mlm_dict=mlm_dict0, + ret_warr_dict=vdd_dict0) + vdd_xxm1 = self.connect_via_stack(self.tr_manager, vdd_hm_list[-1], xxm_layer, 'guard', mlm_dict=mlm_dict1, + ret_warr_dict=vdd_dict1) + + for _layer in (vm_layer, ym_layer): + self.connect_wires([vdd_dict0[_layer][0], vdd_dict0[_layer][-1], + vdd_dict1[_layer][0], vdd_dict1[_layer][-1]]) + + # --- bring all signals to x3m_layer without colliding on yym_layer --- # + # get all yym_layer tracks so that alternate tracks can be used to go from xxm_layer to x3m_layer + tidx_l = self.grid.coord_to_track(yym_layer, vdd_xxm0.lower, RoundMode.GREATER_EQ) + tidx_r = self.grid.coord_to_track(yym_layer, vdd_xxm0.upper, RoundMode.LESS_EQ) + num_yym = self.tr_manager.get_num_wires_between(yym_layer, 'sig_hs', tidx_l, 'sig_hs', tidx_r, 'sig_hs') + 2 + if num_yym & 1 == 0: + num_yym -= 1 + yym_tidx_list = self.tr_manager.spread_wires(yym_layer, ['sig_hs'] * num_yym, tidx_l, tidx_r, + ('sig_hs', 'sig_hs')) + yym_coords = [self.grid.track_to_coord(yym_layer, _tidx) for _tidx in yym_tidx_list] + + # VDD on x3m_layer + vdd_x3m0 = self.connect_via_stack(self.tr_manager, vdd_xxm0, x3m_layer, 'guard', + mlm_dict={yym_layer: MinLenMode.LOWER}, coord_list_o_override=yym_coords[::2]) + vdd_x3m1 = self.connect_via_stack(self.tr_manager, vdd_xxm1, x3m_layer, 'guard', + mlm_dict={yym_layer: MinLenMode.UPPER}, coord_list_o_override=yym_coords[::2]) + self.add_pin('VDD', self.connect_wires([vdd_x3m0, vdd_x3m1])[0]) + + # x3m_layers between two VDD tracks + x3m_tidx_list = self.tr_manager.spread_wires(x3m_layer, ['sig_hs', 'sig_hs', 'sig_hs', 'sig_hs', 'sig_hs'], + vdd_x3m0.track_id.base_index, vdd_x3m1.track_id.base_index, + ('sig_hs', 'sig_hs')) + x3m_coords = [self.grid.track_to_coord(x3m_layer, _tidx) for _tidx in x3m_tidx_list] + + # VSS on x3m_layer + vss_x3m = self.connect_via_stack(self.tr_manager, inst.get_pin('VSS'), x3m_layer, 'sup', + coord_list_o_override=yym_coords[1::2], coord_list_p_override=[x3m_coords[1]]) + self.add_pin('VSS', vss_x3m) + + # left input and output on x3m_layer + v_inp = inst.get_pin('v_inp') + i_outm = inst.get_pin('i_outm') + _l0 = max(v_inp.lower, i_outm.lower) + _r0 = min(v_inp.upper, i_outm.upper) + _coords0 = get_sub_list(yym_coords, _l0, _r0) + + v_inp = self.connect_via_stack(self.tr_manager, v_inp, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.UPPER}, + coord_list_o_override=_coords0[1::2], coord_list_p_override=[x3m_coords[-2]]) + self.add_pin('v_inp', v_inp) + i_outm = self.connect_via_stack(self.tr_manager, i_outm, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.LOWER}, + coord_list_o_override=_coords0[::2], coord_list_p_override=[x3m_coords[-3]]) + self.add_pin('i_outm', i_outm) + + # right input and output on x3m_layer + v_inm = inst.get_pin('v_inm') + i_outp = inst.get_pin('i_outp') + _l1 = max(v_inm.lower, i_outp.lower) + _r1 = min(v_inm.upper, i_outp.upper) + _coords1 = get_sub_list(yym_coords, _l1, _r1) + + v_inm = self.connect_via_stack(self.tr_manager, v_inm, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.UPPER}, + coord_list_o_override=_coords1[-2::-2][::-1], + coord_list_p_override=[x3m_coords[-2]]) + self.add_pin('v_inm', v_inm) + i_outp = self.connect_via_stack(self.tr_manager, i_outp, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.LOWER}, + coord_list_o_override=_coords1[::-2][::-1], + coord_list_p_override=[x3m_coords[-3]]) + self.add_pin('i_outp', i_outp) + + # v_tail_g is DC and exported on xxm_layer + self.reexport(inst.get_port('v_tail_g')) + + # v_tail is exported for debugging + self.reexport(inst.get_port('v_tail')) + + # update schematic parameters + self.sch_params = dict( + **self.sch_params, + guard_ring=True, + ) + + +def get_sub_list(orig_list: Sequence[int], low: int, high: int) -> Sequence[int]: + new_list = [] + for ele in orig_list: + if ele >= low: + if ele > high: + break + new_list.append(ele) + return new_list diff --git a/src/bag3_analog/layout/res/ladder.py b/src/bag3_analog/layout/res/ladder.py index a532295..0528fc1 100644 --- a/src/bag3_analog/layout/res/ladder.py +++ b/src/bag3_analog/layout/res/ladder.py @@ -289,6 +289,11 @@ def _connect_ladder(self, nx_dum = self.params['nx_dum'] ny_dum = self.params['ny_dum'] + #TODO: Add support for clean no-dummy generation. For now these assertions + # are here to ensure clean ResLadder generation + + assert(nx_dum > 0 and ny_dum > 0, "ResLadder generation without dummies is not currently supported.") + nx_core = nx - 2 * nx_dum ny_core = ny - 2 * ny_dum diff --git a/src/bag3_analog/layout/res_diff.py b/src/bag3_analog/layout/res_diff.py new file mode 100644 index 0000000..fff1eb9 --- /dev/null +++ b/src/bag3_analog/layout/res_diff.py @@ -0,0 +1,104 @@ +"""This module defines differential resistors.""" + +from typing import Mapping, Any, Optional, Type, cast + +from bag.util.immutable import Param +from bag.design.module import Module +from bag.layout.template import TemplateDB +from bag.layout.routing.base import TrackManager, WireArray + +from xbase.layout.res.base import ResBasePlaceInfo, ResArrayBase + +from ..schematic.res_diff import bag3_analog__res_diff + + +class ResDiff(ResArrayBase): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + ResArrayBase.__init__(self, temp_db, params, **kwargs) + + @classmethod + def get_schematic_class(cls) -> Optional[Type[Module]]: + return bag3_analog__res_diff + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + return dict( + pinfo='The ResBasePlaceInfo object.', + nx_dum='Number of dummies on each side, X direction', + ny_dum='Number of dummies on each side, Y direction', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(nx_dum=0, ny_dum=0) + + def draw_layout(self) -> None: + pinfo = cast(ResBasePlaceInfo, ResBasePlaceInfo.make_place_info(self.grid, self.params['pinfo'])) + self.draw_base(pinfo) + + # Get hm_layer and vm_layer WireArrays + warrs, bulk_warrs = self.connect_hm_vm() + + # Connect all dummies + self.connect_dummies(warrs, bulk_warrs) + + unit_params = dict( + w=pinfo.w_res, + l=pinfo.l_res, + intent=pinfo.res_type, + ) + nx, ny = pinfo.nx, pinfo.ny + nx_dum: int = self.params['nx_dum'] + ny_dum: int = self.params['ny_dum'] + npar_tot = nx - 2 * nx_dum + nser = ny - 2 * ny_dum + assert npar_tot & 1 == 0, f'nx - 2 * nx_dum = {npar_tot} should be even.' + num_dum = nx * ny - npar_tot * nser + + # --- Routing of unit resistors --- # + hm_layer = self.conn_layer + 1 + vm_layer = hm_layer + 1 + xm_layer = vm_layer + 1 + ym_layer = xm_layer + 1 + xxm_layer = ym_layer + 1 + + # make 2 resistors out of all the resistor units + rp_bot, rp_top = self.connect_units(warrs, nx_dum, nx // 2, ny_dum, ny - ny_dum) + rm_bot, rm_top = self.connect_units(warrs, nx // 2, nx - nx_dum, ny_dum, ny - ny_dum) + + # Supply connections on xxm_layer + sub_type = cast(ResBasePlaceInfo, self.place_info).res_config['sub_type_default'] + sup_top0 = self.connect_via_stack(self.tr_manager, bulk_warrs[vm_layer][0], xxm_layer, 'sup') + sup_top1 = self.connect_via_stack(self.tr_manager, bulk_warrs[vm_layer][1], xxm_layer, 'sup') + sup_name = 'VDD' if sub_type == 'ntap' else 'VSS' + self.add_pin(sup_name, self.connect_wires([sup_top0, sup_top1])[0]) + + # connect XRP and XRM from vm_layer to xxm_layer + for _bot, _top, _suf in [(rp_bot, rp_top, 'p'), (rm_bot, rm_top, 'm')]: + _in = self.connect_stack(self.tr_manager, _bot, xxm_layer, 'sig', xm_layer) + _out = self.connect_stack(self.tr_manager, _top, xxm_layer, 'sig', xm_layer) + self.add_pin(f'{_suf}_in', _in) + self.add_pin(f'{_suf}_out', _out) + + self.sch_params = dict( + load_params=dict( + unit_params=unit_params, + nser=nser, + npar=npar_tot // 2, + ), + dum_params=dict( + unit_params=unit_params, + nser=1, + npar=num_dum, + ), + sub_type=sub_type, + ) + + def connect_stack(self, tr_manager: TrackManager, warr: WireArray, top_layer: int, w_type: str = 'sig', + mid_layer: int = -1): + # this is different from connect_via_stack() as it does not connect the intermediate wires to reduce cap + top_warr = [] + for _warr in warr.warr_iter(): + _mid = self.connect_via_stack(tr_manager, _warr, mid_layer, w_type) + top_warr.append(self.connect_via_stack(tr_manager, _mid, top_layer, w_type)) + return self.connect_wires(top_warr)[0] diff --git a/src/bag3_analog/measurement/drv_shunt_peak.py b/src/bag3_analog/measurement/drv_shunt_peak.py new file mode 100644 index 0000000..895fcf6 --- /dev/null +++ b/src/bag3_analog/measurement/drv_shunt_peak.py @@ -0,0 +1,287 @@ +from __future__ import annotations + +from typing import Any, Mapping, Optional, Union, Sequence +from pathlib import Path +from shutil import copy +import matplotlib.pyplot as plt +import numpy as np + +from bag.simulation.cache import SimulationDB, DesignInstance, SimResults +from bag.simulation.measure import MeasurementManager +from bag.simulation.data import SimData +from bag.concurrent.util import GatherHelper +from bag.math import float_to_si_string + +from bag3_testbenches.measurement.ac.base import ACTB +from bag3_testbenches.measurement.tran.digital import DigitalTranTB +from bag3_testbenches.measurement.tran.eye import EyeAnalysis, EyeResults +from bag3_testbenches.measurement.digital.util import setup_digital_tran + + +class DrvShuntPeakACMeas(MeasurementManager): + async def async_measure_performance(self, name: str, sim_dir: Path, sim_db: SimulationDB, + dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]] = None) -> Mapping[str, Any]: + helper = GatherHelper() + sim_envs: Sequence[str] = self.specs['sim_envs'] + sweep_cases: Sequence[Mapping[str, Any]] = self.specs['sweep_cases'] + for sim_env in sim_envs: + for swidx, sweep_case in enumerate(sweep_cases): + helper.append(self.async_meas_pvt_case(name, sim_dir / sim_env / f'{swidx}', sim_db, dut, harnesses, + sim_env, sweep_case)) + + meas_results = await helper.gather_err() + results = {} + idx = 0 + for sim_env in sim_envs: + results[sim_env] = {} + for swidx, sweep_case in enumerate(sweep_cases): + results[sim_env][swidx] = {'data': meas_results[idx], 'sweep_case': sweep_case} + idx += 1 + + self.plot_results(results) + return results + + async def async_meas_pvt_case(self, name: str, sim_dir: Path, sim_db: SimulationDB, dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]], pvt: str, + sweep_case: Mapping[str, Any]) -> SimData: + # outputs to be saved + save_outputs = ['i_outp', 'i_outm', 'v_inp', 'v_inm', 'v_tail_g', 'v_tail', 'ind_p', 'ind_m'] + + # create loads + load_list = [dict(pin='i_outp', type='cap', value='c_load'), + dict(pin='i_outp', nin='VDD', type='res', value='r_term'), + dict(pin='i_outm', type='cap', value='c_load'), + dict(pin='i_outm', nin='VDD', type='res', value='r_term')] + + # inductors + ind_specs: Optional[Mapping[str, Any]] = self.specs.get('ind_specs') + if ind_specs: + ideal: bool = ind_specs['ideal'] + if ideal: + load_list.extend([dict(pin='ind_p', nin='VDD', type='ind', value='l_shunt'), + dict(pin='ind_m', nin='VDD', type='ind', value='l_shunt')]) + else: + sp_file_specs: Mapping[str, Any] = ind_specs['sp_file_specs'] + sim_dir.mkdir(parents=True, exist_ok=True) + for key, _specs in sp_file_specs.items(): + file_name: Path = Path(_specs['file_name']) + _num = file_name.suffix[2:-1] + ind_sp = f'{key}.s{_num}p' + copy(Path(file_name), sim_dir / ind_sp) + conns: Sequence[Mapping[str, str]] = _specs['conns'] + for _idx, _conns in enumerate(conns): + load_list.append(dict(conns=_conns, type=f'n{_num}port', value=ind_sp, + name=f'NPORT_{key}_{_idx}')) + + # create sources + load_list.extend([dict(pin='v_tail_g', type='vdc', value='v_tail_g'), + dict(pin='v_inp', type='vdc', value={'vdc': 'v_incm', 'acm': 0.5}), + dict(pin='v_inm', type='vdc', value={'vdc': 'v_incm', 'acm': -0.5})]) + + # setup harness + if harnesses: + harnesses_list: Sequence[Mapping[str, Any]] = self.specs['harnesses_list'] + else: + harnesses_list = [] + + tb_params = dict( + load_list=load_list, + harnesses_list=harnesses_list, + sim_envs=[pvt], + ac_options={'oppoint': 'logfile'}, + save_outputs=save_outputs, + ) + tbm_specs, tb_params = setup_digital_tran(self.specs, dut, **tb_params) + tbm = self.make_tbm(ACTB, tbm_specs) + for key, val in sweep_case.items(): + tbm.sim_params[key] = val + sim_results = await sim_db.async_simulate_tbm_obj(f'{name}_{pvt}_{get_label(sweep_case)}', sim_dir, dut, tbm, + tb_params, harnesses=harnesses) + return sim_results.data + + @staticmethod + def plot_results(results: Mapping[str, Any]) -> None: + fig, ax_list = plt.subplots(1, len(results.keys())) + if not isinstance(ax_list, np.ndarray): + ax_list = np.array([ax_list]) + + aidx = 0 + for sim_env, sweeps in results.items(): + ax = ax_list[aidx] + for swidx, ans in results[sim_env].items(): + ac_data = ans['data'] + freq = ac_data['freq'] + out_d = ac_data['i_outp'][0] - ac_data['i_outm'][0] + sweep_case: Mapping[str, Any] = ans['sweep_case'] + ax.semilogx(freq, 20 * np.log10(np.abs(out_d)), label=get_label(sweep_case)) + ax.legend() + ax.grid() + ax.set_xlabel('Frequency (Hz)') + ax.set_ylabel('AC gain (dB)') + ax.set_title(sim_env) + aidx += 1 + + plt.tight_layout() + plt.show() + + +def get_label(sweep_case: Optional[Mapping[str, Any]]) -> str: + if sweep_case is None: + return '' + _label_list = [f'{key}_{float_to_si_string(val)}' for key, val in sweep_case.items()] + return '_'.join(_label_list) + + +class DrvShuntPeakTranMeas(MeasurementManager): + async def async_measure_performance(self, name: str, sim_dir: Path, sim_db: SimulationDB, + dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]] = None) -> Mapping[str, Any]: + helper = GatherHelper() + sim_envs: Sequence[str] = self.specs['sim_envs'] + v_incm_swp: Union[np.ndarray, Sequence[float]] = self.specs['v_incm_swp'] + if isinstance(v_incm_swp, Sequence): + v_incm_swp = np.array(v_incm_swp) + v_tail_g_swp: Union[np.ndarray, Sequence[float]] = self.specs['v_tail_g_swp'] + if isinstance(v_tail_g_swp, Sequence): + v_tail_g_swp = np.array(v_tail_g_swp) + for sim_env in sim_envs: + for v_incm in v_incm_swp: + for v_tail_g in v_tail_g_swp: + _dir = f'v_incm_{float_to_si_string(v_incm)}_v_tail_g_{float_to_si_string(v_tail_g)}' + helper.append(self.async_meas_pvt_case(name, sim_dir / sim_env / _dir, sim_db, dut, harnesses, + sim_env, v_incm, v_tail_g)) + + meas_results = await helper.gather_err() + + # arrange meas_results in "results" for Designer and "plot_results" for plotting + results = {'sim_envs': np.array(sim_envs), 'v_incm': v_incm_swp, 'v_tail_g': v_tail_g_swp} + plot_results = {'sim_envs': np.array(sim_envs), 'v_incm': v_incm_swp, 'v_tail_g': v_tail_g_swp} + len_sim_envs = len(sim_envs) + len_v_incm = len(v_incm_swp) + len_v_tail_g = len(v_tail_g_swp) + results.update({'width': np.empty((len_sim_envs, len_v_incm, len_v_tail_g), dtype=float), + 'height': np.empty((len_sim_envs, len_v_incm, len_v_tail_g), dtype=float), + 'i_avg': np.empty((len_sim_envs, len_v_incm, len_v_tail_g), dtype=float)}) + plot_results['eye'] = [[] for _ in sim_envs] + idx = 0 + for jdx, _ in enumerate(sim_envs): + for kdx, _ in enumerate(v_incm_swp): + for ldx, _ in enumerate(v_tail_g_swp): + ans = meas_results[idx] + eye_res: EyeResults = ans['eye'] + results['width'][jdx, kdx, ldx] = eye_res.width + results['height'][jdx, kdx, ldx] = eye_res.height + results['i_avg'][jdx, kdx, ldx] = ans['i_avg'] + plot_results['eye'][jdx].append(eye_res) + idx += 1 + + plot_eye: bool = self.specs.get('plot_eye', False) + if plot_eye: + self.plot_results(plot_results) + return results + + async def async_meas_pvt_case(self, name: str, sim_dir: Path, sim_db: SimulationDB, dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]], pvt: str, v_incm: float, + v_tail_g: float) -> Mapping[str, Any]: + # outputs to be saved + save_outputs = ['i_outp', 'i_outm', 'v_inp', 'v_inm', 'v_tail_g', 'v_tail', 'ind_p', 'ind_m', 'VDC_VDD:p'] + + # create loads + load_list = [dict(pin='i_outp', type='cap', value='c_load'), + dict(pin='i_outp', nin='VDD', type='res', value='r_term'), + dict(pin='i_outm', type='cap', value='c_load'), + dict(pin='i_outm', nin='VDD', type='res', value='r_term')] + + # inductors + ind_specs: Optional[Mapping[str, Any]] = self.specs.get('ind_specs') + if ind_specs: + ideal: bool = ind_specs['ideal'] + if ideal: + load_list.extend([dict(pin='ind_p', nin='VDD', type='ind', value='l_shunt'), + dict(pin='ind_m', nin='VDD', type='ind', value='l_shunt')]) + else: + sp_file_specs: Mapping[str, Any] = ind_specs['sp_file_specs'] + sim_dir.mkdir(parents=True, exist_ok=True) + for key, _specs in sp_file_specs.items(): + file_name: Path = Path(_specs['file_name']) + _num = file_name.suffix[2:-1] + ind_sp = f'{key}.s{_num}p' + copy(Path(file_name), sim_dir / ind_sp) + conns: Sequence[Mapping[str, str]] = _specs['conns'] + for _idx, _conns in enumerate(conns): + load_list.append(dict(conns=_conns, type=f'n{_num}port', value=ind_sp, + name=f'NPORT_{key}_{_idx}')) + + # create sources + load_list.extend([dict(pin='v_tail_g', type='vdc', value='v_tail_g'), + dict(conns={'vout': 'prbs_data'}, lib='ahdlLib', type='rand_bit_stream', + value={'tperiod': 't_per', 'vlogic_high': 'v_hi', 'vlogic_low': 'v_lo', + 'tdel': 't_delay', 'trise': 't_rf', 'tfall': 't_rf', 'seed': 101}), + dict(conns={'d': 'prbs_data', 'p': 'v_inp', 'n': 'v_inm', 'c': 'v_incm'}, type='ideal_balun', + value={}), + dict(pin='v_incm', type='vdc', value='v_incm')]) + + # setup harness + if harnesses: + harnesses_list: Sequence[Mapping[str, Any]] = self.specs['harnesses_list'] + else: + harnesses_list = [] + + tb_params = dict( + load_list=load_list, + harnesses_list=harnesses_list, + sim_envs=[pvt], + tran_options={'errpreset': 'conservative', 'noisefmax': 'fmax_noise'}, + save_outputs=save_outputs, + ) + tbm_specs, tb_params = setup_digital_tran(self.specs, dut, **tb_params) + tbm = self.make_tbm(DigitalTranTB, tbm_specs) + tbm.sim_params['v_incm'] = v_incm + tbm.sim_params['v_tail_g'] = v_tail_g + sim_results = await sim_db.async_simulate_tbm_obj(name, sim_dir, dut, tbm, tb_params, harnesses=harnesses) + return self.process_results(sim_results) + + @staticmethod + def process_results(sim_results: SimResults) -> Mapping[str, Any]: + sim_data = sim_results.data + time = sim_data['time'] + + # compute average current consumption + i_vdd = - sim_data['VDC_VDD:p'][0] + i_avg = np.trapz(i_vdd, time) / time[-1] + + # analyze eye + out_d = sim_data['i_outp'][0] - sim_data['i_outm'][0] + tbm = sim_results.tbm + t_per = tbm.sim_params['t_per'] + t_delay = tbm.sim_params['t_delay'] + eye_ana = EyeAnalysis(t_per, t_delay) + + return dict( + eye=eye_ana.analyze_eye(time, out_d), + i_avg=i_avg, + ) + + @staticmethod + def plot_results(results: Mapping[str, Any]) -> None: + sim_envs: Sequence[str] = results['sim_envs'] + v_incm_swp: np.ndarray = results['v_incm'] + v_tail_g_swp: np.ndarray = results['v_tail_g'] + fig, ax_list = plt.subplots(len(sim_envs), len(v_incm_swp) * len(v_tail_g_swp)) + if not isinstance(ax_list, np.ndarray): + ax_list = np.array([ax_list]).reshape((1, 1)) + if len(v_incm_swp) * len(v_tail_g_swp) == 1: + ax_list = ax_list.reshape(len(sim_envs), 1) + + for jdx, sim_env in enumerate(sim_envs): + for kdx, v_incm in enumerate(v_incm_swp): + for ldx, v_tail_g in enumerate(v_tail_g_swp): + eidx = kdx * len(v_tail_g_swp) + ldx + ax = ax_list[jdx, eidx] + eye_results: EyeResults = results['eye'][jdx][eidx] + eye_results.plot(ax) + ax.set_title(f'{sim_env}; v_incm={v_incm} V; v_tail_g={v_tail_g} V') + + plt.tight_layout() + plt.show() diff --git a/src/bag3_analog/schematic/drv_shunt_peak.py b/src/bag3_analog/schematic/drv_shunt_peak.py new file mode 100644 index 0000000..59c698d --- /dev/null +++ b/src/bag3_analog/schematic/drv_shunt_peak.py @@ -0,0 +1,138 @@ +# BSD 3-Clause License +# +# Copyright (c) 2018, Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# -*- coding: utf-8 -*- + +from typing import Mapping, Any, Union + +import pkg_resources +from pathlib import Path +from enum import IntEnum + +from bag.design.module import Module +from bag.design.database import ModuleDB +from bag.util.immutable import Param + +from pybag.enum import TermType + + +class LayMode(IntEnum): + TOP = 0 # for top level DRC and LVS + EXT = 1 # for extraction + EM = 2 # for em simulation + + +# noinspection PyPep8Naming +class bag3_analog__drv_shunt_peak(Module): + """Module for library bag3_analog cell drv_shunt_peak. + + Fill in high level description here. + """ + + yaml_file = pkg_resources.resource_filename(__name__, + str(Path('netlist_info', + 'drv_shunt_peak.yaml'))) + + def __init__(self, database: ModuleDB, params: Param, **kwargs: Any) -> None: + Module.__init__(self, self.yaml_file, database, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + """Returns a dictionary from parameter names to descriptions. + + Returns + ------- + param_info : Optional[Mapping[str, str]] + dictionary from parameter names to descriptions. + """ + return dict( + gm='Parameters for gm cells', + res='Parameters for differential resistors', + ind='Parameters for shunt differential inductor', + lay_mode='Layout mode, TOP by default.', + ) + + def design(self, gm: Mapping[str, Any], res: Mapping[str, Any], ind: Mapping[str, Any], + lay_mode: Union[LayMode, str]) -> None: + """To be overridden by subclasses to design this module. + + This method should fill in values for all parameters in + self.parameters. To design instances of this module, you can + call their design() method or any other ways you coded. + + To modify schematic structure, call: + + rename_pin() + delete_instance() + replace_instance_master() + reconnect_instance_terminal() + restore_instance() + array_instance() + """ + remove_pins = [] + + # gm cell + gen_gm = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT + if gen_gm: + self.instances['XGM'].design(**gm) + else: + self.remove_instance('XGM') + remove_pins.extend(['v_inp', 'v_inm', 'v_tail_g', 'v_tail', 'i_outp', 'i_outm', 'VSS']) + + # resistors + gen_res = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT + if gen_res: + self.instances['XRES'].design(**res) + sub_type: str = res['sub_type'] + if sub_type == 'ptap': + self.reconnect_instance_terminal('XRES', 'VSS', 'VSS') + else: + self.remove_instance('XRES') + remove_pins.extend(['VDD']) + + # shunt inductors + gen_ind = lay_mode is LayMode.TOP or lay_mode is LayMode.EM + if gen_ind: + self.instances['XIND'].design(**ind) + if lay_mode is LayMode.TOP: + self.reconnect_instance_terminal('XIND', 'P2_R', 'VDD') + else: + # lay_mode is LayMode.EM + self.reconnect_instance('XIND', [('P1', 'P1'), ('P3', 'P3'), ('P2', 'P2'), + ('P13_R', 'P13_R'), ('P2_R', 'P2_R')]) + self.rename_pin('ind_p', 'P1') + self.rename_pin('ind_m', 'P3') + for pin in ('P2', 'P13_R', 'P2_R'): + self.add_pin(pin, TermType.inout) + else: + self.remove_instance('XIND') + + for pin in remove_pins: + self.remove_pin(pin) diff --git a/src/bag3_analog/schematic/gm_stage.py b/src/bag3_analog/schematic/gm_stage.py new file mode 100644 index 0000000..b5066cc --- /dev/null +++ b/src/bag3_analog/schematic/gm_stage.py @@ -0,0 +1,109 @@ +# BSD 3-Clause License +# +# Copyright (c) 2018, Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# -*- coding: utf-8 -*- + +from typing import Mapping, Any + +import pkg_resources +from pathlib import Path + +from bag.design.module import Module +from bag.design.database import ModuleDB +from bag.util.immutable import Param + + +# noinspection PyPep8Naming +class bag3_analog__gm_stage(Module): + """Module for library bag3_analog cell gm_stage. + + Fill in high level description here. + """ + + yaml_file = pkg_resources.resource_filename(__name__, + str(Path('netlist_info', + 'gm_stage.yaml'))) + + def __init__(self, database: ModuleDB, params: Param, **kwargs: Any) -> None: + Module.__init__(self, self.yaml_file, database, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + """Returns a dictionary from parameter names to descriptions. + + Returns + ------- + param_info : Optional[Mapping[str, str]] + dictionary from parameter names to descriptions. + """ + return dict( + lch='Channel length, in resolution units', + w_dict='Dictionary of transistor widths, in resolution units', + th_dict='Dictionary of transistor thresholds', + seg_dict='Dictionary of transistor segments', + export_tail='True to export tail node; False by default', + is_dum='True if the gm stage is used as dummy load; False by default', + guard_ring='True if gm_stage is in guard ring; False by default', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(export_tail=False, is_dum=False, guard_ring=False) + + def design(self, lch: int, w_dict: Mapping[str, int], th_dict: Mapping[str, str], seg_dict: Mapping[str, int], + export_tail: bool, is_dum: bool, guard_ring: bool) -> None: + """To be overridden by subclasses to design this module. + + This method should fill in values for all parameters in + self.parameters. To design instances of this module, you can + call their design() method or any other ways you coded. + + To modify schematic structure, call: + + rename_pin() + delete_instance() + replace_instance_master() + reconnect_instance_terminal() + restore_instance() + array_instance() + """ + for name, key in [('XTAIL', 'tail'), ('XP', 'gm'), ('XM', 'gm')]: + self.design_transistor(name, w_dict[key], lch, seg_dict[key], th_dict[key]) + + if is_dum or not export_tail: + self.remove_pin('v_tail') + + if is_dum: + for pin in ('v_tail_g', 'v_outp', 'v_outm'): + self.remove_pin(pin) + self.reconnect_instance_terminal('XTAIL', 'G', 'VSS') + + if not guard_ring: + self.remove_pin('VDD') diff --git a/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml new file mode 100644 index 0000000..9fb365b --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml @@ -0,0 +1,503 @@ +lib_name: bag3_analog +cell_name: drv_shunt_peak +view_name: symbol +bbox: + - -4 + - -4 + - 344 + - 284 +terminals: + VDD: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 276 + - 184 + - 284 + stype: 1 + ttype: 2 + VSS: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - -4 + - 184 + - 4 + stype: 2 + ttype: 2 + i_outm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 176 + - 344 + - 184 + stype: 0 + ttype: 1 + i_outp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 196 + - 344 + - 204 + stype: 0 + ttype: 1 + ind_m: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 116 + - 344 + - 124 + stype: 0 + ttype: 2 + ind_p: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 136 + - 344 + - 144 + stype: 0 + ttype: 2 + v_inm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 176 + - 4 + - 184 + stype: 0 + ttype: 0 + v_inp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 196 + - 4 + - 204 + stype: 0 + ttype: 0 + v_tail: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 76 + - 344 + - 84 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 76 + - 4 + - 84 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 80 + - + - 40 + - 80 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 90 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 180 + - + - 40 + - 180 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 210 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 200 + - + - 40 + - 200 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 170 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 140 + - + - 300 + - 140 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 110 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_m + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 120 + - + - 300 + - 120 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 150 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_p + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 80 + - + - 300 + - 80 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 90 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 180 + - + - 300 + - 180 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 210 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 200 + - + - 300 + - 200 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 170 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 280 + - + - 180 + - 240 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 170 + - 274 + alignment: 1 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 0 + - + - 180 + - 40 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 170 + - 6 + alignment: 7 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 0 + - layer: 236 + purpose: 4294967295 + net: "" + bbox: + - 0 + - 0 + - 340 + - 280 + - + - 8 + - layer: 236 + purpose: 237 + net: "" + origin: + - 200 + - 250 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@instanceName]" + evaluator: cdsNLPEvalText + - + - 8 + - layer: 231 + purpose: 237 + net: "" + origin: + - 105 + - 225 + alignment: 4 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@partName]" + evaluator: cdsNLPEvalText + - + - 0 + - layer: 231 + purpose: 4294967295 + net: "" + bbox: + - 40 + - 40 + - 300 + - 240 +instances: + {} +props: + interfaceLastChanged: + - 4 + - time_val: 1676499642 + partName: + - 3 + - drv_shunt_peak + pin#: + - 0 + - 10 + portOrder: + - 5 + - name: ILList + bin_val: ("i_outm" "i_outp" "v_tail" "VDD" "VSS" "ind_m" "ind_p" "v_inm" "v_inp" "v_tail_g") + vendorName: + - 3 + - "" +app_defs: + _dbLastSavedCounter: + - 0 + - 260 + _dbvCvTimeStamp: + - 0 + - 260 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml new file mode 100644 index 0000000..da0c482 --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml @@ -0,0 +1,1029 @@ +lib_name: bag3_analog +cell_name: drv_shunt_peak +view_name: schematic +bbox: + - -769 + - -241 + - 268 + - 450 +terminals: + VDD: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -620 + - 260 + - R0 + bbox: + - -681 + - 234 + - -610 + - 270 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -645 + - 260 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + VSS: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -620 + - 50 + - R0 + bbox: + - -681 + - 24 + - -610 + - 60 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -645 + - 50 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 2 + ttype: 2 + i_outm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -570 + - 160 + - R0 + bbox: + - -570 + - 134 + - -513 + - 170 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -545 + - 160 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + i_outp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -570 + - 190 + - R0 + bbox: + - -570 + - 164 + - -513 + - 200 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -545 + - 190 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + ind_m: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -560 + - -40 + - R0 + bbox: + - -621 + - -66 + - -550 + - -30 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -585 + - -40 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + ind_p: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -560 + - -10 + - R0 + bbox: + - -621 + - -36 + - -550 + - 0 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -585 + - -10 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + v_inm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -680 + - 160 + - R0 + bbox: + - -737 + - 134 + - -680 + - 170 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -710 + - 160 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_inp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -680 + - 190 + - R0 + bbox: + - -737 + - 164 + - -680 + - 200 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -710 + - 190 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_tail: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -570 + - 120 + - R0 + bbox: + - -570 + - 94 + - -513 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -545 + - 120 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -680 + - 120 + - R0 + bbox: + - -737 + - 94 + - -680 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -710 + - 120 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 0 + - 140 + - + - 0 + - 180 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -7 + - 176 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_m + points: + - + - -40 + - 140 + - + - -40 + - 180 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_m + origin: + - -47 + - 176 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_m + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_p + points: + - + - -60 + - 140 + - + - -60 + - 180 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_p + origin: + - -67 + - 176 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_p + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 0 + - 410 + - + - 0 + - 450 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -7 + - 414 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - -40 + - 410 + - + - -40 + - 450 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -47 + - 414 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - -60 + - 410 + - + - -60 + - 450 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -67 + - 414 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outp + points: + - + - 10 + - -10 + - + - 50 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outp + origin: + - 46 + - -3 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_m + points: + - + - 130 + - -230 + - + - 130 + - -190 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_m + origin: + - 123 + - -194 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_m + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 210 + - -10 + - + - 250 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 214 + - -3 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_p + points: + - + - 130 + - 150 + - + - 130 + - 190 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_p + origin: + - 123 + - 154 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_p + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outm + points: + - + - 10 + - -30 + - + - 50 + - -30 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outm + origin: + - 46 + - -23 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outp + points: + - + - -90 + - -40 + - + - -50 + - -40 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outp + origin: + - -86 + - -33 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - -190 + - -180 + - + - -190 + - -140 + - + - 7 + - layer: 228 + purpose: 237 + net: VSS + origin: + - -197 + - -144 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - -190 + - 100 + - + - -190 + - 140 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -197 + - 104 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outm + points: + - + - -90 + - 0 + - + - -50 + - 0 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outm + origin: + - -86 + - 7 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - -90 + - -20 + - + - -50 + - -20 + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail + origin: + - -86 + - -13 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inm + points: + - + - -310 + - -60 + - + - -270 + - -60 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inm + origin: + - -274 + - -53 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inp + points: + - + - -310 + - 20 + - + - -270 + - 20 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inp + origin: + - -274 + - 27 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail_g + points: + - + - -310 + - -20 + - + - -270 + - -20 + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail_g + origin: + - -274 + - -13 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g +instances: + XGM: + lib_name: bag3_analog + cell_name: gm_stage + view_name: symbol + xform: + - -270 + - -140 + - R0 + bbox: + - -283 + - -144 + - -42 + - 104 + connections: + VDD: VDD + VSS: VSS + i_outm: i_outm + i_outp: i_outp + v_inm: v_inm + v_inp: v_inp + v_tail: v_tail + v_tail_g: v_tail_g + params: + {} + is_primitive: false + XIND: + lib_name: bag3_magnetics + cell_name: ind_diff_wrap + view_name: symbol + xform: + - -100 + - 180 + - R0 + bbox: + - -100 + - 176 + - 68 + - 414 + connections: + P1: ind_p + P13_R: VDD + P2: VDD + P24_R: VDD + P3: ind_m + P4: VDD + params: + {} + is_primitive: false + XRES: + lib_name: bag3_analog + cell_name: res_diff + view_name: symbol + xform: + - 50 + - -190 + - R0 + bbox: + - 12 + - -194 + - 268 + - 154 + connections: + VDD: VDD + m_in: i_outm + m_out: ind_m + p_in: i_outp + p_out: ind_p + params: + {} + is_primitive: false +props: + connectivityLastUpdated: + - 0 + - 609 + lastSchematicExtraction: + - 4 + - time_val: 1676499794 + pin#: + - 0 + - 10 + schGeometryLastUpdated: + - 0 + - 609 + schGeometryVersion: + - 3 + - sch.ds.gm.1.4 +app_defs: + _dbLastSavedCounter: + - 0 + - 609 + _dbvCvTimeStamp: + - 0 + - 609 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml b/src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml new file mode 100644 index 0000000..e4a2b8a --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml @@ -0,0 +1,433 @@ +lib_name: bag3_analog +cell_name: gm_stage +view_name: symbol +bbox: + - -13 + - -4 + - 228 + - 244 +terminals: + VDD: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - 236 + - 84 + - 244 + stype: 1 + ttype: 2 + VSS: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - -4 + - 84 + - 4 + stype: 2 + ttype: 2 + i_outm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 136 + - 184 + - 144 + stype: 0 + ttype: 1 + i_outp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 96 + - 184 + - 104 + stype: 0 + ttype: 1 + v_inm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 76 + - 4 + - 84 + stype: 0 + ttype: 0 + v_inp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 156 + - 4 + - 164 + stype: 0 + ttype: 0 + v_tail: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 116 + - 184 + - 124 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 116 + - 4 + - 124 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 240 + - + - 80 + - 220 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 90 + - 234 + alignment: 1 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 0 + - layer: 236 + purpose: 4294967295 + net: "" + bbox: + - 0 + - 0 + - 180 + - 240 + - + - 8 + - layer: 236 + purpose: 237 + net: "" + origin: + - 100 + - 230 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@instanceName]" + evaluator: cdsNLPEvalText + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 80 + - + - 60 + - 80 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 160 + - + - 60 + - 160 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 120 + - + - 60 + - 120 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 0 + - + - 80 + - 50 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 60 + - 160 + - + - 60 + - 40 + - + - 120 + - 80 + - + - 120 + - 160 + - + - 60 + - 200 + - + - 60 + - 150 + - + - 0 + - layer: 231 + purpose: 4294967295 + net: "" + bbox: + - 20 + - 20 + - 160 + - 220 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 140 + - + - 120 + - 140 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 100 + - + - 120 + - 100 + - + - 8 + - layer: 231 + purpose: 237 + net: "" + origin: + - 35 + - 210 + alignment: 4 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@partName]" + evaluator: cdsNLPEvalText + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 90 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 170 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 130 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 90 + - 6 + alignment: 7 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 174 + - 130 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 174 + - 150 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 174 + - 110 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp +instances: + {} +props: + interfaceLastChanged: + - 4 + - time_val: 1648515456 + partName: + - 3 + - gm_stage + pin#: + - 0 + - 15 + portOrder: + - 5 + - name: ILList + bin_val: ("i_outm" "i_outp" "v_tail" "VDD" "VSS" "v_inm" "v_inp" "v_tail_g") + vendorName: + - 3 + - "" +app_defs: + _dbLastSavedCounter: + - 0 + - 344 + _dbvCvTimeStamp: + - 0 + - 344 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/gm_stage.yaml b/src/bag3_analog/schematic/netlist_info/gm_stage.yaml new file mode 100644 index 0000000..d65884a --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/gm_stage.yaml @@ -0,0 +1,736 @@ +lib_name: bag3_analog +cell_name: gm_stage +view_name: schematic +bbox: + - -439 + - -195 + - 188 + - 180 +terminals: + VDD: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -300 + - 170 + - R0 + bbox: + - -361 + - 144 + - -290 + - 180 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -325 + - 170 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + VSS: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -300 + - -20 + - R0 + bbox: + - -361 + - -46 + - -290 + - -10 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -325 + - -20 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 2 + ttype: 2 + i_outm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -260 + - 80 + - R0 + bbox: + - -260 + - 54 + - -203 + - 90 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -235 + - 80 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + i_outp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -260 + - 120 + - R0 + bbox: + - -260 + - 94 + - -203 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -235 + - 120 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + v_inm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -350 + - 80 + - R0 + bbox: + - -407 + - 54 + - -350 + - 90 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -380 + - 80 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_inp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -350 + - 120 + - R0 + bbox: + - -407 + - 94 + - -350 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -380 + - 120 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_tail: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -260 + - 40 + - R0 + bbox: + - -260 + - 14 + - -203 + - 50 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -235 + - 40 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -350 + - 40 + - R0 + bbox: + - -407 + - 14 + - -350 + - 50 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -380 + - 40 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - 0 + - -160 + - + - 0 + - -130 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - 0 + - -190 + - + - 0 + - -160 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - -80 + - -10 + - + - 80 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: VSS + origin: + - -6 + - -3 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - -80 + - -80 + - + - -80 + - -40 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outm + points: + - + - -80 + - 20 + - + - -80 + - 60 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - -80 + - -80 + - + - 0 + - -80 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - 0 + - -100 + - + - 0 + - -80 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - 80 + - -80 + - + - 80 + - -40 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - 0 + - -80 + - + - 80 + - -80 + - + - 4 + - layer: 228 + purpose: 4294967295 + net: "" + bbox: + - -5 + - -85 + - 5 + - -75 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outm + origin: + - -87 + - 24 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inp + points: + - + - -160 + - -10 + - + - -120 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inp + origin: + - -124 + - -3 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outp + points: + - + - 80 + - 20 + - + - 80 + - 60 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outp + origin: + - 73 + - 24 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inm + points: + - + - 120 + - -10 + - + - 160 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inm + origin: + - 124 + - -3 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail_g + points: + - + - -80 + - -130 + - + - -40 + - -130 + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail_g + origin: + - -44 + - -123 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g + - + - 7 + - layer: 228 + purpose: 237 + net: VSS + origin: + - -7 + - -180 + alignment: 5 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail + origin: + - 20 + - -73 + alignment: 5 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail +instances: + XM: + lib_name: BAG_prim + cell_name: nmos4_standard + view_name: symbol + xform: + - 120 + - -10 + - MY + bbox: + - -12 + - -44 + - 188 + - 35 + connections: + B: VSS + D: i_outp + G: v_inm + S: v_tail + params: + l: + - 3 + - 18n + nf: + - 3 + - 1 + w: + - 3 + - 4 + is_primitive: true + XP: + lib_name: BAG_prim + cell_name: nmos4_standard + view_name: symbol + xform: + - -120 + - -10 + - R0 + bbox: + - -188 + - -44 + - 12 + - 35 + connections: + B: VSS + D: i_outm + G: v_inp + S: v_tail + params: + l: + - 3 + - 18n + nf: + - 3 + - 1 + w: + - 3 + - 4 + is_primitive: true + XTAIL: + lib_name: BAG_prim + cell_name: nmos4_standard + view_name: symbol + xform: + - -40 + - -130 + - R0 + bbox: + - -108 + - -164 + - 92 + - -85 + connections: + B: VSS + D: v_tail + G: v_tail_g + S: VSS + params: + l: + - 3 + - 18n + nf: + - 3 + - 1 + w: + - 3 + - 4 + is_primitive: true +props: + connectivityLastUpdated: + - 0 + - 1736 + lastSchematicExtraction: + - 4 + - time_val: 1648515470 + net#: + - 0 + - 3 + pin#: + - 0 + - 8 + schGeometryLastUpdated: + - 0 + - 1736 + schGeometryVersion: + - 3 + - sch.ds.gm.1.4 + schXtrVersion: + - 3 + - sch.10.0 +app_defs: + _dbLastSavedCounter: + - 0 + - 1736 + _dbvCvTimeStamp: + - 0 + - 1736 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml b/src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml new file mode 100644 index 0000000..cf7a1dc --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml @@ -0,0 +1,358 @@ +lib_name: bag3_analog +cell_name: res_diff +view_name: symbol +bbox: + - -38 + - -4 + - 218 + - 344 +terminals: + VDD: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 156 + - 176 + - 164 + - 184 + stype: 1 + ttype: 2 + m_in: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 156 + - 4 + - 164 + stype: 1 + ttype: 2 + m_out: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - -4 + - 84 + - 4 + stype: 0 + ttype: 2 + p_in: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 176 + - 4 + - 184 + stype: 0 + ttype: 2 + p_out: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - 336 + - 84 + - 344 + stype: 1 + ttype: 2 +shapes: + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 150 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_in + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 190 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_in + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 140 + - 180 + - + - 160 + - 180 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 154 + - 190 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 70 + - 334 + alignment: 1 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_out + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 90 + - 6 + alignment: 7 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_out + - + - 0 + - layer: 236 + purpose: 4294967295 + net: "" + bbox: + - 0 + - 0 + - 160 + - 340 + - + - 8 + - layer: 236 + purpose: 237 + net: "" + origin: + - 90 + - 330 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@instanceName]" + evaluator: cdsNLPEvalText + - + - 8 + - layer: 231 + purpose: 237 + net: "" + origin: + - 10 + - 305 + alignment: 4 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@partName]" + evaluator: cdsNLPEvalText + - + - 0 + - layer: 231 + purpose: 4294967295 + net: "" + bbox: + - 20 + - 20 + - 140 + - 320 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 0 + - + - 80 + - 0 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 180 + - + - 80 + - 180 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 0 + - + - 80 + - 40 + - + - 60 + - 60 + - + - 100 + - 80 + - + - 60 + - 100 + - + - 100 + - 120 + - + - 80 + - 140 + - + - 80 + - 160 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 180 + - + - 80 + - 200 + - + - 60 + - 220 + - + - 100 + - 240 + - + - 60 + - 260 + - + - 100 + - 280 + - + - 80 + - 300 + - + - 80 + - 340 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 180 + - + - 0 + - 180 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 160 + - + - 0 + - 160 +instances: + {} +props: + interfaceLastChanged: + - 4 + - time_val: 1676499327 + partName: + - 3 + - res_diff + pin#: + - 0 + - 9 + portOrder: + - 5 + - name: ILList + bin_val: ("VDD" "m_in" "p_in" "m_out" "p_out") + vendorName: + - 3 + - "" +app_defs: + _dbLastSavedCounter: + - 0 + - 364 + _dbvCvTimeStamp: + - 0 + - 364 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/res_diff.yaml b/src/bag3_analog/schematic/netlist_info/res_diff.yaml new file mode 100644 index 0000000..8d92c4f --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/res_diff.yaml @@ -0,0 +1,565 @@ +lib_name: bag3_analog +cell_name: res_diff +view_name: schematic +bbox: + - -383 + - -113 + - 180 + - 430 +terminals: + VDD: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -270 + - 340 + - R0 + bbox: + - -331 + - 314 + - -260 + - 350 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -295 + - 340 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + m_in: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -320 + - 230 + - R0 + bbox: + - -381 + - 204 + - -310 + - 240 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -345 + - 230 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + m_out: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -200 + - 230 + - R0 + bbox: + - -261 + - 204 + - -190 + - 240 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -225 + - 230 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + p_in: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -320 + - 290 + - R0 + bbox: + - -381 + - 264 + - -310 + - 300 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -345 + - 290 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + p_out: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -200 + - 290 + - R0 + bbox: + - -261 + - 264 + - -190 + - 300 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -225 + - 290 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 +shapes: + - + - 5 + - layer: 228 + purpose: 4294967295 + net: p_in + points: + - + - 50 + - 100 + - + - 50 + - 140 + - + - 7 + - layer: 228 + purpose: 237 + net: p_in + origin: + - 43 + - 136 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_in + - + - 5 + - layer: 228 + purpose: 4294967295 + net: p_out + points: + - + - 50 + - 200 + - + - 50 + - 240 + - + - 7 + - layer: 228 + purpose: 237 + net: p_out + origin: + - 43 + - 204 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_out + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 70 + - 160 + - + - 110 + - 160 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 74 + - 167 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: m_out + points: + - + - 50 + - -100 + - + - 50 + - -60 + - + - 7 + - layer: 228 + purpose: 237 + net: m_out + origin: + - 43 + - -64 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_out + - + - 5 + - layer: 228 + purpose: 4294967295 + net: m_in + points: + - + - 50 + - 0 + - + - 50 + - 40 + - + - 7 + - layer: 228 + purpose: 237 + net: m_in + origin: + - 43 + - 4 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_in + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 70 + - -40 + - + - 110 + - -40 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 74 + - -33 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 50 + - 290 + - + - 50 + - 330 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 43 + - 326 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 50 + - 390 + - + - 50 + - 430 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 43 + - 394 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 70 + - 350 + - + - 110 + - 350 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 74 + - 357 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD +instances: + XRDUM: + lib_name: BAG_prim + cell_name: res_standard + view_name: symbol + xform: + - 10 + - 400 + - R0 + bbox: + - -82 + - 326 + - 180 + - 400 + connections: + BULK: VDD + MINUS: VDD + PLUS: VDD + params: + l: + - 3 + - 400n + w: + - 3 + - 400n + is_primitive: true + XRM: + lib_name: BAG_prim + cell_name: res_standard + view_name: symbol + xform: + - 10 + - 10 + - R0 + bbox: + - -82 + - -64 + - 180 + - 10 + connections: + BULK: VDD + MINUS: m_out + PLUS: m_in + params: + l: + - 3 + - 400n + w: + - 3 + - 400n + is_primitive: true + XRP: + lib_name: BAG_prim + cell_name: res_standard + view_name: symbol + xform: + - 10 + - 210 + - R0 + bbox: + - -82 + - 136 + - 180 + - 210 + connections: + BULK: VDD + MINUS: p_in + PLUS: p_out + params: + l: + - 3 + - 400n + w: + - 3 + - 400n + is_primitive: true +props: + connectivityLastUpdated: + - 0 + - 692 + lastSchematicExtraction: + - 4 + - time_val: 1676499343 + net#: + - 0 + - 0 + pin#: + - 0 + - 5 + schGeometryLastUpdated: + - 0 + - 692 + schGeometryVersion: + - 3 + - sch.ds.gm.1.4 + schXtrVersion: + - 3 + - sch.10.0 +app_defs: + _dbLastSavedCounter: + - 0 + - 692 + _dbvCvTimeStamp: + - 0 + - 692 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/res_diff.py b/src/bag3_analog/schematic/res_diff.py new file mode 100644 index 0000000..e4b377e --- /dev/null +++ b/src/bag3_analog/schematic/res_diff.py @@ -0,0 +1,106 @@ +# BSD 3-Clause License +# +# Copyright (c) 2018, Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# -*- coding: utf-8 -*- + +from typing import Mapping, Any, Optional + +import pkg_resources +from pathlib import Path + +from bag.design.module import Module +from bag.design.database import ModuleDB +from bag.util.immutable import Param + + +# noinspection PyPep8Naming +class bag3_analog__res_diff(Module): + """Module for library bag3_analog cell res_diff. + + Fill in high level description here. + """ + + yaml_file = pkg_resources.resource_filename(__name__, + str(Path('netlist_info', + 'res_diff.yaml'))) + + def __init__(self, database: ModuleDB, params: Param, **kwargs: Any) -> None: + Module.__init__(self, self.yaml_file, database, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + """Returns a dictionary from parameter names to descriptions. + + Returns + ------- + param_info : Optional[Mapping[str, str]] + dictionary from parameter names to descriptions. + """ + return dict( + load_params='Parameters for load resistors', + dum_params='Optional Parameters for dummy resistors', + sub_type='"ntap" or "ptap"', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(dum_params=None) + + def design(self, load_params: Mapping[str, Any], dum_params: Optional[Mapping[str, Any]], sub_type: str) -> None: + """To be overridden by subclasses to design this module. + + This method should fill in values for all parameters in + self.parameters. To design instances of this module, you can + call their design() method or any other ways you coded. + + To modify schematic structure, call: + + rename_pin() + delete_instance() + replace_instance_master() + reconnect_instance_terminal() + restore_instance() + array_instance() + """ + if sub_type == 'ntap': + sub_name = 'VDD' + else: + sub_name = 'VSS' + self.rename_pin('VDD', 'VSS') + + # design dummy resistors + if dum_params: + self.design_resistor('XRDUM', **dum_params, mid='dum', plus=sub_name, minus=sub_name, bulk=sub_name) + else: + self.remove_instance('XRDUM') + + # design core resistors + self.design_resistor('XRP', **load_params, mid='p', bulk=sub_name) + self.design_resistor('XRM', **load_params, mid='m', bulk=sub_name)