blob: 7f1df7f109e6fb00448b937dce6fb3681168ce51 [file] [log] [blame]
#!/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()