# 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 = {}
tiles_by_xy = {}
rclk_int_l = []
slices_by_tile = {}
with open(sys.argv[1], "r") as tf:
	for line in tf:
		sl = line.strip().split(",")
		if len(sl) < 4:
			continue
		tiles_by_xy[int(sl[0]), int(sl[1])] = sl[2]
		if sl[2].startswith("RCLK_INT_L"):
			rclk_int_l.append((int(sl[0]), int(sl[1]), sl[2]))
		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(":"))
			elif "SLICE_" in site:
				slices_by_tile[int(sl[0]), int(sl[1])] = site.split(":")[0]

halfcolumn_slices_by_row = {}
for x, y, rclk in rclk_int_l:
	hc_up = []
	hc_down = []
	if y not in halfcolumn_slices_by_row:
		halfcolumn_slices_by_row[y] = []
	for yplus in range(y+1, y+31):
		if (x, yplus) not in tiles_by_xy:
			continue
		if not tiles_by_xy[x, yplus].startswith("INT_"):
			break
		slice_x = x + np.random.choice([+1, -1])
		if (slice_x, yplus) not in slices_by_tile:
			continue
		hc_up.append(slices_by_tile[slice_x, yplus])
	for yminus in range(y-1, y-31, -1):
		if (x, yminus) not in tiles_by_xy:
			continue
		if not tiles_by_xy[x, yminus].startswith("INT_"):
			break
		slice_x = x + np.random.choice([+1, -1])
		if (slice_x, yminus) not in slices_by_tile:
			continue
		hc_down.append(slices_by_tile[slice_x, yminus])
	halfcolumn_slices_by_row[y].append(hc_up)
	halfcolumn_slices_by_row[y].append(hc_down)

X = 32

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(6)
		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
	
	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 + "/clkroute4/gclkb_%d.v" % x, "w") as f:
		print("module top(input [23:0] i, input [9:0] aux, input d, output o, q);", file=f)
		N = 24
		print("    wire [71:0] r;", file=f)
		# print("    assign r[0] = i;", file=f)
		# print("    assign o = r[%d];" % 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)
		print("    assign r[23:0] = i;", file=f)
		for i in range(12):
			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(i[%d])," % i, file=f)
			print("        %s," % random_control(["CE", "CLR"]), file=f)
			print("        .O(r[%d])" % (24+i), file=f)
			print("    );", file=f)
		for i in range(36):
			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_%d (" % i, file=f)
			print("        .I(i[%d])," %  np.random.randint(24), file=f)
			print("        %s," % random_control(["CE"]), file=f)
			print("        .O(r[%d])" % (i+36), file=f)
			print("    );", file=f)

		R2=0
		NS=16
		ffs=""
		for row, hcs in sorted(halfcolumn_slices_by_row.items()):
			row_clks = np.random.randint(16, 25)
			clks = [np.random.randint(72) for k in range(row_clks)]
			halfs = [hcs[np.random.randint(len(hcs))] for k in range(NS)]
			for h in halfs:
				half_clks = np.random.randint(8, 17)
				rclks = [np.random.choice(clks) for k in range(half_clks)]
				for sl in h:
					ffs += "(* LOC=\"%s\" *) FDCE ff_%d (.C(r[%d]), .CE(aux[%d]), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));\n" % (sl, R2, np.random.choice(rclks), np.random.randint(10), R2, R2+1)
					R2 += 1
		print("    wire [%d:0] r2;" % R2, file=f)
		print("    assign r2[0] = d;", file=f)
		print("    assign q = r2[%d];" % R2, file=f)
		print(ffs, file=f)
		print("endmodule", file=f)
	with open(root + "/clkroute4/gclkb_%d.tcl" % x, "w") as f:
		print("add_files %s" % (root + ("/clkroute4/gclkb_%d.v" % x)), file=f)
		#print("read_xdc %s" % (root + ("/clkroute4/gclkb_%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/gclkb_%d.dcp" % (root, x), file=f)
		print("write_edif -force %s/specimen_clk/gclkb_%d.edf" % (root, x), file=f)
		print("write_bitstream -force %s/specimen_clk/gclkb_%d.bit" % (root, x), file=f)
with open(root + "/clkroute4/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 gclkb_%d.tcl" % x, file=f)
		print("if [ $? -eq 0 ]; then", file=f)
		print("    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclkb_%d.bit %s/frames.txt > %s/specimen_clk/gclkb_%d.dump" % (root, x, root, root, x), file=f)
		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclkb_%d.dump > %s/specimen_clk/gclkb_%d.tbits" % (root, root, x, root, x), file=f)
		print("else", file=f)
		print("   rm %s/specimen_clk/gclkb_%d.dump" % (root, x), file=f)
		print("   rm %s/specimen_clk/gclkb_%d.tbits" % (root, x), file=f)
		print("   rm %s/specimen_clk/gclkb_%d.dcp" % (root, x), file=f)
		print("   rm %s/specimen_clk/gclkb_%d.bit" % (root, x), file=f)
		print("   rm %s/specimen_clk/gclkb_%d.features" % (root, x), file=f)
		print("fi", file=f)