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

mode_384 = False
mode_lm4k = False
mode_5k = False
mode_8k = False

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

    -3
        create chipdb for 384 device

    -5
        create chipdb for 5k device

    -8
        create chipdb for 8k device

    -4
        create chipdb for lm4k device
""")
    sys.exit(0)

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

for o, a in opts:
    if o == "-8":
        mode_8k = True
    elif o == "-5":
        mode_5k = True
    elif o == "-3":
        mode_384 = True
    elif o == "-4":
        mode_lm4k = True
    else:
        usage()

ic = icebox.iceconfig()
if mode_8k:
    ic.setup_empty_8k()
elif mode_5k:
    ic.setup_empty_5k()
elif mode_384:
    ic.setup_empty_384()
elif mode_lm4k:
    ic.setup_empty_lm4k()
else:
    ic.setup_empty_1k()

all_tiles = set()
for x in range(ic.max_x+1):
    for y in range(ic.max_y+1):
        if ic.tile(x, y) is not None:
            all_tiles.add((x, y))

seg_to_net = dict()
net_to_segs = list()

print("""#
# IceBox Chip Database Dump (iCE40 %s)
#
#
# Quick File Format Reference:
# ----------------------------
#
# .device DEVICE WIDTH HEIGHT NUM_NETS
#
#    declares the device type
#
#
# .pins PACKAGE
# PIN_NUM TILE_X TILE_Y PIO_NUM
# ...
#
#    associates a package pin with an IO tile and block, and global network
#
#
# .gbufin
# TILE_X TILE_Y GLB_NUM
# ...
#
#    associates an IO tile with the global network can drive via fabout
#
#
# .gbufpin
# TILE_X TILE_Y PIO_NUM GLB_NUM
# ...
#
#    associates an IO tile with the global network can drive via the pad
#
#
# .iolatch
# TILE_X TILE_Y
# ...
#
#    specifies the IO tiles that drive the latch signal for the bank via fabout
#
#
# .ieren
# PIO_TILE_X PIO_TILE_Y PIO_NUM IEREN_TILE_X IEREN_TILE_Y IEREN_NUM
# ...
#
#    associates an IO block with an IeRen-block
#
#
# .colbuf
# SOURCE_TILE_X SOURCE_TILE_Y DEST_TILE_X DEST_TILE_Y
# ...
#
#    declares the positions of the column buffers
#
#
# .io_tile X Y
# .logic_tile X Y
# .ramb_tile X Y
# .ramt_tile X Y
# .dsp[0..3]_tile X Y
# .ipcon_tile X Y
#    declares the existence of a IO/LOGIC/RAM tile with the given coordinates
#
#
# .io_tile_bits COLUMNS ROWS
# .logic_tile_bits COLUMNS ROWS
# .ramb_tile_bits COLUMNS ROWS
# .ramt_tile_bits COLUMNS ROWS
# .dsp[0..3]_tile_bits X Y
# .ipcon_tile_bits X Y
# FUNCTION_1 CONFIG_BITS_NAMES_1
# FUNCTION_2 CONFIG_BITS_NAMES_2
# ...
#
#    declares non-routing configuration bits of IO/LOGIC/RAM tiles
#
#
# .extra_cell X Y <cell-type>
# .extra_cell X Y Z <cell-type>
# KEY MULTI-FIELD-VALUE
# ....
#
#    declares a special-purpose cell that is not part of the FPGA fabric
#
#
# .extra_bits
# FUNCTION BANK_NUM ADDR_X ADDR_Y
# ...
#
#    declares non-routing global configuration bits
#
#
# .net NET_INDEX
# X1 Y1 name1
# X2 Y2 name2
# ...
#
#    declares a net on the chip and lists its various names in different tiles
#
#
# .buffer X Y DST_NET_INDEX CONFIG_BITS_NAMES
# CONFIG_BITS_VALUES_1 SRC_NET_INDEX_1
# CONFIG_BITS_VALUES_2 SRC_NET_INDEX_2
# ...
#
#    declares a buffer in the specified tile
#
#
# .routing X Y DST_NET_INDEX CONFIG_BITS_NAMES
# CONFIG_BITS_VALUES_1 SRC_NET_INDEX_1
# CONFIG_BITS_VALUES_2 SRC_NET_INDEX_2
# ...
#
#    declares a routing switch in the specified tile
#
""" % ic.device)

all_group_segments = ic.group_segments(all_tiles, connect_gb=False)

print(".device %s %d %d %d" % (ic.device, ic.max_x+1, ic.max_y+1, len(all_group_segments)))
print()

for key in sorted(icebox.pinloc_db.keys()):
    key_dev, key_package = key.split("-")
    if key_dev == ic.device:
        print(".pins %s" % (key_package))
        for entry in sorted(icebox.pinloc_db[key]):
            print("%s %d %d %d" % entry)
        print()

print(".gbufin")
for entry in sorted(ic.gbufin_db()):
    print(" ".join(["%d" % k for k in entry]))
print()

print(".gbufpin")
for padin, pio in enumerate(ic.padin_pio_db()):
    entry = pio + (padin,)
    print(" ".join(["%d" % k for k in entry]))
print()

print(".iolatch")
for entry in sorted(ic.iolatch_db()):
    print(" ".join(["%d" % k for k in entry]))
print()

print(".ieren")
for entry in sorted(ic.ieren_db()):
    print(" ".join(["%d" % k for k in entry]))
print()

print(".colbuf")
for entry in sorted(ic.colbuf_db()):
    print(" ".join(["%d" % k for k in entry]))
print()

for idx in sorted(ic.io_tiles):
    print(".io_tile %d %d" % idx)
print()

for idx in sorted(ic.logic_tiles):
    print(".logic_tile %d %d" % idx)
print()

for idx in sorted(ic.ramb_tiles):
    print(".ramb_tile %d %d" % idx)
print()

for idx in sorted(ic.ramt_tiles):
    print(".ramt_tile %d %d" % idx)
print()

for dsp_idx in range(4):
    for idx in sorted(ic.dsp_tiles[dsp_idx]):
        x, y = idx
        print(".dsp%d_tile %d %d" % (dsp_idx, x, y))
    print()    

for idx in sorted(ic.ipcon_tiles):
    print(".ipcon_tile %d %d" % idx)
print()

def print_tile_nonrouting_bits(tile_type, idx):
    tx = idx[0]
    ty = idx[1]

    tile = ic.tile(tx, ty)

    print(".%s_tile_bits %d %d" % (tile_type, len(tile[0]), len(tile)))

    function_bits = dict()
    for entry in ic.tile_db(tx, ty):
        if not ic.tile_has_entry(tx, ty, entry):
            continue
        if entry[1] in ("routing", "buffer"):
            continue

        func = ".".join(entry[1:])
        function_bits[func] = entry[0]

    for x in sorted(function_bits):
        print(" ".join([x] + function_bits[x]))
    print()

print_tile_nonrouting_bits("logic", list(ic.logic_tiles.keys())[0])
print_tile_nonrouting_bits("io", list(ic.io_tiles.keys())[0])
if not mode_384:
    print_tile_nonrouting_bits("ramb", list(ic.ramb_tiles.keys())[0])
    print_tile_nonrouting_bits("ramt", list(ic.ramt_tiles.keys())[0])

if ic.is_ultra():
    for dsp_idx in range(4):
        print_tile_nonrouting_bits("dsp%d" % dsp_idx, list(ic.dsp_tiles[dsp_idx].keys())[0])
    print_tile_nonrouting_bits("ipcon", list(ic.ipcon_tiles.keys())[0])
if ic.is_ultra():
    print(".extra_cell %d 0 WARMBOOT" % ic.max_x)
else:
    print(".extra_cell 0 0 WARMBOOT")
for key in sorted(icebox.warmbootinfo_db[ic.device]):
    print("%s %s" % (key, " ".join([str(k) for k in icebox.warmbootinfo_db[ic.device][key]])))
print()

for pllid in ic.pll_list():
    pllinfo = icebox.pllinfo_db[pllid]
    print(".extra_cell %d %d PLL" % pllinfo["LOC"])
    locked_pkgs = []
    for entry in icebox.noplls_db:
        if pllid in icebox.noplls_db[entry]:
            locked_pkgs.append(entry.split("-")[1])
    if len(locked_pkgs) > 0:
        print("LOCKED %s" % " ".join(sorted(locked_pkgs)))
    for key in sorted(pllinfo):
        if key != "LOC":
            print("%s %s" % (key, " ".join([str(k) for k in pllinfo[key]])))
    print()

for dsploc in ic.dsp_tiles[0]:
    x, y = dsploc
    print(".extra_cell %d %d 0 MAC16" % dsploc)
    nets = ic.get_dsp_nets_db(x, y)
    for key in sorted(nets):
        print("%s %s" % (key, " ".join([str(k) for k in nets[key]])))
    
    cfg = ic.get_dsp_config_db(x, y)
    for key in sorted(cfg):
        print("%s %s" % (key, " ".join([str(k) for k in cfg[key]])))
    print()
    
if ic.device in icebox.extra_cells_db:
    for cell in sorted(icebox.extra_cells_db[ic.device]):
        name, loc = cell
        x, y, z = loc
        print(".extra_cell %d %d %d %s" % (x, y, z, name))
        cellinfo = icebox.extra_cells_db[ic.device][cell]
        for key in sorted(cellinfo):
            print("%s %s" % (key, " ".join([str(k) for k in cellinfo[key]])))
        print()
     
if ic.device in icebox.spram_db:
    for cell in sorted(icebox.spram_db[ic.device]):
        loc = cell
        x, y, z = loc
        print(".extra_cell %d %d %d SPRAM" % (x, y, z))
        cellinfo = icebox.spram_db[ic.device][cell]
        for key in sorted(cellinfo):
            print("%s %s" % (key, " ".join([str(k) for k in cellinfo[key]])))
        print()
     
print(".extra_bits")
extra_bits = dict()
for idx in sorted(ic.extra_bits_db()):
    extra_bits[".".join(ic.extra_bits_db()[idx])] = " ".join(["%d" % k for k in idx])
for idx in sorted(extra_bits):
    print("%s %s" % (idx, extra_bits[idx]))
print()

for group in sorted(all_group_segments):
    netidx = len(net_to_segs)
    net_to_segs.append(group)
    print(".net %d" % netidx)
    for seg in group:
        print("%d %d %s" % seg)
        assert seg not in seg_to_net
        seg_to_net[seg] = netidx
    print()

for idx in sorted(all_tiles):
    db = ic.tile_db(idx[0], idx[1])
    db_by_bits = dict()
    for entry in db:
        if entry[1] in ("buffer", "routing") and ic.tile_has_net(idx[0], idx[1], entry[2]) and ic.tile_has_net(idx[0], idx[1], entry[3]):
            bits = tuple([entry[1]] + sorted([bit.replace("!", "") for bit in entry[0]]))
            db_by_bits.setdefault(bits, list()).append(entry)
    for bits in sorted(db_by_bits):
        dst_net = None
        for entry in sorted(db_by_bits[bits]):
            assert (idx[0], idx[1], entry[3]) in seg_to_net
            if dst_net is None:
                dst_net = seg_to_net[(idx[0], idx[1], entry[3])]
            else:
                assert dst_net == seg_to_net[(idx[0], idx[1], entry[3])]
        print(".%s %d %d %d %s" % (bits[0], idx[0], idx[1], dst_net, " ".join(bits[1:])))
        for entry in sorted(db_by_bits[bits]):
            pattern = ""
            for bit in bits[1:]:
                pattern += "1" if bit in entry[0] else "0"
            assert (idx[0], idx[1], entry[2]) in seg_to_net
            print("%s %d" % (pattern, seg_to_net[(idx[0], idx[1], entry[2])]))
        print()
