aboutsummaryrefslogtreecommitdiffstats
path: root/icefuzz
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2017-11-13 16:51:28 +0000
committerDavid Shah <davey1576@gmail.com>2017-11-17 15:09:17 +0000
commit2f962ac92e018370793b9db3635fabd5b599afef (patch)
tree39f28c1dc8cdb9d154ac1384855084727dc21562 /icefuzz
parent64e3c1a9cd81e61d9a3b163c9e9f9390fa4c5c21 (diff)
downloadicestorm-2f962ac92e018370793b9db3635fabd5b599afef.tar.gz
icestorm-2f962ac92e018370793b9db3635fabd5b599afef.tar.bz2
icestorm-2f962ac92e018370793b9db3635fabd5b599afef.zip
Fix 5k corner routing, and reverse engineer SPRAM
Diffstat (limited to 'icefuzz')
-rw-r--r--icefuzz/tests/spram/.gitignore1
-rwxr-xr-xicefuzz/tests/spram/fuzz_spram.py173
-rw-r--r--icefuzz/tests/spram/up5k_spram_data.txt232
3 files changed, 406 insertions, 0 deletions
diff --git a/icefuzz/tests/spram/.gitignore b/icefuzz/tests/spram/.gitignore
new file mode 100644
index 0000000..c6ebe02
--- /dev/null
+++ b/icefuzz/tests/spram/.gitignore
@@ -0,0 +1 @@
+work_spram/ \ No newline at end of file
diff --git a/icefuzz/tests/spram/fuzz_spram.py b/icefuzz/tests/spram/fuzz_spram.py
new file mode 100755
index 0000000..33e62cb
--- /dev/null
+++ b/icefuzz/tests/spram/fuzz_spram.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+
+import os, sys, re
+
+device = "up5k"
+
+pins = "2 3 4 6 9 10 11 12 13 18 19 20 21 25 26 27 28 31 32 34 35 36 37 38 42 43 44 45 46 47 48".split()
+
+# This script is designed to determine the routing of 5k SPRAM signals,
+# and the location of the enable config bits
+
+spram_locs = [(0, 0, 1), (0, 0, 2), (25, 0, 3), (25, 0, 4)]
+#spram_locs = [(0, 0, 1)]
+spram_data = { }
+
+spram_signals = ["WREN", "CHIPSELECT", "CLOCK", "STANDBY", "SLEEP", "POWEROFF"]
+
+for i in range(14):
+ spram_signals.append("ADDRESS[%d]" % i)
+
+for i in range(16):
+ spram_signals.append("DATAIN[%d]" % i)
+
+for i in range(16):
+ spram_signals.append("DATAOUT[%d]" % i)
+
+for i in range(4):
+ spram_signals.append("MASKWREN[%d]" % i)
+
+fuzz_options = ["ADDRESS", "DATAIN", "MASKWREN", "DATAOUT"]
+
+#Parse the output of an icebox vlog file to determine connectivity
+def parse_vlog(f, pin2net, net_map):
+ current_net = None
+
+ for line in f:
+ m = re.match(r"wire ([a-zA-Z0-9_]+);", line)
+ if m:
+ net = m.group(1)
+ mp = re.match(r"pin_([a-zA-Z0-9]+)", net)
+ if mp:
+ pin = mp.group(1)
+ if pin in pin2net:
+ current_net = pin2net[pin]
+ else:
+ current_net = None
+ else:
+ current_net = None
+ elif current_net is not None:
+ m = re.match(r"// \((\d+), (\d+), '([a-zA-Z0-9_/]+)'\)", line)
+ if m:
+ x = int(m.group(1))
+ y = int(m.group(2))
+ net = m.group(3)
+ if not (net.startswith("sp") or net.startswith("glb") or net.startswith("neigh") or net.startswith("io") or net.startswith("local") or net.startswith("fabout")):
+ net_map[current_net].add((x, y, net))
+def parse_exp(f):
+ current_x = 0
+ current_y = 0
+ bits = set()
+ for line in f:
+ splitline = line.split(' ')
+ if splitline[0].endswith("_tile"):
+ current_x = int(splitline[1])
+ current_y = int(splitline[2])
+ elif splitline[0] == "IpConfig":
+ if splitline[1][:5] == "CBIT_":
+ bitidx = int(splitline[1][5:])
+ bits.add((current_x, current_y, splitline[1].strip()))
+ return bits
+
+if not os.path.exists("./work_spram"):
+ os.mkdir("./work_spram")
+
+for loc in spram_locs:
+ x, y, z = loc
+ net_map = {}
+ for sig in spram_signals:
+ net_map[sig] = set()
+ net_map["C_SPRAM_EN"] = set() # actually a CBIT not a net
+
+ for n in fuzz_options:
+ with open("./work_spram/spram.v","w") as f:
+ print("""
+ module top(
+ input WREN,
+ input CHIPSELECT,
+ input CLOCK,
+ input STANDBY,
+ input SLEEP,
+ input POWEROFF,
+ """, file=f)
+ if n == "ADDRESS":
+ print("\t\t\tinput [13:0] ADDRESS,", file=f)
+ if n == "DATAIN":
+ print("\t\t\tinput [15:0] DATAIN,", file=f)
+ if n == "MASKWREN":
+ print("\t\t\tinput [3:0] MASKWREN,", file=f)
+ if n == "DATAOUT":
+ print("\t\t\toutput [15:0] DATAOUT);", file=f)
+ else:
+ print("\t\t\toutput [0:0] DATAOUT);", file=f) #some dataout is always required to prevent optimisation away
+
+ addr_net = "ADDRESS" if n == "ADDRESS" else ""
+ din_net = "DATAIN" if n == "DATAIN" else ""
+ mwren_net = "MASKWREN" if n == "MASKWREN" else ""
+
+ print("""
+ SB_SPRAM256KA spram_i
+ (
+ .ADDRESS(%s),
+ .DATAIN(%s),
+ .MASKWREN(%s),
+ .WREN(WREN),
+ .CHIPSELECT(CHIPSELECT),
+ .CLOCK(CLOCK),
+ .STANDBY(STANDBY),
+ .SLEEP(SLEEP),
+ .POWEROFF(POWEROFF),
+ .DATAOUT(DATAOUT)
+ );
+ """ % (addr_net, din_net, mwren_net), file=f)
+ print("endmodule",file=f)
+ pin2net = {}
+ with open("./work_spram/spram.pcf","w") as f:
+ temp_pins = list(pins)
+ for sig in spram_signals:
+ if sig.startswith("ADDRESS") and n != "ADDRESS":
+ continue
+ if sig.startswith("DATAIN") and n != "DATAIN":
+ continue
+ if sig.startswith("MASKWREN") and n != "MASKWREN":
+ continue
+ if sig.startswith("DATAOUT") and n != "DATAOUT" and sig != "DATAOUT[0]":
+ continue
+
+ if len(temp_pins) == 0:
+ sys.stderr.write("ERROR: no remaining pins to alloc")
+ sys.exit(1)
+
+ pin = temp_pins.pop()
+ pin2net[pin] = sig
+ print("set_io %s %s" % (sig, pin), file=f)
+ print("set_location spram_i %d %d %d" % loc, file=f)
+ retval = os.system("bash ../../icecube.sh -" + device + " ./work_spram/spram.v > ./work_spram/icecube.log 2>&1")
+ if retval != 0:
+ sys.stderr.write('ERROR: icecube returned non-zero error code\n')
+ sys.exit(1)
+ retval = os.system("../../../icebox/icebox_explain.py ./work_spram/spram.asc > ./work_spram/spram.exp")
+ if retval != 0:
+ sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n')
+ sys.exit(1)
+ retval = os.system("../../../icebox/icebox_vlog.py -l ./work_spram/spram.asc > ./work_spram/spram.vlog")
+ if retval != 0:
+ sys.stderr.write('ERROR: icebox_vlog returned non-zero error code\n')
+ sys.exit(1)
+ with open("./work_spram/spram.vlog", "r") as f:
+ parse_vlog(f, pin2net, net_map)
+ bits = []
+ with open("./work_spram/spram.exp", "r") as f:
+ bits = parse_exp(f)
+ net_map["C_SPRAM_EN"].update(bits)
+ spram_data[loc] = net_map
+
+with open(device + "_spram_data.txt", "w") as f:
+ for loc in spram_data:
+ print("SPRAM %d %d %d" % loc, file=f)
+ data = spram_data[loc]
+ for net in sorted(data):
+ cnets = []
+ for cnet in data[net]:
+ cnets.append("(%d, %d, %s)" % cnet)
+ print("\t%s: %s" % (net, " ".join(cnets)), file=f) \ No newline at end of file
diff --git a/icefuzz/tests/spram/up5k_spram_data.txt b/icefuzz/tests/spram/up5k_spram_data.txt
new file mode 100644
index 0000000..c824e73
--- /dev/null
+++ b/icefuzz/tests/spram/up5k_spram_data.txt
@@ -0,0 +1,232 @@
+SPRAM 0 0 1
+ ADDRESS[0]: (0, 2, lutff_0/in_1)
+ ADDRESS[10]: (0, 2, lutff_2/in_0)
+ ADDRESS[11]: (0, 2, lutff_3/in_0)
+ ADDRESS[12]: (0, 2, lutff_4/in_0)
+ ADDRESS[13]: (0, 2, lutff_5/in_0)
+ ADDRESS[1]: (0, 2, lutff_1/in_1)
+ ADDRESS[2]: (0, 2, lutff_2/in_1)
+ ADDRESS[3]: (0, 2, lutff_3/in_1)
+ ADDRESS[4]: (0, 2, lutff_4/in_1)
+ ADDRESS[5]: (0, 2, lutff_5/in_1)
+ ADDRESS[6]: (0, 2, lutff_6/in_1)
+ ADDRESS[7]: (0, 2, lutff_7/in_1)
+ ADDRESS[8]: (0, 2, lutff_0/in_0)
+ ADDRESS[9]: (0, 2, lutff_1/in_0)
+ CHIPSELECT: (0, 3, lutff_6/in_1)
+ CLOCK: (0, 1, clk)
+ C_SPRAM_EN: (0, 1, CBIT_0)
+ DATAIN[0]: (0, 1, lutff_0/in_3)
+ DATAIN[10]: (0, 1, lutff_2/in_1)
+ DATAIN[11]: (0, 1, lutff_3/in_1)
+ DATAIN[12]: (0, 1, lutff_4/in_1)
+ DATAIN[13]: (0, 1, lutff_5/in_1)
+ DATAIN[14]: (0, 1, lutff_6/in_1)
+ DATAIN[15]: (0, 1, lutff_7/in_1)
+ DATAIN[1]: (0, 1, lutff_1/in_3)
+ DATAIN[2]: (0, 1, lutff_2/in_3)
+ DATAIN[3]: (0, 1, lutff_3/in_3)
+ DATAIN[4]: (0, 1, lutff_4/in_3)
+ DATAIN[5]: (0, 1, lutff_5/in_3)
+ DATAIN[6]: (0, 1, lutff_6/in_3)
+ DATAIN[7]: (0, 1, lutff_7/in_3)
+ DATAIN[8]: (0, 1, lutff_0/in_1)
+ DATAIN[9]: (0, 1, lutff_1/in_1)
+ DATAOUT[0]: (0, 1, slf_op_0)
+ DATAOUT[10]: (0, 2, slf_op_2)
+ DATAOUT[11]: (0, 2, slf_op_3)
+ DATAOUT[12]: (0, 2, slf_op_4)
+ DATAOUT[13]: (0, 2, slf_op_5)
+ DATAOUT[14]: (0, 2, slf_op_6)
+ DATAOUT[15]: (0, 2, slf_op_7)
+ DATAOUT[1]: (0, 1, slf_op_1)
+ DATAOUT[2]: (0, 1, slf_op_2)
+ DATAOUT[3]: (0, 1, slf_op_3)
+ DATAOUT[4]: (0, 1, slf_op_4)
+ DATAOUT[5]: (0, 1, slf_op_5)
+ DATAOUT[6]: (0, 1, slf_op_6)
+ DATAOUT[7]: (0, 1, slf_op_7)
+ DATAOUT[8]: (0, 2, slf_op_0)
+ DATAOUT[9]: (0, 2, slf_op_1)
+ MASKWREN[0]: (0, 3, lutff_0/in_0)
+ MASKWREN[1]: (0, 3, lutff_1/in_0)
+ MASKWREN[2]: (0, 3, lutff_2/in_0)
+ MASKWREN[3]: (0, 3, lutff_3/in_0)
+ POWEROFF: (0, 4, lutff_4/in_3)
+ SLEEP: (0, 4, lutff_2/in_3)
+ STANDBY: (0, 4, lutff_0/in_3)
+ WREN: (0, 3, lutff_4/in_1)
+SPRAM 0 0 2
+ ADDRESS[0]: (0, 2, lutff_6/in_0)
+ ADDRESS[10]: (0, 3, lutff_0/in_1)
+ ADDRESS[11]: (0, 3, lutff_1/in_1)
+ ADDRESS[12]: (0, 3, lutff_2/in_1)
+ ADDRESS[13]: (0, 3, lutff_3/in_1)
+ ADDRESS[1]: (0, 2, lutff_7/in_0)
+ ADDRESS[2]: (0, 3, lutff_0/in_3)
+ ADDRESS[3]: (0, 3, lutff_1/in_3)
+ ADDRESS[4]: (0, 3, lutff_2/in_3)
+ ADDRESS[5]: (0, 3, lutff_3/in_3)
+ ADDRESS[6]: (0, 3, lutff_4/in_3)
+ ADDRESS[7]: (0, 3, lutff_5/in_3)
+ ADDRESS[8]: (0, 3, lutff_6/in_3)
+ ADDRESS[9]: (0, 3, lutff_7/in_3)
+ CHIPSELECT: (0, 3, lutff_7/in_1)
+ CLOCK: (0, 2, clk)
+ C_SPRAM_EN: (0, 1, CBIT_1)
+ DATAIN[0]: (0, 1, lutff_0/in_0)
+ DATAIN[10]: (0, 2, lutff_2/in_3)
+ DATAIN[11]: (0, 2, lutff_3/in_3)
+ DATAIN[12]: (0, 2, lutff_4/in_3)
+ DATAIN[13]: (0, 2, lutff_5/in_3)
+ DATAIN[14]: (0, 2, lutff_6/in_3)
+ DATAIN[15]: (0, 2, lutff_7/in_3)
+ DATAIN[1]: (0, 1, lutff_1/in_0)
+ DATAIN[2]: (0, 1, lutff_2/in_0)
+ DATAIN[3]: (0, 1, lutff_3/in_0)
+ DATAIN[4]: (0, 1, lutff_4/in_0)
+ DATAIN[5]: (0, 1, lutff_5/in_0)
+ DATAIN[6]: (0, 1, lutff_6/in_0)
+ DATAIN[7]: (0, 1, lutff_7/in_0)
+ DATAIN[8]: (0, 2, lutff_0/in_3)
+ DATAIN[9]: (0, 2, lutff_1/in_3)
+ DATAOUT[0]: (0, 3, slf_op_0)
+ DATAOUT[10]: (0, 4, slf_op_2)
+ DATAOUT[11]: (0, 4, slf_op_3)
+ DATAOUT[12]: (0, 4, slf_op_4)
+ DATAOUT[13]: (0, 4, slf_op_5)
+ DATAOUT[14]: (0, 4, slf_op_6)
+ DATAOUT[15]: (0, 4, slf_op_7)
+ DATAOUT[1]: (0, 3, slf_op_1)
+ DATAOUT[2]: (0, 3, slf_op_2)
+ DATAOUT[3]: (0, 3, slf_op_3)
+ DATAOUT[4]: (0, 3, slf_op_4)
+ DATAOUT[5]: (0, 3, slf_op_5)
+ DATAOUT[6]: (0, 3, slf_op_6)
+ DATAOUT[7]: (0, 3, slf_op_7)
+ DATAOUT[8]: (0, 4, slf_op_0)
+ DATAOUT[9]: (0, 4, slf_op_1)
+ MASKWREN[0]: (0, 3, lutff_4/in_0)
+ MASKWREN[1]: (0, 3, lutff_5/in_0)
+ MASKWREN[2]: (0, 3, lutff_6/in_0)
+ MASKWREN[3]: (0, 3, lutff_7/in_0)
+ POWEROFF: (0, 4, lutff_5/in_3)
+ SLEEP: (0, 4, lutff_3/in_3)
+ STANDBY: (0, 4, lutff_1/in_3)
+ WREN: (0, 3, lutff_5/in_1)
+SPRAM 25 0 3
+ ADDRESS[0]: (25, 2, lutff_0/in_1)
+ ADDRESS[10]: (25, 2, lutff_2/in_0)
+ ADDRESS[11]: (25, 2, lutff_3/in_0)
+ ADDRESS[12]: (25, 2, lutff_4/in_0)
+ ADDRESS[13]: (25, 2, lutff_5/in_0)
+ ADDRESS[1]: (25, 2, lutff_1/in_1)
+ ADDRESS[2]: (25, 2, lutff_2/in_1)
+ ADDRESS[3]: (25, 2, lutff_3/in_1)
+ ADDRESS[4]: (25, 2, lutff_4/in_1)
+ ADDRESS[5]: (25, 2, lutff_5/in_1)
+ ADDRESS[6]: (25, 2, lutff_6/in_1)
+ ADDRESS[7]: (25, 2, lutff_7/in_1)
+ ADDRESS[8]: (25, 2, lutff_0/in_0)
+ ADDRESS[9]: (25, 2, lutff_1/in_0)
+ CHIPSELECT: (25, 3, lutff_6/in_1)
+ CLOCK: (25, 1, clk)
+ C_SPRAM_EN: (25, 1, CBIT_0)
+ DATAIN[0]: (25, 1, lutff_0/in_3)
+ DATAIN[10]: (25, 1, lutff_2/in_1)
+ DATAIN[11]: (25, 1, lutff_3/in_1)
+ DATAIN[12]: (25, 1, lutff_4/in_1)
+ DATAIN[13]: (25, 1, lutff_5/in_1)
+ DATAIN[14]: (25, 1, lutff_6/in_1)
+ DATAIN[15]: (25, 1, lutff_7/in_1)
+ DATAIN[1]: (25, 1, lutff_1/in_3)
+ DATAIN[2]: (25, 1, lutff_2/in_3)
+ DATAIN[3]: (25, 1, lutff_3/in_3)
+ DATAIN[4]: (25, 1, lutff_4/in_3)
+ DATAIN[5]: (25, 1, lutff_5/in_3)
+ DATAIN[6]: (25, 1, lutff_6/in_3)
+ DATAIN[7]: (25, 1, lutff_7/in_3)
+ DATAIN[8]: (25, 1, lutff_0/in_1)
+ DATAIN[9]: (25, 1, lutff_1/in_1)
+ DATAOUT[0]: (25, 1, slf_op_0)
+ DATAOUT[10]: (25, 2, slf_op_2)
+ DATAOUT[11]: (25, 2, slf_op_3)
+ DATAOUT[12]: (25, 2, slf_op_4)
+ DATAOUT[13]: (25, 2, slf_op_5)
+ DATAOUT[14]: (25, 2, slf_op_6)
+ DATAOUT[15]: (25, 2, slf_op_7)
+ DATAOUT[1]: (25, 1, slf_op_1)
+ DATAOUT[2]: (25, 1, slf_op_2)
+ DATAOUT[3]: (25, 1, slf_op_3)
+ DATAOUT[4]: (25, 1, slf_op_4)
+ DATAOUT[5]: (25, 1, slf_op_5)
+ DATAOUT[6]: (25, 1, slf_op_6)
+ DATAOUT[7]: (25, 1, slf_op_7)
+ DATAOUT[8]: (25, 2, slf_op_0)
+ DATAOUT[9]: (25, 2, slf_op_1)
+ MASKWREN[0]: (25, 3, lutff_0/in_0)
+ MASKWREN[1]: (25, 3, lutff_1/in_0)
+ MASKWREN[2]: (25, 3, lutff_2/in_0)
+ MASKWREN[3]: (25, 3, lutff_3/in_0)
+ POWEROFF: (25, 4, lutff_4/in_3)
+ SLEEP: (25, 4, lutff_2/in_3)
+ STANDBY: (25, 4, lutff_0/in_3)
+ WREN: (25, 3, lutff_4/in_1)
+SPRAM 25 0 4
+ ADDRESS[0]: (25, 2, lutff_6/in_0)
+ ADDRESS[10]: (25, 3, lutff_0/in_1)
+ ADDRESS[11]: (25, 3, lutff_1/in_1)
+ ADDRESS[12]: (25, 3, lutff_2/in_1)
+ ADDRESS[13]: (25, 3, lutff_3/in_1)
+ ADDRESS[1]: (25, 2, lutff_7/in_0)
+ ADDRESS[2]: (25, 3, lutff_0/in_3)
+ ADDRESS[3]: (25, 3, lutff_1/in_3)
+ ADDRESS[4]: (25, 3, lutff_2/in_3)
+ ADDRESS[5]: (25, 3, lutff_3/in_3)
+ ADDRESS[6]: (25, 3, lutff_4/in_3)
+ ADDRESS[7]: (25, 3, lutff_5/in_3)
+ ADDRESS[8]: (25, 3, lutff_6/in_3)
+ ADDRESS[9]: (25, 3, lutff_7/in_3)
+ CHIPSELECT: (25, 3, lutff_7/in_1)
+ CLOCK: (25, 2, clk)
+ C_SPRAM_EN: (25, 1, CBIT_1)
+ DATAIN[0]: (25, 1, lutff_0/in_0)
+ DATAIN[10]: (25, 2, lutff_2/in_3)
+ DATAIN[11]: (25, 2, lutff_3/in_3)
+ DATAIN[12]: (25, 2, lutff_4/in_3)
+ DATAIN[13]: (25, 2, lutff_5/in_3)
+ DATAIN[14]: (25, 2, lutff_6/in_3)
+ DATAIN[15]: (25, 2, lutff_7/in_3)
+ DATAIN[1]: (25, 1, lutff_1/in_0)
+ DATAIN[2]: (25, 1, lutff_2/in_0)
+ DATAIN[3]: (25, 1, lutff_3/in_0)
+ DATAIN[4]: (25, 1, lutff_4/in_0)
+ DATAIN[5]: (25, 1, lutff_5/in_0)
+ DATAIN[6]: (25, 1, lutff_6/in_0)
+ DATAIN[7]: (25, 1, lutff_7/in_0)
+ DATAIN[8]: (25, 2, lutff_0/in_3)
+ DATAIN[9]: (25, 2, lutff_1/in_3)
+ DATAOUT[0]: (25, 3, slf_op_0)
+ DATAOUT[10]: (25, 4, slf_op_2)
+ DATAOUT[11]: (25, 4, slf_op_3)
+ DATAOUT[12]: (25, 4, slf_op_4)
+ DATAOUT[13]: (25, 4, slf_op_5)
+ DATAOUT[14]: (25, 4, slf_op_6)
+ DATAOUT[15]: (25, 4, slf_op_7)
+ DATAOUT[1]: (25, 3, slf_op_1)
+ DATAOUT[2]: (25, 3, slf_op_2)
+ DATAOUT[3]: (25, 3, slf_op_3)
+ DATAOUT[4]: (25, 3, slf_op_4)
+ DATAOUT[5]: (25, 3, slf_op_5)
+ DATAOUT[6]: (25, 3, slf_op_6)
+ DATAOUT[7]: (25, 3, slf_op_7)
+ DATAOUT[8]: (25, 4, slf_op_0)
+ DATAOUT[9]: (25, 4, slf_op_1)
+ MASKWREN[0]: (25, 3, lutff_4/in_0)
+ MASKWREN[1]: (25, 3, lutff_5/in_0)
+ MASKWREN[2]: (25, 3, lutff_6/in_0)
+ MASKWREN[3]: (25, 3, lutff_7/in_0)
+ POWEROFF: (25, 4, lutff_5/in_3)
+ SLEEP: (25, 4, lutff_3/in_3)
+ STANDBY: (25, 4, lutff_1/in_3)
+ WREN: (25, 3, lutff_5/in_1)