Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
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()
Beispiel #4
0
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