| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright (C) 2017-2020 The Project X-Ray Authors. |
| # |
| # Use of this source code is governed by a ISC-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/ISC |
| # |
| # SPDX-License-Identifier: ISC |
| """ TileSegbitsAlias provides an alias from one tile type to another. |
| TileSegbitsAlias performs severals functions to achieve the alias: |
| - Remaps tile type from the original tile type to the alias tile type |
| - Offsets the bits from the original to the alias type |
| - Renames sites from the original to the alias type |
| - Filters bits outside of the alias. |
| |
| |
| """ |
| |
| from prjxray import bitstream |
| from prjxray.grid_types import Bits |
| from prjxray.tile_segbits import read_ppips |
| from prjxray.util import OpenSafeFile |
| |
| |
| class TileSegbitsAlias(object): |
| def __init__(self, db, tile_type, bits_map): |
| # Name of tile_type that is using the alias |
| self.tile_type = tile_type |
| |
| # Name of aliased tile_type |
| self.alias_tile_type = None |
| |
| # BlockType -> BitAlias map |
| self.alias = {} |
| |
| self.bits_map = bits_map |
| |
| # BlockType -> aliased Bits map |
| self.alias_bits_map = {} |
| |
| # aliased site name to site name map |
| self.sites_rev_map = {} |
| |
| for block_type in bits_map: |
| self.alias[block_type] = bits_map[block_type].alias |
| self.alias_bits_map[block_type] = Bits( |
| base_address=bits_map[block_type].base_address, |
| frames=bits_map[block_type].frames, |
| offset=bits_map[block_type].offset - |
| self.alias[block_type].start_offset, |
| words=bits_map[block_type].words, |
| alias=None, |
| ) |
| |
| if self.alias_tile_type is None: |
| self.alias_tile_type = self.alias[block_type].tile_type |
| else: |
| assert self.alias_tile_type == self.alias[block_type].tile_type |
| |
| self.sites_rev_map[block_type] = {} |
| for site, alias_site in self.alias[block_type].sites.items(): |
| assert alias_site not in self.sites_rev_map[block_type] |
| self.sites_rev_map[block_type][alias_site] = site |
| |
| tile_db = db.tile_types[self.tile_type] |
| self.ppips = {} |
| |
| if tile_db.ppips is not None: |
| with OpenSafeFile(tile_db.ppips) as f: |
| self.ppips = read_ppips(f) |
| self.tile_segbits = db.get_tile_segbits(self.alias_tile_type) |
| |
| def map_feature_to_segbits(self, feature): |
| """ Map from the output feature name to the aliased feature name. """ |
| parts = feature.split('.') |
| |
| assert parts[0] == self.tile_type |
| parts[0] = self.alias_tile_type |
| |
| for block_type in self.alias: |
| if len(parts) > 1 and parts[1] in self.alias[block_type].sites: |
| parts[1] = self.alias[block_type].sites[parts[1]] |
| |
| return '.'.join(parts) |
| |
| def map_feature_from_segbits(self, feature): |
| """ Map from the aliases feature name to the output feature name. """ |
| parts = feature.split('.') |
| |
| assert parts[0] == self.alias_tile_type |
| parts[0] = self.tile_type |
| |
| for block_type in self.alias: |
| if len(parts) > 1 and parts[1] in self.sites_rev_map[block_type]: |
| parts[1] = self.sites_rev_map[block_type][parts[1]] |
| |
| return '.'.join(parts) |
| |
| def match_filter(self, block_type, query_bit): |
| word = query_bit.word_bit // bitstream.WORD_SIZE_BITS |
| real_word = word - self.alias[block_type].start_offset |
| if real_word < 0 or real_word >= self.bits_map[block_type].words: |
| return False |
| |
| return True |
| |
| def match_bitdata(self, block_type, bits, bitdata): |
| alias_bits = self.alias_bits_map[block_type] |
| |
| for bits_found, alias_feature in self.tile_segbits.match_bitdata( |
| block_type, alias_bits, bitdata, |
| match_filter=self.match_filter): |
| feature = self.map_feature_from_segbits(alias_feature) |
| |
| yield (bits_found, feature) |
| |
| def feature_to_bits(self, bits_map, feature, address=0): |
| if feature in self.ppips: |
| return |
| |
| alias_feature = self.map_feature_to_segbits(feature) |
| for block_type, bit in self.tile_segbits.feature_to_bits( |
| self.alias_bits_map, alias_feature, address): |
| yield block_type, bit |