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, )
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)
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)