#!/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

check_mode = False
fixup_mode = False

def usage():
    print("""
Usage: icebox_colbuf [options] [input.asc [output.asc]]

    -c
        check colbuf bits

    -f
        fix colbuf bits
""")
    sys.exit(1)

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

for o, a in opts:
    if o == "-c":
        check_mode = True
    elif o == "-f":
        fixup_mode = True
    else:
        usage()

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

if len(args) not in [1, 2]:
    usage()

if check_mode == fixup_mode:
    print("Error: Use either -c or -f!")
    sys.exit(1)

print("Reading file '%s'.." % args[0])
ic = icebox.iceconfig()
ic.read_file(args[0])

def make_cache(stmt, raw_db):
    cache = list()
    for entry in raw_db:
        if entry[1] == stmt and entry[2].startswith("glb_netwk_"):
            cache_entry = [int(entry[2][-1]), []]
            for bit in entry[0]:
                value = "1"
                if bit.startswith("!"):
                    value = "0"
                    bit = bit[1:]
                match = re.match("B([0-9]+)\[([0-9]+)\]", bit)
                cache_entry[1].append((int(match.group(1)), int(match.group(2)), value))
            cache.append(cache_entry)
    return cache

def match_cache_entry(cache_entry, tile_dat):
    for entry in cache_entry[1]:
        if tile_dat[entry[0]][entry[1]] != entry[2]:
            return False
    return True

def analyze_tile(ic, cache, tile_pos):
    glbs = set()
    tile_dat = ic.tile(tile_pos[0], tile_pos[1])
    for cache_entry in cache:
        if match_cache_entry(cache_entry, tile_dat):
            glbs.add(cache_entry[0])
    return glbs

colbuf_map = dict()
used_glbs_map = dict()
driven_glbs_map = dict()

for entry in ic.colbuf_db():
    colbuf_map[(entry[2], entry[3])] = (entry[0], entry[1])

for tiles in [ic.io_tiles, ic.logic_tiles, ic.ramb_tiles, ic.ramt_tiles]:
    cache = None
    for tile in tiles:
        if cache is None:
            cache = make_cache("buffer", ic.tile_db(tile[0], tile[1]))
        glbs = analyze_tile(ic, cache, tile)
        if len(glbs):
            assert tile in colbuf_map
            s = used_glbs_map.setdefault(colbuf_map[tile], set())
            used_glbs_map[colbuf_map[tile]] = s.union(glbs)

    cache = None
    for tile in tiles:
        if cache is None:
            cache = make_cache("ColBufCtrl", ic.tile_db(tile[0], tile[1]))
        glbs = analyze_tile(ic, cache, tile)
        if len(glbs):
            driven_glbs_map[tile] = glbs

def set_colbuf(ic, tile, bit, value):
    tile_dat = ic.tile(tile[0], tile[1])
    tile_db = ic.tile_db(tile[0], tile[1])
    for entry in tile_db:
        if entry[1] == "ColBufCtrl" and entry[2] == "glb_netwk_%d" % bit:
            match = re.match("B([0-9]+)\[([0-9]+)\]", entry[0][0])
            l = tile_dat[int(match.group(1))]
            n = int(match.group(2))
            l = l[:n] + value + l[n+1:]
            tile_dat[int(match.group(1))] = l
            return
    assert False

error_count = 0
correct_count = 0
for tile, bits in sorted(used_glbs_map.items()):
    for bit in bits:
        if tile not in driven_glbs_map or bit not in driven_glbs_map[tile]:
            print("Missing driver for glb_netwk_%d in tile %s" % (bit, tile))
            set_colbuf(ic, tile, bit, "1")
            error_count += 1
for tile, bits in sorted(driven_glbs_map.items()):
    for bit in bits:
        if tile not in used_glbs_map or bit not in used_glbs_map[tile]:
            print("Unused driver for glb_netwk_%d in tile %s" % (bit, tile))
            set_colbuf(ic, tile, bit, "0")
            error_count += 1
        else:
            # print("Correct driver for glb_netwk_%d in tile %s" % (bit, tile))
            correct_count += 1
print("Found %d correct driver bits." % correct_count)
if error_count != 0:
    if not fixup_mode:
        print("Found %d errors!" % error_count)
        sys.exit(1)
    ic.write_file(args[0] if len(args) == 1 else args[1])
    print("Corrected %d errors." % error_count)
else:
    print("No errors found.")

