| # 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") |