blob: 117641e7ca2fc5d39ca3ca3164c80fcf9d68bab2 [file] [log] [blame] [edit]
# 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)