def run(db_root, part, filename_in, f_out, sparse=False, roi=None, debug=False, dump_bits=False): db = Database(db_root, part) assembler = fasm_assembler.FasmAssembler(db) set_features = set() def feature_callback(feature): set_features.add(feature) assembler.set_feature_callback(feature_callback) extra_features = [] if roi: with open(roi) as f: roi_j = json.load(f) x1 = roi_j['info']['GRID_X_MIN'] x2 = roi_j['info']['GRID_X_MAX'] y1 = roi_j['info']['GRID_Y_MIN'] y2 = roi_j['info']['GRID_Y_MAX'] assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2)) if 'required_features' in roi_j: extra_features = list( fasm.parse_fasm_string('\n'.join(roi_j['required_features']))) # Get required extra features for the part required_features = db.get_required_fasm_features(part) extra_features += list(fasm.parse_fasm_string( '\n'.join(required_features))) assembler.parse_fasm_filename(filename_in, extra_features=extra_features) frames = assembler.get_frames(sparse=sparse) if debug: dump_frames_sparse(frames) if dump_bits: output_bits(f_out, frames) else: dump_frm(f_out, frames)
def run(db_root, filename_in, f_out, sparse=False, roi=None, debug=False): db = Database(db_root) assembler = fasm_assembler.FasmAssembler(db) extra_features = [] if roi: with open(roi) as f: roi_j = json.load(f) x1 = roi_j['info']['GRID_X_MIN'] x2 = roi_j['info']['GRID_X_MAX'] y1 = roi_j['info']['GRID_Y_MIN'] y2 = roi_j['info']['GRID_Y_MAX'] assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2)) if 'required_features' in roi_j: extra_features = fasm.parse_fasm_string('\n'.join( roi_j['required_features'])) assembler.parse_fasm_filename(filename_in, extra_features=extra_features) frames = assembler.get_frames(sparse=sparse) if debug: dump_frames_sparse(frames) dump_frm(f_out, frames)
def fasm_to_frames( db_root, part, filename_in, sparse, bits_file, frames_file, ): db = Database(db_root, part) assembler = fasm_assembler.FasmAssembler(db) set_features = set() def feature_callback(feature): set_features.add(feature) assembler.set_feature_callback(feature_callback) extra_features = [] # Get required extra features for the part required_features = db.get_required_fasm_features(part) extra_features += list( fasm.parse_fasm_string('\n'.join(required_features))) assembler.parse_fasm_filename(filename_in, extra_features=extra_features) frames = assembler.get_frames(sparse=sparse) print('Have {} frames'.format(len(frames))) if bits_file: output_bits(bits_file, frames) dump_frm(frames_file, frames)
def initlines_to_memfasm(initlines, infile_name): print(initlines) print("###") print(infile_name) fasmlines = [] for tileaddr, tile in initlines.items(): for yaddr, inits in tile.items(): for init_type, data in inits.items(): line_header = '{}.RAMB18_{}.{}_'.format( tileaddr, yaddr, init_type) #line_header2 = f'{tileaddr}.RAMB18_{yaddr}.{init_type}_' #assert(line_header == line_header2) #print(str(len(data)) + "...") for count, data in enumerate(data): if int(data) > 0: # print(data) while data[0] == '0': data = data[1:] datalen = len(data) #count2 = count count = hex(count)[2:].upper() l = '{}{}[{}:0] = {}\'b{}'.format( line_header, pad('0', 2, count), datalen - 1, datalen, data) fasmlines.append(l) #l2 = f'{line_header}{count2:02X}[{datalen-1}:0] = {datalen}\'b{data}' #print(l) #print(l2) #assert(l == l2) #fasmlines.append( # f'{line_header}{count:02X}[{datalen-1}:0] = {datalen}\'b{data}') memfasm = (next(fasm.parse_fasm_string(line)) for line in fasmlines) return memfasm
def initlines_to_memfasm(initlines, infile_name): fasmlines = [] for tileaddr, tile in initlines.items(): for yaddr, inits in tile.items(): for init_type, data in inits.items(): line_header = f'{tileaddr}.RAMB18_{yaddr}.{init_type}_' for count, data in enumerate(data): # if '1' in data: # fasmlines.append( # f'{line_header}{count:02X}[255:0] = 256\'b{data}') fasmlines.append( f'{line_header}{count:02X}[255:0] = 256\'b{data}') # print(f'{line_header}{count:02X}[255:0] = 256\'b{data}') # print() # print() with open(f'{infile_name.split(".")[0]}_check.txt', 'w+') as w: for line in fasmlines: w.write(f'{line}\n') # print(line) memfasm = (next(fasm.parse_fasm_string(line)) for line in fasmlines) # for mf in memfasm: # print(type(mf)) # print(next(fasm.fasm_line_to_string(mf))) return memfasm
def fasm2frames(db_root, part, filename_in, f_out=None, sparse=False, roi=None, debug=False, emit_pudc_b_pullup=False): db = Database(db_root, part) assembler = fasm_assembler.FasmAssembler(db) set_features = set() def feature_callback(feature): set_features.add(feature) assembler.set_feature_callback(feature_callback) # Build mapping of tile to IO bank tile_to_bank = {} bank_to_tile = defaultdict(lambda: set()) if part is not None: with open(os.path.join(db_root, part, "package_pins.csv"), "r") as fp: reader = csv.DictReader(fp) package_pins = [l for l in reader] with open(os.path.join(db_root, part, "part.json"), "r") as fp: part_data = json.load(fp) for bank, loc in part_data["iobanks"].items(): tile = "HCLK_IOI3_" + loc bank_to_tile[bank].add(tile) tile_to_bank[tile] = bank for pin in package_pins: bank_to_tile[pin["bank"]].add(pin["tile"]) tile_to_bank[pin["tile"]] = pin["bank"] if emit_pudc_b_pullup: pudc_b_in_use = False pudc_b_tile_site = find_pudc_b(db) def check_for_pudc_b(set_feature): feature_callback(set_feature) parts = set_feature.feature.split('.') if parts[0] == pudc_b_tile_site[0] and parts[ 1] == pudc_b_tile_site[1]: nonlocal pudc_b_in_use pudc_b_in_use = True if pudc_b_tile_site is not None: assembler.set_feature_callback(check_for_pudc_b) extra_features = [] if roi: with open(roi) as f: roi_j = json.load(f) x1 = roi_j['info']['GRID_X_MIN'] x2 = roi_j['info']['GRID_X_MAX'] y1 = roi_j['info']['GRID_Y_MIN'] y2 = roi_j['info']['GRID_Y_MAX'] assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2)) if 'required_features' in roi_j: extra_features = list( fasm.parse_fasm_string('\n'.join(roi_j['required_features']))) # Get required extra features for the part required_features = db.get_required_fasm_features(part) extra_features += list(fasm.parse_fasm_string( '\n'.join(required_features))) assembler.parse_fasm_filename(filename_in, extra_features=extra_features) if emit_pudc_b_pullup and not pudc_b_in_use and pudc_b_tile_site is not None: # Enable IN-only and PULLUP on PUDC_B IOB. # # TODO: The following FASM string only works on Artix 50T and Zynq 10 # fabrics. It is known to be wrong for the K70T fabric, but it is # unclear how to know which IOSTANDARD to use. missing_features = [] for line in fasm.parse_fasm_string(""" {tile}.{site}.LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135_SSTL15.IN_ONLY {tile}.{site}.LVCMOS25_LVCMOS33_LVTTL.IN {tile}.{site}.PULLTYPE.PULLUP """.format( tile=pudc_b_tile_site[0], site=pudc_b_tile_site[1], )): assembler.add_fasm_line(line, missing_features) if missing_features: raise fasm_assembler.FasmLookupError('\n'.join(missing_features)) if part is not None: # Make a set of all used IOB tiles and sites. Look for the "STEPDOWN" # feature. If one is set for an IOB then set it for all other IOBs of # the same bank. stepdown_tags = defaultdict(lambda: set()) stepdown_banks = set() used_iob_sites = set() for set_feature in set_features: if set_feature.value == 0: continue feature = set_feature.feature parts = feature.split(".") if len(parts) >= 3: tile, site, tag = feature.split(".", maxsplit=2) if "IOB33" in tile: used_iob_sites.add(( tile, site, )) # Store STEPDOWN related tags. if "STEPDOWN" in tag: bank = tile_to_bank[tile] stepdown_banks.add(bank) stepdown_tags[bank].add(tag) # Set the feature for unused IOBs, loop over all banks which were # observed to have the STEPDOWN feature set. missing_features = [] for bank in stepdown_banks: for tile in bank_to_tile[bank]: # This is an IOB33 tile. Set the STEPDOWN feature in it but # only if it is unused. if "IOB33" in tile: for site in get_iob_sites(db, tile): if (tile, site) in used_iob_sites: continue for tag in stepdown_tags[bank]: feature = "{}.{}.{}".format(tile, site, tag) for line in fasm.parse_fasm_string(feature): assembler.add_fasm_line(line, missing_features) # This is a HCLK_IOI3 tile, set the stepdown feature for it # too. if "HCLK_IOI3" in tile: feature = "{}.STEPDOWN".format(tile) for line in fasm.parse_fasm_string(feature): assembler.add_fasm_line(line, missing_features) if missing_features: raise fasm_assembler.FasmLookupError('\n'.join(missing_features)) frames = assembler.get_frames(sparse=sparse) if debug: dump_frames_sparse(frames) if f_out is not None: dump_frm(f_out, frames) return frames
def check_round_trip(test, result): s = fasm.fasm_tuple_to_string(result) test.assertEqual(list(fasm.parse_fasm_string(s)), result)
def run( db_root, filename_in, f_out, sparse=False, roi=None, debug=False, emit_pudc_b_pullup=False): db = Database(db_root) assembler = fasm_assembler.FasmAssembler(db) if emit_pudc_b_pullup: pudc_b_in_use = False pudc_b_tile_site = find_pudc_b(db) def check_for_pudc_b(set_feature): parts = set_feature.feature.split('.') if parts[0] == pudc_b_tile_site[0] and parts[ 1] == pudc_b_tile_site[1]: nonlocal pudc_b_in_use pudc_b_in_use = True if pudc_b_tile_site is not None: assembler.set_feature_callback(check_for_pudc_b) extra_features = [] if roi: with open(roi) as f: roi_j = json.load(f) x1 = roi_j['info']['GRID_X_MIN'] x2 = roi_j['info']['GRID_X_MAX'] y1 = roi_j['info']['GRID_Y_MIN'] y2 = roi_j['info']['GRID_Y_MAX'] assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2)) if 'required_features' in roi_j: extra_features = fasm.parse_fasm_string( '\n'.join(roi_j['required_features'])) assembler.parse_fasm_filename(filename_in, extra_features=extra_features) if emit_pudc_b_pullup and not pudc_b_in_use and pudc_b_tile_site is not None: # Enable IN-only and PULLUP on PUDC_B IOB. # # TODO: The following FASM string only works on Artix 50T and Zynq 10 # fabrics. It is known to be wrong for the K70T fabric, but it is # unclear how to know which IOSTANDARD to use. missing_features = [] for line in fasm.parse_fasm_string(""" {tile}.{site}.LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135.IN_ONLY {tile}.{site}.LVCMOS25_LVCMOS33_LVTTL.IN {tile}.{site}.PULLTYPE.PULLUP """.format( tile=pudc_b_tile_site[0], site=pudc_b_tile_site[1], )): assembler.add_fasm_line(line, missing_features) if missing_features: raise fasm_assembler.FasmLookupError('\n'.join(missing_features)) frames = assembler.get_frames(sparse=sparse) if debug: dump_frames_sparse(frames) dump_frm(f_out, frames)
if args.input_pcf is not None: pcf_data = parse_pcf(args.input_pcf) # Load data from the database with open(args.vpr_db, "rb") as fp: db = pickle.load(fp) f2b = Fasm2Bels(db, args.package_name) if args.input_type == 'bitstream': qlfasmdb = load_quicklogic_database() assembler = QL732BAssembler(qlfasmdb) assembler.read_bitstream(args.input_file) fasmlines = assembler.disassemble() fasmlines = [ line for line in fasm.parse_fasm_string('\n'.join(fasmlines)) ] else: fasmlines = [ line for line in fasm.parse_fasm_filename(args.input_file) ] verilog, pcf, qcf = f2b.convert_to_verilog(fasmlines) with open(args.output_verilog, 'w') as outv: outv.write(verilog) if args.output_pcf: with open(args.output_pcf, 'w') as outpcf: outpcf.write(pcf) if args.output_qcf: with open(args.output_qcf, 'w') as outqcf:
def fasm_to_asc(in_fasm, outf, device): """Convert an FASM input to an ASC file Set input enable defaults, RAM powerup, and enables all ColBufCtrl (until modeled in VPR see: #464) """ ic = icebox.iceconfig() init_method_name = "setup_empty_{}".format(device.lower()[2:]) assert hasattr(ic, init_method_name), "no icebox method to init empty device" getattr(ic, init_method_name)() device_1k = ic.device == "1k" fasmdb = read_ice_db(ic) # TODO: upstream init "default" bitstream locs = [(x, y) for x in range(ic.max_x + 1) for y in range(ic.max_y + 1)] for tile_loc in locs: tile = ic.tile(*tile_loc) if tile is None: continue db = ic.tile_db(*tile_loc) tile_type = ic.tile_type(*tile_loc) for entry in db: if (device_1k and ((tile_type == "IO" and entry[-1] in ["IE_0", "IE_1"]) or (tile_type == "RAMB" and entry[-1] == "PowerUp")) or (entry[-2] == "ColBufCtrl")): tile_bits = _tile_to_array(tile) tile_type = ic.tile_type(*tile_loc) bm, bv = _get_iceconfig_bits(tile_bits, entry[0]) tile_bits[bm] = bv[bm] _array_to_tile(tile_bits, tile) missing_features = [] for line in fasm.parse_fasm_string(in_fasm.read()): if not line.set_feature: continue line_strs = tuple(fasm.fasm_line_to_string(line)) assert len(line_strs) == 1 feature = Feature.from_fasm_entry( FasmEntry(line.set_feature.feature, [])) def find_ieren(ic, loc, iob): tmap = [ xx[3:] for xx in ic.ieren_db() if xx[:3] == (tuple(loc) + (iob, )) ] assert len(tmap) < 2, "expected 1 IEREN_DB entry found {}".format( len(tmap)) if len(tmap) == 0: print("no ieren found for {}".format((tile_loc + (iob, )))) return return tmap[0] # fix up for IO if feature.parts[-1] == "SimpleInput": iob = int(feature.parts[-2][-1]) new_ieren = find_ieren(ic, feature.loc, iob) feature.parts[-1] = "PINTYPE_0" db_entry = fasmdb[feature.to_fasm_entry().feature] _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples) feature.loc = new_ieren[:2] feature.parts[-2] = "IoCtrl" feature.parts[-1] = "IE_{}".format(new_ieren[2]) db_entry = fasmdb[feature.to_fasm_entry().feature] _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples) feature.parts[-1] = "REN_{}".format(new_ieren[2]) db_entry = fasmdb[feature.to_fasm_entry().feature] _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples) continue if feature.parts[-1] == "SimpleOutput": iob = int(feature.parts[-2][-1]) new_ieren = find_ieren(ic, feature.loc, iob) feature.parts[-1] = "PINTYPE_3" db_entry = fasmdb[feature.to_fasm_entry().feature] _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples) feature.parts[-1] = "PINTYPE_4" db_entry = fasmdb[feature.to_fasm_entry().feature] _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples) feature.loc = new_ieren[:2] feature.parts[-2] = "IoCtrl" feature.parts[-1] = "REN_{}".format(new_ieren[2]) db_entry = fasmdb[feature.to_fasm_entry().feature] _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples) continue ## special case for RAM INIT values tile_type, loc = feature.tile_type, feature.loc if tile_type == "RAMB" and feature.parts[-1].startswith("INIT"): tloc = tuple(loc) if tloc not in ic.ram_data: ic.ram_data[tloc] = [64 * "0" for _ in range(16)] tile = ic.ram_data[tloc] tile_bits = _tile_to_array(tile, is_hex=True) elif tile_type == "RAMB" and feature.parts[-1].endswith("_MODE"): # hack to force modes to the RAMT tile = ic.tile(loc[0], loc[1] + 1) tile_bits = _tile_to_array(tile) else: tile = ic.tile(*loc) tile_bits = _tile_to_array(tile) # lookup feature and convert for canonical_feature in fasm.canonical_features(line.set_feature): key = fasm.set_feature_to_str(canonical_feature) feature = fasmdb[key] bm, bv = _get_feature_bits(tile_bits, feature.bit_tuples) tile_bits[bm] = bv[bm] if tile_type == "RAMB" and feature.parts[-1].startswith("INIT"): _array_to_tile(tile_bits, tile, is_hex=True) else: _array_to_tile(tile_bits, tile) # TODO: would be nice to upstream a way to write to non-files ic.write_file(outf.name)