# Copyright 2020 Project U-Ray Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import re
import sys
import json

tiles = {}
site_to_tile = {}
tile_to_bits = {}  # (frame, bit start, bit size)

with open(sys.argv[1], 'r') as tilef:
    for line in tilef:
        sl = line.strip().split(",")
        if len(sl) < 4:
            continue
        x = int(sl[0])
        y = int(sl[1])
        name = sl[2]
        ttype = sl[3]
        tiles[(x, y)] = (name + ":" + ttype, ttype, [])
        for site in sl[4:]:
            sitename, sitetype = site.split(":")
            tiles[(x, y)][2].append((sitename, sitetype))
            site_to_tile[sitename] = (x, y)

ll_line_re = re.compile(
    r'Bit\s+\d+\s+(0x[0-9A-Fa-f]+)\s+(\d+)\s+SLR\d\s+\d+\s+Block=([A-Za-z0-9_]+).*'
)
site_re = re.compile(r'SLICE_X(\d+)Y(\d+)')
with open(sys.argv[2], 'r') as llf:
    for line in llf:
        m = ll_line_re.match(line)
        if not m:
            continue
        frame = int(m.group(1), 16)
        bit = int(m.group(2))
        start_bit = bit - 2
        site = m.group(3)
        bus = (frame >> 24) & 0x7
        half = (frame >> 23) & 0x1
        row = (frame >> 18) & 0x1F
        col = (frame >> 8) & 0x3FF
        m = frame & 0xFF

        sm = site_re.match(site)
        site_x = int(sm.group(1))
        site_y = int(sm.group(2))
        frame_upper = frame & ~0xFF

        if site not in site_to_tile:
            continue
        tx, ty = site_to_tile[site]
        tiledata = tiles[tx, ty]
        tile_to_bits[tiledata[0]] = []
        for m in range(16):
            tile_to_bits[tiledata[0]].append((frame_upper | m, start_bit, 48))

        def process_nonlogic(x, y, icol):
            if (x, y) not in tiles:
                return
            itiledata = tiles[x, y]
            if itiledata[1] == "INT":
                if (x + 1, y) not in tiles:
                    return

                int_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
                tile_to_bits[itiledata[0]] = []
                for m in range(76):
                    tile_to_bits[itiledata[0]].append((int_frame_base | m,
                                                       start_bit, 48))
                process_clock(x, y - 1, int_frame_base, start_bit + 48, 76)
                process_cmt(x - 2, y, icol - 2)
                process_int_intf(x - 1, y, icol - 1)
            elif itiledata[1] == "BRAM":
                bram_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
                tile_to_bits[itiledata[0]] = []
                for m in range(6):
                    tile_to_bits[itiledata[0]].append((bram_frame_base | m,
                                                       start_bit, 5 * 48))
                process_clock(x, y - 5, bram_frame_base, start_bit + 5 * 48, 6)
            elif itiledata[1] == "DSP":
                dsp_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
                tile_to_bits[itiledata[0]] = []
                for m in range(8):
                    tile_to_bits[itiledata[0]].append((dsp_frame_base | m,
                                                       start_bit, 5 * 48))
                process_clock(x, y - 5, dsp_frame_base, start_bit + 5 * 48, 8)

                if (x - 1, y) in tiles and "INT_INTF" in tiles[x - 1, y][1]:
                    process_clock(x - 1, y - 5, dsp_frame_base,
                                  start_bit + 5 * 48, 8)

        def process_clock(cx, cy, frame_base, end_bit, height):
            if (cx, cy) not in tiles:
                return
            if end_bit != (1392 + 48):
                return
            ctiledata = tiles[cx, cy]
            if not ctiledata[1].startswith("RCLK"):
                return
            tile_to_bits[ctiledata[0]] = []
            for m in range(height):
                tile_to_bits[ctiledata[0]].append((frame_base | m,
                                                   end_bit + 48, 48))

        def process_cmt(x, y, icol):
            if (x, y) not in tiles:
                return
            ctiledata = tiles[x, y]
            if not ctiledata[1] in ("CMT_L", "CMT_RIGHT"):
                return
            cmt_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
            tile_to_bits[ctiledata[0]] = []
            for m in range(12):
                tile_to_bits[ctiledata[0]].append((cmt_frame_base | m,
                                                   start_bit, 60 * 48))

        def process_int_intf(x, y, icol):
            if (x, y) not in tiles:
                return
            itiledata = tiles[x, y]
            if not itiledata[1] in ("INT_INTF_L_IO", "INT_INTF_R_IO"):
                return
            int_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
            tile_to_bits[itiledata[0]] = []
            for m in range(4):
                tile_to_bits[itiledata[0]].append((int_frame_base | m,
                                                   start_bit, 48))

        process_nonlogic(tx - 1, ty, col - 1)
        process_nonlogic(tx + 1, ty, col + 1)
        process_clock(tx, ty - 1, frame_upper, start_bit + 48, 16)
# Original JSON
with open(sys.argv[3], 'w') as tj:
    tj.write(
        json.dumps(
            tile_to_bits, sort_keys=True, indent=4, separators=(',', ': ')))
    tj.write("\n")
# New simplified text format
with open(sys.argv[4], 'w') as tf:
    for loc, tiledata in sorted(tiles.items()):
        print(
            ".tile %s %s %d %d" % (tiledata[0].split(":")[0], tiledata[1],
                                   loc[0], loc[1]),
            file=tf)
        for site in tiledata[2]:
            print("site %s %s" % site, file=tf)
        if tiledata[0] in tile_to_bits:
            for frame, offset, size in tile_to_bits[tiledata[0]]:
                print(
                    "frame 0x%08x bits %d +: %d" % (frame, offset, size),
                    file=tf)
