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()) 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()