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