Пример #1
0
    def find_features_in_bitstream(self, bitdata, verbose=False):
        frames = set(bitdata.keys())
        tiles_checked = set()

        while len(frames) > 0:
            frame = frames.pop()

            # Skip frames that were emptied in a previous iteration.
            if not bitdata[frame]:
                continue

            # Iterate over all tiles that use this frame.
            for bits_info in self.segment_map.segment_info_for_frame(frame):
                # Don't examine a tile twice
                if bits_info.tile in tiles_checked:
                    continue

                # Check if this frame has any data for the relevant tile.
                any_column = False
                for word_idx in range(bits_info.bits.words):
                    if word_idx + bits_info.bits.offset in bitdata[frame][0]:
                        any_column = True
                        break

                if not any_column:
                    continue

                tiles_checked.add(bits_info.tile)

                for fasm_line in self.find_features_in_tile(bits_info.tile,
                                                            bits_info.bits,
                                                            bitdata,
                                                            verbose=verbose):
                    yield fasm_line

            if len(bitdata[frame][1]) > 0 and verbose:
                # Some bits were not decoded, add warning and annotations to
                # FASM.
                yield fasm.FasmLine(
                    set_feature=None,
                    annotations=None,
                    comment=" In frame 0x{:08x} {} bits were not converted.".
                    format(
                        frame,
                        len(bitdata[frame][1]),
                    ))

                for bit in bitdata[frame][1]:
                    wordidx = bit // bitstream.WORD_SIZE_BITS
                    bitidx = bit % bitstream.WORD_SIZE_BITS
                    annotation = fasm.Annotation(
                        'unknown_bit',
                        '{:08x}_{}_{}'.format(frame, wordidx, bitidx))
                    yield fasm.FasmLine(
                        set_feature=None,
                        annotations=[annotation],
                        comment=None,
                    )
Пример #2
0
    def find_features_in_bitstream(self, bitdata, fmap=[], verbose=False):
        solved_bitdata = {}
        frames = set(bitdata.keys())
        tiles_checked = set()

        emitted_features = set()

        while len(frames) > 0:
            frame = frames.pop()

            # Skip frames that were emptied in a previous iteration.
            if not bitdata[frame]:
                continue

            # Iterate over all tiles that use this frame.
            for bits_info in self.segment_map.segment_info_for_frame(frame):
                # Don't examine a tile twice
                if (bits_info.tile, bits_info.block_type) in tiles_checked:
                    continue

                # Check if this frame has any data for the relevant tile.
                any_column = False
                for word_idx in range(bits_info.bits.words):
                    if word_idx + bits_info.bits.offset in bitdata[frame][0]:
                        any_column = True
                        break

                if not any_column:
                    continue

                tiles_checked.add((bits_info.tile, bits_info.block_type))

                for fasm_line in self.find_features_in_tile(
                        bits_info.tile, bits_info.block_type, bits_info.bits,
                        solved_bitdata, bitdata, fmap=fmap, verbose=verbose):
                    if fasm_line not in emitted_features:
                        emitted_features.add(fasm_line)
                        yield fasm_line

            remaining_bits = bitdata[frame][1]
            if frame in solved_bitdata:
                remaining_bits -= solved_bitdata[frame]

            if len(remaining_bits) > 0 and verbose:
                # Some bits were not decoded, add warning and annotations to
                # FASM.
                yield fasm.FasmLine(
                    set_feature=None,
                    annotations=None,
                    comment=" In frame 0x{:08x} {} bits were not converted.".
                    format(
                        frame,
                        len(remaining_bits),
                    ))

                ff = dict()
                ff['bit'] = []
                ff['bit'].append('bit_{:08x}_{}_{}'.format(frame, 0, 0))
                ff['feature'] = 'unknown'
                fmap.append(ff)
