コード例 #1
0
ファイル: nonrouting.py プロジェクト: xobs/prjtrellis
def fuzz_word_setting(config,
                      name,
                      length,
                      get_ncl_substs,
                      empty_bitfile=None):
    """
    Fuzz a multi-bit setting, such as LUT initialisation

    :param config: FuzzConfig instance containing target device and tile of interest
    :param name: name of the setting to store in the database
    :param length: number of bits in the setting
    :param get_ncl_substs: a callback function, that is first called with an array of bits to create a design with that setting
    :param empty_bitfile: a path to a bit file without the parameter included, optional, which is used to determine the
    default value
    """
    prefix = "thread{}_".format(threading.get_ident())
    tile_dbs = {
        tile: pytrellis.get_tile_bitdata(
            pytrellis.TileLocator(config.family, config.device,
                                  tiles.type_from_fullname(tile)))
        for tile in config.tiles
    }
    if empty_bitfile is not None:
        none_chip = pytrellis.Bitstream.read_bit(
            empty_bitfile).deserialise_chip()
    else:
        none_chip = None
    baseline_bitf = config.build_design(
        config.ncl, get_ncl_substs([False for _ in range(length)]), prefix)
    baseline_chip = pytrellis.Bitstream.read_bit(
        baseline_bitf).deserialise_chip()

    wsb = {tile: pytrellis.WordSettingBits() for tile in config.tiles}
    is_empty = {tile: True for tile in config.tiles}
    for t in config.tiles:
        wsb[t].name = name
    for i in range(length):
        bit_bitf = config.build_design(
            config.ncl, get_ncl_substs([(_ == i) for _ in range(length)]),
            prefix)
        bit_chip = pytrellis.Bitstream.read_bit(bit_bitf).deserialise_chip()
        diff = bit_chip - baseline_chip
        for tile in config.tiles:
            if tile in diff:
                wsb[tile].bits.append(pytrellis.BitGroup(diff[tile]))
                is_empty[tile] = False
            else:
                wsb[tile].bits.append(pytrellis.BitGroup())
            if none_chip is not None:
                if wsb[tile].bits[i].match(none_chip.tiles[tile].cram):
                    wsb[tile].defval.append(True)
                else:
                    wsb[tile].defval.append(False)
    for t in config.tiles:
        if not is_empty[t]:
            tile_dbs[t].add_setting_word(wsb[t])
            tile_dbs[t].save()
コード例 #2
0
ファイル: fuzzer.py プロジェクト: xobs/prjtrellis
def main():
    pytrellis.load_database("../../../database")

    config = [
        (46, 1, 0),
        (48, 1, 0),
        (50, 1, 0),
        (54, 1, 0),
        (56, 1, 0),
        (58, 1, 0),
        (60, 1, 0),
        (62, 1, 0),
    ]

    tile = pytrellis.get_tile_bitdata(
        pytrellis.TileLocator("ECP5", "LFE5U-25F", "EFB1_PICB1"))
    wsb = pytrellis.WordSettingBits()
    wsb.name = "BOOTADDR"

    for bframe, bbit, inv in config:
        bg = pytrellis.BitGroup()
        cb = pytrellis.ConfigBit()
        cb.frame = bframe
        cb.bit = bbit
        cb.inv = inv
        bg.bits.add(cb)
        wsb.bits.append(bg)
        wsb.defval.append(False)

    tile.add_setting_word(wsb)
    tile.save()
コード例 #3
0
ファイル: dbfixup.py プロジェクト: themkots/prjtrellis
def remove_enum_bits(family, device, tiletype, lowerright, upperleft=(0, 0)):
    """
    Remove bits from enumerations in a given tile that actually belong
    to routing bits. This can happen when e.g. routing is required for Diamond
    to set certain bits in the output, as is the case for fuzzing I/O enums
    in PIC_L0 and PIC_R0.

    Bounds are (0,0)-based. Upperleft is inclusive, lowerright is exclusive.
    """
    def in_bounding_box(bit):
        (x, y) = (bit.frame, bit.bit)

        if upperleft[0] > x or upperleft[1] > y:
            return False

        if lowerright[0] <= x or lowerright[1] <= y:
            return False

        return True

    db = pytrellis.get_tile_bitdata(
        pytrellis.TileLocator(family, device, tiletype))

    for enum in db.get_settings_enums():
        fixed_enum = pytrellis.EnumSettingBits()

        for option in db.get_data_for_enum(enum).options:
            key = option.key()
            fixed_bg = pytrellis.BitGroup()

            for bit in option.data().bits:
                if in_bounding_box(bit):
                    fixed_bg.bits.add(bit)

            fixed_enum.options[key] = fixed_bg

        fixed_enum.name = db.get_data_for_enum(enum).name
        fixed_enum.defval = db.get_data_for_enum(enum).defval

        db.remove_setting_enum(enum)
        db.add_setting_enum(fixed_enum)
    db.save()
