| #!/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 random |
| import itertools |
| random.seed(int(os.getenv("SEED"), 16)) |
| from prjxray import util |
| from prjxray.db import Database |
| |
| |
| def gen_fifos(): |
| 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_name, site_type in gridinfo.sites.items(): |
| if site_type in ['IN_FIFO']: |
| if gridinfo.tile_type[-1] == 'L': |
| int_grid_x = loc.grid_x + 2 |
| int_tile_type = 'INT_L' |
| else: |
| int_grid_x = loc.grid_x - 2 |
| int_tile_type = 'INT_R' |
| |
| int_tile_locs = [ |
| (int_grid_x, loc.grid_y + idx - 5) for idx in range(12) |
| ] |
| |
| int_tiles = [] |
| for int_tile_loc in int_tile_locs: |
| int_gridinfo = grid.gridinfo_at_loc(int_tile_loc) |
| assert int_gridinfo.tile_type == int_tile_type, ( |
| int_tile_loc, int_gridinfo.tile_type, int_tile_type) |
| |
| int_tiles.append(grid.tilename_at_loc(int_tile_loc)) |
| |
| yield site_name, int_tiles |
| |
| |
| def write_params(params): |
| pinstr = 'tile,val\n' |
| for tile, (val, ) in sorted(params.items()): |
| pinstr += '%s,%s\n' % (tile, val) |
| open('params.csv', 'w').write(pinstr) |
| |
| |
| def run(): |
| print(''' |
| module top(); |
| ''') |
| |
| params = {} |
| |
| sites = list(gen_fifos()) |
| N_INT = 12 |
| |
| fuzz_iter = iter(util.gen_fuzz_states(len(sites) * N_INT)) |
| for site, int_tiles in sites: |
| assert len(int_tiles) == N_INT |
| int_tiles.reverse() |
| |
| bits = itertools.islice(fuzz_iter, N_INT) |
| |
| assigns = [] |
| |
| # CMT_FIFO mux usage is regular with IMUX_L40 and IMUX_L42. |
| # |
| # INT[idx].IMUX_L40 = IN.D{idx}[1] |
| # INT[idx].IMUX_L42 = IN.D{idx}[3] |
| CHANNEL = [0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9] |
| HOLD_BIT_0 = [1, 1, 1, 1, 1, 1, 5, 5, 1, 1, 1, 1] |
| TOGGLE_BIT = [3, 3, 3, 3, 3, 3, 7, 7, 3, 3, 3, 3] |
| # 0 1 2 3 4 5 6 7 8 9 |
| WIDTH = [4, 4, 4, 4, 4, 8, 8, 4, 4, 4] |
| |
| bits_set = set() |
| |
| for idx, (int_tile, bit) in enumerate(zip(int_tiles, bits)): |
| bits_set.add((CHANNEL[idx], HOLD_BIT_0[idx])) |
| bits_set.add((CHANNEL[idx], TOGGLE_BIT[idx])) |
| |
| assigns.append(' // {}'.format(int_tile)) |
| assigns.append( |
| ' assign {site}_in_d{channel}[{bit}] = 0;'.format( |
| site=site, |
| channel=CHANNEL[idx], |
| bit=HOLD_BIT_0[idx], |
| )) |
| assigns.append( |
| ' assign {site}_in_d{channel}[{bit}] = {toggle_bit};' |
| .format( |
| site=site, |
| channel=CHANNEL[idx], |
| bit=TOGGLE_BIT[idx], |
| toggle_bit=bit, |
| )) |
| params[int_tile] = (bit, ) |
| |
| assigns.append('') |
| |
| for channel, width in enumerate(WIDTH): |
| for bit in range(width): |
| if (channel, bit) not in bits_set: |
| assigns.append( |
| ' assign {site}_in_d{channel}[{bit}] = 1;'. |
| format( |
| site=site, |
| channel=channel, |
| bit=bit, |
| )) |
| |
| print( |
| ''' |
| wire [3:0] {site}_in_d0; |
| wire [3:0] {site}_in_d1; |
| wire [3:0] {site}_in_d2; |
| wire [3:0] {site}_in_d3; |
| wire [3:0] {site}_in_d4; |
| wire [7:0] {site}_in_d5; |
| wire [7:0] {site}_in_d6; |
| wire [3:0] {site}_in_d7; |
| wire [3:0] {site}_in_d8; |
| wire [3:0] {site}_in_d9; |
| |
| {assign_statements} |
| |
| (* KEEP, DONT_TOUCH, LOC = "{site}" *) |
| IN_FIFO fifo_{site} ( |
| .D0({site}_in_d0), |
| .D1({site}_in_d1), |
| .D2({site}_in_d2), |
| .D3({site}_in_d3), |
| .D4({site}_in_d4), |
| .D5({site}_in_d5), |
| .D6({site}_in_d6), |
| .D7({site}_in_d7), |
| .D8({site}_in_d8), |
| .D9({site}_in_d9) |
| ); |
| '''.format( |
| site=site, |
| assign_statements='\n'.join(assigns), |
| )) |
| |
| print("endmodule") |
| write_params(params) |
| |
| |
| if __name__ == '__main__': |
| run() |