2015-08-22 09:43:14 +02:00
|
|
|
#!/usr/bin/env python3
|
2015-07-18 13:05:02 +02:00
|
|
|
#
|
|
|
|
|
# Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
|
|
|
|
|
#
|
|
|
|
|
# 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
|
|
|
|
|
import getopt, sys, re
|
|
|
|
|
|
2017-03-06 23:24:52 +01:00
|
|
|
mode_384 = False
|
2017-06-22 19:28:22 +02:00
|
|
|
mode_5k = False
|
2015-07-18 13:10:40 +02:00
|
|
|
mode_8k = False
|
|
|
|
|
|
|
|
|
|
def usage():
|
|
|
|
|
print("""
|
2016-01-01 15:08:41 +01:00
|
|
|
Usage: icebox_chipdb [options] [bitmap.asc]
|
2015-07-18 13:10:40 +02:00
|
|
|
|
2017-03-06 23:24:52 +01:00
|
|
|
-3
|
|
|
|
|
create chipdb for 384 device
|
|
|
|
|
|
2017-06-22 19:28:22 +02:00
|
|
|
-5
|
|
|
|
|
create chipdb for 5k device
|
|
|
|
|
|
2015-07-18 13:10:40 +02:00
|
|
|
-8
|
|
|
|
|
create chipdb for 8k device
|
|
|
|
|
""")
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
|
|
try:
|
2017-06-22 19:28:22 +02:00
|
|
|
opts, args = getopt.getopt(sys.argv[1:], "358")
|
2015-07-18 13:10:40 +02:00
|
|
|
except:
|
|
|
|
|
usage()
|
|
|
|
|
|
|
|
|
|
for o, a in opts:
|
|
|
|
|
if o == "-8":
|
|
|
|
|
mode_8k = True
|
2017-06-22 19:28:22 +02:00
|
|
|
elif o == "-5":
|
|
|
|
|
mode_5k = True
|
2017-03-06 23:24:52 +01:00
|
|
|
elif o == "-3":
|
|
|
|
|
mode_384 = True
|
2015-07-18 13:10:40 +02:00
|
|
|
else:
|
|
|
|
|
usage()
|
|
|
|
|
|
2015-07-18 13:05:02 +02:00
|
|
|
ic = icebox.iceconfig()
|
2015-07-18 13:10:40 +02:00
|
|
|
if mode_8k:
|
|
|
|
|
ic.setup_empty_8k()
|
2017-06-22 19:28:22 +02:00
|
|
|
elif mode_5k:
|
|
|
|
|
ic.setup_empty_5k()
|
2017-03-06 23:24:52 +01:00
|
|
|
elif mode_384:
|
|
|
|
|
ic.setup_empty_384()
|
2015-07-18 13:10:40 +02:00
|
|
|
else:
|
|
|
|
|
ic.setup_empty_1k()
|
2015-07-18 13:05:02 +02:00
|
|
|
|
|
|
|
|
all_tiles = set()
|
|
|
|
|
for x in range(ic.max_x+1):
|
|
|
|
|
for y in range(ic.max_y+1):
|
|
|
|
|
if ic.tile(x, y) is not None:
|
|
|
|
|
all_tiles.add((x, y))
|
|
|
|
|
|
|
|
|
|
seg_to_net = dict()
|
|
|
|
|
net_to_segs = list()
|
|
|
|
|
|
|
|
|
|
print("""#
|
2015-07-18 13:10:40 +02:00
|
|
|
# IceBox Chip Database Dump (iCE40 %s)
|
2015-07-18 13:05:02 +02:00
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# Quick File Format Reference:
|
|
|
|
|
# ----------------------------
|
|
|
|
|
#
|
2015-07-18 13:07:39 +02:00
|
|
|
# .device DEVICE WIDTH HEIGHT NUM_NETS
|
2015-07-18 13:06:48 +02:00
|
|
|
#
|
2015-07-18 13:10:40 +02:00
|
|
|
# declares the device type
|
2015-07-18 13:06:48 +02:00
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .pins PACKAGE
|
2015-07-18 13:10:40 +02:00
|
|
|
# PIN_NUM TILE_X TILE_Y PIO_NUM
|
2015-07-18 13:06:48 +02:00
|
|
|
# ...
|
|
|
|
|
#
|
2015-07-18 13:07:39 +02:00
|
|
|
# associates a package pin with an IO tile and block, and global network
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .gbufin
|
|
|
|
|
# TILE_X TILE_Y GLB_NUM
|
|
|
|
|
# ...
|
|
|
|
|
#
|
2015-07-18 13:10:40 +02:00
|
|
|
# associates an IO tile with the global network can drive via fabout
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .gbufpin
|
|
|
|
|
# TILE_X TILE_Y PIO_NUM GLB_NUM
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# associates an IO tile with the global network can drive via the pad
|
2015-07-18 13:07:39 +02:00
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .iolatch
|
|
|
|
|
# TILE_X TILE_Y
|
|
|
|
|
# ...
|
|
|
|
|
#
|
2015-07-18 13:10:40 +02:00
|
|
|
# specifies the IO tiles that drive the latch signal for the bank via fabout
|
2015-07-18 13:07:39 +02:00
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .ieren
|
|
|
|
|
# PIO_TILE_X PIO_TILE_Y PIO_NUM IEREN_TILE_X IEREN_TILE_Y IEREN_NUM
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# associates an IO block with an IeRen-block
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .colbuf
|
|
|
|
|
# SOURCE_TILE_X SOURCE_TILE_Y DEST_TILE_X DEST_TILE_Y
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# declares the positions of the column buffers
|
2015-07-18 13:06:48 +02:00
|
|
|
#
|
2015-07-18 13:05:02 +02:00
|
|
|
#
|
|
|
|
|
# .io_tile X Y
|
|
|
|
|
# .logic_tile X Y
|
2015-07-18 13:06:48 +02:00
|
|
|
# .ramb_tile X Y
|
|
|
|
|
# .ramt_tile X Y
|
2017-11-15 17:31:17 +01:00
|
|
|
# .dsp[0..3]_tile X Y
|
|
|
|
|
# .ipcon_tile X Y
|
2015-07-18 13:05:02 +02:00
|
|
|
# declares the existence of a IO/LOGIC/RAM tile with the given coordinates
|
|
|
|
|
#
|
|
|
|
|
#
|
2015-07-18 13:07:39 +02:00
|
|
|
# .io_tile_bits COLUMNS ROWS
|
|
|
|
|
# .logic_tile_bits COLUMNS ROWS
|
|
|
|
|
# .ramb_tile_bits COLUMNS ROWS
|
|
|
|
|
# .ramt_tile_bits COLUMNS ROWS
|
2017-11-15 17:31:17 +01:00
|
|
|
# .dsp[0..3]_tile_bits X Y
|
|
|
|
|
# .ipcon_tile_bits X Y
|
2015-07-18 13:07:39 +02:00
|
|
|
# FUNCTION_1 CONFIG_BITS_NAMES_1
|
|
|
|
|
# FUNCTION_2 CONFIG_BITS_NAMES_2
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# declares non-routing configuration bits of IO/LOGIC/RAM tiles
|
|
|
|
|
#
|
|
|
|
|
#
|
2015-07-18 13:10:40 +02:00
|
|
|
# .extra_cell X Y <cell-type>
|
2017-11-15 17:31:17 +01:00
|
|
|
# .extra_cell X Y Z <cell-type>
|
2015-07-18 13:10:40 +02:00
|
|
|
# KEY MULTI-FIELD-VALUE
|
|
|
|
|
# ....
|
|
|
|
|
#
|
|
|
|
|
# declares a special-purpose cell that is not part of the FPGA fabric
|
|
|
|
|
#
|
2017-06-22 19:28:22 +02:00
|
|
|
#
|
2015-07-18 13:07:39 +02:00
|
|
|
# .extra_bits
|
|
|
|
|
# FUNCTION BANK_NUM ADDR_X ADDR_Y
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# declares non-routing global configuration bits
|
|
|
|
|
#
|
|
|
|
|
#
|
2015-07-18 13:05:02 +02:00
|
|
|
# .net NET_INDEX
|
|
|
|
|
# X1 Y1 name1
|
|
|
|
|
# X2 Y2 name2
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# declares a net on the chip and lists its various names in different tiles
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .buffer X Y DST_NET_INDEX CONFIG_BITS_NAMES
|
|
|
|
|
# CONFIG_BITS_VALUES_1 SRC_NET_INDEX_1
|
|
|
|
|
# CONFIG_BITS_VALUES_2 SRC_NET_INDEX_2
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# declares a buffer in the specified tile
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# .routing X Y DST_NET_INDEX CONFIG_BITS_NAMES
|
|
|
|
|
# CONFIG_BITS_VALUES_1 SRC_NET_INDEX_1
|
|
|
|
|
# CONFIG_BITS_VALUES_2 SRC_NET_INDEX_2
|
|
|
|
|
# ...
|
|
|
|
|
#
|
|
|
|
|
# declares a routing switch in the specified tile
|
|
|
|
|
#
|
2015-07-18 13:10:40 +02:00
|
|
|
""" % ic.device)
|
2015-07-18 13:05:02 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
all_group_segments = ic.group_segments(all_tiles, connect_gb=False)
|
|
|
|
|
|
2015-07-18 13:10:40 +02:00
|
|
|
print(".device %s %d %d %d" % (ic.device, ic.max_x+1, ic.max_y+1, len(all_group_segments)))
|
2015-07-18 13:06:48 +02:00
|
|
|
print()
|
|
|
|
|
|
2016-10-08 17:59:47 +02:00
|
|
|
for key in sorted(icebox.pinloc_db.keys()):
|
2015-07-18 13:10:40 +02:00
|
|
|
key_dev, key_package = key.split("-")
|
|
|
|
|
if key_dev == ic.device:
|
|
|
|
|
print(".pins %s" % (key_package))
|
|
|
|
|
for entry in sorted(icebox.pinloc_db[key]):
|
|
|
|
|
print("%s %d %d %d" % entry)
|
|
|
|
|
print()
|
2015-07-18 13:06:48 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
print(".gbufin")
|
|
|
|
|
for entry in sorted(ic.gbufin_db()):
|
|
|
|
|
print(" ".join(["%d" % k for k in entry]))
|
|
|
|
|
print()
|
|
|
|
|
|
2015-07-18 13:10:40 +02:00
|
|
|
print(".gbufpin")
|
|
|
|
|
for padin, pio in enumerate(ic.padin_pio_db()):
|
|
|
|
|
entry = pio + (padin,)
|
|
|
|
|
print(" ".join(["%d" % k for k in entry]))
|
|
|
|
|
print()
|
|
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
print(".iolatch")
|
|
|
|
|
for entry in sorted(ic.iolatch_db()):
|
|
|
|
|
print(" ".join(["%d" % k for k in entry]))
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
print(".ieren")
|
|
|
|
|
for entry in sorted(ic.ieren_db()):
|
|
|
|
|
print(" ".join(["%d" % k for k in entry]))
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
print(".colbuf")
|
|
|
|
|
for entry in sorted(ic.colbuf_db()):
|
|
|
|
|
print(" ".join(["%d" % k for k in entry]))
|
|
|
|
|
print()
|
|
|
|
|
|
2015-07-18 13:05:02 +02:00
|
|
|
for idx in sorted(ic.io_tiles):
|
|
|
|
|
print(".io_tile %d %d" % idx)
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
for idx in sorted(ic.logic_tiles):
|
|
|
|
|
print(".logic_tile %d %d" % idx)
|
|
|
|
|
print()
|
|
|
|
|
|
2015-07-18 13:06:48 +02:00
|
|
|
for idx in sorted(ic.ramb_tiles):
|
|
|
|
|
print(".ramb_tile %d %d" % idx)
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
for idx in sorted(ic.ramt_tiles):
|
|
|
|
|
print(".ramt_tile %d %d" % idx)
|
2015-07-18 13:05:02 +02:00
|
|
|
print()
|
|
|
|
|
|
2017-11-15 17:31:17 +01:00
|
|
|
for dsp_idx in range(4):
|
|
|
|
|
for idx in sorted(ic.dsp_tiles[dsp_idx]):
|
|
|
|
|
x, y = idx
|
|
|
|
|
print(".dsp%d_tile %d %d" % (dsp_idx, x, y))
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
for idx in sorted(ic.ipcon_tiles):
|
|
|
|
|
print(".ipcon_tile %d %d" % idx)
|
|
|
|
|
print()
|
|
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
def print_tile_nonrouting_bits(tile_type, idx):
|
|
|
|
|
tx = idx[0]
|
|
|
|
|
ty = idx[1]
|
2017-06-22 19:28:22 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
tile = ic.tile(tx, ty)
|
2017-06-22 19:28:22 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
print(".%s_tile_bits %d %d" % (tile_type, len(tile[0]), len(tile)))
|
2017-06-22 19:28:22 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
function_bits = dict()
|
|
|
|
|
for entry in ic.tile_db(tx, ty):
|
|
|
|
|
if not ic.tile_has_entry(tx, ty, entry):
|
|
|
|
|
continue
|
|
|
|
|
if entry[1] in ("routing", "buffer"):
|
|
|
|
|
continue
|
2017-06-22 19:28:22 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
func = ".".join(entry[1:])
|
|
|
|
|
function_bits[func] = entry[0]
|
2017-06-22 19:28:22 +02:00
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
for x in sorted(function_bits):
|
|
|
|
|
print(" ".join([x] + function_bits[x]))
|
|
|
|
|
print()
|
|
|
|
|
|
2015-08-22 09:43:14 +02:00
|
|
|
print_tile_nonrouting_bits("logic", list(ic.logic_tiles.keys())[0])
|
|
|
|
|
print_tile_nonrouting_bits("io", list(ic.io_tiles.keys())[0])
|
2017-03-08 20:30:45 +01:00
|
|
|
if not mode_384:
|
|
|
|
|
print_tile_nonrouting_bits("ramb", list(ic.ramb_tiles.keys())[0])
|
|
|
|
|
print_tile_nonrouting_bits("ramt", list(ic.ramt_tiles.keys())[0])
|
2015-07-18 13:07:39 +02:00
|
|
|
|
2017-11-15 17:31:17 +01:00
|
|
|
if ic.is_ultra():
|
|
|
|
|
for dsp_idx in range(4):
|
|
|
|
|
print_tile_nonrouting_bits("dsp%d" % dsp_idx, list(ic.dsp_tiles[dsp_idx].keys())[0])
|
|
|
|
|
print_tile_nonrouting_bits("ipcon", list(ic.ipcon_tiles.keys())[0])
|
2017-11-24 19:49:28 +01:00
|
|
|
if ic.is_ultra():
|
|
|
|
|
print(".extra_cell %d 0 WARMBOOT" % ic.max_x)
|
|
|
|
|
else:
|
|
|
|
|
print(".extra_cell 0 0 WARMBOOT")
|
2015-07-18 13:10:40 +02:00
|
|
|
for key in sorted(icebox.warmbootinfo_db[ic.device]):
|
|
|
|
|
print("%s %s" % (key, " ".join([str(k) for k in icebox.warmbootinfo_db[ic.device][key]])))
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
for pllid in ic.pll_list():
|
|
|
|
|
pllinfo = icebox.pllinfo_db[pllid]
|
|
|
|
|
print(".extra_cell %d %d PLL" % pllinfo["LOC"])
|
2016-05-15 13:31:35 +02:00
|
|
|
locked_pkgs = []
|
|
|
|
|
for entry in icebox.noplls_db:
|
|
|
|
|
if pllid in icebox.noplls_db[entry]:
|
|
|
|
|
locked_pkgs.append(entry.split("-")[1])
|
|
|
|
|
if len(locked_pkgs) > 0:
|
2016-10-08 17:59:47 +02:00
|
|
|
print("LOCKED %s" % " ".join(sorted(locked_pkgs)))
|
2015-07-18 13:10:40 +02:00
|
|
|
for key in sorted(pllinfo):
|
|
|
|
|
if key != "LOC":
|
|
|
|
|
print("%s %s" % (key, " ".join([str(k) for k in pllinfo[key]])))
|
|
|
|
|
print()
|
|
|
|
|
|
2017-11-15 17:31:17 +01:00
|
|
|
for dsploc in ic.dsp_tiles[0]:
|
|
|
|
|
x, y = dsploc
|
|
|
|
|
print(".extra_cell %d %d 0 MAC16" % dsploc)
|
|
|
|
|
nets = ic.get_dsp_nets_db(x, y)
|
|
|
|
|
for key in sorted(nets):
|
|
|
|
|
print("%s %s" % (key, " ".join([str(k) for k in nets[key]])))
|
|
|
|
|
|
|
|
|
|
cfg = ic.get_dsp_config_db(x, y)
|
|
|
|
|
for key in sorted(cfg):
|
|
|
|
|
print("%s %s" % (key, " ".join([str(k) for k in cfg[key]])))
|
2017-11-17 11:06:35 +01:00
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
if ic.device in icebox.extra_cells_db:
|
|
|
|
|
for cell in icebox.extra_cells_db[ic.device]:
|
|
|
|
|
name, loc = cell
|
|
|
|
|
x, y, z = loc
|
|
|
|
|
print(".extra_cell %d %d %d %s" % (x, y, z, name))
|
|
|
|
|
cellinfo = icebox.extra_cells_db[ic.device][cell]
|
|
|
|
|
for key in sorted(cellinfo):
|
|
|
|
|
print("%s %s" % (key, " ".join([str(k) for k in cellinfo[key]])))
|
2017-11-17 12:27:40 +01:00
|
|
|
print()
|
2017-11-17 15:29:00 +01:00
|
|
|
|
|
|
|
|
if ic.device in icebox.spram_db:
|
|
|
|
|
for cell in icebox.spram_db[ic.device]:
|
|
|
|
|
loc = cell
|
|
|
|
|
x, y, z = loc
|
|
|
|
|
print(".extra_cell %d %d %d SPRAM" % (x, y, z))
|
|
|
|
|
cellinfo = icebox.spram_db[ic.device][cell]
|
|
|
|
|
for key in sorted(cellinfo):
|
|
|
|
|
print("%s %s" % (key, " ".join([str(k) for k in cellinfo[key]])))
|
|
|
|
|
print()
|
|
|
|
|
|
2015-07-18 13:07:39 +02:00
|
|
|
print(".extra_bits")
|
|
|
|
|
extra_bits = dict()
|
|
|
|
|
for idx in sorted(ic.extra_bits_db()):
|
|
|
|
|
extra_bits[".".join(ic.extra_bits_db()[idx])] = " ".join(["%d" % k for k in idx])
|
|
|
|
|
for idx in sorted(extra_bits):
|
|
|
|
|
print("%s %s" % (idx, extra_bits[idx]))
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
for group in sorted(all_group_segments):
|
2015-07-18 13:05:02 +02:00
|
|
|
netidx = len(net_to_segs)
|
|
|
|
|
net_to_segs.append(group)
|
|
|
|
|
print(".net %d" % netidx)
|
|
|
|
|
for seg in group:
|
|
|
|
|
print("%d %d %s" % seg)
|
|
|
|
|
assert seg not in seg_to_net
|
|
|
|
|
seg_to_net[seg] = netidx
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
for idx in sorted(all_tiles):
|
|
|
|
|
db = ic.tile_db(idx[0], idx[1])
|
|
|
|
|
db_by_bits = dict()
|
|
|
|
|
for entry in db:
|
|
|
|
|
if entry[1] in ("buffer", "routing") and ic.tile_has_net(idx[0], idx[1], entry[2]) and ic.tile_has_net(idx[0], idx[1], entry[3]):
|
|
|
|
|
bits = tuple([entry[1]] + sorted([bit.replace("!", "") for bit in entry[0]]))
|
|
|
|
|
db_by_bits.setdefault(bits, list()).append(entry)
|
|
|
|
|
for bits in sorted(db_by_bits):
|
|
|
|
|
dst_net = None
|
|
|
|
|
for entry in sorted(db_by_bits[bits]):
|
|
|
|
|
assert (idx[0], idx[1], entry[3]) in seg_to_net
|
|
|
|
|
if dst_net is None:
|
|
|
|
|
dst_net = seg_to_net[(idx[0], idx[1], entry[3])]
|
|
|
|
|
else:
|
|
|
|
|
assert dst_net == seg_to_net[(idx[0], idx[1], entry[3])]
|
|
|
|
|
print(".%s %d %d %d %s" % (bits[0], idx[0], idx[1], dst_net, " ".join(bits[1:])))
|
|
|
|
|
for entry in sorted(db_by_bits[bits]):
|
|
|
|
|
pattern = ""
|
|
|
|
|
for bit in bits[1:]:
|
|
|
|
|
pattern += "1" if bit in entry[0] else "0"
|
|
|
|
|
assert (idx[0], idx[1], entry[2]) in seg_to_net
|
|
|
|
|
print("%s %d" % (pattern, seg_to_net[(idx[0], idx[1], entry[2])]))
|
|
|
|
|
print()
|