#!/usr/bin/env python3
#
#  Copyright (C) 2015  Clifford Wolf <clifford@clifford.at>
#
#  Permission to use, copy, modify, and/or distribute this software for any
#  purpose with or without fee is hereby granted, provided that the above
#  copyright notice and this permission notice appear in all copies.
#
#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

import icebox
import getopt, sys, re

verbose = False

def usage():
    print("""
Usage: icebox_stat [options] [bitmap.asc]

    -v
        verbose output

""")
    sys.exit(0)

try:
    opts, args = getopt.getopt(sys.argv[1:], "v")
except:
    usage()

for o, a in opts:
    if o == "-v":
        verbose = True
    else:
        usage()

if len(args) == 0:
    args.append("/dev/stdin")

if len(args) != 1:
    usage()

if verbose:
    print("Reading input file.")

ic = icebox.iceconfig()
ic.read_file(args[0])

dff_locations = set()
lut_locations = set()
carry_locations = set()
bram_locations = set()
io_locations = set()
pll_locations = set()
global_nets = set()

if verbose:
    print("Analyzing connectivity.")

connections = sorted(ic.group_segments())

if verbose:
    print("Counting resources.")

for segs in connections:
    for seg in segs:
        if ic.tile_type(seg[0], seg[1]) == "IO" and seg[2].startswith("io_"):
            match = re.match("io_(\d+)/D_(IN|OUT)_(\d+)", seg[2])
            if match:
                loc = (seg[0], seg[1], int(match.group(1)))
                io_locations.add(loc)

        if ic.tile_type(seg[0], seg[1]) == "LOGIC" and seg[2].startswith("lutff_"):
            match = re.match("lutff_(\d)/in_\d", seg[2])
            if match:
                loc = (seg[0], seg[1], int(match.group(1)))
                lut_locations.add(loc)

            match = re.match("lutff_(\d)/cout", seg[2])
            if match:
                loc = (seg[0], seg[1], int(match.group(1)))
                carry_locations.add(loc)

            match = re.match("lutff_(\d)/out", seg[2])
            if match:
                loc = (seg[0], seg[1], int(match.group(1)))
                seq_bits = icebox.get_lutff_seq_bits(ic.tile(loc[0], loc[1]), loc[2])
                if seq_bits[1] == "1":
                    dff_locations.add(loc)

        if ic.tile_type(seg[0], seg[1]) in ("RAMB", "RAMT") and seg[2].startswith("ram/"):
            loc = (seg[0], seg[1] - (seg[1] % 2))
            bram_locations.add(loc)

        if seg[2].startswith("glb_netwk_"):
            match = re.match("glb_netwk_(\d)", seg[2])
            if match:
                global_nets.add(int(match.group(1)))

pll_config_bitidx = dict()

for entry in icebox.iotile_l_db:
    if entry[1] == "PLL":
        match = re.match(r"B(\d+)\[(\d+)\]", entry[0][0]);
        assert match
        pll_config_bitidx[entry[2]] = (int(match.group(1)), int(match.group(2)))

def get_pll_bit(pllinfo, name):
    bit = pllinfo[name]
    assert bit[2] in pll_config_bitidx
    return ic.tile(bit[0], bit[1])[pll_config_bitidx[bit[2]][0]][pll_config_bitidx[bit[2]][1]]

def get_pll_bits(pllinfo, name, n):
    return "".join([get_pll_bit(pllinfo, "%s_%d" % (name, i)) for i in range(n-1, -1, -1)])

for pllid in ic.pll_list():
    pllinfo = icebox.pllinfo_db[pllid]
    plltype = get_pll_bits(pllinfo, "PLLTYPE", 3)
    if plltype != "000":
        pll_locations.add(pllid)

if verbose:
    print()

print("DFFs:   %4d" % len(dff_locations))
print("LUTs:   %4d" % len(lut_locations))
print("CARRYs: %4d" % len(carry_locations))
print("BRAMs:  %4d" % len(bram_locations))
print("IOBs:   %4d" % len(io_locations))
print("PLLs:   %4d" % len(pll_locations))
print("GLBs:   %4d" % len(global_nets))

