| #!/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 io |
| import os |
| import random |
| import re |
| random.seed(int(os.getenv("SEED"), 16)) |
| from prjxray import util |
| from prjxray import lut_maker |
| from prjxray import verilog |
| from prjxray.db import Database |
| |
| |
| def gen_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) |
| if gridinfo.tile_type.endswith("_SING"): |
| continue |
| # Y9 tiles have frame address 1 frame higher than the rest |
| # Need to investigate what is so special about them |
| if tile_name.endswith("Y9"): |
| continue |
| |
| sites = [] |
| for site_name, site_type in gridinfo.sites.items(): |
| if site_type == 'IDELAYE2_FINEDELAY': |
| yield tile_name, site_name |
| |
| |
| def write_params(params): |
| pinstr = 'tile,isone,site\n' |
| for vals in params: |
| pinstr += ','.join(map(str, vals)) + '\n' |
| |
| open('params.csv', 'w').write(pinstr) |
| |
| |
| def use_idelay(p, luts, connects): |
| print( |
| ''' |
| wire idelay_{site}; |
| |
| (* KEEP, DONT_TOUCH, LOC = "{site}" *) |
| IDELAYE2_FINEDELAY #( |
| .HIGH_PERFORMANCE_MODE("{param}"), |
| .DELAY_SRC("DATAIN") |
| ) idelay_site_{site} ( |
| .DATAIN({onet}), |
| .DATAOUT(idelay_{site}) |
| ); |
| assign {net} = idelay_{site}; |
| '''.format( |
| onet=luts.get_next_output_net(), |
| net=luts.get_next_input_net(), |
| param="TRUE" if p['isone'] else "FALSE", |
| **p), |
| file=connects) |
| |
| |
| def run(): |
| luts = lut_maker.LutMaker() |
| connects = io.StringIO() |
| |
| tile_params = [] |
| params = [] |
| sites = sorted(list(gen_sites())) |
| for idx, ((tile, site), isone) in enumerate(zip( |
| sites, util.gen_fuzz_states(len(sites)))): |
| |
| p = {} |
| p['tile'] = tile |
| p['site'] = site |
| p['isone'] = isone |
| params.append(p) |
| tile_params.append((tile, p['isone'], site)) |
| |
| write_params(tile_params) |
| |
| print(''' |
| module top(); |
| ''') |
| |
| # Always output a LUT6 to make placer happy. |
| print(''' |
| (* KEEP, DONT_TOUCH *) |
| LUT6 dummy_lut(); |
| ''') |
| |
| # Need IDELAYCTRL for IDEALAYs |
| print(''' |
| (* KEEP, DONT_TOUCH *) |
| IDELAYCTRL(); |
| ''') |
| |
| for p in params: |
| use_idelay(p, luts, connects) |
| |
| for l in luts.create_wires_and_luts(): |
| print(l) |
| |
| print(connects.getvalue()) |
| |
| print("endmodule") |
| |
| |
| if __name__ == '__main__': |
| run() |