Merge branch 'tannewt'

This commit is contained in:
Clifford Wolf 2017-07-04 12:24:38 +02:00
commit 3fb5934d54
32 changed files with 6778 additions and 340 deletions

View File

@ -1,6 +1,6 @@
include ../config.mk
all: chipdb-384.txt chipdb-1k.txt chipdb-8k.txt
all: chipdb-384.txt chipdb-1k.txt chipdb-5k.txt chipdb-8k.txt
chipdb-384.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py -3 > chipdb-384.new
@ -10,12 +10,16 @@ chipdb-1k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py > chipdb-1k.new
mv chipdb-1k.new chipdb-1k.txt
chipdb-5k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py -5 > chipdb-5k.new
mv chipdb-5k.new chipdb-5k.txt
chipdb-8k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py -8 > chipdb-8k.new
mv chipdb-8k.new chipdb-8k.txt
clean:
rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt
rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt chipdb-5k.txt
rm -f icebox.pyc iceboxdb.pyc
install: all
@ -52,4 +56,3 @@ uninstall:
-rmdir $(DESTDIR)$(PREFIX)/share/icebox
.PHONY: all clean install uninstall

View File

@ -76,6 +76,26 @@ class iceconfig:
self.io_tiles[(0, y)] = ["0" * 18 for i in range(16)]
self.io_tiles[(self.max_x, y)] = ["0" * 18 for i in range(16)]
def setup_empty_5k(self):
self.clear()
self.device = "5k"
self.max_x = 26
self.max_y = 33
for x in range(1, self.max_x):
for y in range(1, self.max_y):
if x in (6, 18):
if y % 2 == 1:
self.ramb_tiles[(x, y)] = ["0" * 42 for i in range(16)]
else:
self.ramt_tiles[(x, y)] = ["0" * 42 for i in range(16)]
else:
self.logic_tiles[(x, y)] = ["0" * 54 for i in range(16)]
for x in range(1, self.max_x):
self.io_tiles[(x, 0)] = ["0" * 18 for i in range(16)]
self.io_tiles[(x, self.max_y)] = ["0" * 18 for i in range(16)]
def setup_empty_8k(self):
self.clear()
self.device = "8k"
@ -116,6 +136,7 @@ class iceconfig:
def pinloc_db(self):
if self.device == "384": return pinloc_db["384-qn32"]
if self.device == "1k": return pinloc_db["1k-tq144"]
if self.device == "5k": return pinloc_db["5k-sg48"]
if self.device == "8k": return pinloc_db["8k-ct256"]
assert False
@ -137,6 +158,8 @@ class iceconfig:
def pll_list(self):
if self.device == "1k":
return ["1k"]
if self.device == "5k":
return ["5k"]
if self.device == "8k":
return ["8k_0", "8k_1"]
if self.device == "384":
@ -185,20 +208,28 @@ class iceconfig:
assert False
def tile_db(self, x, y):
if x == 0: return iotile_l_db
# Only these devices have IO on the left and right sides.
if self.device in ["384", "1k", "8k"]:
if x == 0: return iotile_l_db
if x == self.max_x: return iotile_r_db
if y == 0: return iotile_b_db
if x == self.max_x: return iotile_r_db
if y == self.max_y: return iotile_t_db
if self.device == "1k":
if (x, y) in self.logic_tiles: return logictile_db
if (x, y) in self.ramb_tiles: return rambtile_db
if (x, y) in self.ramt_tiles: return ramttile_db
if self.device == "8k":
elif self.device == "5k":
if (x, y) in self.logic_tiles: return logictile_5k_db
if (x, y) in self.ramb_tiles: return rambtile_5k_db
if (x, y) in self.ramt_tiles: return ramttile_5k_db
elif self.device == "8k":
if (x, y) in self.logic_tiles: return logictile_8k_db
if (x, y) in self.ramb_tiles: return rambtile_8k_db
if (x, y) in self.ramt_tiles: return ramttile_8k_db
if self.device == "384":
elif self.device == "384":
if (x, y) in self.logic_tiles: return logictile_384_db
print("Tile type unknown at (%d, %d)" % (x, y))
assert False
def tile_type(self, x, y):
@ -474,6 +505,8 @@ class iceconfig:
seed_segments.add((idx[0], idx[1], "lutff_7/cout"))
if self.device == "1k":
add_seed_segments(idx, tile, logictile_db)
elif self.device == "5k":
add_seed_segments(idx, tile, logictile_5k_db)
elif self.device == "8k":
add_seed_segments(idx, tile, logictile_8k_db)
elif self.device == "384":
@ -484,6 +517,8 @@ class iceconfig:
for idx, tile in self.ramb_tiles.items():
if self.device == "1k":
add_seed_segments(idx, tile, rambtile_db)
elif self.device == "5k":
add_seed_segments(idx, tile, rambtile_5k_db)
elif self.device == "8k":
add_seed_segments(idx, tile, rambtile_8k_db)
else:
@ -492,6 +527,8 @@ class iceconfig:
for idx, tile in self.ramt_tiles.items():
if self.device == "1k":
add_seed_segments(idx, tile, ramttile_db)
elif self.device == "5k":
add_seed_segments(idx, tile, ramttile_5k_db)
elif self.device == "8k":
add_seed_segments(idx, tile, ramttile_8k_db)
else:
@ -539,7 +576,9 @@ class iceconfig:
for s in self.expand_net(queue.pop()):
if s not in segments:
segments.add(s)
assert s not in seen_segments
if s in seen_segments:
print("//", s, "has already been seen. Check your bitmapping.")
assert False
seen_segments.add(s)
seed_segments.discard(s)
if s in connected_segments:
@ -611,7 +650,7 @@ class iceconfig:
self.extra_bits.add((int(line[1]), int(line[2]), int(line[3])))
continue
if line[0] == ".device":
assert line[1] in ["1k", "8k", "384"]
assert line[1] in ["1k", "5k", "8k", "384"]
self.device = line[1]
continue
if line[0] == ".sym":
@ -983,7 +1022,8 @@ def key_netname(netname):
def run_checks_neigh():
print("Running consistency checks on neighbour finder..")
ic = iceconfig()
ic.setup_empty_1k()
# ic.setup_empty_1k()
ic.setup_empty_5k()
# ic.setup_empty_8k()
# ic.setup_empty_384()
@ -999,8 +1039,12 @@ def run_checks_neigh():
for x in range(ic.max_x+1):
for y in range(ic.max_x+1):
# Skip the corners.
if x in (0, ic.max_x) and y in (0, ic.max_y):
continue
# Skip the sides of a 5k device.
if ic.device == "5k" and x in (0, ic.max_x):
continue
add_segments((x, y), ic.tile_db(x, y))
if (x, y) in ic.logic_tiles:
all_segments.add((x, y, "lutff_7/cout"))
@ -1021,24 +1065,27 @@ def run_checks_neigh():
def run_checks():
run_checks_neigh()
def parse_db(text, grep_8k=False, grep_384=False):
def parse_db(text, device="1k"):
db = list()
for line in text.split("\n"):
line_384 = line.replace("384_glb_netwk_", "glb_netwk_")
line_1k = line.replace("1k_glb_netwk_", "glb_netwk_")
line_5k = line.replace("5k_glb_netwk_", "glb_netwk_")
line_8k = line.replace("8k_glb_netwk_", "glb_netwk_")
if line_1k != line:
if grep_8k:
continue
if grep_384:
if device != "1k":
continue
line = line_1k
elif line_8k != line:
if not grep_8k:
if device != "8k":
continue
line = line_8k
elif line_5k != line:
if device != "5k":
continue
line = line_5k
elif line_384 != line:
if not grep_384:
if device != "384":
continue
line = line_384
line = line.split("\t")
@ -1059,6 +1106,16 @@ extra_bits_db = {
(0, 330, 143): ("padin_glb_netwk", "6"),
(0, 331, 143): ("padin_glb_netwk", "7"),
},
"5k": {
(0, 870, 270): ("padin_glb_netwk", "0"),
(0, 871, 270): ("padin_glb_netwk", "1"),
(1, 870, 271): ("padin_glb_netwk", "2"),
(1, 871, 271): ("padin_glb_netwk", "3"),
(1, 870, 270): ("padin_glb_netwk", "4"),
(1, 871, 270): ("padin_glb_netwk", "5"),
(0, 870, 271): ("padin_glb_netwk", "6"),
(0, 871, 271): ("padin_glb_netwk", "7"),
},
"8k": {
(0, 870, 270): ("padin_glb_netwk", "0"),
(0, 871, 270): ("padin_glb_netwk", "1"),
@ -1092,6 +1149,8 @@ gbufin_db = {
( 6, 0, 5),
( 6, 17, 4),
],
"5k": [
],
"8k": [
(33, 16, 7),
( 0, 16, 6),
@ -1114,6 +1173,14 @@ gbufin_db = {
]
}
# To figure these out:
# 1. Copy io_latched.sh and convert it for your pinout (like io_latched_5k.sh).
# 2. Run it. It will create an io_latched_<device>.work directory with a bunch of files.
# 3. Grep the *.ve files in that directory for "'fabout')". The coordinates
# before it are where the io latches are.
#
# Note: This may not work if your icepack configuration of cell sizes is incorrect because
# icebox_vlog.py won't correctly interpret the meaning of particular bits.
iolatch_db = {
"1k": [
( 0, 7),
@ -1121,6 +1188,10 @@ iolatch_db = {
( 5, 0),
( 8, 17),
],
"5k": [
(14, 0),
(14, 31),
],
"8k": [
( 0, 15),
(33, 18),
@ -1135,12 +1206,20 @@ iolatch_db = {
],
}
# The x, y cell locations of the WARMBOOT controls. Run tests/sb_warmboot.v
# through icecube.sh to determine these values.
warmbootinfo_db = {
"1k": {
"BOOT": ( 12, 0, "fabout" ),
"S0": ( 13, 1, "fabout" ),
"S1": ( 13, 2, "fabout" ),
},
"5k": {
# These are the right locations but may be the wrong order.
"BOOT": ( 22, 0, "fabout" ),
"S0": ( 23, 0, "fabout" ),
"S1": ( 24, 0, "fabout" ),
},
"8k": {
"BOOT": ( 31, 0, "fabout" ),
"S0": ( 33, 1, "fabout" ),
@ -1164,6 +1243,7 @@ noplls_db = {
"1k-cb121": [ "1k" ],
"1k-vq100": [ "1k" ],
"384-qn32": [ "384" ],
"5k-sg48": [ "5k" ],
}
pllinfo_db = {
@ -1260,6 +1340,99 @@ pllinfo_db = {
"SDI": ( 4, 0, "fabout"),
"SCLK": ( 3, 0, "fabout"),
},
"5k": {
"LOC" : (16, 0),
# 3'b000 = "DISABLED"
# 3'b010 = "SB_PLL40_PAD"
# 3'b100 = "SB_PLL40_2_PAD"
# 3'b110 = "SB_PLL40_2F_PAD"
# 3'b011 = "SB_PLL40_CORE"
# 3'b111 = "SB_PLL40_2F_CORE"
"PLLTYPE_0": ( 16, 0, "PLLCONFIG_5"),
"PLLTYPE_1": ( 18, 0, "PLLCONFIG_1"),
"PLLTYPE_2": ( 18, 0, "PLLCONFIG_3"),
# 3'b000 = "DELAY"
# 3'b001 = "SIMPLE"
# 3'b010 = "PHASE_AND_DELAY"
# 3'b110 = "EXTERNAL"
"FEEDBACK_PATH_0": ( 18, 0, "PLLCONFIG_5"),
"FEEDBACK_PATH_1": ( 15, 0, "PLLCONFIG_9"),
"FEEDBACK_PATH_2": ( 16, 0, "PLLCONFIG_1"),
# 1'b0 = "FIXED"
# 1'b1 = "DYNAMIC" (also set FDA_FEEDBACK=4'b1111)
"DELAY_ADJMODE_FB": ( 17, 0, "PLLCONFIG_4"),
# 1'b0 = "FIXED"
# 1'b1 = "DYNAMIC" (also set FDA_RELATIVE=4'b1111)
"DELAY_ADJMODE_REL": ( 17, 0, "PLLCONFIG_9"),
# 2'b00 = "GENCLK"
# 2'b01 = "GENCLK_HALF"
# 2'b10 = "SHIFTREG_90deg"
# 2'b11 = "SHIFTREG_0deg"
"PLLOUT_SELECT_A_0": ( 16, 0, "PLLCONFIG_6"),
"PLLOUT_SELECT_A_1": ( 16, 0, "PLLCONFIG_7"),
# 2'b00 = "GENCLK"
# 2'b01 = "GENCLK_HALF"
# 2'b10 = "SHIFTREG_90deg"
# 2'b11 = "SHIFTREG_0deg"
"PLLOUT_SELECT_B_0": ( 16, 0, "PLLCONFIG_2"),
"PLLOUT_SELECT_B_1": ( 16, 0, "PLLCONFIG_3"),
# Numeric Parameters
"SHIFTREG_DIV_MODE": ( 16, 0, "PLLCONFIG_4"),
"FDA_FEEDBACK_0": ( 16, 0, "PLLCONFIG_9"),
"FDA_FEEDBACK_1": ( 17, 0, "PLLCONFIG_1"),
"FDA_FEEDBACK_2": ( 17, 0, "PLLCONFIG_2"),
"FDA_FEEDBACK_3": ( 17, 0, "PLLCONFIG_3"),
"FDA_RELATIVE_0": ( 17, 0, "PLLCONFIG_5"),
"FDA_RELATIVE_1": ( 17, 0, "PLLCONFIG_6"),
"FDA_RELATIVE_2": ( 17, 0, "PLLCONFIG_7"),
"FDA_RELATIVE_3": ( 17, 0, "PLLCONFIG_8"),
"DIVR_0": ( 14, 0, "PLLCONFIG_1"),
"DIVR_1": ( 14, 0, "PLLCONFIG_2"),
"DIVR_2": ( 14, 0, "PLLCONFIG_3"),
"DIVR_3": ( 14, 0, "PLLCONFIG_4"),
"DIVF_0": ( 14, 0, "PLLCONFIG_5"),
"DIVF_1": ( 14, 0, "PLLCONFIG_6"),
"DIVF_2": ( 14, 0, "PLLCONFIG_7"),
"DIVF_3": ( 14, 0, "PLLCONFIG_8"),
"DIVF_4": ( 14, 0, "PLLCONFIG_9"),
"DIVF_5": ( 15, 0, "PLLCONFIG_1"),
"DIVF_6": ( 15, 0, "PLLCONFIG_2"),
"DIVQ_0": ( 15, 0, "PLLCONFIG_3"),
"DIVQ_1": ( 15, 0, "PLLCONFIG_4"),
"DIVQ_2": ( 15, 0, "PLLCONFIG_5"),
"FILTER_RANGE_0": ( 15, 0, "PLLCONFIG_6"),
"FILTER_RANGE_1": ( 15, 0, "PLLCONFIG_7"),
"FILTER_RANGE_2": ( 15, 0, "PLLCONFIG_8"),
"TEST_MODE": ( 16, 0, "PLLCONFIG_8"),
# PLL Ports
"PLLOUT_A": ( 16, 0, 1),
"PLLOUT_B": ( 17, 0, 0),
"REFERENCECLK": ( 13, 0, "fabout"),
"EXTFEEDBACK": ( 14, 0, "fabout"),
"DYNAMICDELAY_0": ( 5, 0, "fabout"),
"DYNAMICDELAY_1": ( 6, 0, "fabout"),
"DYNAMICDELAY_2": ( 7, 0, "fabout"),
"DYNAMICDELAY_3": ( 8, 0, "fabout"),
"DYNAMICDELAY_4": ( 9, 0, "fabout"),
"DYNAMICDELAY_5": ( 10, 0, "fabout"),
"DYNAMICDELAY_6": ( 11, 0, "fabout"),
"DYNAMICDELAY_7": ( 12, 0, "fabout"),
"LOCK": ( 1, 1, "neigh_op_bnl_1"),
"BYPASS": ( 19, 0, "fabout"),
"RESETB": ( 20, 0, "fabout"),
"LATCHINPUTVALUE": ( 15, 0, "fabout"),
"SDO": ( 32, 1, "neigh_op_bnr_3"),
"SDI": ( 22, 0, "fabout"),
"SCLK": ( 21, 0, "fabout"),
},
"8k_0": {
"LOC" : (16, 0),
@ -1459,6 +1632,13 @@ padin_pio_db = {
( 6, 0, 1), # glb_netwk_6
( 6, 17, 1), # glb_netwk_7
],
"5k": [
( 6, 0, 1),
(19, 0, 1),
( 6, 31, 0),
(12, 31, 1),
(13, 31, 0),
],
"8k": [
(33, 16, 1),
( 0, 16, 1),
@ -1847,6 +2027,9 @@ ieren_db = {
],
}
# This dictionary maps package variants to a table of pin names and their
# corresponding grid location (x, y, block). This is most easily found through
# the package view in iCEcube2 by hovering the mouse over each pin.
pinloc_db = {
"1k-swg16tr": [
( "A2", 6, 17, 1),
@ -3850,17 +4033,61 @@ pinloc_db = {
( "G3", 3, 0, 0),
( "G4", 4, 0, 1),
( "G6", 5, 0, 1),
]
],
"5k-sg48": [
( "2", 8, 0, 0),
( "3", 9, 0, 1),
( "4", 9, 0, 0),
( "6", 13, 0, 1),
( "9", 15, 0, 0),
( "10", 16, 0, 0),
( "11", 17, 0, 0),
( "12", 18, 0, 0),
( "13", 19, 0, 0),
( "14", 23, 0, 0),
( "15", 24, 0, 0),
( "16", 24, 0, 1),
( "17", 23, 0, 1),
( "18", 22, 0, 1),
( "19", 21, 0, 1),
( "20", 19, 0, 1),
( "21", 18, 0, 1),
( "23", 19, 31, 0),
( "25", 19, 31, 1),
( "26", 18, 31, 0),
( "27", 18, 31, 1),
( "28", 17, 31, 0),
( "31", 16, 31, 1),
( "32", 16, 31, 0),
( "34", 13, 31, 1),
( "35", 12, 31, 1),
( "36", 9, 31, 1),
( "37", 13, 31, 0),
( "38", 8, 31, 1),
( "39", 4, 31, 0),
( "40", 5, 31, 0),
( "41", 6, 31, 0),
( "42", 8, 31, 0),
( "43", 9, 31, 0),
( "44", 6, 0, 1),
( "45", 7, 0, 1),
( "46", 5, 0, 0),
( "47", 6, 0, 0),
( "48", 7, 0, 0),
],
}
iotile_full_db = parse_db(iceboxdb.database_io_txt)
logictile_db = parse_db(iceboxdb.database_logic_txt)
logictile_8k_db = parse_db(iceboxdb.database_logic_txt, True)
logictile_384_db = parse_db(iceboxdb.database_logic_txt, False, True)
rambtile_db = parse_db(iceboxdb.database_ramb_txt)
ramttile_db = parse_db(iceboxdb.database_ramt_txt)
rambtile_8k_db = parse_db(iceboxdb.database_ramb_8k_txt, True)
ramttile_8k_db = parse_db(iceboxdb.database_ramt_8k_txt, True)
logictile_db = parse_db(iceboxdb.database_logic_txt, "1k")
logictile_5k_db = parse_db(iceboxdb.database_logic_txt, "5k")
logictile_8k_db = parse_db(iceboxdb.database_logic_txt, "8k")
logictile_384_db = parse_db(iceboxdb.database_logic_txt, "384")
rambtile_db = parse_db(iceboxdb.database_ramb_txt, "1k")
ramttile_db = parse_db(iceboxdb.database_ramt_txt, "1k")
rambtile_5k_db = parse_db(iceboxdb.database_ramb_8k_txt, "5k")
ramttile_5k_db = parse_db(iceboxdb.database_ramt_8k_txt, "5k")
rambtile_8k_db = parse_db(iceboxdb.database_ramb_8k_txt, "8k")
ramttile_8k_db = parse_db(iceboxdb.database_ramt_8k_txt, "8k")
iotile_l_db = list()
iotile_r_db = list()
@ -3914,4 +4141,3 @@ for db in [iotile_l_db, iotile_r_db, iotile_t_db, iotile_b_db, logictile_db, log
if __name__ == "__main__":
run_checks()

View File

@ -19,6 +19,7 @@ import icebox
import getopt, sys, re
mode_384 = False
mode_5k = False
mode_8k = False
def usage():
@ -28,19 +29,24 @@ Usage: icebox_chipdb [options] [bitmap.asc]
-3
create chipdb for 384 device
-5
create chipdb for 5k device
-8
create chipdb for 8k device
""")
sys.exit(0)
try:
opts, args = getopt.getopt(sys.argv[1:], "38")
opts, args = getopt.getopt(sys.argv[1:], "358")
except:
usage()
for o, a in opts:
if o == "-8":
mode_8k = True
elif o == "-5":
mode_5k = True
elif o == "-3":
mode_384 = True
else:
@ -49,6 +55,8 @@ for o, a in opts:
ic = icebox.iceconfig()
if mode_8k:
ic.setup_empty_8k()
elif mode_5k:
ic.setup_empty_5k()
elif mode_384:
ic.setup_empty_384()
else:
@ -142,7 +150,7 @@ print("""#
#
# declares a special-purpose cell that is not part of the FPGA fabric
#
#
#
# .extra_bits
# FUNCTION BANK_NUM ADDR_X ADDR_Y
# ...
@ -233,21 +241,21 @@ print()
def print_tile_nonrouting_bits(tile_type, idx):
tx = idx[0]
ty = idx[1]
tile = ic.tile(tx, ty)
print(".%s_tile_bits %d %d" % (tile_type, len(tile[0]), len(tile)))
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
func = ".".join(entry[1:])
function_bits[func] = entry[0]
for x in sorted(function_bits):
print(" ".join([x] + function_bits[x]))
print()
@ -318,4 +326,3 @@ for idx in sorted(all_tiles):
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()

View File

@ -728,7 +728,7 @@ for tile in ic.ramb_tiles:
if len(wire_bits) > 1:
return "{%s}" % ", ".join(wire_bits)
return wire_bits[0]
if get_ram_config('PowerUp') == (ic.device == "8k"):
if get_ram_config('PowerUp') == (ic.device in ("8k", "5k")):
if not strip_comments:
text_func.append("// RAM TILE %d %d" % tile)
text_func.append("SB_RAM40_4K%s%s #(" % ("NR" if negclk_rd else "", "NW" if negclk_wr else ""));

View File

@ -2,8 +2,26 @@ include ../config.mk
export LC_ALL=C
export ICE_SBTIMER_LP=1
#EIGTHK = _8k
THREEH = _384
DEVICECLASS = 1k
ifeq ($(DEVICECLASS), 384)
DEVICE := lp384-cm49
THREEH = _384
endif
ifeq ($(DEVICECLASS), 1k)
DEVICE := hx1k-tq144
endif
ifeq ($(DEVICECLASS), 5k)
DEVICE := up5k-sg48
RAM_SUFFIX := _5k
endif
ifeq ($(DEVICECLASS), 8k)
DEVICE := hx8k-ct256
RAM_SUFFIX = _8k
endif
TESTS =
TESTS += binop
@ -18,49 +36,52 @@ TESTS += gbio
TESTS += gbio2
TESTS += prim
TESTS += fflogic
ifneq ($(THREEH),_384)
ifneq ($(DEVICECLASS),384)
TESTS += ram40
TESTS += mem
TESTS += pll
TESTS += aig
endif
database: bitdata_io.txt bitdata_logic.txt bitdata_ramb$(EIGTHK).txt bitdata_ramt$(EIGTHK).txt
ifeq ($(EIGTHK),_8k)
database: bitdata_io.txt bitdata_logic.txt bitdata_ramb$(RAM_SUFFIX).txt bitdata_ramt$(RAM_SUFFIX).txt
ifneq ($(RAM_SUFFIX),)
cp cached_ramb.txt bitdata_ramb.txt
cp cached_ramt.txt bitdata_ramt.txt
else
endif
ifneq ($(RAM_SUFFIX),_8k)
cp cached_ramb_8k.txt bitdata_ramb_8k.txt
cp cached_ramt_8k.txt bitdata_ramt_8k.txt
endif
python3 database.py
ifneq ($(RAM_SUFFIX),_5k)
cp cached_ramb_5k.txt bitdata_ramb_5k.txt
cp cached_ramt_5k.txt bitdata_ramt_5k.txt
endif
ICEDEVICE=$(DEVICECLASS) python3 database.py
python3 export.py
diff -U0 cached_io.txt bitdata_io.txt || cp -v bitdata_io.txt cached_io.txt
diff -U0 cached_logic.txt bitdata_logic.txt || cp -v bitdata_logic.txt cached_logic.txt
diff -U0 cached_ramb.txt bitdata_ramb.txt || cp -v bitdata_ramb.txt cached_ramb.txt
diff -U0 cached_ramt.txt bitdata_ramt.txt || cp -v bitdata_ramt.txt cached_ramt.txt
diff -U0 cached_ramb_8k.txt bitdata_ramb_8k.txt || cp -v bitdata_ramb_8k.txt cached_ramb_8k.txt
diff -U0 cached_ramt_8k.txt bitdata_ramt_8k.txt || cp -v bitdata_ramt_8k.txt cached_ramt_8k.txt
diff -U0 cached_ramb$(RAM_SUFFIX).txt bitdata_ramb$(RAM_SUFFIX).txt || cp -v bitdata_ramb$(RAM_SUFFIX).txt cached_ramb$(RAM_SUFFIX).txt
diff -U0 cached_ramt$(RAM_SUFFIX).txt bitdata_ramt$(RAM_SUFFIX).txt || cp -v bitdata_ramt$(RAM_SUFFIX).txt cached_ramt$(RAM_SUFFIX).txt
timings:
ifeq ($(EIGTHK),_8k)
ifeq ($(DEVICECLASS),8k)
cp tmedges.txt tmedges.tmp
set -e; for f in work_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
python3 timings.py -t timings_hx8k.txt work_*/*.sdf > timings_hx8k.new
mv timings_hx8k.new timings_hx8k.txt
python3 timings.py -t timings_lp8k.txt work_*/*.slp > timings_lp8k.new
mv timings_lp8k.new timings_lp8k.txt
else
ifeq ($(THREEH),_384)
ifeq ($(DEVICECLASS),384)
cp tmedges.txt tmedges.tmp
set -e; for f in work_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
python3 timings.py -t timings_lp384.txt work_*/*.slp > timings_lp384.new
mv timings_lp384.new timings_lp384.txt
else
cp tmedges.txt tmedges.tmp
set -e; for f in work_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
python3 timings.py -t timings_hx1k.txt work_*/*.sdf > timings_hx1k.new
mv timings_hx1k.new timings_hx1k.txt
@ -76,24 +97,24 @@ timings_html:
python3 timings.py -h tmedges.txt -t timings_lp8k.txt -l "LP8K with default temp/volt settings" > timings_lp8k.html
python3 timings.py -h tmedges.txt -t timings_lp384.txt -l "LP384 with default temp/volt settings" > timings_lp384.html
data_cached.txt: cached_io.txt cached_logic.txt cached_ramb$(EIGTHK).txt cached_ramt$(EIGTHK).txt
data_cached.txt: cached_io.txt cached_logic.txt cached_ramb$(RAM_SUFFIX).txt cached_ramt$(RAM_SUFFIX).txt
gawk '{ print "io", $$0; }' cached_io.txt > data_cached.new
gawk '{ print "logic", $$0; }' cached_logic.txt >> data_cached.new
gawk '{ print "ramb$(EIGTHK)", $$0; }' cached_ramb$(EIGTHK).txt >> data_cached.new
gawk '{ print "ramt$(EIGTHK)", $$0; }' cached_ramt$(EIGTHK).txt >> data_cached.new
gawk '{ print "ramb$(RAM_SUFFIX)", $$0; }' cached_ramb$(RAM_SUFFIX).txt >> data_cached.new
gawk '{ print "ramt$(RAM_SUFFIX)", $$0; }' cached_ramt$(RAM_SUFFIX).txt >> data_cached.new
mv data_cached.new data_cached.txt
bitdata_io.txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
bitdata_io.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
grep ^io $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_logic.txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
bitdata_logic.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
grep ^logic $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_ramb$(EIGTHK).txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
grep ^ramb$(EIGTHK) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_ramb$(RAM_SUFFIX).txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
grep ^ramb$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_ramt$(EIGTHK).txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
grep ^ramt$(EIGTHK) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_ramt$(RAM_SUFFIX).txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
grep ^ramt$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
datafiles: $(addprefix data_,$(addsuffix .txt,$(TESTS)))
@ -101,22 +122,10 @@ datafiles: $(addprefix data_,$(addsuffix .txt,$(TESTS)))
$(MAKE) -C ../icepack
define data_template
data_$(1).txt: make_$(1).py ../icepack/icepack
ifeq ($(EIGTHK),_8k)
ICE8KPINS=1 python3 make_$(1).py
+ICEDEV=hx8k-ct256 $(MAKE) -C work_$(1)
python3 extract.py -8 work_$(1)/*.glb > $$@
else
ifeq ($(THREEH),_384)
ICE384PINS=1 python3 make_$(1).py
+ICEDEV=lp384-cm49 $(MAKE) -C work_$(1)
python3 extract.py -3 work_$(1)/*.glb > $$@
else
python3 make_$(1).py
+$(MAKE) -C work_$(1)
python3 extract.py work_$(1)/*.glb > $$@
endif
endif
data_$(DEVICECLASS)_$(1).txt: make_$(1).py ../icepack/icepack
ICEDEVICE=$(DEVICECLASS) python3 make_$(1).py
+ICEDEV=$(DEVICE) $(MAKE) -C work_$(DEVICECLASS)_$(1)
ICEDEVICE=$(DEVICECLASS) python3 extract.py work_$(DEVICECLASS)_$(1)/*.glb > $$@
endef
$(foreach test,$(TESTS),$(eval $(call data_template,$(test))))
@ -124,21 +133,20 @@ $(foreach test,$(TESTS),$(eval $(call data_template,$(test))))
%.ok: %.bin
bash check.sh $<
check: $(addsuffix .ok,$(basename $(wildcard work_binop/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_pin2pin/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_mesh/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_fanout/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_logic/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_cluster/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_iopack/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_pll/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_binop/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_pin2pin/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_mesh/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_fanout/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_logic/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_cluster/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_iopack/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_$(DEVICECLASS)_pll/*.bin)))
clean:
rm -rf work_*
rm -rf work_$(DEVICECLASS)_*
rm -rf data_*.txt
rm -rf bitdata_*.txt
rm -rf database_*.txt
rm -rf timings_*.html
.PHONY: database datafiles check clean

View File

@ -340,6 +340,19 @@
(14 14) routing glb_netwk_5 <X> wire_io_cluster/io_1/outclk
(14 14) routing glb_netwk_6 <X> wire_io_cluster/io_1/outclk
(14 14) routing glb_netwk_7 <X> wire_io_cluster/io_1/outclk
(14 15) IO control bit: BIODOWN_extra_padeb_test_0
(14 15) IO control bit: BIOUP_extra_padeb_test_0
(14 15) IO control bit: GIODOWN0_extra_padeb_test_0
(14 15) IO control bit: GIODOWN1_extra_padeb_test_0
(14 15) IO control bit: GIOLEFT0_extra_padeb_test_0
(14 15) IO control bit: GIOLEFT1_extra_padeb_test_0
(14 15) IO control bit: GIORIGHT0_extra_padeb_test_0
(14 15) IO control bit: GIORIGHT1_extra_padeb_test_0
(14 15) IO control bit: GIOUP0_extra_padeb_test_0
(14 15) IO control bit: GIOUP1_extra_padeb_test_0
(14 15) IO control bit: HIPBIOUP_extra_padeb_test_0
(14 15) IO control bit: IODOWN_extra_padeb_test_0
(14 15) IO control bit: IOUP_extra_padeb_test_0
(14 2) routing span4_horz_l_13 <X> span4_vert_7
(14 2) routing span4_horz_r_1 <X> span4_vert_7
(14 2) routing span4_vert_b_1 <X> span4_horz_7
@ -388,6 +401,28 @@
(15 11) routing glb_netwk_7 <X> wire_io_cluster/io_1/cen
(15 11) routing lc_trk_g1_2 <X> wire_io_cluster/io_1/cen
(15 11) routing lc_trk_g1_5 <X> wire_io_cluster/io_1/cen
(15 12) IO control bit: BIODOWN_cf_bit_39
(15 12) IO control bit: BIOUP_cf_bit_39
(15 12) IO control bit: GIODOWN0_cf_bit_39
(15 12) IO control bit: GIOLEFT1_cf_bit_39
(15 12) IO control bit: GIORIGHT0_cf_bit_39
(15 12) IO control bit: GIORIGHT1_cf_bit_39
(15 12) IO control bit: GIOUP0_cf_bit_39
(15 12) IO control bit: GIOUP1_cf_bit_39
(15 12) IO control bit: IODOWN_cf_bit_39
(15 14) IO control bit: BIODOWN_extra_padeb_test_1
(15 14) IO control bit: BIOUP_extra_padeb_test_1
(15 14) IO control bit: GIODOWN0_extra_padeb_test_1
(15 14) IO control bit: GIODOWN1_extra_padeb_test_1
(15 14) IO control bit: GIOLEFT0_extra_padeb_test_1
(15 14) IO control bit: GIOLEFT1_extra_padeb_test_1
(15 14) IO control bit: GIORIGHT0_extra_padeb_test_1
(15 14) IO control bit: GIORIGHT1_extra_padeb_test_1
(15 14) IO control bit: GIOUP0_extra_padeb_test_1
(15 14) IO control bit: GIOUP1_extra_padeb_test_1
(15 14) IO control bit: HIPBIOUP_extra_padeb_test_1
(15 14) IO control bit: IODOWN_extra_padeb_test_1
(15 14) IO control bit: IOUP_extra_padeb_test_1
(15 15) Enable bit of Mux _clock_links/clk_mux => glb_netwk_0 wire_io_cluster/io_1/outclk
(15 15) Enable bit of Mux _clock_links/clk_mux => glb_netwk_1 wire_io_cluster/io_1/outclk
(15 15) Enable bit of Mux _clock_links/clk_mux => glb_netwk_2 wire_io_cluster/io_1/outclk
@ -424,6 +459,13 @@
(15 5) routing lc_trk_g1_4 <X> wire_gbuf/in
(15 5) routing lc_trk_g1_6 <X> fabout
(15 5) routing lc_trk_g1_6 <X> wire_gbuf/in
(15 6) IO control bit: BIODOWN_cf_bit_35
(15 6) IO control bit: BIOUP_cf_bit_35
(15 6) IO control bit: GIOLEFT1_cf_bit_35
(15 6) IO control bit: GIORIGHT0_cf_bit_35
(15 6) IO control bit: GIORIGHT1_cf_bit_35
(15 6) IO control bit: GIOUP0_cf_bit_35
(15 6) IO control bit: IODOWN_cf_bit_35
(15 9) Enable bit of Mux _clock_links/inclk_mux => glb_netwk_0 wire_io_cluster/io_1/inclk
(15 9) Enable bit of Mux _clock_links/inclk_mux => glb_netwk_1 wire_io_cluster/io_1/inclk
(15 9) Enable bit of Mux _clock_links/inclk_mux => glb_netwk_2 wire_io_cluster/io_1/inclk
@ -489,7 +531,12 @@
(2 0) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_1
(2 0) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_1
(2 0) PLL config bit: CLOCK_T_0_5_IOLEFT_cf_bit_1
(2 0) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_1
(2 0) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_1
(2 0) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_1
(2 0) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_1
(2 0) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_1
(2 0) PLL config bit: CLOCK_T_14_31_IOUP_cf_bit_1
(2 0) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_1
(2 0) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_1
(2 0) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_1
@ -506,7 +553,12 @@
(2 2) PLL config bit: CLOCK_T_0_2_IOLEFT_cf_bit_4
(2 2) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_4
(2 2) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_4
(2 2) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_4
(2 2) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_4
(2 2) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_4
(2 2) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_4
(2 2) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_4
(2 2) PLL config bit: CLOCK_T_14_31_IOUP_cf_bit_4
(2 2) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_4
(2 2) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_4
(2 2) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_4
@ -518,6 +570,10 @@
(2 4) PLL config bit: CLOCK_T_0_2_IOLEFT_cf_bit_7
(2 4) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_7
(2 4) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_7
(2 4) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_7
(2 4) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_7
(2 4) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_7
(2 4) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_7
(2 4) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_7
(2 4) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_7
(2 4) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_7
@ -525,6 +581,7 @@
(2 5) Enable bit of Mux _out_links/OutMux4_1 => wire_io_cluster/io_0/D_IN_1 span4_horz_34
(2 5) Enable bit of Mux _out_links/OutMux4_1 => wire_io_cluster/io_0/D_IN_1 span4_vert_34
(2 6) IO control bit: BIODOWN_REN_0
(2 6) IO control bit: BIODOWN_REN_1
(2 6) IO control bit: BIOLEFT_REN_0
(2 6) IO control bit: BIORIGHT_REN_0
(2 6) IO control bit: BIORIGHT_REN_1
@ -563,12 +620,18 @@
(3 0) PLL config bit: CLOCK_T_0_2_IOLEFT_cf_bit_2
(3 0) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_2
(3 0) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_2
(3 0) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_2
(3 0) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_2
(3 0) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_2
(3 0) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_2
(3 0) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_2
(3 0) PLL config bit: CLOCK_T_14_31_IOUP_cf_bit_2
(3 0) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_2
(3 0) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_2
(3 0) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_2
(3 0) PLL config bit: CLOCK_T_18_0_IODOWN_cf_bit_2
(3 0) PLL config bit: CLOCK_T_18_33_IOUP_cf_bit_2
(3 1) IO control bit: BIODOWN_REN_0
(3 1) IO control bit: BIODOWN_REN_1
(3 1) IO control bit: BIOLEFT_REN_1
(3 1) IO control bit: BIORIGHT_REN_0
@ -611,7 +674,12 @@
(3 2) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_5
(3 2) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_5
(3 2) PLL config bit: CLOCK_T_0_5_IOLEFT_cf_bit_5
(3 2) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_5
(3 2) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_5
(3 2) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_5
(3 2) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_5
(3 2) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_5
(3 2) PLL config bit: CLOCK_T_14_31_IOUP_cf_bit_5
(3 2) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_5
(3 2) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_5
(3 2) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_5
@ -621,7 +689,12 @@
(3 3) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_3
(3 3) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_3
(3 3) PLL config bit: CLOCK_T_0_5_IOLEFT_cf_bit_3
(3 3) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_3
(3 3) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_3
(3 3) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_3
(3 3) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_3
(3 3) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_3
(3 3) PLL config bit: CLOCK_T_14_31_IOUP_cf_bit_3
(3 3) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_3
(3 3) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_3
(3 3) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_3
@ -630,6 +703,9 @@
(3 4) PLL config bit: CLOCK_T_0_2_IOLEFT_cf_bit_8
(3 4) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_8
(3 4) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_8
(3 4) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_8
(3 4) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_8
(3 4) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_8
(3 4) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_8
(3 4) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_8
(3 4) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_8
@ -637,10 +713,15 @@
(3 5) PLL config bit: CLOCK_T_0_2_IOLEFT_cf_bit_6
(3 5) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_6
(3 5) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_6
(3 5) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_6
(3 5) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_6
(3 5) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_6
(3 5) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_6
(3 5) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_6
(3 5) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_6
(3 5) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_6
(3 5) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_6
(3 6) IO control bit: BIODOWN_IE_0
(3 6) IO control bit: BIODOWN_IE_1
(3 6) IO control bit: BIOLEFT_IE_1
(3 6) IO control bit: BIORIGHT_IE_0
@ -674,11 +755,16 @@
(3 7) PLL config bit: CLOCK_T_0_2_IOLEFT_cf_bit_9
(3 7) PLL config bit: CLOCK_T_0_3_IOLEFT_cf_bit_9
(3 7) PLL config bit: CLOCK_T_0_4_IOLEFT_cf_bit_9
(3 7) PLL config bit: CLOCK_T_10_31_IOUP_cf_bit_9
(3 7) PLL config bit: CLOCK_T_11_31_IOUP_cf_bit_9
(3 7) PLL config bit: CLOCK_T_12_31_IOUP_cf_bit_9
(3 7) PLL config bit: CLOCK_T_13_31_IOUP_cf_bit_9
(3 7) PLL config bit: CLOCK_T_14_0_IODOWN_cf_bit_9
(3 7) PLL config bit: CLOCK_T_15_0_IODOWN_cf_bit_9
(3 7) PLL config bit: CLOCK_T_16_0_IODOWN_cf_bit_9
(3 7) PLL config bit: CLOCK_T_17_0_IODOWN_cf_bit_9
(3 9) IO control bit: BIODOWN_IE_0
(3 9) IO control bit: BIODOWN_IE_1
(3 9) IO control bit: BIOLEFT_IE_0
(3 9) IO control bit: BIORIGHT_IE_0
(3 9) IO control bit: BIORIGHT_IE_1

2911
icefuzz/cached_ramb_5k.txt Normal file

File diff suppressed because it is too large Load Diff

3007
icefuzz/cached_ramt_5k.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,8 @@
import re, sys, os
device_class = os.getenv("ICEDEVICE")
def sort_bits_key(a):
if a[0] == "!": a = a[1:]
return re.sub(r"\d+", lambda m: "%02d" % int(m.group(0)), a)
@ -136,11 +138,11 @@ with open("database_ramt.txt", "w") as f:
for entry in read_database("bitdata_ramt.txt", "ramt"):
print("\t".join(entry), file=f)
with open("database_ramb_8k.txt", "w") as f:
for entry in read_database("bitdata_ramb_8k.txt", "ramb_8k"):
print("\t".join(entry), file=f)
with open("database_ramt_8k.txt", "w") as f:
for entry in read_database("bitdata_ramt_8k.txt", "ramt_8k"):
print("\t".join(entry), file=f)
for device_class in ["5k", "8k"]:
with open("database_ramb_%s.txt" % (device_class, ), "w") as f:
for entry in read_database("bitdata_ramb_%s.txt" % (device_class, ), "ramb_" + device_class):
print("\t".join(entry), file=f)
with open("database_ramt_%s.txt" % (device_class, ), "w") as f:
for entry in read_database("bitdata_ramt_%s.txt" % (device_class, ), "ramt_" + device_class):
print("\t".join(entry), file=f)

View File

@ -1,10 +1,16 @@
#!/usr/bin/env python3
import os
device_class = os.getenv("ICEDEVICE")
with open("../icebox/iceboxdb.py", "w") as f:
for i in [ "database_io", "database_logic", "database_ramb", "database_ramt", "database_ramb_8k", "database_ramt_8k" ]:
files = [ "database_io", "database_logic", "database_ramb", "database_ramt"]
for device_class in ["5k", "8k"]:
files.append("database_ramb_" + device_class)
files.append("database_ramt_" + device_class)
for i in files:
print('%s_txt = """' % i, file=f)
with open("%s.txt" % i, "r") as fi:
for line in fi:
print(line, end="", file=f)
print('"""', file=f)

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
import os
import sys, re
db = set()
@ -9,36 +9,38 @@ mode_384 = False
cur_text_db = None
max_x, max_y = 0, 0
if sys.argv[1] == '-8':
sys.argv = sys.argv[1:]
mode_8k = True
if sys.argv[1] == '-3':
sys.argv = sys.argv[1:]
mode_384 = True
device_class = os.getenv("ICEDEVICE")
for filename in sys.argv[1:]:
with open(filename, "r") as f:
ignore = False
for line in f:
if line == "\n":
pass
elif line.startswith("GlobalNetwork"):
cur_text_db = set()
ignore = False
elif line.startswith("IO"):
match = re.match("IO_Tile_(\d+)_(\d+)", line)
assert match
max_x = max(max_x, int(match.group(1)))
max_y = max(max_y, int(match.group(2)))
cur_text_db = text_db.setdefault("io", set())
ignore = False
elif line.startswith("Logic"):
cur_text_db = text_db.setdefault("logic", set())
ignore = False
elif line.startswith("RAM"):
match = re.match(r"RAM_Tile_\d+_(\d+)", line)
if int(match.group(1)) % 2 == 1:
cur_text_db = text_db.setdefault("ramb_8k" if mode_8k else "ramb", set())
cur_text_db = text_db.setdefault("ramb_" + device_class if device_class in ["5k", "8k"] else "ramb", set())
else:
cur_text_db = text_db.setdefault("ramt_8k" if mode_8k else "ramt", set())
else:
cur_text_db = text_db.setdefault("ramt_" + device_class if device_class in ["5k", "8k"] else "ramt", set())
ignore = False
elif device_class == "5k" and line.startswith(("IpCon", "DSP")):
ignore = True
elif not ignore:
print("'" + line + "'")
assert line.startswith(" ")
cur_text_db.add(line)
@ -60,4 +62,3 @@ for tile_type in text_db:
for line in sorted(db):
print(line)

View File

@ -2,8 +2,11 @@ import os
num = 20
if os.getenv('ICE8KPINS'):
device_class = os.getenv("ICEDEVICE")
if device_class == "8k":
num_ramb40 = 32
num_iobanks = 4
pins="""
A1 A2 A5 A6 A7 A9 A10 A11 A15 A16
@ -26,8 +29,9 @@ if os.getenv('ICE8KPINS'):
gpins = "C8 F7 G1 H11 H16 I3 K9 R9".split()
elif os.getenv('ICE384PINS'):
elif device_class == "384":
num_ramb40 = 0
num_iobanks = 3
pins = """
A1 A2 A3 A4 A5 A6 A7
@ -41,8 +45,9 @@ elif os.getenv('ICE384PINS'):
gpins = "B4 C4 D2 D6 D7 E2 F3 F4".split()
else:
elif device_class == "1k":
num_ramb40 = 16
num_iobanks = 4
pins = """
1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34
@ -52,4 +57,26 @@ else:
""".split()
gpins = "20 21 49 50 93 94 128 129".split()
elif device_class == "5k":
num_ramb40 = 30
num_iobanks = 2
#TODO(tannewt): Add 39, 40, 41 to this list. It causes placement failures for some reason.
# Also add 14 15 16 17 which are constrained to SPI.
pins = """2 3 4 6 9 10 11 12
13 18 19 20 21 23
25 26 27 28 31 32 34 35 36
37 38 42 43 44 45 46 47 48
""".split()
#TODO(tannewt): Add 39, 40, 41 to this list. It causes placement failures for some reason.
gpins = "20 35 37 44".split()
def output_makefile(working_dir, fuzzname):
with open(working_dir + "/Makefile", "w") as f:
print("all: %s" % " ".join(["%s_%02d.bin" % (fuzzname, i) for i in range(num)]), file=f)
for i in range(num):
basename = "%s_%02d" % (fuzzname, i)
print("%s.bin:" % basename, file=f)
print("\t-bash ../icecube.sh %s > %s.log 2>&1 && rm -rf %s.tmp || tail %s.log" % (basename, basename, basename, basename), file=f)
print("\tpython3 ../glbcheck.py %s.asc %s.glb" % (basename, basename), file=f)

View File

@ -30,13 +30,13 @@ with open(argv[1]) as f:
with open(argv[2]) as f:
current_tile = None
for line in f:
if line.find("Tile_") >= 0:
if line.startswith(("Tile", "IO_Tile", "RAM_Tile", "LogicTile")):
f = line.replace("IO_", "").replace("RAM_", "").split("_")
assert len(f) == 3
current_tile = "%02d.%02d" % (int(f[1]), int(f[2]))
continue
if line.find("GlobalNetwork") >= 0:
if line.find("GlobalNetwork") >= 0 or line.startswith(("IpCon", "DSP")):
current_tile = None
continue
@ -54,10 +54,15 @@ only_in_asc = asc_bits - glb_bits
only_in_glb = glb_bits - asc_bits
assert len(only_in_asc) != 0 or len(only_in_glb) != 0
if len(only_in_asc) != 0:
print("Only in ASC: %s" % sorted(only_in_asc))
if len(only_in_glb) != 0:
print("Only in GLB: %s" % sorted(only_in_glb))
print("Only in ASC:")
for bit in sorted(only_in_asc):
print(bit)
print()
print("Only in GLB:")
for bit in sorted(only_in_glb):
print(bit)
exit(1)

View File

@ -51,6 +51,13 @@ if [ "$1" == "-ul1k" ]; then
shift
fi
if [ "$1" == "-up5k" ]; then
ICEDEV=up5k-sg48
shift
fi
ICECUBEDIR=~/lscc/iCEcube2.2017.01
set -ex
set -- ${1%.v}
icecubedir="${ICECUBEDIR:-/opt/lscc/iCEcube2.2015.08}"
@ -62,7 +69,7 @@ export TCL_LIBRARY="$icecubedir/sbt_backend/bin/linux/lib/tcl8.4"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/sbt_backend/bin/linux/opt"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/sbt_backend/bin/linux/opt/synpwrap"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/sbt_backend/lib/linux/opt"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/LSE/bin/lin"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/LSE/bin/lin64"
case "${ICEDEV:-hx1k-tq144}" in
hx1k-cb132)
@ -173,6 +180,10 @@ case "${ICEDEV:-hx1k-tq144}" in
iCEPACKAGE="CM36A"
iCE40DEV="iCE40UL1K"
;;
up5k-sg48)
iCEPACKAGE="SG48"
iCE40DEV="iCE40UP5K"
;;
*)
echo "ERROR: Invalid \$ICEDEV device config '$ICEDEV'."
exit 1
@ -219,6 +230,11 @@ case "$iCE40DEV" in
libfile="ice40BT1K.lib"
devfile="ICE40T01.dev"
;;
iCE40UP5K)
icetech="SBTiCE40UP"
libfile="ice40UP5K.lib"
devfile="ICE40T05.dev"
;;
esac
(
@ -334,7 +350,7 @@ fi
# synthesis (Lattice LSE)
if true; then
"$icecubedir"/LSE/bin/lin/synthesis -f "impl_lse.prj"
"$icecubedir"/LSE/bin/lin64/synthesis -f "impl_lse.prj"
fi
# convert netlist
@ -403,5 +419,4 @@ if [ -n "$ICE_SBTIMER_LP" ]; then
fi
export LD_LIBRARY_PATH=""
$scriptdir/../icepack/iceunpack "$1.bin" "$1.asc"
$scriptdir/../icepack/iceunpack -vv "$1.bin" "$1.asc"

View File

@ -4,14 +4,20 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_aig")
os.mkdir("work_aig")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_aig" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
w = len(pins) // 2
for idx in range(num):
with open("work_aig/aig_%02d.v" % idx, "w") as f:
print("module top(input [31:0] a, output [31:0] y);", file=f)
with open(working_dir + "/aig_%02d.v" % idx, "w") as f:
print("module top(input [%d:0] a, output [%d:0] y);" % (w-1, w-1), file=f)
sigs = ["a[%d]" % i for i in range(32)]
sigs = ["a[%d]" % i for i in range(w)]
netidx = 0
for i in range(100 if num_ramb40 < 20 else 1000):
@ -40,20 +46,16 @@ for idx in range(num):
sigs.append(newnet)
for i in range(32):
for i in range(w):
print(" assign y[%d] = %s;" % (i, sigs[i]), file=f)
print("endmodule", file=f)
with open("work_aig/aig_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/aig_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
for i in range(32):
for i in range(w):
print("set_io a[%d] %s" % (i, p[i]), file=f)
print("set_io y[%d] %s" % (i, p[i+32]), file=f)
print("set_io y[%d] %s" % (i, p[i+w]), file=f)
with open("work_aig/Makefile", "w") as f:
print("all: %s" % " ".join(["aig_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("aig_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh aig_%02d > aig_%02d.log 2>&1 && rm -rf aig_%02d.tmp || tail aig_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "aig")

View File

@ -4,23 +4,24 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_binop")
os.mkdir("work_binop")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_binop" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
with open("work_binop/binop_%02d.v" % idx, "w") as f:
with open(working_dir + "/binop_%02d.v" % idx, "w") as f:
print("module top(input a, b, output y);", file=f)
print(" assign y = a%sb;" % np.random.choice([" ^ ", " ^ ~", " & ", " & ~", " | ", " | ~"]), file=f)
print("endmodule", file=f)
with open("work_binop/binop_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/binop_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
print("set_io a %s" % p[0], file=f)
print("set_io b %s" % p[1], file=f)
print("set_io y %s" % p[2], file=f)
with open("work_binop/Makefile", "w") as f:
print("all: %s" % " ".join(["binop_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("binop_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh binop_%02d > binop_%02d.log 2>&1 && rm -rf binop_%02d.tmp || tail binop_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "binop")

View File

@ -4,24 +4,23 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_cluster")
os.mkdir("work_cluster")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_cluster" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
with open("work_cluster/cluster_%02d.v" % idx, "w") as f:
with open(working_dir + "/cluster_%02d.v" % idx, "w") as f:
print("module top(input [3:0] a, output [3:0] y);", file=f)
print(" assign y = {|a, &a, ^a, a[3:2] == a[1:0]};", file=f)
print("endmodule", file=f)
with open("work_cluster/cluster_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/cluster_%02d.pcf" % idx, "w") as f:
i = np.random.randint(len(pins))
netnames = np.random.permutation(["a[%d]" % i for i in range(4)] + ["y[%d]" % i for i in range(4)])
for net in netnames:
print("set_io %s %s" % (net, pins[i]), file=f)
i = (i + 1) % len(pins)
with open("work_cluster/Makefile", "w") as f:
print("all: %s" % " ".join(["cluster_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("cluster_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh cluster_%02d > cluster_%02d.log 2>&1 && rm -rf cluster_%02d.tmp || tail cluster_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "cluster")

View File

@ -4,29 +4,26 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_fanout")
os.mkdir("work_fanout")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_fanout" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
with open("work_fanout/fanout_%02d.v" % idx, "w") as f:
if os.getenv('ICE384PINS'):
print("module top(input [1:0] a, output [33:0] y);", file=f)
print(" assign y = {8{a}};", file=f)
else:
print("module top(input [1:0] a, output [63:0] y);", file=f)
print(" assign y = {32{a}};", file=f)
output_count = len(pins) - 2
with open(working_dir + "/fanout_%02d.v" % idx, "w") as f:
print("module top(input [1:0] a, output [%d:0] y);" % (output_count,), file=f)
print(" assign y = {%d{a}};" % (output_count,), file=f)
print("endmodule", file=f)
with open("work_fanout/fanout_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/fanout_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
r = 34 if os.getenv('ICE384PINS') else 64
for i in range(r):
for i in range(output_count):
print("set_io y[%d] %s" % (i, p[i]), file=f)
print("set_io a[0] %s" % p[r], file=f)
print("set_io a[1] %s" % p[r+1], file=f)
print("set_io a[0] %s" % p[output_count], file=f)
print("set_io a[1] %s" % p[output_count+1], file=f)
with open("work_fanout/Makefile", "w") as f:
print("all: %s" % " ".join(["fanout_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("fanout_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh fanout_%02d > fanout_%02d.log 2>&1 && rm -rf fanout_%02d.tmp || tail fanout_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "fanout")

View File

@ -4,8 +4,14 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_fflogic")
os.mkdir("work_fflogic")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_fflogic" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
w = (len(pins) - 4) // 5
def random_op():
return np.random.choice(["+", "-", "*", "^", "&", "|"])
@ -36,22 +42,14 @@ def print_seq_op(dst, src1, src2, op, f):
assert False
for idx in range(num):
with open("work_fflogic/fflogic_%02d.v" % idx, "w") as f:
if os.getenv('ICE384PINS'):
print("module top(input clk, rst, en, input [4:0] a, b, c, d, output [4:0] y, output z);", file=f)
print(" reg [4:0] p, q;", file=f)
else:
print("module top(input clk, rst, en, input [15:0] a, b, c, d, output [15:0] y, output z);", file=f)
print(" reg [15:0] p, q;", file=f)
with open(working_dir + "/fflogic_%02d.v" % idx, "w") as f:
print("module top(input clk, rst, en, input [%d:0] a, b, c, d, output [%d:0] y, output z);" % (w-1, w-1), file=f)
print(" reg [%d:0] p, q;" % (w-1,), file=f)
print_seq_op("p", "a", "b", random_op(), f)
print_seq_op("q", "c", "d", random_op(), f)
print(" assign y = p %s q, z = clk ^ rst ^ en;" % random_op(), file=f)
print("endmodule", file=f)
with open("work_fflogic/Makefile", "w") as f:
print("all: %s" % " ".join(["fflogic_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("fflogic_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh fflogic_%02d > fflogic_%02d.log 2>&1 && rm -rf fflogic_%02d.tmp || tail fflogic_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "fflogic")

View File

@ -4,17 +4,31 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_gbio")
os.mkdir("work_gbio")
device_class = os.getenv("ICEDEVICE")
w = 4 if os.getenv('ICE384PINS') else 8
working_dir = "work_%s_gbio" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for p in gpins:
if p in pins: pins.remove(p)
# We can either tickle every global buffer or we don't have enough pins to do
# the full logic for each one.
w = min(min((len(pins) - 8) // 4, len(gpins)), 8)
for idx in range(num):
with open("work_gbio/gbio_%02d.v" % idx, "w") as f:
with open(working_dir + "/gbio_%02d.v" % idx, "w") as f:
glbs = np.random.permutation(list(range(8)))
if w <= 4:
din_0 = (w - 2, w)
else:
din_0 = (4, "%d:4" % (w - 1,))
din_0 = np.random.choice(["din_0", "{din_0[%d:0], din_0[%s]}" % din_0])
din_1 = np.random.choice(["din_1", "{din_1[1:0], din_1[%d:2]}" % (w - 1,)])
globals_0 = np.random.choice(["globals", "{globals[0], globals[%d:1]}" % (w - 1, )])
print("""
module top (
inout [%s:0] pin,
@ -64,15 +78,12 @@ for idx in range(num):
np.random.choice(["oen", "globals", "din_0+din_1", "din_0^din_1"]),
np.random.choice(["dout_1", "globals", "globals^dout_0", "din_0+din_1", "~din_0"]),
np.random.choice(["dout_0", "globals", "globals^dout_1", "din_0+din_1", "~din_1"]),
np.random.choice(["din_0", "{din_0[2:0], din_0[3]}"]) if os.getenv('ICE384PINS')
else np.random.choice(["din_0", "{din_0[3:0], din_0[7:4]}"]) ,
np.random.choice(["din_1", "{din_1[1:0], din_1[3:2]}"]) if os.getenv('ICE384PINS')
else np.random.choice(["din_1", "{din_1[1:0], din_1[7:2]}"]),
np.random.choice(["globals", "{globals[0], globals[3:1]}"]) if os.getenv('ICE384PINS')
else np.random.choice(["globals", "{globals[0], globals[7:1]}"]),
din_0,
din_1,
globals_0,
glbs[0], glbs[1], glbs[1], glbs[2], glbs[3]
), file=f)
with open("work_gbio/gbio_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/gbio_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
g = np.random.permutation(gpins)
for i in range(w):
@ -84,9 +95,5 @@ for idx in range(num):
print("set_io %s %s" % (n, p[4*w+i]), file=f)
print("set_io q %s" % (p[-1]), file=f)
with open("work_gbio/Makefile", "w") as f:
print("all: %s" % " ".join(["gbio_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("gbio_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh gbio_%02d > gbio_%02d.log 2>&1 && rm -rf gbio_%02d.tmp || tail gbio_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "gbio")

View File

@ -4,16 +4,22 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_gbio2")
os.mkdir("work_gbio2")
device_class = os.getenv("ICEDEVICE")
w = 4 if os.getenv('ICE384PINS') else 8
working_dir = "work_%s_gbio2" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for p in gpins:
if p in pins: pins.remove(p)
# We can either tickle every global buffer or we don't have enough pins to do
# the full logic for each one.
w = min(min((len(pins) - 8) // 4, len(gpins)), 8)
for idx in range(num):
with open("work_gbio2/gbio2_%02d.v" % idx, "w") as f:
with open(working_dir + "/gbio2_%02d.v" % idx, "w") as f:
glbs = np.random.permutation(list(range(8)))
print("""
module top (
@ -69,7 +75,7 @@ for idx in range(num):
""" % (
glbs[0], glbs[1], glbs[1], glbs[2], glbs[3]
), file=f)
with open("work_gbio2/gbio2_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/gbio2_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
g = np.random.permutation(gpins)
for i in range(w):
@ -81,9 +87,5 @@ for idx in range(num):
print("set_io %s %s" % (n, p[4*w+i]), file=f)
print("set_io q %s" % (p[-1]), file=f)
with open("work_gbio2/Makefile", "w") as f:
print("all: %s" % " ".join(["gbio2_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("gbio2_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh gbio2_%02d > gbio2_%02d.log 2>&1 && rm -rf gbio2_%02d.tmp || tail gbio2_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "gbio2")

View File

@ -4,14 +4,17 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_io")
os.mkdir("work_io")
device_class = os.getenv("ICEDEVICE")
if os.getenv('ICE384PINS'): w = 3
else: w = 4
working_dir = "work_%s_io" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
w = num_iobanks
for idx in range(num):
with open("work_io/io_%02d.v" % idx, "w") as f:
with open(working_dir + "/io_%02d.v" % idx, "w") as f:
glbs = np.random.permutation(list(range(8)))
print("""
module top (
@ -49,15 +52,11 @@ for idx in range(num):
np.random.choice(["0000", "0110", "1010", "1110", "0101", "1001", "1101", "0100", "1000", "1100", "0111", "1111"]),
np.random.choice(["00", "01", "10", "11"]), np.random.choice(["0", "1"]), np.random.choice(["0", "1"]), w-1
), file=f)
with open("work_io/io_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/io_%02d.pcf" % idx, "w") as f:
p = list(np.random.permutation(pins))
for k in ["pin", "latch_in", "clk_en", "clk_in", "clk_out", "oen", "dout_0", "dout_1", "din_0", "din_1"]:
for i in range(w):
print("set_io %s[%d] %s" % (k, i, p.pop()), file=f)
with open("work_io/Makefile", "w") as f:
print("all: %s" % " ".join(["io_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("io_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh io_%02d > io_%02d.log 2>&1 && rm -rf io_%02d.tmp || tail io_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "io")

View File

@ -10,8 +10,12 @@ num_xor = 8
num_luts = 8
num_outputs_range = (5, 20)
os.system("rm -rf work_iopack")
os.mkdir("work_iopack")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_iopack" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
def get_pin_directions():
pindirs = ["i" for i in range(len(pins))]
@ -32,7 +36,7 @@ def get_nearby_inputs(p, n, r):
return [choice(ipins) for i in range(n)]
for idx in range(num):
with open("work_iopack/iopack_%02d.v" % idx, "w") as f:
with open(working_dir + "/iopack_%02d.v" % idx, "w") as f:
pindirs = get_pin_directions()
print("module top(%s);" % ", ".join(["%sput p%d" % ("in" if pindirs[i] == "i" else "out", i) for i in range(len(pins))]), file=f)
for outp in range(len(pins)):
@ -45,13 +49,9 @@ for idx in range(num):
xor_nets.add("%sp%d_in%d" % (choice(["~", ""]), outp, i))
print(" assign p%d = ^{%s};" % (outp, ", ".join(sorted(xor_nets))), file=f)
print("endmodule", file=f)
with open("work_iopack/iopack_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/iopack_%02d.pcf" % idx, "w") as f:
for i in range(len(pins)):
print("set_io p%d %s" % (i, pins[i]), file=f)
with open("work_iopack/Makefile", "w") as f:
print("all: %s" % " ".join(["iopack_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("iopack_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh iopack_%02d > iopack_%02d.log 2>&1 && rm -rf iopack_%02d.tmp || tail iopack_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "iopack")

View File

@ -4,33 +4,29 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_logic")
os.mkdir("work_logic")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_logic" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
def random_op():
return np.random.choice(["+", "-", "^", "&", "|", "&~", "|~"])
for idx in range(num):
with open("work_logic/logic_%02d.v" % idx, "w") as f:
if os.getenv('ICE384PINS'):
print("module top(input [5:0] a, b, c, d, output [5:0] y);", file=f)
else:
print("module top(input [15:0] a, b, c, d, output [15:0] y);", file=f)
bus_width = len(pins) // 5
with open(working_dir + "/logic_%02d.v" % idx, "w") as f:
print("module top(input [%d:0] a, b, c, d, output [%d:0] y);" % (bus_width, bus_width), file=f)
print(" assign y = (a %s b) %s (c %s d);" % (random_op(), random_op(), random_op()), file=f)
print("endmodule", file=f)
with open("work_logic/logic_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/logic_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
r = 6 if os.getenv('ICE384PINS') else 16
for i in range(r):
for i in range(bus_width):
print("set_io a[%d] %s" % (i, p[i]), file=f)
print("set_io b[%d] %s" % (i, p[i+r]), file=f)
print("set_io c[%d] %s" % (i, p[i+r*2]), file=f)
print("set_io d[%d] %s" % (i, p[i+r*3]), file=f)
print("set_io y[%d] %s" % (i, p[i+r*4]), file=f)
with open("work_logic/Makefile", "w") as f:
print("all: %s" % " ".join(["logic_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("logic_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh logic_%02d > logic_%02d.log 2>&1 && rm -rf logic_%02d.tmp || tail logic_%02d.log" % (i, i, i, i), file=f)
print("set_io b[%d] %s" % (i, p[i+bus_width]), file=f)
print("set_io c[%d] %s" % (i, p[i+bus_width*2]), file=f)
print("set_io d[%d] %s" % (i, p[i+bus_width*3]), file=f)
print("set_io y[%d] %s" % (i, p[i+bus_width*4]), file=f)
output_makefile(working_dir, "logic")

View File

@ -4,11 +4,15 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_mem")
os.mkdir("work_mem")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_mem" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
with open("work_mem/mem_%02d.v" % idx, "w") as f:
with open(working_dir + "/mem_%02d.v" % idx, "w") as f:
print("""
module top(input clk, i0, i1, i2, i3, output reg o0, o1, o2, o3, o4);
reg [9:0] raddr, waddr, rdata, wdata;
@ -27,14 +31,11 @@ for idx in range(num):
end
endmodule
""", file=f)
with open("work_mem/mem_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/mem_%02d.pcf" % idx, "w") as f:
p = list(np.random.permutation(pins))
for port in [ "clk", "i0", "i1", "i2", "i3", "o0", "o1", "o2", "o3", "o4" ]:
print("set_io %s %s" % (port, p.pop()), file=f)
with open("work_mem/Makefile", "w") as f:
print("all: %s" % " ".join(["mem_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("mem_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh mem_%02d > mem_%02d.log 2>&1 && rm -rf mem_%02d.tmp || tail mem_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "mem")

View File

@ -4,29 +4,30 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_mesh")
os.mkdir("work_mesh")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_mesh" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
# This test maps a random set of pins to another random set of outputs.
device_class = os.getenv("ICEDEVICE")
for idx in range(num):
with open("work_mesh/mesh_%02d.v" % idx, "w") as f:
if os.getenv('ICE384PINS'):
print("module top(input [13:0] a, output [13:0] y);", file=f)
else:
print("module top(input [39:0] a, output [39:0] y);", file=f)
io_count = len(pins) // 2
with open(working_dir + "/mesh_%02d.v" % idx, "w") as f:
print("module top(input [%d:0] a, output [%d:0] y);" % (io_count, io_count), file=f)
print(" assign y = a;", file=f)
print("endmodule", file=f)
with open("work_mesh/mesh_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/mesh_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
if os.getenv('ICE384PINS'): r = 14
else: r = 40
for i in range(r):
for i in range(io_count):
print("set_io a[%d] %s" % (i, p[i]), file=f)
for i in range(r):
print("set_io y[%d] %s" % (i, p[r+i]), file=f)
for i in range(io_count):
print("set_io y[%d] %s" % (i, p[io_count+i]), file=f)
with open("work_mesh/Makefile", "w") as f:
print("all: %s" % " ".join(["mesh_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("mesh_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh mesh_%02d > mesh_%02d.log 2>&1 && rm -rf mesh_%02d.tmp || tail mesh_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "mesh")

View File

@ -4,22 +4,23 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_pin2pin")
os.mkdir("work_pin2pin")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_pin2pin" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
with open("work_pin2pin/pin2pin_%02d.v" % idx, "w") as f:
with open(working_dir + "/pin2pin_%02d.v" % idx, "w") as f:
print("module top(input a, output y);", file=f)
print(" assign y = a;", file=f)
print("endmodule", file=f)
with open("work_pin2pin/pin2pin_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/pin2pin_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
print("set_io a %s" % p[0], file=f)
print("set_io y %s" % p[1], file=f)
with open("work_pin2pin/Makefile", "w") as f:
print("all: %s" % " ".join(["pin2pin_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("pin2pin_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh pin2pin_%02d > pin2pin_%02d.log 2>&1 && rm -rf pin2pin_%02d.tmp || tail pin2pin_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "pin2pin")

View File

@ -11,9 +11,14 @@ def randbin(n):
for p in gpins:
if p in pins: pins.remove(p)
os.system("rm -rf work_pll")
os.mkdir("work_pll")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_pll" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
pin_names = list()
@ -110,20 +115,17 @@ for idx in range(num):
pll_inst.append("defparam uut.TEST_MODE = 1'b0;")
with open("work_pll/pll_%02d.v" % idx, "w") as f:
with open(working_dir + "/pll_%02d.v" % idx, "w") as f:
print("module top(%s);" % ", ".join(pin_names), file=f)
print("\n".join(vlog_body), file=f)
print("\n".join(pll_inst), file=f)
print("endmodule", file=f)
with open("work_pll/pll_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/pll_%02d.pcf" % idx, "w") as f:
for pll_pin, package_pin in zip(pin_names, list(permutation(pins))[0:len(pin_names)]):
if pll_pin == "packagepin": package_pin = "49"
print("set_io %s %s" % (pll_pin, package_pin), file=f)
with open("work_pll/Makefile", "w") as f:
print("all: %s" % " ".join(["pll_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("pll_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh pll_%02d > pll_%02d.log 2>&1 && rm -rf pll_%02d.tmp || tail pll_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "pll")

View File

@ -4,13 +4,17 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_prim")
os.mkdir("work_prim")
device_class = os.getenv("ICEDEVICE")
w = 10 if os.getenv('ICE384PINS') else 24
working_dir = "work_%s_prim" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
w = len(pins) // 4
for idx in range(num):
with open("work_prim/prim_%02d.v" % idx, "w") as f:
with open(working_dir + "/prim_%02d.v" % idx, "w") as f:
clkedge = np.random.choice(["pos", "neg"])
print("module top(input clk, input [%s:0] a, b, output reg x, output reg [%s:0] y);""" % ( w-1, w-1 ), file=f)
print(" reg [%s:0] aa, bb;""" % ( w-1 ), file=f)
@ -25,7 +29,7 @@ for idx in range(num):
else:
print(" always @(%sedge clk) y <= %s%s;" % (clkedge, np.random.choice(["~", "-", ""]), np.random.choice(["a", "b"])), file=f)
print("endmodule", file=f)
with open("work_prim/prim_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/prim_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
if np.random.choice([True, False]):
for i in range(w):
@ -43,9 +47,5 @@ for idx in range(num):
if np.random.choice([True, False]):
print("set_io clk %s" % p[3*w+2], file=f)
with open("work_prim/Makefile", "w") as f:
print("all: %s" % " ".join(["prim_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("prim_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh prim_%02d > prim_%02d.log 2>&1 && rm -rf prim_%02d.tmp || tail prim_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "prim")

View File

@ -4,17 +4,21 @@ from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_ram40")
os.mkdir("work_ram40")
device_class = os.getenv("ICEDEVICE")
working_dir = "work_%s_ram40" % (device_class, )
os.system("rm -rf " + working_dir)
os.mkdir(working_dir)
for idx in range(num):
with open("work_ram40/ram40_%02d.v" % idx, "w") as f:
glbs = ["glb[%d]" % i for i in range(np.random.randint(9))]
with open(working_dir + "/ram40_%02d.v" % idx, "w") as f:
glbs = ["glb[%d]" % i for i in range(np.random.randint(8)+1)]
glbs_choice = ["wa", "ra", "msk", "wd", "we", "wce", "wc", "re", "rce", "rc"]
print("""
module top (
input [%d:0] glb_pins,
input [59:0] in_pins,
input [%d:0] in_pins,
output [15:0] out_pins
);
wire [%d:0] glb, glb_pins;
@ -22,7 +26,7 @@ for idx in range(num):
.USER_SIGNAL_TO_GLOBAL_BUFFER(glb_pins),
.GLOBAL_BUFFER_OUTPUT(glb)
);
""" % (len(glbs)-1, len(glbs)-1, len(glbs)-1), file=f)
""" % (len(glbs)-1, len(pins) - 16 - 1, len(glbs)-1, len(glbs)-1), file=f)
bits = ["in_pins[%d]" % i for i in range(60)]
bits = list(np.random.permutation(bits))
for i in range(num_ramb40):
@ -96,16 +100,12 @@ for idx in range(num):
bits[k] = "rdata_%d[%d] ^ %s" % (i, k, bits[k])
print("assign out_pins = rdata_%d;" % i, file=f)
print("endmodule", file=f)
with open("work_ram40/ram40_%02d.pcf" % idx, "w") as f:
with open(working_dir + "/ram40_%02d.pcf" % idx, "w") as f:
p = list(np.random.permutation(pins))
for i in range(60):
for i in range(len(pins) - 16):
print("set_io in_pins[%d] %s" % (i, p.pop()), file=f)
for i in range(16):
print("set_io out_pins[%d] %s" % (i, p.pop()), file=f)
with open("work_ram40/Makefile", "w") as f:
print("all: %s" % " ".join(["ram40_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("ram40_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh ram40_%02d > ram40_%02d.log 2>&1 && rm -rf ram40_%02d.tmp || tail ram40_%02d.log" % (i, i, i, i), file=f)
output_makefile(working_dir, "ram40")

View File

@ -0,0 +1,27 @@
#!/bin/bash
set -ex
mkdir -p io_latched_5k.work
cd io_latched_5k.work
pins="
2 3 4 6 9 10 11 12
13 18 19 20 21 23
25 26 27 28 31 32 34 35 36
37 38 42 43 44 45 46 47 48
"
pins="$( echo $pins )"
for pin in $pins ; do
pf="io_latched_$pin"
cp ../io_latched.v ${pf}.v
read pin_latch pin_data < <( echo $pins | tr ' ' '\n' | grep -v $pin | sort -R; )
{
echo "set_io pin $pin"
echo "set_io latch_in $pin_latch"
echo "set_io data_out $pin_data"
} > ${pf}.pcf
ICEDEV=up5k-sg48 bash ../../icecube.sh ${pf}.v
../../../icebox/icebox_vlog.py -SP ${pf}.psb ${pf}.asc > ${pf}.ve
done

View File

@ -249,7 +249,7 @@ void FpgaConfig::read_bits(std::istream &ifs)
{
// one command byte. the lower 4 bits of the command byte specify
// the length of the command payload.
uint8_t command = read_byte(ifs, crc_value, file_offset);
uint32_t payload = 0;
@ -396,9 +396,11 @@ void FpgaConfig::read_bits(std::istream &ifs)
this->device = "1k";
else if (this->cram_width == 872 && this->cram_height == 272)
this->device = "8k";
else if (this->cram_width == 692 && this->cram_height == 336)
this->device = "5k";
else
error("Failed to detect chip type.\n");
info("Chip type is '%s'.\n", this->device.c_str());
}
@ -413,7 +415,7 @@ void FpgaConfig::write_bits(std::ostream &ofs) const
for (auto byte : this->initblop)
ofs << byte;
debug("Writing preamble.\n");
info("Writing preamble.\n");
write_byte(ofs, crc_value, file_offset, 0x7E);
write_byte(ofs, crc_value, file_offset, 0xAA);
write_byte(ofs, crc_value, file_offset, 0x99);
@ -620,6 +622,12 @@ void FpgaConfig::read_ascii(std::istream &ifs)
this->cram_height = 272;
this->bram_width = 128;
this->bram_height = 2 * 128;
} else
if (this->device == "5k") {
this->cram_width = 692;
this->cram_height = 336;
this->bram_width = 160;
this->bram_height = 2 * 128;
} else
error("Unsupported chip type '%s'.\n", this->device.c_str());
@ -725,10 +733,10 @@ void FpgaConfig::read_ascii(std::istream &ifs)
continue;
}
if (command == ".sym")
continue;
if (command.substr(0, 1) == ".")
error("Unknown statement: %s\n", command.c_str());
error("Unexpected data line: %s\n", line.c_str());
@ -765,7 +773,7 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
{
CramIndexConverter cic(this, x, y);
if (cic.tile_type == "corner")
if (cic.tile_type == "corner" || cic.tile_type == "unsupported")
continue;
ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y);
@ -775,6 +783,12 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
int cram_bank, cram_x, cram_y;
cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y));
if (cram_x > int(this->cram[cram_bank].size())) {
error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size());
}
if (cram_y > int(this->cram[cram_bank][cram_x].size())) {
error("cram_y %d larger than bank size %lu\n", cram_y, this->cram[cram_bank][cram_x].size());
}
ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0');
}
ofs << '\n';
@ -791,6 +805,14 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
for (int i = 0; i < 4; i++) {
int bram_bank, bram_x, bram_y;
bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y);
if (bram_x >= int(this->bram[bram_bank].size())) {
error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size());
break;
}
if (bram_y >= int(this->bram[bram_bank][bram_x].size())) {
error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size());
break;
}
if (this->bram[bram_bank][bram_x][bram_y])
value += 1 << i;
}
@ -825,8 +847,47 @@ void FpgaConfig::write_cram_pbm(std::ostream &ofs, int bank_num) const
debug("## %s\n", __PRETTY_FUNCTION__);
info("Writing cram pbm file..\n");
ofs << "P1\n";
ofs << "P3\n";
ofs << stringf("%d %d\n", 2*this->cram_width, 2*this->cram_height);
ofs << "255\n";
uint32_t tile_type[4][this->cram_width][this->cram_height];
for (int y = 0; y <= this->chip_height()+1; y++)
for (int x = 0; x <= this->chip_width()+1; x++)
{
CramIndexConverter cic(this, x, y);
uint32_t color = 0x000000;
if (cic.tile_type == "io") {
color = 0x00aa00;
} else if (cic.tile_type == "logic") {
if ((x + y) % 2 == 0) {
color = 0x0000ff;
} else {
color = 0x0000aa;
}
if (x == 12 && y == 25) {
color = 0xaa00aa;
}
if (x == 12 && y == 24) {
color = 0x888888;
}
} else if (cic.tile_type == "ramt") {
color = 0xff0000;
} else if (cic.tile_type == "ramb") {
color = 0xaa0000;
} else if (cic.tile_type == "unsupported") {
color = 0x333333;
} else {
info("%s\n", cic.tile_type.c_str());
}
for (int bit_y = 0; bit_y < 16; bit_y++)
for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) {
int cram_bank, cram_x, cram_y;
cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
tile_type[cram_bank][cram_x][cram_y] = color;
}
}
for (int y = 2*this->cram_height-1; y >= 0; y--) {
for (int x = 0; x < 2*this->cram_width; x++) {
int bank = 0, bank_x = x, bank_y = y;
@ -835,9 +896,16 @@ void FpgaConfig::write_cram_pbm(std::ostream &ofs, int bank_num) const
if (bank_y >= this->cram_height)
bank |= 2, bank_y = 2*this->cram_height - bank_y - 1;
if (bank_num >= 0 && bank != bank_num)
ofs << " 0";
else
ofs << (this->cram[bank][bank_x][bank_y] ? " 1" : " 0");
ofs << " 255 255 255";
else if (this->cram[bank][bank_x][bank_y]) {
ofs << " 255 255 255";
} else {
uint32_t color = tile_type[bank][bank_x][bank_y];
uint8_t r = color >> 16;
uint8_t g = color >> 8;
uint8_t b = color & 0xff;
ofs << stringf(" %d %d %d", r, g, b);
}
}
ofs << '\n';
}
@ -857,6 +925,7 @@ void FpgaConfig::write_bram_pbm(std::ostream &ofs, int bank_num) const
bank |= 1, bank_x = 2*this->bram_width - bank_x - 1;
if (bank_y >= this->bram_height)
bank |= 2, bank_y = 2*this->bram_height - bank_y - 1;
info("%d %d %d\n", bank, bank_x, bank_y);
if (bank_num >= 0 && bank != bank_num)
ofs << " 0";
else
@ -870,6 +939,7 @@ int FpgaConfig::chip_width() const
{
if (this->device == "384") return 6;
if (this->device == "1k") return 12;
if (this->device == "5k") return 24;
if (this->device == "8k") return 32;
panic("Unknown chip type '%s'.\n", this->device.c_str());
}
@ -878,6 +948,7 @@ int FpgaConfig::chip_height() const
{
if (this->device == "384") return 8;
if (this->device == "1k") return 16;
if (this->device == "5k") return 30;
if (this->device == "8k") return 32;
panic("Unknown chip type '%s'.\n", this->device.c_str());
}
@ -886,6 +957,8 @@ vector<int> FpgaConfig::chip_cols() const
{
if (this->device == "384") return vector<int>({18, 54, 54, 54, 54});
if (this->device == "1k") return vector<int>({18, 54, 54, 42, 54, 54, 54});
// Its IPConnect or Mutiplier block, five logic, ram, six logic.
if (this->device == "5k") return vector<int>({54, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54});
if (this->device == "8k") return vector<int>({18, 54, 54, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54, 54, 54});
panic("Unknown chip type '%s'.\n", this->device.c_str());
}
@ -893,6 +966,8 @@ vector<int> FpgaConfig::chip_cols() const
string FpgaConfig::tile_type(int x, int y) const
{
if ((x == 0 || x == this->chip_width()+1) && (y == 0 || y == this->chip_height()+1)) return "corner";
// The sides on the 5k devices are unsupported tile types.
if (this->device == "5k" && (x == 0 || x == this->chip_width()+1)) return "unsupported";
if ((x == 0 || x == this->chip_width()+1) || (y == 0 || y == this->chip_height()+1)) return "io";
if (this->device == "384") return "logic";
@ -902,6 +977,11 @@ string FpgaConfig::tile_type(int x, int y) const
return "logic";
}
if (this->device == "5k") {
if (x == 6 || x == 19) return y % 2 == 1 ? "ramb" : "ramt";
return "logic";
}
if (this->device == "8k") {
if (x == 8 || x == 25) return y % 2 == 1 ? "ramb" : "ramt";
return "logic";
@ -912,11 +992,12 @@ string FpgaConfig::tile_type(int x, int y) const
int FpgaConfig::tile_width(const string &type) const
{
if (type == "corner") return 0;
if (type == "logic") return 54;
if (type == "ramb") return 42;
if (type == "ramt") return 42;
if (type == "io") return 18;
if (type == "corner") return 0;
if (type == "logic") return 54;
if (type == "ramb") return 42;
if (type == "ramt") return 42;
if (type == "io") return 18;
if (type == "unsupported") return 76;
panic("Unknown tile type '%s'.\n", type.c_str());
}
@ -951,7 +1032,7 @@ void FpgaConfig::cram_checkerboard(int m)
{
if ((x+y) % 2 == m)
continue;
CramIndexConverter cic(this, x, y);
for (int bit_y = 0; bit_y < 16; bit_y++)
@ -979,7 +1060,11 @@ CramIndexConverter::CramIndexConverter(const FpgaConfig *fpga, int tile_x, int t
this->left_right_io = this->tile_x == 0 || this->tile_x == chip_width+1;
this->right_half = this->tile_x > chip_width / 2;
this->top_half = this->tile_y > chip_height / 2;
if (this->fpga->device == "5k") {
this->top_half = this->tile_y > (chip_height * 2 / 3);
} else {
this->top_half = this->tile_y > chip_height / 2;
}
this->bank_num = 0;
if (this->top_half) this->bank_num |= 1;
@ -1031,7 +1116,7 @@ void CramIndexConverter::get_cram_index(int bit_x, int bit_y, int &cram_bank, in
cram_x = bank_xoff + column_width - 1 - bit_x;
else
cram_x = bank_xoff + bit_x;
if (top_half)
cram_y = bank_yoff + (15 - bit_y);
else
@ -1050,12 +1135,25 @@ BramIndexConverter::BramIndexConverter(const FpgaConfig *fpga, int tile_x, int t
bool right_half = this->tile_x > chip_width / 2;
bool top_half = this->tile_y > chip_height / 2;
// The UltraPlus 5k line is special because the top quarter of the chip is
// used for SRAM instead of logic. Therefore the bitstream for the top two
// quadrants are half the height of the bottom.
if (this->fpga->device == "5k") {
top_half = this->tile_y > (chip_height / 3);
}
this->bank_num = 0;
if (top_half) this->bank_num |= 1;
int y_offset = this->tile_y - 1;
if (!top_half) {
this->bank_num |= 1;
} else if (this->fpga->device == "5k") {
y_offset = this->tile_y - (chip_height / 3);
} else {
y_offset = this->tile_y - chip_height / 2;
}
if (right_half) this->bank_num |= 2;
this->bank_off = 16 * ((top_half ? this->tile_y - chip_height / 2 : this->tile_y - 1) / 2);
this->bank_off = 16 * (y_offset / 2);
}
void BramIndexConverter::get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const
@ -1192,9 +1290,13 @@ int main(int argc, char **argv)
fpga_config.cram_checkerboard(checkerboard_m);
}
info("netpbm\n");
if (netpbm_fill_tiles)
fpga_config.cram_fill_tiles();
info("fill done\n");
if (netpbm_mode) {
if (netpbm_bram)
fpga_config.write_bram_pbm(*osp, netpbm_banknum);
@ -1205,4 +1307,3 @@ int main(int argc, char **argv)
info("Done.\n");
return 0;
}