# 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 numpy as np
import sys

bufgces_by_tile = {}
with open(sys.argv[1], "r") as tf:
    for line in tf:
        sl = line.strip().split(",")
        if len(sl) < 4:
            continue
        for site in sl[4:]:
            if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
                if sl[2] not in bufgces_by_tile:
                    bufgces_by_tile[sl[2]] = []
                bufgces_by_tile[sl[2]].append(site.split(":"))

X = 64

root = sys.argv[2]

for x in range(X):
    buffers = []

    tiles = list(sorted(bufgces_by_tile.keys()))
    np.random.shuffle(tiles)

    for tile in tiles:
        shuffled_bufs = list(bufgces_by_tile[tile])
        np.random.shuffle(shuffled_bufs)
        target_type = np.random.choice(
            ["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"]
            if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
        tile_buffers = np.random.randint(8)
        found_buffers = 0
        for buf, buftype in shuffled_bufs:
            if found_buffers >= tile_buffers:
                break
            if buftype != target_type:
                continue
            buffers.append((buf, buftype))
            print("%s %s" % (tile, buf))
            found_buffers += 1
    print()

    def random_inversion(pins):
        return ", ".join(
            [".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])

    def random_control(pins):
        return ", ".join(
            [".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])

    with open(root + "/clkroute3/gclk%d.v" % x, "w") as f:
        print("module top(input i, input [9:0] aux, d, output o, q);", file=f)
        N = len(buffers)
        print("    wire [%d:0] r;" % N, file=f)
        print("    assign r[0] = i;", file=f)
        print("    assign o = r[%d];" % N, file=f)
        print("    wire [%d:0] r2;" % (2 * N), file=f)
        print("    assign r2[0] = d;", file=f)
        print("    assign q = r2[%d];" % (2 * N), file=f)
        for i in range(N):
            bg, buftype = buffers[i]
            print("(* LOC=\"%s\" *)" % bg, file=f)
            if "BUFGCTRL" in buftype:
                print("    BUFGCTRL #(", file=f)
                print(
                    "        %s," % random_inversion([
                        "I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0",
                        "IGNORE1"
                    ]),
                    file=f)
                print(
                    "        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")"
                    % (np.random.randint(2), np.random.choice([
                        "TRUE", "FALSE"
                    ]), np.random.choice(["TRUE", "FALSE"])),
                    file=f)
                print("    ) bufgctrl_%d (" % i, file=f)
                print(
                    "        .I0(r[%d]), .I1(r[%d]), " %
                    (i, np.random.randint(i + 1)),
                    file=f)
                print(
                    "        %s," % random_control(
                        ["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]),
                    file=f)
                print("        .O(r[%d])" % (i + 1), file=f)
                print("    );", file=f)
            elif "DIV" in buftype:
                print("    BUFGCE_DIV #(", file=f)
                print(
                    "        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9),
                    file=f)
                print(
                    "        %s" % random_inversion(["I", "CE", "CLR"]),
                    file=f)
                print("    ) bufgce_div_%d (" % i, file=f)
                print("        .I(r[%d])," % i, file=f)
                print("        %s," % random_control(["CE", "CLR"]), file=f)
                print("        .O(r[%d])" % (i + 1), file=f)
                print("    );", file=f)
            else:
                print("    BUFGCE #(", file=f)
                print(
                    "        .CE_TYPE(\"%s\")," % np.random.choice(
                        ["SYNC", "ASYNC"]),
                    file=f)
                print("        %s" % random_inversion(["I", "CE"]), file=f)
                print("    ) bufgce_div_%d (" % i, file=f)
                print("        .I(r[%d])," % i, file=f)
                print("        %s," % random_control(["CE"]), file=f)
                print("        .O(r[%d])" % (i + 1), file=f)
                print("    );", file=f)

            if np.random.randint(2) == 1:
                print(
                    "FDCE ff_%d(.C(r[%d]), .CE(1'b1), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));"
                    % (i, i, 2 * i, 2 * i + 1),
                    file=f)
            else:
                print("assign r2[%d] = r2[%d];" % (2 * i + 1, 2 * i), file=f)

            if np.random.randint(2) == 1:
                print(
                    "SRLC32E srl_%d(.CLK(r[%d]), .CE(1'b1), .A(aux[4:0]), .D(r2[%d]), .Q(r2[%d]));"
                    % (i, i, 2 * i + 1, 2 * i + 2),
                    file=f)
            else:
                print(
                    "assign r2[%d] = r2[%d];" % (2 * i + 2, 2 * i + 1), file=f)

            print("", file=f)
        print("endmodule", file=f)
    with open(root + "/clkroute3/gclk%d.tcl" % x, "w") as f:
        print("add_files %s" % (root + ("/clkroute3/gclk%d.v" % x)), file=f)
        #print("read_xdc %s" % (root + ("/clkroute3/gclk%d.xdc" % x)), file=f)
        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
        print("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
        print("opt_design", file=f)
        print("place_design", file=f)
        print("route_design", file=f)
        print(
            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
        print(
            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
        print(
            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
            file=f)
        print(
            "write_checkpoint -force %s/specimen_clk/gclk%d.dcp" % (root, x),
            file=f)
        print(
            "write_edif -force %s/specimen_clk/gclk%d.edf" % (root, x), file=f)
        print(
            "write_bitstream -force %s/specimen_clk/gclk%d.bit" % (root, x),
            file=f)
with open(root + "/clkroute3/run.sh", "w") as f:
    print("#/usr/bin/env bash", file=f)
    #print("set -ex", file=f)
    for x in range(X):
        print(
            "vivado -mode batch -nolog -nojournal -source gclk%d.tcl" % x,
            file=f)
        print("if [ $? -eq 0 ]; then", file=f)
        print(
            "    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclk%d.bit %s/frames.txt > %s/specimen_clk/gclk%d.dump"
            % (root, x, root, root, x),
            file=f)
        print(
            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclk%d.dump > %s/specimen_clk/gclk%d.tbits"
            % (root, root, x, root, x),
            file=f)
        print("else", file=f)
        print("   rm %s/specimen_clk/gclk%d.dump" % (root, x), file=f)
        print("   rm %s/specimen_clk/gclk%d.tbits" % (root, x), file=f)
        print("   rm %s/specimen_clk/gclk%d.dcp" % (root, x), file=f)
        print("   rm %s/specimen_clk/gclk%d.bit" % (root, x), file=f)
        print("   rm %s/specimen_clk/gclk%d.features" % (root, x), file=f)
        print("fi", file=f)
