#!/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 math import os import functools import random random.seed(int(os.getenv("SEED"), 16)) from prjxray import util from prjxray import verilog from prjxray.verilog import vrandbits 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 not in ['BRAM_L', 'BRAM_R']: continue sites = {} for site_name, site_type in gridinfo.sites.items(): sites[site_type] = site_name yield tile_name, sites @functools.lru_cache(maxsize=None) def prepare_rand_int_choices(minval, maxval): """ Creates list ints between minval and maxval to allow fuzzer to uniquely identify all bits.""" assert minval >= 0 assert maxval >= minval min_p2 = math.floor(math.log(max(minval, 1), 2)) max_p2 = math.ceil(math.log(maxval + 1, 2)) if 2**max_p2 > maxval: max_search_p2 = max_p2 - 1 else: max_search_p2 = max_p2 choices = set( [minval, maxval, 2**(min_p2 + 1) - 1, 2**(max_search_p2) - 1]) lb = min_p2 ub = max_search_p2 while lb < ub: ub = int(round(ub / 2.)) val = 2**ub - 1 lowval = val if lowval < minval: lowval |= (1 << max_search_p2) assert lowval >= minval, (val, ub) choices.add(lowval) highval = val << (max_search_p2 - ub) if highval > minval: assert highval <= maxval, (val, ub) choices.add(highval) for bit in range(max_search_p2): if 2**bit > minval: choices.add(2**bit) else: choices.add(2**bit | 2**max_search_p2) choices.add(2**bit | 2**(max_search_p2 - 1)) zeros = set() ones = set() for choice in choices: assert choice >= minval, choice assert choice <= maxval, choice for bit in range(max_p2): if (1 << bit) & choice: ones.add(bit) else: zeros.add(bit) assert len(ones) == max_p2 assert len(zeros) == max_p2 return tuple(sorted(choices)) def rand_int(minval, maxval): return random.choice(prepare_rand_int_choices(minval, maxval)) def main(): print(''' module top(); ''') params_list = [] for tile_name, sites in gen_sites(): params = {} params['tile'] = tile_name params['site'] = sites['RAMBFIFO36E1'] params['DATA_WIDTH'] = random.choice([4, 9, 18, 36, 72]) params['EN_SYN'] = random.randint(0, 1) params['DO_REG'] = 1 if params['EN_SYN']: params['FIRST_WORD_FALL_THROUGH'] = 0 else: params['FIRST_WORD_FALL_THROUGH'] = random.randint(0, 1) if params['EN_SYN']: MIN_ALMOST_FULL_OFFSET = 1 if params['DATA_WIDTH'] == 4: MAX_ALMOST_FULL_OFFSET = 8190 elif params['DATA_WIDTH'] == 9: MAX_ALMOST_FULL_OFFSET = 4094 elif params['DATA_WIDTH'] == 18: MAX_ALMOST_FULL_OFFSET = 2046 elif params['DATA_WIDTH'] == 36: MAX_ALMOST_FULL_OFFSET = 1022 elif params['DATA_WIDTH'] == 72: MAX_ALMOST_FULL_OFFSET = 510 else: assert False MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET else: MIN_ALMOST_FULL_OFFSET = 4 if params['DATA_WIDTH'] == 4: MAX_ALMOST_FULL_OFFSET = 8185 elif params['DATA_WIDTH'] == 9: MAX_ALMOST_FULL_OFFSET = 4089 elif params['DATA_WIDTH'] == 18: MAX_ALMOST_FULL_OFFSET = 2041 elif params['DATA_WIDTH'] == 36: MAX_ALMOST_FULL_OFFSET = 1017 elif params['DATA_WIDTH'] == 72: MAX_ALMOST_FULL_OFFSET = 505 else: assert False if params['FIRST_WORD_FALL_THROUGH']: MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET + 2 MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET + 2 else: MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET + 1 MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET + 1 ALMOST_EMPTY_OFFSET = rand_int( MIN_ALMOST_EMPTY_OFFSET, MAX_ALMOST_EMPTY_OFFSET) ALMOST_FULL_OFFSET = rand_int( MIN_ALMOST_FULL_OFFSET, MAX_ALMOST_FULL_OFFSET) params['ALMOST_EMPTY_OFFSET'] = "13'b{:013b}".format( ALMOST_EMPTY_OFFSET) params['ALMOST_FULL_OFFSET'] = "13'b{:013b}".format(ALMOST_FULL_OFFSET) if params['DATA_WIDTH'] == 36: params['FIFO_MODE'] = verilog.quote('FIFO36_72') else: params['FIFO_MODE'] = verilog.quote( 'FIFO36_72' ) #verilog.quote('FIFO18') #verilog.quote(random.choice(('FIFO18', 'FIFO18_36'))) params['INIT'] = '0' #vrandbits(36) params['SRVAL'] = '0' #vrandbits(36) print( ''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) FIFO36E1 #( .ALMOST_EMPTY_OFFSET({ALMOST_EMPTY_OFFSET}), .ALMOST_FULL_OFFSET({ALMOST_FULL_OFFSET}), .DATA_WIDTH({DATA_WIDTH}), .DO_REG({DO_REG}), .EN_SYN({EN_SYN}), .FIFO_MODE({FIFO_MODE}), .FIRST_WORD_FALL_THROUGH({FIRST_WORD_FALL_THROUGH}), .INIT({INIT}), .SRVAL({SRVAL}) ) fifo_{site} ( ); '''.format(**params, )) params['FIFO_MODE'] = verilog.unquote(params['FIFO_MODE']) params_list.append(params) print("endmodule") with open('params.json', 'w') as f: json.dump(params_list, f, indent=2) if __name__ == '__main__': main()