def group_hlc_name(group): """Get the HLC "global name" from a group local names.""" assert_type(group, list) global ic hlcnames = defaultdict(int) hlcnames_details = [] for ipos, localnames in group: for name in localnames: assert_type(ipos, PositionIcebox) hlcname = icebox_asc2hlc.translate_netname(*ipos, ic.max_x-1, ic.max_y-1, name) if hlcname != name: hlcnames_details.append((ipos, name, hlcname)) hlcnames[hlcname] += 1 if not hlcnames: return None if len(hlcnames) > 1: logging.warn("Multiple HLC names (%s) found group %s", hlcnames, group) filtered_hlcnames = {k: v for k,v in hlcnames.items() if v > 1} if not filtered_hlcnames: return None if len(filtered_hlcnames) != 1: logging.warn("Skipping as conflicting names for %s (%s)", hlcnames, hlcnames_details) return None hlcnames = filtered_hlcnames assert len(hlcnames) == 1, (hlcnames, hlcnames_details) return list(hlcnames.keys())[0]
def filter_track_names(group): """Filter out unusable icebox track names.""" assert_type(group, list) for p in group: assert_type(p.pos, PositionIcebox) names = list(p.names) p.names.clear() for n in names: # FIXME: Get the sp4_r_v_ wires working if "sp4_r_v_" in n: continue # FIXME: Fix the carry logic. if "cout" in n or "carry_in" in n: continue if "lout" in n: continue p.names.append(n) rgroup = [] for p in group: if not p.names: continue rgroup.append(p) return rgroup
def group_seg_type(group): """Get the segment type from a group of local names.""" assert_type(group, list) types = defaultdict(int) for ipos, localnames in group: assert_type(ipos, PositionIcebox) for name in localnames: # ??? if "/" in name: types["pin"] += 1 continue if "carry" in name: types["pin"] += 1 continue # Normal tracks... if "local" in name: types["local"] += 1 if "op" in name: types["neigh"] += 1 if "global" in name: types["global"] += 1 if "sp4" in name or "span4" in name: types["span4"] += 1 if "sp12" in name or "span12" in name: types["span12"] += 1 # The global drivers if "fabout" in name: types["local"] += 1 if "pin" in name: types["local"] += 1 assert types, "No group types for {}".format(group) if len(types) > 1: logging.warn("Multiple types (%s) found for group %s", types, group) filtered_types = {k: v for k, v in types.items() if v > 1} assert len(filtered_types) == 1, (filtered_types, types, group) types = filtered_types assert len(types) == 1, "Multiple group types {} for {}".format( types, group) for k in types: return k assert False, types
def group_chan_type(group): """Get the channel track type from a group of local names.""" assert_type(group, list) for ipos, netname in group: assert_type(ipos, PositionIcebox) if "local" in netname: return channel.Track.Type.Y if "_h" in netname: return channel.Track.Type.X if "_v" in netname: return channel.Track.Type.Y # The drivers if "fabout" in netname: return channel.Track.Type.X if "pin" in netname: return channel.Track.Type.X if "/" in netname: return channel.Track.Type.Y assert False, group return None
def create_edge_with_names(g, src_name, dst_name, ipos, switch, skip=None, bidir=None): """Create an edge at a given icebox position from two local names.""" assert_type(src_name, str) assert_type(dst_name, str) assert_type(ipos, PositionIcebox) assert_type(switch, graph.Switch) if skip is None: def skip(fmt, *a, **k): raise AssertionError(fmt % a) if switch.type in (graph.SwitchType.SHORT, graph.SwitchType.PASS_GATE): if bidir is None: bidir = True else: assert bidir is True, "Switch {} must be bidir ({})".format( switch, (ipos, src_name, dst_name, bidir)) elif bidir is None: bidir = False src_hlc_name = group_hlc_name([NP(ipos, [src_name])]) dst_hlc_name = group_hlc_name([NP(ipos, [dst_name])]) vpos = pos_icebox2vpr(ipos) src_node = g.routing.get_by_name(src_name, vpos, None) dst_node = g.routing.get_by_name(dst_name, vpos, None) if src_node is None: skip( "src missing *%s:%s* (%s) node %s => %s:%s (%s) node %s", vpos, src_name, src_hlc_name, format_node(g, src_node), vpos, dst_name, dst_hlc_name, format_node(g, dst_node), level=logging.WARNING, ) return if dst_node is None: skip( "dst missing %s:%s (%s) node %s => *%s:%s* (%s) node %s", vpos, src_name, src_hlc_name, format_node(g, src_node), vpos, dst_name, dst_hlc_name, format_node(g, dst_node), ) return logging.debug( "On %s add %-8s edge %s - %s:%s (%s) node %s => %s:%s (%s) node %s", ipos, switch.name, len(g.routing.id2element[graph.RoutingEdge]), vpos, src_name, src_hlc_name, format_node(g, src_node), vpos, dst_name, dst_hlc_name, format_node(g, dst_node), ) g.routing.create_edge_with_nodes( src_node, dst_node, switch=switch, bidir=bidir, metadata={Offset(0,0):{"hlc_coord": "{},{}".format(*ipos)}}, )
def group_seg_type(group): """Get the segment type from a group of local names.""" assert_type(group, list) types = defaultdict(int) for ipos, localnames in group: assert_type(ipos, PositionIcebox) for name in localnames: # ??? if "/" in name: types["pin"] += 1 continue if "carry" in name: types["pin"] += 1 continue # DSP Pins # FIXME: Must be a better way to do this. if name in ("clk", "ce", "c", "a", "b", "c", "ci", "o", "co"): types["pin"] += 1 continue if "hold" in name: types["pin"] += 1 continue if "rst" in name: # irsttop, irstbot, orsttop, orstbot types["pin"] += 1 continue if "load" in name: # oloadtop, oloadbot types["pin"] += 1 continue if "addsub" in name: # oloadtop, oloadbot types["pin"] += 1 continue # Normal tracks... if "local" in name: types["local"] += 1 if "op" in name: types["neigh"] += 1 if "global" in name: types["global"] += 1 if "sp4" in name or "span4" in name: types["span4"] += 1 if "sp12" in name or "span12" in name: types["span12"] += 1 # The global drivers if "fabout" in name: types["local"] += 1 if "pin" in name: types["local"] += 1 assert types, "No group types for {}".format(group) if len(types) > 1: logging.warn("Multiple types (%s) found for group %s", types, group) filtered_types = {k: v for k,v in types.items() if v > 1} assert len(filtered_types) == 1, (filtered_types, types, group) types = filtered_types assert len(types) == 1, "Multiple group types {} for {}".format(types, group) for k in types: return k assert False, types
def pos_vpr2icebox(pos): """Convert VTR to icebox coordinates.""" assert_type(pos, PositionVPR) return PositionIcebox(pos.x - 2, pos.y - 2)
def pos_icebox2vpr(pos): """Convert icebox to VTR coordinates.""" assert_type(pos, PositionIcebox) return PositionVPR(pos.x + 2, pos.y + 2)