Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)