Пример #3
0
    def find_features_in_tile(self,
                              tile_name,
                              block_type,
                              bits,
                              solved_bitdata,
                              bitdata,
                              verbose=False):
        gridinfo = self.grid.gridinfo_at_tilename(tile_name)

        try:
            tile_segbits = self.grid.get_tile_segbits_at_tilename(tile_name)
        except KeyError as e:
            if not verbose:
                return

            if gridinfo.tile_type in self.decode_warnings:
                return

            comment = " WARNING: failed to load DB for tile type {}".format(
                gridinfo.tile_type)
            yield fasm.FasmLine(
                set_feature=None,
                annotations=None,
                comment=comment,
            )
            yield fasm.FasmLine(
                set_feature=None,
                annotations=(
                    fasm.Annotation('missing_segbits', gridinfo.tile_type),
                    fasm.Annotation('exception', str(e)),
                ),
                comment=None,
            )

            self.decode_warnings.add(gridinfo.tile_type)
            return

        for ones_matched, feature in tile_segbits.match_bitdata(
                block_type, bits, bitdata):
            for frame, bit in ones_matched:
                if frame not in solved_bitdata:
                    solved_bitdata[frame] = set()
                solved_bitdata[frame].add(bit)

            yield mk_fasm(tile_name=tile_name, feature=feature)
Пример #4
0
    def test_comment_file(self):
        result = list(fasm.parse_fasm_filename(example('comment.fasm')))
        self.assertEqual(result, [
            fasm.FasmLine(
                set_feature=None,
                annotations=None,
                comment=' Only a comment.',
            )
        ])

        check_round_trip(self, result)
Пример #5
0
    def test_comment_file(self):
        for name, parser in parsers.items():
            with self.subTest(name, parser=name):
                result = list(
                    parser.parse_fasm_filename(example('comment.fasm')))
                self.assertEqual(result, [
                    fasm.FasmLine(
                        set_feature=None,
                        annotations=None,
                        comment=' Only a comment.',
                    )
                ])

                check_round_trip(self, parser, result)
Пример #6
0
    def test_one_line_feature(self):
        result = list(fasm.parse_fasm_filename(example('feature_only.fasm')))
        self.assertEqual(result, [
            fasm.FasmLine(
                set_feature=fasm.SetFasmFeature(
                    feature='EXAMPLE_FEATURE.X0.Y0.BLAH',
                    start=None,
                    end=None,
                    value=1,
                    value_format=None,
                ),
                annotations=None,
                comment=None,
            )
        ])

        self.assertEqual(fasm.fasm_tuple_to_string(result),
                         'EXAMPLE_FEATURE.X0.Y0.BLAH\n')
        check_round_trip(self, result)
Пример #7
0
def process_fasm(db_root, part, fasm_file, canonical):
    database = db.Database(db_root, part)
    grid = database.grid()

    for fasm_line in fasm.parse_fasm_filename(fasm_file):
        if not fasm_line.set_feature:
            if not canonical:
                yield fasm_line

        for feature in fasm.canonical_features(fasm_line.set_feature):
            parts = feature.feature.split('.')
            tile = parts[0]

            gridinfo = grid.gridinfo_at_tilename(tile)
            tile_segbits = database.get_tile_segbits(gridinfo.tile_type)

            address = 0
            if feature.start is not None:
                address = feature.start

            feature_name = '{}.{}'.format(gridinfo.tile_type,
                                          '.'.join(parts[1:]))

            # Convert feature to bits.  If no bits are set, feature is
            # psuedo pip, and should not be output from canonical FASM.
            bits = tuple(
                tile_segbits.feature_to_bits(feature_name, address=address))
            if len(bits) == 0 and canonical:
                continue

            # In canonical output, only output the canonical features.
            if canonical:
                yield fasm.FasmLine(
                    set_feature=feature,
                    annotations=None,
                    comment=None,
                )

        # If not in canonical mode, output original FASM line
        if not canonical:
            yield fasm_line
Пример #8
0
def mk_fasm(tile_name, feature):
    """ Convert matches tile and feature to FasmLine tuple. """
    # Seperate addressing of multi-bit features:
    # TILE.ALUT[0] -> ('TILE', 'ALUT', '0')
    # TILE.ALUT.SMALL -> ('TILE', 'ALUT.SMALL', None)
    m = re.match(r'([A-Za-z0-9_]+).([^\[]+)(\[[0-9]+\])?', feature)
    tag_post = m.group(2)
    address = None
    if m.group(3) is not None:
        address = int(m.group(3)[1:-1])

    feature = '{}.{}'.format(tile_name, tag_post)

    return fasm.FasmLine(set_feature=fasm.SetFasmFeature(
        feature=feature,
        start=address,
        end=None,
        value=1,
        value_format=None,
    ),
                         annotations=None,
                         comment=None)
