mirror of https://github.com/openXC7/prjxray.git
107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
""" 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
|
|
|
|
|
|
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
|
|
|
|
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):
|
|
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
|