コード例 #4
0
    def per_netname(net):
        # Get a unique prefix from the thread ID
        prefix = "thread{}_".format(threading.get_ident())
        assoc_arcs = net_arcs[net]
        # Obtain the set of databases
        tile_dbs = {tile: pytrellis.get_tile_bitdata(
            pytrellis.TileLocator(config.family, config.device, tiles.type_from_fullname(tile))) for tile in
            config.tiles}
        # First filter using netname predicate
        if netname_filter_union:
            assoc_arcs = filter(lambda x: netname_predicate(x[0], netnames) and netname_predicate(x[1], netnames),
                                assoc_arcs)
        else:
            assoc_arcs = filter(lambda x: netname_predicate(x[0], netnames) or netname_predicate(x[1], netnames),
                                assoc_arcs)
        # Then filter using the arc predicate
        fuzz_arcs = list(filter(lambda x: arc_predicate(x, netnames), assoc_arcs))

        # Ful fullmux mode only
        changed_bits = set()
        arc_tiles = {}
        tiles_changed = set()

        for arc in fuzz_arcs:
            # Route statement containing arc for NCL file
            arc_route = "route\n\t\t\t" + arc[0] + "." + arc[1] + ";"
            # Build a bitstream and load it using libtrellis
            arc_bitf = config.build_design(config.ncl, {"route": arc_route}, prefix)
            arc_chip = pytrellis.Bitstream.read_bit(arc_bitf).deserialise_chip()
            # Compare the bitstream with the arc to the baseline bitstream
            diff = arc_chip - baseline_chip
            if (not full_mux_style) or len(fuzz_arcs) == 1:
                if len(diff) == 0:
                    # No difference means fixed interconnect
                    # We consider this to be in the first tile if multiple tiles are being analysed
                    if fc_predicate(arc, netnames):
                        norm_arc = normalise_arc_in_tile(config.tiles[0], arc)
                        fc = pytrellis.FixedConnection()
                        norm_arc = [fc_prefix + _ if not _.startswith("G_") else _ for _ in norm_arc]
                        norm_arc = [add_nonlocal_prefix(_) for _ in norm_arc]
                        fc.source, fc.sink = norm_arc
                        tile_dbs[config.tiles[0]].add_fixed_conn(fc)
                else:
                    for tile in config.tiles:
                        if tile in diff:
                            # Configurable interconnect in <tile>
                            norm_arc = normalise_arc_in_tile(tile, arc)
                            norm_arc = [add_nonlocal_prefix(_) for _ in norm_arc]
                            ad = pytrellis.ArcData()
                            ad.source, ad.sink = norm_arc
                            ad.bits = pytrellis.BitGroup(diff[tile])
                            tile_dbs[tile].add_mux_arc(ad)
            else:
                arc_tiles[arc] = {}
                for tile in config.tiles:
                    if tile in diff:
                        tiles_changed.add(tile)
                        for bit in diff[tile]:
                            changed_bits.add((tile, bit.frame, bit.bit))
                    arc_tiles[arc][tile] = arc_chip.tiles[tile]

        if full_mux_style and len(fuzz_arcs) > 1:
            for tile in tiles_changed:
                for arc in arc_tiles:
                    bg = pytrellis.BitGroup()
                    for (btile, bframe, bbit) in changed_bits:
                        if btile == tile:
                            state = arc_tiles[arc][tile].cram.bit(bframe, bbit)
                            cb = pytrellis.ConfigBit()
                            cb.frame = bframe
                            cb.bit = bbit
                            cb.inv = (state == 0)
                            bg.bits.add(cb)
                    ad = pytrellis.ArcData()
                    ad.source, ad.sink = normalise_arc_in_tile(tile, arc)
                    ad.bits = bg
                    tile_dbs[tile].add_mux_arc(ad)
        # Flush database to disk
        for tile, db in tile_dbs.items():
            db.save()
