def pos_mode(args): pytrellis.load_database("../../../database") cfg = FuzzConfig(job="FINDNETS_R{}C{}".format(args.row, args.col), family="MachXO2", device="LCMXO2-1200HC", ncl="plc2route.ncl", tiles=[]) cfg.setup() netdata = isptcl.get_wires_at_position(cfg.ncd_prf, (args.row, args.col)) netnames = [x[0] for x in netdata] arcs = isptcl.get_arcs_on_wires(cfg.ncd_prf, netnames, False, defaultdict(lambda: str("mark"))) with open( "r{}c{}_{}out.txt".format(args.row, args.col, "a_" if args.a else ""), "w") as fp: for (k, v) in arcs.items(): print("{}:".format(k), file=fp) for c in v: if isinstance(c, isptcl.AmbiguousArc): print(str(c), file=fp) else: if not args.a: print("{} --> {}".format(c[0], c[1]), file=fp) fp.flush() print("", file=fp)
def fuzz_interconnect(config, location, netname_predicate=lambda x, nets: True, arc_predicate=lambda x, nets: True, fc_predicate=lambda x, nets: True, netname_filter_union=False, enable_span1_fix=False, func_cib=False, fc_prefix="", nonlocal_prefix="", bias=0): """ The fully-automatic interconnect fuzzer function. This performs the fuzzing and updates the database with the results. It is expected that PyTrellis has already been initialised with the database prior to this function being called. :param config: FuzzConfig instance containing target device and tile(s) of interest :param location: The grid location to analyse as a (row, col) tuple. This is the grid location passed to the Tcl API, which corresponds to the location of the site of interest, which for non-CIBs is not necessarily the same as the tile location but the location at which the item of interest appears in the floorplan. :param netname_predicate: a predicate function which should return True if a netname is of interest, given the netname and the set of all nets :param arc_predicate: a predicate function which should return True if an arc, given the arc as a (source, sink) tuple and the set of all netnames, is of interest :param fc_predicate: a predicate function which should return True if a fixed connection should be included :param netname_filter_union: if True, arcs will be included if either net passes netname_predicate, if False both nets much pass the predicate. :param enable_span1_fix: if True, include span1 wires that are excluded due to a Tcl API bug :param func_cib: if True, we are fuzzing a special function to CIB interconnect, enable optimisations for this :param fc_prefix: add a prefix to non-global fixed connections for device-specific fuzzers :param nonlocal_prefix: add a prefix to non-global and non-neighbour wires for device-specific fuzzers :param bias: Apply offset correction for n-based column numbering, n > 0. Used used by Lattice on certain families. """ netdata = isptcl.get_wires_at_position(config.ncd_prf, location) netnames = [x[0] for x in netdata] if enable_span1_fix: extra_netnames = [] for net in netnames: m = re.match("R(\d+)C(\d+)_V01N(\d{4})", net) if m: row = int(m.group(1)) col = int(m.group(2)) idn = m.group(3) if row == location[0] + 1 and col == location[1]: fixednet = "R{}C{}_V01N{}".format(location[0] - 1, col, idn) print("added {}".format(fixednet)) extra_netnames.append(fixednet) netnames = extra_netnames + netnames if func_cib and not netname_filter_union: netnames = list( filter(lambda x: netname_predicate(x, netnames), netnames)) fuzz_interconnect_with_netnames(config, netnames, netname_predicate, arc_predicate, fc_predicate, func_cib, netname_filter_union, False, fc_prefix, nonlocal_prefix, bias)
def filter_mode(args): span1_re = re.compile(r'R\d+C\d+_[VH]01[NESWTLBR]\d{4}') location = (args.row, args.col) def netname_predicate(net, netnames): """ Match nets that are: in the tile according to Tcl, global nets, or span-1 nets that are accidentally left out by Tcl""" return net in netnames or nets.machxo2.is_global( net) or span1_re.match(net) def arc_predicate(arc, netnames): return True def fc_predicate(arc, netnames): return True pytrellis.load_database("../../../database") cfg = FuzzConfig(job="FINDNETS_FILTER_R{}C{}".format(args.row, args.col), family="MachXO2", device="LCMXO2-1200HC", ncl="plc2route.ncl", tiles=[]) cfg.setup() # fuzz_interconnect netdata = isptcl.get_wires_at_position(cfg.ncd_prf, (args.row, args.col)) netnames = [x[0] for x in netdata] extra_netnames = [] if args.s: for net in netnames: m = re.match("R(\d+)C(\d+)_V01N(\d{4})", net) if m: row = int(m.group(1)) col = int(m.group(2)) idn = m.group(3) if row == location[0] + 1 and col == location[1]: fixednet = "R{}C{}_V01N{}".format(location[0] - 1, col, idn) print("added {}".format(fixednet)) extra_netnames.append(fixednet) netnames = extra_netnames + netnames if args.f and not args.n: netnames = list( filter(lambda x: netname_predicate(x, netnames), netnames)) # fuzz_interconnect_with_netnames arcs = isptcl.get_arcs_on_wires(cfg.ncd_prf, netnames, not args.f, defaultdict(lambda: str("mark"))) def per_netname(net): assoc_arcs = arcs[net] if args.n: filt_net_pred = list( itertools.filterfalse( lambda x: netname_predicate(x[0], netnames) and netname_predicate(x[1], netnames), assoc_arcs.copy())) assoc_arcs = list( filter( lambda x: netname_predicate(x[0], netnames) and netname_predicate(x[1], netnames), assoc_arcs)) else: filt_net_pred = list( itertools.filterfalse( lambda x: netname_predicate(x[0], netnames) or netname_predicate(x[1], netnames), assoc_arcs.copy())) assoc_arcs = list( filter( lambda x: netname_predicate(x[0], netnames) or netname_predicate(x[1], netnames), assoc_arcs)) filt_arcs_pred = list( itertools.filterfalse(lambda x: arc_predicate(x, netnames), assoc_arcs.copy())) fuzz_arcs = list( filter(lambda x: arc_predicate(x, netnames), assoc_arcs)) filt_fc_pred = list( itertools.filterfalse(lambda x: fc_predicate(x, netnames), fuzz_arcs.copy())) return (fuzz_arcs, filt_net_pred, filt_arcs_pred, filt_fc_pred) # Write to file, describing which nets did/didn't make the cut. with open("r{}c{}_filter.txt".format(args.row, args.col), "w") as fp: def print_arc(arc): if isinstance(arc, isptcl.AmbiguousArc): print(str(arc), file=fp) else: print("{} --> {}".format(arc[0], arc[1]), file=fp) print("Args: {}".format(vars(args)), file=fp) print("", file=fp) print("Extra nets (span 1s):", file=fp) for net in extra_netnames: print("{}:".format(net), file=fp) print("", file=fp) print("Filters:", file=fp) print("Netname:\n{}".format(inspect.getsource(netname_predicate)), file=fp) print("Arc:\n{}".format(inspect.getsource(arc_predicate)), file=fp) print("FC:\n{}".format(inspect.getsource(fc_predicate)), file=fp) print("", file=fp) for net in netnames: print("{}:".format(net), file=fp) (fuzz, filt_net, filt_arc, filt_fc) = per_netname(net) print("Arcs to fuzz:", file=fp) for f in fuzz: print_arc(f) print("Arcs filtered by netname_predicate:", file=fp) for f in filt_net: print_arc(f) print("Arcs filtered by arc_predicate:", file=fp) for f in filt_arc: print_arc(f) print("Would be filtered by fc_predicate (if fixed connection):", file=fp) for f in filt_fc: print_arc(f) fp.flush() print("", file=fp)