#!/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 json import os import random random.seed(int(os.getenv("SEED"), 16)) from prjxray.db import Database from prjxray import util from prjxray.lut_maker import LutMaker def gen_sites(): xy_fun = util.create_xy_fun('BUFR_') 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 = [] xs = [] ys = [] for site, site_type in gridinfo.sites.items(): if site_type == 'BUFR': x, y = xy_fun(site) xs.append(x) ys.append(y) sites.append((site, x, y)) if not sites: continue ioi3 = grid.gridinfo_at_loc((loc.grid_x, loc.grid_y - 1)) if 'IOI3' not in ioi3.tile_type: continue if ioi3.tile_type.startswith('R'): dx = 1 else: assert ioi3.tile_type.startswith('L') dx = -1 iobs = [] for dy in (-1, -3, 2, 4): iob = grid.gridinfo_at_loc((loc.grid_x + dx, loc.grid_y + dy)) for site, site_type in iob.sites.items(): if site_type == 'IOB33M': iobs.append(site) yield tile_name, min(xs), min(ys), sorted(sites), sorted(iobs) def main(): params_list = [] num_clocks = 0 outputs = [] luts = LutMaker() for tile_name, x_min, y_min, sites, iobs in gen_sites(): ioclks = [] for iob in iobs: ioclk = 'clk_{}'.format(iob) ioclks.append(ioclk) idx = num_clocks num_clocks += 1 outputs.append( ''' wire {ioclk}; (* KEEP, DONT_TOUCH, LOC="{site}" *) IBUF #( .IOSTANDARD("LVCMOS33") ) ibuf_{site} ( .I(clks[{idx}]), .O({ioclk}) );'''.format( ioclk=ioclk, site=iob, idx=idx, )) for site, x, y in sites: params = {} params['tile'] = tile_name params['site'] = site params['IN_USE'] = random.randint(0, 1) params['x'] = x - x_min params['y'] = y - y_min if params['IN_USE']: params['BUFR_DIVIDE'] = random.choice( ( '"BYPASS"', '1', '2', '3', '4', '5', '6', '7', '8', )) params['I'] = random.choice(ioclks) if params['BUFR_DIVIDE'] == '"BYPASS"': params['CE'] = '1' params['CLR'] = '0' else: params['CE'] = luts.get_next_output_net() params['CLR'] = luts.get_next_output_net() outputs.append( ''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFR #( .BUFR_DIVIDE({BUFR_DIVIDE}) ) buf_{site} ( .CE({CE}), .CLR({CLR}), .I({I}) ); '''.format(**params)) params_list.append(params) print( ''' module top(input [{n1}:0] clks); '''.format(n1=num_clocks - 1)) print(""" (* KEEP, DONT_TOUCH *) LUT6 dummy ( );""") for l in luts.create_wires_and_luts(): print(l) for l in outputs: print(l) print("endmodule") with open('params.json', 'w') as f: json.dump(params_list, f, indent=2) if __name__ == '__main__': main()