Пример #9
0
    def find_features_in_bitstream(self, bitdata, verbose=False):
        solved_bitdata = {}
        frames = set(bitdata.keys())
        tiles_checked = set()

        emitted_features = set()

        while len(frames) > 0:
            frame = frames.pop()

            # Skip frames that were emptied in a previous iteration.
            if not bitdata[frame]:
                continue

            # Iterate over all tiles that use this frame.
            for bits_info in self.segment_map.segment_info_for_frame(frame):
                # Don't examine a tile twice
                if bits_info.tile in tiles_checked:
                    continue

                # Check if this frame has any data for the relevant tile.
                any_column = False
                for word_idx in range(bits_info.bits.words):
                    if word_idx + bits_info.bits.offset in bitdata[frame][0]:
                        any_column = True
                        break

                if not any_column:
                    continue

                tiles_checked.add(bits_info.tile)

                for fasm_line in self.find_features_in_tile(bits_info.tile,
                                                            bits_info.bits,
                                                            solved_bitdata,
                                                            bitdata,
                                                            verbose=verbose):
                    if fasm_line not in emitted_features:
                        emitted_features.add(fasm_line)
                        yield fasm_line

            remaining_bits = bitdata[frame][1]
            if frame in solved_bitdata:
                remaining_bits -= solved_bitdata[frame]

            if len(remaining_bits) > 0 and verbose:
                # Some bits were not decoded, add warning and annotations to
                # FASM.
                yield fasm.FasmLine(
                    set_feature=None,
                    annotations=None,
                    comment=" In frame 0x{:08x} {} bits were not converted.".
                    format(
                        frame,
                        len(remaining_bits),
                    ))

                for bit in remaining_bits:
                    frame_offset = frame % bitstream.FRAME_ALIGNMENT
                    aligned_frame = frame - frame_offset
                    wordidx = bit // bitstream.WORD_SIZE_BITS
                    bitidx = bit % bitstream.WORD_SIZE_BITS

                    annotations = []
                    annotations.append(
                        fasm.Annotation(
                            'unknown_bit',
                            '{:08x}_{}_{}'.format(frame, wordidx, bitidx)))
                    annotations.append(
                        fasm.Annotation('unknown_segment',
                                        '0x{:08x}'.format(aligned_frame)))
                    annotations.append(
                        fasm.Annotation(
                            'unknown_segbit',
                            '{:02d}_{:02d}'.format(frame_offset, bit)))
                    yield fasm.FasmLine(
                        set_feature=None,
                        annotations=annotations,
                        comment=None,
                    )
    def find_features_in_tile(self,
                              tile_name,
                              block_type,
                              bits,
                              solved_bitdata,
                              bitdata,
                              fmap=None,
                              verbose=False):
        gridinfo = self.grid.gridinfo_at_tilename(tile_name)

        try:
            tile_segbits = self.grid.get_tile_segbits_at_tilename(tile_name)
        except KeyError as e:
            if not verbose:
                return

            if gridinfo.tile_type in self.decode_warnings:
                return

            comment = " WARNING: failed to load DB for tile type {}".format(
                gridinfo.tile_type)
            yield fasm.FasmLine(
                set_feature=None,
                annotations=None,
                comment=comment,
            )
            yield fasm.FasmLine(
                set_feature=None,
                annotations=(
                    fasm.Annotation('missing_segbits', gridinfo.tile_type),
                    fasm.Annotation('exception', str(e)),
                ),
                comment=None,
            )

            self.decode_warnings.add(gridinfo.tile_type)
            return

        for ones_matched, feature in tile_segbits.match_bitdata(
                block_type, bits, bitdata):
            ff = dict()
            ff['bit'] = []
            ff['seg'] = []

            for frame, bit in ones_matched:
                if frame not in solved_bitdata:
                    solved_bitdata[frame] = set()

                ff['bit'].append('bit_' + ('%08x' % frame) + '_' +
                                 ('%03d' % bits.offset) + '_' +
                                 str(bit - bits.offset * 32))
                ff['seg'].append(('%02d' % (frame - bits.base_address)) + '_' +
                                 str(bit - bits.offset * 32))

                solved_bitdata[frame].add(bit)

            ff['tile'] = tile_name
            ff['feature'] = feature
            fmap.append(ff)

            yield mk_fasm(tile_name=tile_name, feature=feature)