def merge(self, track_set): # type: (TrackSet) -> None """Merge the given TrackSet to this one.""" for hidx, new_intv_set in track_set._tracks.items(): if hidx not in self._tracks: intv_set = IntervalSet() self._tracks[hidx] = intv_set else: intv_set = self._tracks[hidx] for intv, val in new_intv_set.items(): intv_set.add(intv, val, merge=True)
def add_track(self, hidx, intv, width, value=None): # type: (int, Tuple[int, int], int, Any) -> None """Add tracks to this data structure. Parameters ---------- hidx : int the half track index. intv : Tuple[int, int] the track interval. width : int the track width. value : Any value associated with this track. """ if intv[1] - intv[0] >= self._min_len: if hidx not in self._tracks: intv_set = IntervalSet() self._tracks[hidx] = intv_set else: intv_set = self._tracks[hidx] # TODO: add more robust checking? intv_set.add(intv, val=[width, value], merge=True)
class LaygoIntvSet(object): def __init__(self): super(LaygoIntvSet, self).__init__() self._intv = IntervalSet() self._end_flags = {} def add(self, intv, endl, endr): ans = self._intv.add(intv) if ans: start, stop = intv if start in self._end_flags: del self._end_flags[start] else: self._end_flags[start] = endl if stop in self._end_flags: del self._end_flags[stop] else: self._end_flags[stop] = endr return True else: return False def get_complement(self, total_intv): compl_intv = self._intv.get_complement(total_intv) intv_list = [] end_list = [] for intv in compl_intv: intv_list.append(intv) end_list.append((self._end_flags.get(intv[0], False), self._end_flags.get(intv[1], False))) return intv_list, end_list def get_end_flags(self, num_col): if 0 not in self._end_flags: start_flag = False else: start_flag = self._end_flags[0] if num_col not in self._end_flags: end_flag = False else: end_flag = self._end_flags[num_col] return start_flag, end_flag def get_end(self): if not self._intv: return 0 return self._intv.get_end()
def join_bias_vroutes(template, vm_layer, vdd_dx, vss_dx, xr, num_vdd_tot, num_vss_tot, hm_bias_info_list, bias_config, vdd_pins, vss_pins, xl=0, yt=None, vss_warrs=None, vdd_warrs=None): grid = template.grid vss_intvs = IntervalSet() vdd_intvs = IntervalSet() if vss_warrs is not None: for w in WireArray.single_warr_iter(vss_warrs): vss_intvs.add(w.track_id.get_bounds(grid, unit_mode=True), val=w) if vdd_warrs is not None: for w in WireArray.single_warr_iter(vdd_warrs): vdd_intvs.add(w.track_id.get_bounds(grid, unit_mode=True), val=w) vdd_xl, vdd_xr = vdd_dx vss_xl, vss_xr = vss_dx vdd_xl += xl vdd_xr += xl vss_xl += xl vss_xr += xl vss_params = dict( nwire=num_vss_tot, width=1, space_sig=0, ) vdd_params = dict( nwire=num_vdd_tot, width=1, space_sig=0, ) hm_layer = vm_layer + 1 vss_hm_list = [] vdd_hm_list = [] inst_info_list = [] vss_y_prev = vdd_y_prev = None params = dict( bot_layer=vm_layer, bias_config=bias_config, ) for idx, (code, num, y0) in enumerate(hm_bias_info_list): if code == 0: params['bot_params'] = vss_params if vss_y_prev is not None and y0 > vss_y_prev: sup_warrs = list(vss_intvs.overlap_values((vss_y_prev, y0))) tmp = BiasShield.draw_bias_shields(template, vm_layer, bias_config, num_vss_tot, vss_xl, vss_y_prev, y0, sup_warrs=sup_warrs) vss_hm_list.extend(tmp[0]) else: params['bot_params'] = vdd_params if vdd_y_prev is not None and y0 > vdd_y_prev: sup_warrs = list(vdd_intvs.overlap_values((vdd_y_prev, y0))) tmp = BiasShield.draw_bias_shields(template, vm_layer, bias_config, num_vdd_tot, vdd_xl, vdd_y_prev, y0, sup_warrs=sup_warrs) vdd_hm_list.extend(tmp[0]) if vss_y_prev is not None and y0 > vss_y_prev: sup_warrs = list(vss_intvs.overlap_values((vss_y_prev, y0))) tmp = BiasShield.draw_bias_shields(template, vm_layer, bias_config, num_vss_tot, vss_xl, vss_y_prev, y0, sup_warrs=sup_warrs) vss_hm_list.extend(tmp[0]) params['top_params'] = dict( nwire=num, width=1, space_sig=0, ) if idx == 0: master = template.new_template(params=params, temp_cls=BiasShieldJoin) if code == 1: inst_info_list.append((1, master, vdd_xl, y0)) BiasShield.draw_bias_shields(template, hm_layer, bias_config, num, y0, vdd_xr, xr) vdd_y_prev = y0 + master.array_box.top_unit else: inst_info_list.append((0, master, vss_xl, y0)) BiasShield.draw_bias_shields(template, hm_layer, bias_config, num, y0, vss_xr, xr) vss_y_prev = y0 + master.array_box.top_unit elif code == 1: params['bot_open'] = True master = template.new_template(params=params, temp_cls=BiasShieldJoin) inst_info_list.append((1, master, vdd_xl, y0)) BiasShield.draw_bias_shields(template, hm_layer, bias_config, num, y0, vdd_xr, vss_xl, tb_mode=1) vdd_y_prev = y0 + master.array_box.top_unit params['draw_top'] = False params['bot_params'] = vss_params master = template.new_template(params=params, temp_cls=BiasShieldCrossing) inst_info_list.append((0, master, vss_xl, y0)) BiasShield.draw_bias_shields(template, hm_layer, bias_config, num, y0, vss_xr, xr) vss_y_prev = y0 + master.array_box.top_unit else: params['bot_open'] = True master = template.new_template(params=params, temp_cls=BiasShieldJoin) inst_info_list.append((0, master, vss_xl, y0)) BiasShield.draw_bias_shields(template, hm_layer, bias_config, num, y0, vss_xr, xr) vss_y_prev = y0 + master.array_box.top_unit if yt is None: yt = max(vss_y_prev, vdd_y_prev) if vss_y_prev < yt: sup_warrs = list(vss_intvs.overlap_values((vss_y_prev, yt))) tmp = BiasShield.draw_bias_shields(template, vm_layer, bias_config, num_vss_tot, vss_xl, vss_y_prev, yt, sup_warrs=sup_warrs) vss_hm_list.extend(tmp[0]) if vdd_y_prev < yt: sup_warrs = list(vdd_intvs.overlap_values((vdd_y_prev, yt))) tmp = BiasShield.draw_bias_shields(template, vm_layer, bias_config, num_vdd_tot, vdd_xl, vdd_y_prev, yt, sup_warrs=sup_warrs) vdd_hm_list.extend(tmp[0]) sup_layer = hm_layer + 1 vss_list = [] vdd_list = [] for code, master, x0, y0 in inst_info_list: inst = _add_inst_r180(template, master, x0, y0) if code == 1: vdd_list.extend(inst.port_pins_iter('sup', layer=sup_layer)) else: vss_list.extend(inst.port_pins_iter('sup', layer=sup_layer)) vdd_list = template.connect_wires(vdd_list, upper=yt, unit_mode=True) vss_list = template.connect_wires(vss_list, upper=yt, unit_mode=True) template.draw_vias_on_intersections(vdd_hm_list, vdd_list) template.draw_vias_on_intersections(vss_hm_list, vss_list) # connect pins vss_tidx_list = BiasShield.get_route_tids(grid, vm_layer, vss_xl, bias_config, num_vss_tot) vdd_tidx_list = BiasShield.get_route_tids(grid, vm_layer, vdd_xl, bias_config, num_vdd_tot) pin_map = {} vss_tr_warrs = [] vdd_tr_warrs = [] for pins, tidx_list, result_list in ((vss_pins, vss_tidx_list, vss_tr_warrs), (vdd_pins, vdd_tidx_list, vdd_tr_warrs)): next_idx = 0 for name, warr in pins: if name in pin_map: cur_idx = pin_map[name] add_pin = False else: cur_idx = pin_map[name] = next_idx next_idx += 1 add_pin = True tidx, tr_w = tidx_list[cur_idx + 1] tid = TrackID(vm_layer, tidx, width=tr_w) warr = template.connect_to_tracks(warr, tid, track_upper=yt, unit_mode=True) if add_pin: result_list.append((name, warr)) pin_map.clear() return vdd_tr_warrs, vss_tr_warrs, vdd_list, vss_list