blob: 20ad4feb349058879dbfec420cae8b1de531f2f9 [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 = {}
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 ("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(":"))
X = 64
root = sys.argv[2]
for x in range(X):
buffers = []
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)
target_type = np.random.choice(
["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"]
if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
tile_buffers = np.random.randint(8)
found_buffers = 0
for buf, buftype in shuffled_bufs:
if found_buffers >= tile_buffers:
break
if buftype != target_type:
continue
buffers.append((buf, buftype))
print("%s %s" % (tile, buf))
found_buffers += 1
print()
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 + "/clkroute3/gclk%d.v" % x, "w") as f:
print("module top(input i, input [9:0] aux, d, output o, q);", file=f)
N = len(buffers)
print(" wire [%d:0] r;" % N, file=f)
print(" assign r[0] = i;", file=f)
print(" assign o = r[%d];" % N, file=f)
print(" wire [%d:0] r2;" % (2 * N), file=f)
print(" assign r2[0] = d;", file=f)
print(" assign q = r2[%d];" % (2 * 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)
elif "DIV" in buftype:
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)
print(" .I(r[%d])," % i, file=f)
print(" %s," % random_control(["CE", "CLR"]), file=f)
print(" .O(r[%d])" % (i + 1), file=f)
print(" );", file=f)
else:
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_div_%d (" % i, file=f)
print(" .I(r[%d])," % i, file=f)
print(" %s," % random_control(["CE"]), file=f)
print(" .O(r[%d])" % (i + 1), file=f)
print(" );", file=f)
if np.random.randint(2) == 1:
print(
"FDCE ff_%d(.C(r[%d]), .CE(1'b1), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));"
% (i, i, 2 * i, 2 * i + 1),
file=f)
else:
print("assign r2[%d] = r2[%d];" % (2 * i + 1, 2 * i), file=f)
if np.random.randint(2) == 1:
print(
"SRLC32E srl_%d(.CLK(r[%d]), .CE(1'b1), .A(aux[4:0]), .D(r2[%d]), .Q(r2[%d]));"
% (i, i, 2 * i + 1, 2 * i + 2),
file=f)
else:
print(
"assign r2[%d] = r2[%d];" % (2 * i + 2, 2 * i + 1), file=f)
print("", file=f)
print("endmodule", file=f)
with open(root + "/clkroute3/gclk%d.tcl" % x, "w") as f:
print("add_files %s" % (root + ("/clkroute3/gclk%d.v" % x)), file=f)
#print("read_xdc %s" % (root + ("/clkroute3/gclk%d.xdc" % x)), file=f)
print("synth_design -top top -part xczu7ev-ffvc1156-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/specimen_clk/gclk%d.dcp" % (root, x),
file=f)
print(
"write_edif -force %s/specimen_clk/gclk%d.edf" % (root, x), file=f)
print(
"write_bitstream -force %s/specimen_clk/gclk%d.bit" % (root, x),
file=f)
with open(root + "/clkroute3/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 gclk%d.tcl" % x,
file=f)
print("if [ $? -eq 0 ]; then", file=f)
print(
" ../../ultra/tools/dump_bitstream %s/specimen_clk/gclk%d.bit %s/frames.txt > %s/specimen_clk/gclk%d.dump"
% (root, x, root, root, x),
file=f)
print(
" python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclk%d.dump > %s/specimen_clk/gclk%d.tbits"
% (root, root, x, root, x),
file=f)
print("else", file=f)
print(" rm %s/specimen_clk/gclk%d.dump" % (root, x), file=f)
print(" rm %s/specimen_clk/gclk%d.tbits" % (root, x), file=f)
print(" rm %s/specimen_clk/gclk%d.dcp" % (root, x), file=f)
print(" rm %s/specimen_clk/gclk%d.bit" % (root, x), file=f)
print(" rm %s/specimen_clk/gclk%d.features" % (root, x), file=f)
print("fi", file=f)