| # 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 |
| |
| top_slices_orig = [] |
| bot_slices_orig = [] |
| top_laguna_orig = [] |
| bot_laguna_orig = [] |
| |
| with open(sys.argv[1], "r") as tf: |
| for line in tf: |
| sl = line.strip().split(",") |
| if len(sl) < 4: |
| continue |
| for site in sl[4:]: |
| if site.startswith("SLICE_"): |
| if int(sl[1]) > 310 and int(sl[1]) < 355: |
| bot_slices_orig.append(site.split(":")[0]) |
| elif int(sl[1]) < 310 and int(sl[1]) > 275: |
| top_slices_orig.append(site.split(":")[0]) |
| elif site.startswith("LAGUNA"): |
| if int(sl[1]) > 310 and int(sl[1]) < 355: |
| bot_laguna_orig.append(site.split(":")[0]) |
| elif int(sl[1]) < 310 and int(sl[1]) > 249: |
| top_laguna_orig.append(site.split(":")[0]) |
| |
| X = 10 |
| root = sys.argv[2] |
| |
| for x in range(X): |
| top_slices = list(top_slices_orig) |
| bot_slices = list(bot_slices_orig) |
| top_laguna = list(top_laguna_orig) |
| bot_laguna = list(bot_laguna_orig) |
| |
| np.random.shuffle(top_slices) |
| np.random.shuffle(bot_slices) |
| |
| np.random.shuffle(top_laguna) |
| np.random.shuffle(bot_laguna) |
| |
| with open(root + "/lagff/lagff%d.v" % x, "w") as f: |
| print("module top;", file=f) |
| print("wire clk, sr, ce;", file=f) |
| print("(* KEEP, DONT_TOUCH *) LUT1 drv_clk (.O(clk));", file=f) |
| print("(* KEEP, DONT_TOUCH *) LUT1 drv_sr (.O(sr));", file=f) |
| print("(* KEEP, DONT_TOUCH *) LUT1 drv_ce (.O(ce));", file=f) |
| N = np.random.randint(1000, len(bot_laguna)) |
| for i in range(N): |
| top = False |
| rx = np.random.choice([True, False]) |
| print("wire d%d, q%d;" % (i, i), file=f) |
| if top: |
| lag = top_laguna.pop() |
| else: |
| lag = bot_laguna.pop() |
| if rx: |
| bel = "RX_REG%d" % (np.random.randint(0, 6)) |
| if top: |
| sink_slice = top_slices.pop() |
| source_slice = bot_slices.pop() |
| else: |
| sink_slice = bot_slices.pop() |
| source_slice = top_slices.pop() |
| else: |
| bel = "TX_REG%d" % (np.random.randint(0, 6)) |
| if top: |
| sink_slice = bot_slices.pop() |
| source_slice = top_slices.pop() |
| else: |
| sink_slice = top_slices.pop() |
| source_slice = bot_slices.pop() |
| if np.random.choice([True, False, False]): |
| # bypass |
| print("assign q%d = d%d;" % (i, i), file=f) |
| else: |
| prim, sr = np.random.choice(["FDRE_R", "FDSE_S", "FDPE_PRE", "FDCE_CLR"]).split("_") |
| print("(* KEEP, DONT_TOUCH, LOC=\"%s\", BEL=\"%s\" *)" % (lag, bel), file=f) |
| print("%s #(" % prim, file=f) |
| print(" .INIT(%d)," % np.random.randint(2), file=f) |
| print(" .IS_C_INVERTED(%d)," % np.random.randint(2), file=f) |
| print(" .IS_%s_INVERTED(%d)" % (sr, np.random.randint(2)), file=f) |
| print(") ff_%d (" % i, file=f) |
| print(" .C(%s)," % np.random.choice(["clk", ""]), file=f) |
| if np.random.choice([True, False]): |
| print(" .CE(ce),", file=f) |
| if np.random.choice([True, False]): |
| print(" .%s(sr)," % sr, file=f) |
| print(" .D(d%d)," % i, file=f) |
| print(" .Q(q%d)" % i, file=f) |
| print(");", file=f) |
| if np.random.choice([True, True, False]) or rx: |
| print("(* KEEP, DONT_TOUCH, LOC=\"%s\" *) LUT1 drv%d(.O(d%d));" % (source_slice, i, i), file=f) |
| if np.random.choice([True, True, False]) or not rx: |
| print("(* KEEP, DONT_TOUCH, LOC=\"%s\" *) LUT1 usr%d(.I0(q%d));" % (sink_slice, i, i), file=f) |
| print("endmodule", file=f) |
| |
| with open(root + "/lagff/lagff%d.tcl" % x, "w") as f: |
| print("add_files %s" % (root + ("/lagff/lagff%d.v" % x)), file=f) |
| print("synth_design -top top -part xcvu5p-flvc2104-2-e", 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_lag/lagff%d.dcp" % (root, x), file=f) |
| print("write_edif -force %s/specimen_lag/lagff%d.edf" % (root, x), file=f) |
| print("write_bitstream -force %s/specimen_lag/lagff%d.bit" % (root, x), file=f) |
| with open(root + "/lagff/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 lagff%d.tcl" % x, file=f) |
| print("if [ $? -eq 0 ]; then", file=f) |
| print(" ../../ultra/tools/dump_bitstream %s/specimen_lag/lagff%d.bit %s/frames.txt > %s/specimen_lag/lagff%d.dump" % (root, x, root, root, x), file=f) |
| print(" python3 ../../ultra/tools/bits_to_tiles.py %s/tilebits.json %s/specimen_lag/lagff%d.dump > %s/specimen_lag/lagff%d.tbits" % (root, root, x, root, x), file=f) |
| print("else", file=f) |
| print(" rm %s/specimen_lag/lagff%d.dump" % (root, x), file=f) |
| print(" rm %s/specimen_lag/lagff%d.tbits" % (root, x), file=f) |
| print(" rm %s/specimen_lag/lagff%d.dcp" % (root, x), file=f) |
| print(" rm %s/specimen_lag/lagff%d.bit" % (root, x), file=f) |
| print(" rm %s/specimen_lag/lagff%d.features" % (root, x), file=f) |
| print("fi", file=f) |