#!/usr/bin/env python3 # # Copyright (C) 2015 Clifford Wolf # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # import icebox from icebox import re_match_cached, re_search_cached import getopt, sys, re, os print_bits = False print_map = False single_tile = None print_all = False def usage(): print(""" Usage: %s [options] [bitmap.asc] -b print config bit names for each config statement -m print tile config bitmaps -A don't skip uninteresting tiles -t ' ' print only the specified tile """ % os.path.basename(sys.argv[0])) sys.exit(0) try: opts, args = getopt.getopt(sys.argv[1:], "bmAt:") except: usage() for o, a in opts: if o == "-b": print_bits = True elif o == "-m": print_map = True elif o == "-A": print_all = True elif o == "-t": single_tile = tuple([int(s) for s in a.split()]) else: usage() if len(args) == 0: args.append("/dev/stdin") if len(args) != 1: usage() print("Reading file '%s'.." % args[0]) ic = icebox.iceconfig() ic.read_file(args[0]) print("Fabric size (without IO tiles): %d x %d" % (ic.max_x-1, ic.max_y-1)) def print_tile(stmt, ic, x, y, tile, db): if single_tile is not None and single_tile != (x, y): return bits = set() mapped_bits = set() for k, line in enumerate(tile): for i in range(len(line)): if line[i] == "1": bits.add("B%d[%d]" % (k, i)) else: bits.add("!B%d[%d]" % (k, i)) if re_search_cached(r"logic_tile", stmt): active_luts = set([i for i in range(8) if "1" in icebox.get_lutff_bits(tile, i)]) text = set() used_lc = set() text_default_mask = 0 for entry in db: if re_match_cached(r"LC_", entry[1]): continue if entry[1] in ("routing", "buffer"): if not ic.tile_has_net(x, y, entry[2]): continue if not ic.tile_has_net(x, y, entry[3]): continue match = True for bit in entry[0]: if not bit in bits: match = False if match: for bit in entry[0]: mapped_bits.add(bit) if entry[1] == "IoCtrl" and entry[2] == "IE_0": text_default_mask |= 1 if entry[1] == "IoCtrl" and entry[2] == "IE_1": text_default_mask |= 2 if entry[1] == "RamConfig" and entry[2] == "PowerUp": text_default_mask |= 4 if print_bits: text.add("<%s> %s" % (" ".join(entry[0]), " ".join(entry[1:]))) else: text.add(" ".join(entry[1:])) bitinfo = list() print_bitinfo = False for k, line in enumerate(tile): bitinfo.append("") extra_text = "" for i in range(len(line)): if 36 <= i <= 45 and re_search_cached(r"(logic_tile|dsp\d_tile|ipcon_tile)", stmt): lutff_idx = k // 2 lutff_bitnum = (i-36) + 10*(k%2) if line[i] == "1": used_lc.add(lutff_idx) bitinfo[-1] += "*" else: bitinfo[-1] += "-" elif line[i] == "1" and "B%d[%d]" % (k, i) not in mapped_bits: print_bitinfo = True extra_text += " B%d[%d]" % (k, i) bitinfo[-1] += "?" else: bitinfo[-1] += "+" if line[i] == "1" else "-" bitinfo[-1] += extra_text for lcidx in sorted(used_lc): lutff_options = "".join(icebox.get_lutff_seq_bits(tile, lcidx)) if lutff_options[0] == "1": lutff_options += " CarryEnable" if lutff_options[1] == "1": lutff_options += " DffEnable" if lutff_options[2] == "1": lutff_options += " Set_NoReset" if lutff_options[3] == "1": lutff_options += " AsyncSetReset" text.add("LC_%d %s %s" % (lcidx, "".join(icebox.get_lutff_lut_bits(tile, lcidx)), lutff_options)) if not print_bitinfo and not print_all: if text_default_mask == 3 and len(text) == 2: return if text_default_mask == 4 and len(text) == 1: return if len(text) or print_bitinfo or print_all: print("\n%s" % stmt) if print_bitinfo: print("Warning: No DB entries for some bits:") if print_bitinfo or print_map: for k, line in enumerate(bitinfo): print("%4s %s" % ("B%d" % k, line)) for line in sorted(text): print(line) for idx in ic.io_tiles: print_tile(".io_tile %d %d" % idx, ic, idx[0], idx[1], ic.io_tiles[idx], ic.tile_db(idx[0], idx[1])) for idx in ic.logic_tiles: print_tile(".logic_tile %d %d" % idx, ic, idx[0], idx[1], ic.logic_tiles[idx], ic.tile_db(idx[0], idx[1])) for idx in ic.ramb_tiles: print_tile(".ramb_tile %d %d" % idx, ic, idx[0], idx[1], ic.ramb_tiles[idx], ic.tile_db(idx[0], idx[1])) for idx in ic.ramt_tiles: print_tile(".ramt_tile %d %d" % idx, ic, idx[0], idx[1], ic.ramt_tiles[idx], ic.tile_db(idx[0], idx[1])) for i in range(4): for idx in ic.dsp_tiles[i]: print_tile(".dsp%d_tile %d %d" % (i, idx[0], idx[1]), ic, idx[0], idx[1], ic.dsp_tiles[i][idx], ic.tile_db(idx[0], idx[1])) for idx in ic.ipcon_tiles: print_tile(".ipcon_tile %d %d" % idx, ic, idx[0], idx[1], ic.ipcon_tiles[idx], ic.tile_db(idx[0], idx[1])) for bit in ic.extra_bits: print() print(".extra_bit %d %d %d" % bit) print(" ".join(ic.lookup_extra_bit(bit))) print()