# 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

print("module top(input [15:0] clk, sr, ce, input [7:0] d, output [31:0] q);")
N = 350
D = ["d[%d]" % i for i in range(8)]

slices = []
with open(sys.argv[1], "r") as tf:
	for line in tf:
		sl = line.strip().split(",")
		if len(sl) < 4:
			continue
		if "CLEM" not in sl[3]:
			continue
		for site in sl[4:]:
			if "SLICEM" in site or "SLICEL" in site:
				slices.append(site.split(":")[0])

np.random.shuffle(slices)

for i in range(N):
	sl = slices.pop()
	ffmode = np.random.randint(3, size=2)
	clk = tuple(np.random.randint(16, size=2))
	wclk = None
	while wclk is None or wclk in clk:
		wclk = np.random.randint(16)
	sr = tuple(["1'b1" if y >= 16 else "sr[%d]" % y for y in np.random.randint(25, size=2)])
	ce = tuple(["1'b1" if y >= 16 else "ce[%d]" % y for y in np.random.randint(25, size=4)])
	we = np.random.randint(16)
	def random_fftype(mode):
		if mode == 0:
			return np.random.choice(["NONE", "FDSE", "FDRE"])
		elif mode == 1:
			return np.random.choice(["NONE", "FDPE", "FDCE"])
		elif mode == 2:
			return np.random.choice(["NONE", "LDPE", "LDCE"])

	def random_bit():
		return np.random.choice(D)

	def random_data(width):
		return "{%s}" % (", ".join([random_bit() for k in range(width)]))

	#fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
	fftypes = ["NONE" for j in range(16)]

	dimux = []
	mode = []
	ram_legal = True
	for lut in "HGFEDCBA":
		choices = ["LOGIC"]
		if lut == "H":
			choices += ["RAMD64", "RAMS64", "RAMD32", "SRL16", "SRL32"]
		else:
			if mode[0][0:3] != "RAM":
				choices += ["SRL16", "SRL32"]
			if ram_legal:
				choices.append(mode[0])
		p = [0.1]
		for j in range(1, len(choices)):
			p.append(0.9 / (len(choices) - 1))
		if len(choices) == 1:
			p[0] = 1
		next_mode = np.random.choice(choices, p=p)
		if len(mode) > 0 and mode[-1] == "SRL32" and next_mode == "SRL32":
			dimux.append(np.random.choice(["DI", "SIN"], p=[0.2, 0.8]))
		else:
			dimux.append("DI")
		if next_mode[0:3] != "RAM":
			ram_legal = False
		mode.append(next_mode)

	dimux = list(reversed(dimux))
	mode = list(reversed(mode))

	print('   wire [31:0] d%d;' % i)
	print('   ultra_slice_memory #(')
	print('      .LOC("%s"),' % sl)
	for j in range(8):
		print('      .%s_MODE("%s"),' % ("ABCDEFGH"[j], mode[j]))
	for lut in "ABCDEFGH":
		print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(str(_) for _ in np.random.randint(2, size=64))))
	for j in range(16):
		print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH"[j//2], "2" if (j % 2) == 1 else "", fftypes[j]))
	print("      .FF_INIT(16'b%s)," % "".join(str(_) for _ in np.random.randint(2, size=16)))
	for j1 in "ABCDEFGH":
		for j2 in ("1", "2"):
			print('        .FFMUX%s%s("%s"),' % (j1, j2, np.random.choice(["F7F8", "D6", "D5"])))
	for j in "ABCDEFGH":
		print('        .OUTMUX%s("%s"),' % (j, np.random.choice(["F7F8", "D6", "D5"])))
	for j in range(7):
		print('      .DIMUX%s("%s"),' % ("ABCDEFG"[j], dimux[j]))
	print("      .WCLKINV(1'd%d)," % np.random.randint(2))

	waused = np.random.randint(4)

	print("      .WA6USED(1'd%d)," % (1 if waused > 0 else 0))
	print("      .WA7USED(1'd%d)," % (1 if waused > 1 else 0))
	print("      .WA8USED(1'd%d)," % (1 if waused > 2 else 0))
	print("      .CLKINV(2'd%d)," % np.random.randint(4))
	print("      .SRINV(2'd%d)" % np.random.randint(4))
	print('   ) slice%d (' % i)
	for j in range(1, 7):
		print("      .A%d(%s)," % (j, random_data(8)))
	print("      .I(%s)," % random_data(8))
	print("      .X(%s)," % random_data(8))
	print("      .CLK({clk[%d], clk[%d]})," % clk[0:2])
	print("      .WCLK(clk[%d])," % wclk)
	print("      .SR({%s, %s})," % sr)
	print("      .CE({%s, %s, %s, %s})," % ce[0:4])
	print("      .WE(ce[%d])," % we)
	print("      .O(d%d[7:0])," % i)
	print("      .Q(d%d[15:8])," % i)
	print("      .Q2(d%d[23:16])," % i)
	print("      .MUX(d%d[31:24])" % i)
	print('   );')
	print()
	D.clear()
	for j in range(8):
		D.append("d%d[%d]" % (i, j))
		D.append("d%d[%d]" % (i, 24 + j))
		if fftypes[2 * j] != "NONE":
			D.append("d%d[%d]" % (i, 8 + j))
		if fftypes[2 * j + 1] != "NONE":
			D.append("d%d[%d]" % (i, 16 + j))
print("    assign q = d%d;" % (N-1))
print("endmodule")