blob: 927e3337b7174a1ba30eb509e5a3dd8f1760977e [file] [log] [blame]
import re
from collections import namedtuple
FasmEntry = namedtuple("FasmDbEntry", "feature bits")
IceDbEntry = namedtuple("IceDbEntry", "tile_type loc bits names idx")
def _parse_icedb_bit(bit):
mm = re.match(r"([\!]?)B([0-9]+)\[([0-9]*)\]", bit)
if mm is None:
print("ERROR", bit)
return mm.group(1), int(mm.group(2)), int(mm.group(3))
def _parse_fasm_bit(bit):
mm = re.match(r"([\!]?)([0-9]+)_([0-9]+)", bit)
if mm is None:
print("ERROR", bit)
return mm.group(1), int(mm.group(2)), int(mm.group(3))
class Feature(object):
def __init__(self, tile_type, loc, bit_tuples, parts, idx=None):
self.tile_type = tile_type
self.loc = loc
self.bit_tuples = bit_tuples
self.parts = parts
self.idx = idx
def to_icedb_entry(self):
parts = [
re.sub(r"((lutff|io)_[a-z0-9]+|ram_)(_)([^\.]*)", r"\1/\4", part)
for part in self.parts
]
bits = ["{}B{}[{}]".format(*bit) for bit in self.bit_tuples]
return IceDbEntry(self.tile_type, self.loc, bits, parts, self.idx)
def to_fasm_entry(self):
rem = ".".join(self.parts)
feature = "{}_X{}_Y{}.{}".format(self.tile_type, *self.loc, rem)
if self.idx is not None and self.idx is not 0:
feature += "[{}]".format(self.idx)
bits = ["{}{}_{}".format(*bit) for bit in self.bit_tuples]
return FasmEntry(feature, bits)
@classmethod
def from_fasm_entry(cls, entry):
tile, rem = entry.feature.split(".", 1)
mm = re.match(r"([A-Za-z]+)_X([0-9]+)_Y([0-9]+)", tile)
tile_type = mm.group(1)
loc = [int(mm.group(2)), int(mm.group(3))]
parts = rem.split(".")
# if there is '[5]' set bit_idx to 5
mm = re.match(r"([^\[\]]+)\[([0-9]+)\]", parts[-1])
bit_idx = None
if mm:
bit_idx = int(mm.group(2))
parts[-1] = mm.group(1)
bits = [_parse_fasm_bit(each) for each in entry.bits]
return cls(tile_type, loc, bits, parts, bit_idx)
@classmethod
def from_icedb_entry(cls, entry):
parts = [part.replace("/", "_") for part in entry.names]
bits = [_parse_icedb_bit(bit) for bit in entry.bits]
idx = entry.idx
return cls(entry.tile_type, entry.loc, bits, parts, idx)