| #!/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() |