# 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 = 2

root = sys.argv[2]

for x in range(X):
	buffers_by_type = {"BUFGCTRL": [], "BUFGCE": [], "BUFGCE_DIV": []}

	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)
		#tile_buffers = 8
		found_buffers = 0
		for buf, buftype in shuffled_bufs:
			buffers_by_type[buftype].append(buf)
			print("%s %s" % (tile, buf))
			found_buffers += 1
	np.random.shuffle(buffers_by_type["BUFGCE"])
	np.random.shuffle(buffers_by_type["BUFGCTRL"])
	np.random.shuffle(buffers_by_type["BUFGCE_DIV"])
	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 + "/clkroute6/gclkd_%d.v" % x, "w") as f:
		print("module top(input [29:0] i, input [9:0] aux, input d, output o, q);", file=f)
		N = 30
		print("    wire [29: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)
		for i in range(15):
			print("    (* LOC=\"%s\", KEEP, DONT_TOUCH *)" % buffers_by_type["BUFGCE_DIV"].pop(), file=f)
			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)
			if np.random.choice([True, False]):
				print("        .I(i[%d])," % i, file=f)
			print("        %s," % random_control(["CE", "CLR"]), file=f)
			print("        .O(r[%d])" % (i), file=f)
			print("    );", file=f)
		for i in range(15):
			print("    (* LOC=\"%s\", KEEP, DONT_TOUCH *)" % buffers_by_type["BUFGCTRL"].pop(), file=f)
			print("    BUFGCTRL", file=f)
			print("    bufgctrl_%d (" % i, file=f)
			if np.random.choice([True, False]):
				print("        .I0(i[%d])," % (i + 15), file=f)
			elif np.random.choice([True, False]):
				print("        .I1(i[%d])," % (i + 15), file=f)
			print("        %s," % random_control(["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
			print("        .O(r[%d])" % (i+15), file=f)
			print("    );", file=f)
		# for i in range(8):
		# 	print("    (* LOC=\"%s\" *)" % buffers_by_type["BUFGCE"].pop(), file=f)
		# 	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])," % (i+16), file=f)
		# 	print("        %s," % random_control(["CE"]), file=f)
		# 	print("        .O(r[%d])" % (i+16), file=f)
		# 	print("    );", file=f)

		R2=0
		NS=64
		ffs=""
		for i in range(30):
			ffs += "FDCE ff_%d (.C(r[%d]), .CE(aux[%d]), .CLR(~aux[%d]), .D(r2[%d]), .Q(r2[%d]));\n" % (i, i, np.random.randint(10), 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 + "/clkroute6/gclkd_%d.tcl" % x, "w") as f:
		print("add_files %s" % (root + ("/clkroute6/gclkd_%d.v" % x)), file=f)
		#print("read_xdc %s" % (root + ("/clkroute6/gclkd_%d.xdc" % x)), file=f)
		print("synth_design -top top -part xczu7ev-ffvf1517-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/ioexp/gclkd_%d.dcp" % (root, x), file=f)
		print("write_edif -force %s/ioexp/gclkd_%d.edf" % (root, x), file=f)
		print("write_bitstream -force %s/ioexp/gclkd_%d.bit" % (root, x), file=f)
with open(root + "/clkroute6/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 gclkd_%d.tcl" % x, file=f)
