import pytrellis
import route
import tiles

# Simple demo design builder
class Design:
    def __init__(self, family):
        self.chip = pytrellis.Chip("LFE5U-45F")
        self.router = route.Autorouter(self.chip)
        self.config = {_.info.name: pytrellis.TileConfig() for _ in self.chip.get_all_tiles()}
        # TODO: load skeleton config
        self.bels = dict()
        self.bel_to_cell = {}
        self.bels_by_type = {}

        self.auto_netid = 0
        self.auto_cellid = 0

        self.init_bels()

    def get_netid(self, postfix=""):
        self.auto_netid += 1
        return "n{}{}".format(self.auto_netid, postfix)

    def get_cellid(self, postfix=""):
        self.auto_cellid += 1
        return "c{}{}".format(self.auto_cellid, postfix)

    def init_bels(self):
        self.bels_by_type = {"SLICE": []}
        all_tiles = self.chip.get_all_tiles()
        for tile in all_tiles:
            tinf = tile.info
            tname = tinf.name
            chip_size = (self.chip.get_max_row(), self.chip.get_max_col())
            pos = tiles.pos_from_name(tname, chip_size, 0)
            if tinf.type == "PLC2":
                for loc in ("A", "B", "C", "D"):
                    bel = "R{}C{}{}".format(pos[0], pos[1], loc)
                    self.bels[bel] = ("SLICE", (tname, loc))
                    self.bels_by_type["SLICE"].append(bel)

    def connect_input(self, wire, net):
        if net is not None:
            self.router.route_net_to_wire(net, wire, self.config)

    def connect_output(self, wire, net):
        if net is not None:
            self.router.bind_net_to_port(net, wire)

    def bel_for_cell(self, cell, type):
        for bel in self.bels_by_type["SLICE"]:
            if bel not in self.bel_to_cell:
                self.bel_to_cell[bel] = cell
                return bel
        assert False, "can't place cell {}, no remaining bels of type {}".format(cell, type)

    def inst_slice(self, name, a0=None, a1=None, b0=None, b1=None, c0=None, c1=None, d0=None, d1=None, m0=None, m1=None,
                   clk=None, ce=None, lsr=None, f0=None, f1=None, q0=None, q1=None, params=dict()):
        print("Instantiating slice {}".format(name))
        bel = self.bel_for_cell(name, "SLICE")
        beltype, belloc = self.bels[bel]
        tile, loc = belloc
        chip_size = (self.chip.get_max_row(), self.chip.get_max_col())
        pos = tiles.pos_from_name(tile, chip_size, 0)
        net_prefix = "R{}C{}".format(pos[0], pos[1])
        slice_index = "ABCD".index(loc)
        lc0 = 2 * slice_index
        lc1 = 2 * slice_index + 1

        self.connect_output("{}_F{}".format(net_prefix, lc0), f0)
        self.connect_output("{}_F{}".format(net_prefix, lc1), f1)
        self.connect_output("{}_Q{}".format(net_prefix, lc0), q0)
        self.connect_output("{}_Q{}".format(net_prefix, lc1), q1)

        self.connect_input("{}_A{}".format(net_prefix, lc0), a0)
        self.connect_input("{}_A{}".format(net_prefix, lc1), a1)
        self.connect_input("{}_B{}".format(net_prefix, lc0), b0)
        self.connect_input("{}_B{}".format(net_prefix, lc1), b1)
        self.connect_input("{}_C{}".format(net_prefix, lc0), c0)
        self.connect_input("{}_C{}".format(net_prefix, lc1), c1)
        self.connect_input("{}_D{}".format(net_prefix, lc0), d0)
        self.connect_input("{}_D{}".format(net_prefix, lc1), d1)

        self.connect_input("{}_M{}".format(net_prefix, lc0), m0)
        self.connect_input("{}_M{}".format(net_prefix, lc1), m1)

        self.connect_input("{}_MUXCLK{}".format(net_prefix, slice_index), clk)
        self.connect_input("{}_CE{}".format(net_prefix, slice_index), ce)
        self.connect_input("{}_MUXLSR{}".format(net_prefix, slice_index), lsr)

        for key, value in sorted(params.items()):
            if key.endswith(".INIT"):
                bv = pytrellis.BoolVector()
                for x in value:
                    bv.append(x)
                self.config[tile].add_word("SLICE{}.{}".format(loc, key), bv)
            else:
                self.config[tile].add_enum("SLICE{}.{}".format(loc, key), value)
        print()

    def make_bitstream(self, filename):
        # Open debug file
        debugfile = filename + ".dbg"
        with open(debugfile, 'w') as dbgf:
            for tname, tcfg in sorted(self.config.items()):
                tile = self.chip.tiles[tname]
                tinfo = tile.info
                tdb = pytrellis.get_tile_bitdata(
                    pytrellis.TileLocator(self.chip.info.family, self.chip.info.name, tinfo.type))
                tile.cram.clear()
                tdb.config_to_tile_cram(tcfg, tile.cram)
                textcfg = tcfg.to_string()
                if len(textcfg.strip()) > 0:
                    dbgf.write(".tile {}\n".format(tname))
                    dbgf.write(textcfg)
                    dbgf.write("\n")

        bs = pytrellis.Bitstream.serialise_chip(self.chip)
        bs.write_bit(filename)
