Source code for bag3_digital.layout.stdcells.reset_sync

from typing import Any, Optional, Mapping, Type, Sequence

from bag.util.immutable import Param
from bag.design.module import Module
from bag.layout.template import TemplateDB

from pybag.enum import MinLenMode

from xbase.layout.mos.base import MOSBasePlaceInfo, MOSBase
from xbase.layout.enum import MOSWireType

from ..stdcells.gates import InvChainCore
from ..stdcells.memory import FlopCore
from ...schematic.reset_sync import bag3_digital__reset_sync


[docs]class ResetSync(MOSBase): def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: MOSBase.__init__(self, temp_db, params, **kwargs) @classmethod
[docs] def get_schematic_class(cls) -> Optional[Type[Module]]: return bag3_digital__reset_sync
@classmethod
[docs] def get_params_info(cls) -> Mapping[str, str]: return dict( pinfo='The MOSBasePlaceInfo object.', ridx_p='pch row index', ridx_n='nch row index', seg_dict='Dictionary of segments', reset_priority='"high" or "low"; "high" by default', vertical_rst='True to have input rst_async on vertical layer; True by default',
) @classmethod
[docs] def get_default_param_values(cls) -> Mapping[str, Any]: return dict( ridx_p=-1, ridx_n=0, reset_priority='high', vertical_rst=True,
)
[docs] def draw_layout(self) -> None: pinfo = MOSBasePlaceInfo.make_place_info(self.grid, self.params['pinfo']) self.draw_base(pinfo) ridx_p: int = self.params['ridx_p'] ridx_n: int = self.params['ridx_n'] seg_dict: Mapping[str, Any] = self.params['seg_dict'] reset_priority: str = self.params['reset_priority'] vertical_rst: bool = self.params['vertical_rst'] # --- Make masters & Placement --- # ff_rst_params = dict(pinfo=pinfo, seg=seg_dict['ff'], resetable=True) ff_rst_master = self.new_template(FlopCore, params=ff_rst_params) ff_rst_ncols = ff_rst_master.num_cols cur_col = 0 ff0 = self.add_tile(ff_rst_master, 0, cur_col) cur_col += ff_rst_ncols + self.min_sep_col ff1 = self.add_tile(ff_rst_master, 0, cur_col) vdd_list = [ff0.get_pin('VDD'), ff1.get_pin('VDD')] vss_list = [ff0.get_pin('VSS'), ff1.get_pin('VSS')] if 'buf' in seg_dict: pg0_tidx = self.get_track_index(ridx_p, MOSWireType.G, 'sig', -3) ng_tidx = self.get_track_index(ridx_n, MOSWireType.G, 'sig', 1) seg_buf: Sequence[int] = seg_dict['buf'] dual_output = len(seg_buf) > 1 buf_params = dict(pinfo=pinfo, seg_list=seg_buf, dual_output=dual_output, sig_locs={'nin0': pg0_tidx, 'nin1': ng_tidx}) buf_master = self.new_template(InvChainCore, params=buf_params) buf_sch_params = buf_master.sch_params cur_col += ff_rst_ncols + self.min_sep_col buf = self.add_tile(buf_master, 0, cur_col) vdd_list.append(buf.get_pin('VDD')) vss_list.append(buf.get_pin('VSS')) # internal rstb self.connect_to_track_wires(buf.get_pin('in'), ff1.get_pin('out')) # outputs if dual_output: self.reexport(buf.get_port('out'), net_name='rstb_sync') self.reexport(buf.get_port('outb'), net_name='rst_sync') else: buf_sch_params = None self.reexport(ff1.get_port('out'), net_name='rstb_sync') self.set_mos_size() # --- Routing --- # # supplies vdd_hm = self.connect_wires(vdd_list)[0] self.add_pin('VDD', vdd_hm) vss_hm = self.connect_wires(vss_list)[0] self.add_pin('VSS', vss_hm) # din if reset_priority == 'high': clk_vm = ff0.get_pin('clk') in_vm_tid = self.tr_manager.get_next_track_obj(clk_vm, 'clk', 'sig', -1) self.connect_to_tracks([ff0.get_pin('nin'), vdd_hm], in_vm_tid) elif reset_priority == 'low': self.reexport(ff0.get_port('nin'), net_name='din', hide=False) else: raise ValueError(f'Unknown reset_priority={reset_priority}. Use "high" or "low".') # dint ff0_out = ff0.get_pin('out') self.connect_to_track_wires(ff1.get_pin('nin'), ff0_out) # rst_async rst = self.connect_wires([ff0.get_pin('prst'), ff1.get_pin('prst')])[0] if vertical_rst: rst_vm_tid = self.tr_manager.get_next_track_obj(ff0_out, 'sig', 'sig', 1) rst = self.connect_to_tracks(rst, rst_vm_tid, min_len_mode=MinLenMode.MIDDLE) self.add_pin('rst_async', rst) # clocks clk_vm = self.connect_wires([ff0.get_pin('clk'), ff1.get_pin('clk')])[0] self.add_pin('clk', clk_vm, connect=True) clkb_vm = self.connect_wires([ff0.get_pin('clkb'), ff1.get_pin('clkb')])[0] self.add_pin('clkb', clkb_vm, connect=True) # set schematic parameters self.sch_params = dict( ff=ff_rst_master.sch_params, buf=buf_sch_params, reset_priority=reset_priority,
)