コード例 #5
0
ファイル: nonrouting.py プロジェクト: xobs/prjtrellis
def fuzz_enum_setting(config,
                      name,
                      values,
                      get_ncl_substs,
                      empty_bitfile=None,
                      include_zeros=True,
                      ignore_cover=None,
                      opt_pref=None):
    """
    Fuzz a setting with multiple possible values

    :param config: FuzzConfig instance containing target device and tile of interest
    :param name: name of the setting to store in the database
    :param values: list of values taken by the enum
    :param get_ncl_substs: a callback function, that is first called with an array of bits to create a design with that setting
    :param empty_bitfile: a path to a bit file without the parameter included, optional, which is used to determine the
    default value
    :param include_zeros: if set, bits set to zero are not included in db. Needed for settings such as CEMUX which share
    bits with routing muxes to prevent conflicts.
    :param ignore_cover: these values will also be checked, and bits changing between these will be ignored
    :param opt_pref: bits exclusively set in these options will be included in all options overriding include_zeros
    """
    prefix = "thread{}_".format(threading.get_ident())
    tile_dbs = {
        tile: pytrellis.get_tile_bitdata(
            pytrellis.TileLocator(config.family, config.device,
                                  tiles.type_from_fullname(tile)))
        for tile in config.tiles
    }
    if empty_bitfile is not None:
        none_chip = pytrellis.Bitstream.read_bit(
            empty_bitfile).deserialise_chip()
    else:
        none_chip = None

    changed_bits = set()
    prev_tiles = {}
    tiles_changed = set()
    for val in values:
        print("****** Fuzzing {} = {} ******".format(name, val))
        bit_bitf = config.build_design(config.ncl, get_ncl_substs(val), prefix)
        bit_chip = pytrellis.Bitstream.read_bit(bit_bitf).deserialise_chip()
        for prev in prev_tiles.values():
            for tile in config.tiles:
                diff = bit_chip.tiles[tile].cram - prev[tile]
                if len(diff) > 0:
                    tiles_changed.add(tile)
                    for bit in diff:
                        changed_bits.add((tile, bit.frame, bit.bit))
        prev_tiles[val] = {}
        for tile in config.tiles:
            prev_tiles[val][tile] = bit_chip.tiles[tile].cram
    if ignore_cover is not None:
        ignore_changed_bits = set()
        ignore_prev_tiles = {}
        for ival in ignore_cover:
            print("****** Fuzzing {} = {} [to ignore] ******".format(
                name, ival))
            bit_bitf = config.build_design(config.ncl, get_ncl_substs(ival),
                                           prefix)
            bit_chip = pytrellis.Bitstream.read_bit(
                bit_bitf).deserialise_chip()
            for prev in ignore_prev_tiles.values():
                for tile in config.tiles:
                    diff = bit_chip.tiles[tile].cram - prev[tile]
                    if len(diff) > 0:
                        for bit in diff:
                            ignore_changed_bits.add((tile, bit.frame, bit.bit))
            ignore_prev_tiles[ival] = {}
            for tile in config.tiles:
                ignore_prev_tiles[ival][tile] = bit_chip.tiles[tile].cram
        for ibit in ignore_changed_bits:
            if ibit in changed_bits:
                changed_bits.remove(ibit)
    for tile in tiles_changed:
        esb = pytrellis.EnumSettingBits()
        esb.name = name
        pref_exclusive = {}
        if opt_pref is not None:
            for val in values:
                for (btile, bframe, bbit) in changed_bits:
                    if btile == tile:
                        state = prev_tiles[val][tile].bit(bframe, bbit)
                        if state:
                            if val in opt_pref:
                                if (btile, bframe, bbit) not in pref_exclusive:
                                    pref_exclusive[(btile, bframe,
                                                    bbit)] = True
                            else:
                                pref_exclusive[(btile, bframe, bbit)] = False
        for val in values:
            bg = pytrellis.BitGroup()
            for (btile, bframe, bbit) in changed_bits:
                if btile == tile:
                    state = prev_tiles[val][tile].bit(bframe, bbit)
                    if state == 0 and not include_zeros and (
                            none_chip is not None and not none_chip.tiles[tile].cram.bit(bframe, bbit)) \
                            and (
                            (btile, bframe, bbit) not in pref_exclusive or not pref_exclusive[(btile, bframe, bbit)]):
                        continue
                    cb = pytrellis.ConfigBit()
                    cb.frame = bframe
                    cb.bit = bbit
                    cb.inv = (state == 0)
                    bg.bits.add(cb)
            esb.options[val] = bg
            if none_chip is not None and bg.match(none_chip.tiles[tile].cram):
                esb.defval = val
        tile_dbs[tile].add_setting_enum(esb)
        tile_dbs[tile].save()