#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Copyright (C) 2017-2020 The Project X-Ray Authors. # # Use of this source code is governed by a ISC-style # license that can be found in the LICENSE file or at # https://opensource.org/licenses/ISC # # SPDX-License-Identifier: ISC import os import itertools import re import random random.seed(int(os.getenv("SEED"), 16)) from prjxray import util from prjxray.db import Database XY_RE = re.compile('^BUFHCE_X([0-9]+)Y([0-9]+)$') BUFGCTRL_XY_RE = re.compile('^BUFGCTRL_X([0-9]+)Y([0-9]+)$') """ BUFHCE's can be driven from: MMCME2_ADV BUFHCE PLLE2_ADV BUFGCTRL """ def get_xy(s): m = BUFGCTRL_XY_RE.match(s) x = int(m.group(1)) y = int(m.group(2)) return x, y def gen_sites(desired_site_type): db = Database(util.get_db_root(), util.get_part()) grid = db.grid() for tile_name in sorted(grid.tiles()): loc = grid.loc_of_tilename(tile_name) gridinfo = grid.gridinfo_at_loc(loc) for site, site_type in gridinfo.sites.items(): if site_type == desired_site_type: yield site def gen_bufhce_sites(): db = Database(util.get_db_root(), util.get_part()) grid = db.grid() for tile_name in sorted(grid.tiles()): loc = grid.loc_of_tilename(tile_name) gridinfo = grid.gridinfo_at_loc(loc) sites = [] for site, site_type in gridinfo.sites.items(): if site_type == 'BUFHCE': sites.append(site) if sites: yield tile_name, set(sites) def main(): print(''' module top(); ''') gclks = [] for site in sorted(gen_sites("BUFGCTRL"), key=get_xy): wire_name = 'clk_{}'.format(site) gclks.append(wire_name) print( """ wire {wire_name}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFG bufg_{site} ( .O({wire_name}) ); """.format( site=site, wire_name=wire_name, )) bufhce_sites = list(gen_bufhce_sites()) opts = [] for count in range(len(bufhce_sites)): for opt in itertools.combinations(bufhce_sites, count + 1): opts.append(opt) for gclk in gclks: for tile_name, sites in random.choice(opts): for site in sorted(sites): print( """ (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE buf_{site} ( .I({wire_name}) );""".format( site=site, wire_name=gclk, )) sites.remove(site) break print("endmodule") if __name__ == '__main__': main()