aboutsummaryrefslogtreecommitdiffstats
path: root/icefuzz
diff options
context:
space:
mode:
Diffstat (limited to 'icefuzz')
-rw-r--r--icefuzz/fuzzconfig.py4
-rw-r--r--icefuzz/glbcheck.py7
-rw-r--r--icefuzz/make_prim.py22
-rw-r--r--icefuzz/make_ram40.py10
-rw-r--r--icefuzz/tests/.gitignore2
-rw-r--r--icefuzz/tests/intosc.pcf3
-rw-r--r--icefuzz/tests/intosc.v14
-rw-r--r--icefuzz/tests/ioctrl_5k.py21
-rwxr-xr-xicefuzz/tests/ioctrl_5k.sh28
-rw-r--r--icefuzz/tests/pllauto/.gitignore1
-rw-r--r--icefuzz/tests/pllauto/pll_data_up5k.txt39
-rwxr-xr-xicefuzz/tests/pllauto/pllauto.py276
-rw-r--r--icefuzz/tests/sb_io_od.pcf12
-rw-r--r--icefuzz/tests/sb_io_od.v62
-rw-r--r--icefuzz/tests/sb_mac16.v65
-rw-r--r--icefuzz/tests/sb_rgba_drv.pcf3
-rw-r--r--icefuzz/tests/sb_rgba_drv.v32
-rw-r--r--icefuzz/tests/sb_spram256ka.v25
18 files changed, 617 insertions, 9 deletions
diff --git a/icefuzz/fuzzconfig.py b/icefuzz/fuzzconfig.py
index 2e925ef..a5c1e2c 100644
--- a/icefuzz/fuzzconfig.py
+++ b/icefuzz/fuzzconfig.py
@@ -63,8 +63,10 @@ elif device_class == "5k":
#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.
+ #TODO(daveshah1): Add back I3C IO 23 which cause placement failures when assigned to
+ #an SB_IO clk_in
pins = """2 3 4 6 9 10 11 12
- 13 18 19 20 21 23
+ 13 18 19 20 21
25 26 27 28 31 32 34 35 36
37 38 42 43 44 45 46 47 48
""".split()
diff --git a/icefuzz/glbcheck.py b/icefuzz/glbcheck.py
index 742c335..49008ca 100644
--- a/icefuzz/glbcheck.py
+++ b/icefuzz/glbcheck.py
@@ -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.startswith(("Tile", "IO_Tile", "RAM_Tile", "LogicTile")):
- f = line.replace("IO_", "").replace("RAM_", "").split("_")
+ if line.startswith(("Tile", "IO_Tile", "RAM_Tile", "LogicTile", "DSP_Tile", "IpCon_Tile")):
+ f = line.replace("IO_", "").replace("RAM_", "").replace("DSP_","").replace("IpCon_","").split("_")
assert len(f) == 3
current_tile = "%02d.%02d" % (int(f[1]), int(f[2]))
continue
- if line.find("GlobalNetwork") >= 0 or line.startswith(("IpCon", "DSP")):
+ if line.find("GlobalNetwork") >= 0:
current_tile = None
continue
@@ -65,4 +65,3 @@ for bit in sorted(only_in_glb):
print(bit)
exit(1)
-
diff --git a/icefuzz/make_prim.py b/icefuzz/make_prim.py
index b96a100..90186da 100644
--- a/icefuzz/make_prim.py
+++ b/icefuzz/make_prim.py
@@ -31,20 +31,40 @@ for idx in range(num):
print("endmodule", file=f)
with open(working_dir + "/prim_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
+ used_pins = []
if np.random.choice([True, False]):
for i in range(w):
print("set_io a[%d] %s" % (i, p[i]), file=f)
+ used_pins.append(p[i])
if np.random.choice([True, False]):
for i in range(w):
print("set_io b[%d] %s" % (i, p[w+i]), file=f)
+ used_pins.append(p[w+i])
if np.random.choice([True, False]):
for i in range(w):
print("set_io y[%d] %s" % (i, p[2*w+i]), file=f)
+ used_pins.append(p[2*w+i])
if np.random.choice([True, False]):
print("set_io x %s" % p[3*w], file=f)
+ used_pins.append(p[3*w])
+
if np.random.choice([True, False]):
print("set_io y %s" % p[3*w+1], file=f)
- if np.random.choice([True, False]):
+ used_pins.append(p[3*w+1])
+
+ # There is a low but non-zero probability, particularly on devices with
+ # fewer pins and GBINs such as the UltraPlus, that a permutation will be
+ # picked where all of the GBINs are already constrained at this point,
+ # hence icecube fails to assign clk successfully. This is fixed by
+ # forcing clock assignment if no GBINs are free.
+
+ global_free = False
+ for glbi in gpins:
+ if not glbi in used_pins:
+ global_free = True
+ break
+
+ if np.random.choice([True, False]) or not global_free:
print("set_io clk %s" % p[3*w+2], file=f)
diff --git a/icefuzz/make_ram40.py b/icefuzz/make_ram40.py
index f4acb4e..75ac604 100644
--- a/icefuzz/make_ram40.py
+++ b/icefuzz/make_ram40.py
@@ -14,7 +14,11 @@ os.mkdir(working_dir)
for idx in range(num):
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"]
+ # Connecting GLB to CE pins seemingly disallowed
+ if device_class == "5k":
+ glbs_choice = ["wa", "ra", "msk", "wd", "we", "wc", "re", "rc"]
+ else:
+ glbs_choice = ["wa", "ra", "msk", "wd", "we", "wce", "wc", "re", "rce", "rc"]
print("""
module top (
input [%d:0] glb_pins,
@@ -26,7 +30,7 @@ for idx in range(num):
.USER_SIGNAL_TO_GLOBAL_BUFFER(glb_pins),
.GLOBAL_BUFFER_OUTPUT(glb)
);
- """ % (len(glbs)-1, len(pins) - 16 - 1, len(glbs)-1, len(glbs)-1), file=f)
+ """ % (len(glbs)-1, len(pins) - len(glbs) - 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):
@@ -102,7 +106,7 @@ for idx in range(num):
print("endmodule", file=f)
with open(working_dir + "/ram40_%02d.pcf" % idx, "w") as f:
p = list(np.random.permutation(pins))
- for i in range(len(pins) - 16):
+ for i in range(len(pins) - len(glbs) - 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)
diff --git a/icefuzz/tests/.gitignore b/icefuzz/tests/.gitignore
new file mode 100644
index 0000000..cc0ba46
--- /dev/null
+++ b/icefuzz/tests/.gitignore
@@ -0,0 +1,2 @@
+ioctrl.work
+intosc.work
diff --git a/icefuzz/tests/intosc.pcf b/icefuzz/tests/intosc.pcf
new file mode 100644
index 0000000..9e580de
--- /dev/null
+++ b/icefuzz/tests/intosc.pcf
@@ -0,0 +1,3 @@
+set_io clkhfpu 2
+set_io clkhfen 3
+set_io clkhf 4
diff --git a/icefuzz/tests/intosc.v b/icefuzz/tests/intosc.v
new file mode 100644
index 0000000..227cb55
--- /dev/null
+++ b/icefuzz/tests/intosc.v
@@ -0,0 +1,14 @@
+module top (
+ input clkhfpu,
+ input clkhfen,
+ output clkhf
+);
+SB_HFOSC #(
+
+ .CLKHF_DIV("0b10")
+) hfosc (
+ .CLKHFPU(clkhfpu),
+ .CLKHFEN(clkhfen),
+ .CLKHF(clkhf)
+);
+endmodule
diff --git a/icefuzz/tests/ioctrl_5k.py b/icefuzz/tests/ioctrl_5k.py
new file mode 100644
index 0000000..67c0c6d
--- /dev/null
+++ b/icefuzz/tests/ioctrl_5k.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+
+import fileinput
+
+for line in fileinput.input():
+ line = line.split()
+ if len(line) == 0:
+ continue
+ if line[0] == ".io_tile":
+ current_tile = (int(line[1]), int(line[2]))
+ if line[0] == "IoCtrl" and line[1] == "REN_0":
+ ren = (current_tile[0], current_tile[1], 0)
+ if line[0] == "IoCtrl" and line[1] == "REN_1":
+ ren = (current_tile[0], current_tile[1], 1)
+ if line[0] == "IOB_0":
+ iob = (current_tile[0], current_tile[1], 0)
+ if line[0] == "IOB_1":
+ iob = (current_tile[0], current_tile[1], 1)
+
+print("(%2d, %2d, %2d, %2d, %2d, %2d)," % (iob[0], iob[1], iob[2], ren[0], ren[1], ren[2]))
+
diff --git a/icefuzz/tests/ioctrl_5k.sh b/icefuzz/tests/ioctrl_5k.sh
new file mode 100755
index 0000000..339cac7
--- /dev/null
+++ b/icefuzz/tests/ioctrl_5k.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+set -ex
+
+mkdir -p ioctrl.work
+cd ioctrl.work
+
+pins="2 3 4 6 9 10 11 12
+ 13 14 15 16 17 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="ioctrl_$pin"
+ echo "module top (output pin); assign pin = 1; endmodule" > ${pf}.v
+ echo "set_io pin $pin" > ${pf}.pcf
+ bash ../../icecube.sh -up5k ${pf}.v > ${pf}.log 2>&1
+ ../../../icebox/icebox_explain.py ${pf}.asc > ${pf}.exp
+done
+
+set +x
+echo "--snip--"
+for pin in $pins; do
+ python3 ../ioctrl_5k.py ioctrl_${pin}.exp
+done | tee ioctrl_db.txt
+echo "--snap--"
diff --git a/icefuzz/tests/pllauto/.gitignore b/icefuzz/tests/pllauto/.gitignore
new file mode 100644
index 0000000..7fafebe
--- /dev/null
+++ b/icefuzz/tests/pllauto/.gitignore
@@ -0,0 +1 @@
+work_pllauto/ \ No newline at end of file
diff --git a/icefuzz/tests/pllauto/pll_data_up5k.txt b/icefuzz/tests/pllauto/pll_data_up5k.txt
new file mode 100644
index 0000000..2010989
--- /dev/null
+++ b/icefuzz/tests/pllauto/pll_data_up5k.txt
@@ -0,0 +1,39 @@
+"PLLTYPE_1": (14, 31, "PLLCONFIG_1"),
+"PLLTYPE_2": (14, 31, "PLLCONFIG_3"),
+"PLLTYPE_0": (12, 31, "PLLCONFIG_5"),
+"FEEDBACK_PATH_0": (14, 31, "PLLCONFIG_5"),
+"FEEDBACK_PATH_1": (11, 31, "PLLCONFIG_9"),
+"FEEDBACK_PATH_2": (12, 31, "PLLCONFIG_1"),
+"PLLOUT_SELECT_A_0": (12, 31, "PLLCONFIG_6"),
+"PLLOUT_SELECT_A_1": (12, 31, "PLLCONFIG_7"),
+"PLLOUT_SELECT_B_0": (12, 31, "PLLCONFIG_2"),
+"PLLOUT_SELECT_B_1": (12, 31, "PLLCONFIG_3"),
+"SHIFTREG_DIV_MODE": (12, 31, "PLLCONFIG_4"),
+"FDA_FEEDBACK_0": (12, 31, "PLLCONFIG_9"),
+"FDA_FEEDBACK_1": (13, 31, "PLLCONFIG_1"),
+"FDA_FEEDBACK_2": (13, 31, "PLLCONFIG_2"),
+"FDA_FEEDBACK_3": (13, 31, "PLLCONFIG_3"),
+"FDA_RELATIVE_0": (13, 31, "PLLCONFIG_5"),
+"FDA_RELATIVE_1": (13, 31, "PLLCONFIG_6"),
+"FDA_RELATIVE_2": (13, 31, "PLLCONFIG_7"),
+"FDA_RELATIVE_3": (13, 31, "PLLCONFIG_8"),
+"DIVR_0": (10, 31, "PLLCONFIG_1"),
+"DIVR_1": (10, 31, "PLLCONFIG_2"),
+"DIVR_2": (10, 31, "PLLCONFIG_3"),
+"DIVR_3": (10, 31, "PLLCONFIG_4"),
+"DIVF_0": (10, 31, "PLLCONFIG_5"),
+"DIVF_1": (10, 31, "PLLCONFIG_6"),
+"DIVF_2": (10, 31, "PLLCONFIG_7"),
+"DIVF_3": (10, 31, "PLLCONFIG_8"),
+"DIVF_4": (10, 31, "PLLCONFIG_9"),
+"DIVF_5": (11, 31, "PLLCONFIG_1"),
+"DIVF_6": (11, 31, "PLLCONFIG_2"),
+"DIVQ_0": (11, 31, "PLLCONFIG_3"),
+"DIVQ_1": (11, 31, "PLLCONFIG_4"),
+"DIVQ_2": (11, 31, "PLLCONFIG_5"),
+"FILTER_RANGE_0": (11, 31, "PLLCONFIG_6"),
+"FILTER_RANGE_1": (11, 31, "PLLCONFIG_7"),
+"FILTER_RANGE_2": (11, 31, "PLLCONFIG_8"),
+"TEST_MODE": (12, 31, "PLLCONFIG_8"),
+"DELAY_ADJMODE_FB": (13, 31, "PLLCONFIG_4"),
+"DELAY_ADJMODE_REL": (13, 31, "PLLCONFIG_9"),
diff --git a/icefuzz/tests/pllauto/pllauto.py b/icefuzz/tests/pllauto/pllauto.py
new file mode 100755
index 0000000..647be29
--- /dev/null
+++ b/icefuzz/tests/pllauto/pllauto.py
@@ -0,0 +1,276 @@
+#!/usr/bin/env python3
+
+import os, sys
+# PLL automatic fuzzing script (WIP)
+
+device = "up5k"
+
+# PLL config bits to be fuzzed
+# These must be in an order such that a config with bit i set doesn't set any other undiscovered bits yet
+# e.g. PLL_TYPE must be fuzzed first as these will need to be set later on by virtue of enabling the PLL
+
+fuzz_bits = [
+ "PLLTYPE_1",
+ "PLLTYPE_2",
+ "PLLTYPE_0", #NB: as per the rule above this comes later is it can only be set by also setting 1 or 2
+
+ "FEEDBACK_PATH_0",
+ "FEEDBACK_PATH_1",
+ "FEEDBACK_PATH_2",
+
+ "PLLOUT_SELECT_A_0",
+ "PLLOUT_SELECT_A_1",
+
+ "PLLOUT_SELECT_B_0",
+ "PLLOUT_SELECT_B_1",
+
+ "SHIFTREG_DIV_MODE",
+
+ "FDA_FEEDBACK_0",
+ "FDA_FEEDBACK_1",
+ "FDA_FEEDBACK_2",
+ "FDA_FEEDBACK_3",
+
+ "FDA_RELATIVE_0",
+ "FDA_RELATIVE_1",
+ "FDA_RELATIVE_2",
+ "FDA_RELATIVE_3",
+
+ "DIVR_0",
+ "DIVR_1",
+ "DIVR_2",
+ "DIVR_3",
+
+ "DIVF_0",
+ "DIVF_1",
+ "DIVF_2",
+ "DIVF_3",
+ "DIVF_4",
+ "DIVF_5",
+ "DIVF_6",
+
+ #DIVQ_0 is missing, see comments later on
+ "DIVQ_1",
+ "DIVQ_2",
+
+ "FILTER_RANGE_0",
+ "FILTER_RANGE_1",
+ "FILTER_RANGE_2",
+
+ "TEST_MODE",
+
+ "DELAY_ADJMODE_FB", #these come at the end in case they set FDA_RELATIVE??
+ "DELAY_ADJMODE_REL"
+]
+
+# Boilerplate code based on the icefuzz script
+code_prefix = """
+module top(packagepin, a, b, w, x, y, z, extfeedback, bypass, resetb, lock, latchinputvalue, sdi, sdo, sclk, dynamicdelay_0, dynamicdelay_1, dynamicdelay_2, dynamicdelay_3, dynamicdelay_4, dynamicdelay_5, dynamicdelay_6, dynamicdelay_7);
+input packagepin;
+input a;
+input b;
+output w;
+output x;
+output reg y;
+output reg z;
+input extfeedback;
+input bypass;
+input resetb;
+output lock;
+input latchinputvalue;
+input sdi;
+output sdo;
+input sclk;
+wire plloutcorea;
+wire plloutcoreb;
+wire plloutglobala;
+wire plloutglobalb;
+assign w = plloutcorea ^ a;
+assign x = plloutcoreb ^ b;
+always @(posedge plloutglobala) y <= a;
+always @(posedge plloutglobalb) z <= b;
+input dynamicdelay_0;
+input dynamicdelay_1;
+input dynamicdelay_2;
+input dynamicdelay_3;
+input dynamicdelay_4;
+input dynamicdelay_5;
+input dynamicdelay_6;
+input dynamicdelay_7;
+"""
+
+def get_param_value(param_name, param_size, fuzz_bit):
+ param = str(param_size) + "'b";
+ for i in range(param_size - 1, -1, -1):
+ if fuzz_bit == param_name + "_" + str(i):
+ param += '1'
+ else:
+ param += '0'
+ return param
+def inst_pll(fuzz_bit):
+ pll_type = "SB_PLL40_2F_PAD" #default to this as it's most flexible
+
+ if fuzz_bit == "PLLTYPE_0":
+ pll_type = "SB_PLL40_CORE"
+ elif fuzz_bit == "PLLTYPE_1":
+ pll_type = "SB_PLL40_PAD"
+ elif fuzz_bit == "PLLTYPE_2":
+ pll_type = "SB_PLL40_2_PAD"
+
+ v = pll_type + " pll_inst (\n"
+ if pll_type == "SB_PLL40_CORE":
+ v += "\t.REFERENCECLK(referenceclk), \n"
+ else:
+ v += "\t.PACKAGEPIN(packagepin), \n"
+ v += "\t.RESETB(resetb),\n"
+ v += "\t.BYPASS(bypass),\n"
+ v += "\t.EXTFEEDBACK(extfeedback),\n"
+ v += "\t.LOCK(lock),\n"
+ v += "\t.LATCHINPUTVALUE(latchinputvalue),\n"
+ v += "\t.SDI(sdi),\n"
+ v += "\t.SDO(sdo),\n"
+ v += "\t.SCLK(sclk),\n"
+ if pll_type == "SB_PLL40_2F_PAD" or pll_type == "SB_PLL40_2_PAD":
+ v += "\t.PLLOUTCOREA(plloutcorea),\n"
+ v += "\t.PLLOUTGLOBALA(plloutglobala),\n"
+ v += "\t.PLLOUTCOREB(plloutcoreb),\n"
+ v += "\t.PLLOUTGLOBALB(plloutglobalb),\n"
+ else:
+ v += "\t.PLLOUTCORE(plloutcorea),\n"
+ v += "\t.PLLOUTGLOBAL(plloutglobala),\n"
+ v += "\t.DYNAMICDELAY({dynamicdelay_7, dynamicdelay_6, dynamicdelay_5, dynamicdelay_4, dynamicdelay_3, dynamicdelay_2, dynamicdelay_1, dynamicdelay_0})\n"
+ v += ");\n"
+
+ v += "defparam pll_inst.DIVR = " + get_param_value("DIVR", 4, fuzz_bit) + ";\n"
+ v += "defparam pll_inst.DIVF = " + get_param_value("DIVF", 7, fuzz_bit) + ";\n"
+ v += "defparam pll_inst.DIVQ = " + get_param_value("DIVQ", 3, fuzz_bit) + ";\n"
+ v += "defparam pll_inst.FILTER_RANGE = " + get_param_value("FILTER_RANGE", 3, fuzz_bit) + ";\n"
+
+ if fuzz_bit == "FEEDBACK_PATH_0":
+ v += "defparam pll_inst.FEEDBACK_PATH = \"SIMPLE\";\n"
+ elif fuzz_bit == "FEEDBACK_PATH_1":
+ v += "defparam pll_inst.FEEDBACK_PATH = \"PHASE_AND_DELAY\";\n"
+ elif fuzz_bit == "FEEDBACK_PATH_2":
+ v += "defparam pll_inst.FEEDBACK_PATH = \"EXTERNAL\";\n"
+ else:
+ v += "defparam pll_inst.FEEDBACK_PATH = \"DELAY\";\n"
+
+ v += "defparam pll_inst.DELAY_ADJUSTMENT_MODE_FEEDBACK = \"" + ("DYNAMIC" if (fuzz_bit == "DELAY_ADJMODE_FB") else "FIXED") + "\";\n"
+ v += "defparam pll_inst.FDA_FEEDBACK = " + get_param_value("FDA_FEEDBACK", 4, fuzz_bit) + ";\n"
+ v += "defparam pll_inst.DELAY_ADJUSTMENT_MODE_RELATIVE = \"" + ("DYNAMIC" if (fuzz_bit == "DELAY_ADJMODE_REL") else "FIXED") + "\";\n"
+ v += "defparam pll_inst.FDA_RELATIVE = " + get_param_value("FDA_RELATIVE", 4, fuzz_bit) + ";\n"
+ v += "defparam pll_inst.SHIFTREG_DIV_MODE = " + ("1'b1" if (fuzz_bit == "SHIFTREG_DIV_MODE") else "1'b0") + ";\n"
+
+
+
+ if pll_type == "SB_PLL40_2F_PAD" or pll_type == "SB_PLL40_2_PAD":
+ if pll_type == "SB_PLL40_2F_PAD":
+ if fuzz_bit == "PLLOUT_SELECT_A_0":
+ v += "defparam pll_inst.PLLOUT_SELECT_PORTA = \"GENCLK_HALF\";\n"
+ elif fuzz_bit == "PLLOUT_SELECT_A_1":
+ v += "defparam pll_inst.PLLOUT_SELECT_PORTA = \"SHIFTREG_90deg\";\n"
+ else:
+ v += "defparam pll_inst.PLLOUT_SELECT_PORTA = \"GENCLK\";\n"
+ if fuzz_bit == "PLLOUT_SELECT_B_0":
+ v += "defparam pll_inst.PLLOUT_SELECT_PORTB = \"GENCLK_HALF\";\n"
+ elif fuzz_bit == "PLLOUT_SELECT_B_1":
+ v += "defparam pll_inst.PLLOUT_SELECT_PORTB = \"SHIFTREG_90deg\";\n"
+ else:
+ v += "defparam pll_inst.PLLOUT_SELECT_PORTB = \"GENCLK\";\n"
+ else:
+ if fuzz_bit == "PLLOUT_SELECT_A_0":
+ v += "defparam pll_inst.PLLOUT_SELECT = \"GENCLK_HALF\";\n"
+ elif fuzz_bit == "PLLOUT_SELECT_A_1":
+ v += "defparam pll_inst.PLLOUT_SELECT = \"SHIFTREG_90deg\";\n"
+ else:
+ v += "defparam pll_inst.PLLOUT_SELECT = \"GENCLK\";\n"
+ v += "defparam pll_inst.TEST_MODE = " + ("1'b1" if (fuzz_bit == "TEST_MODE") else "1'b0") + ";\n"
+
+ return v;
+
+def make_vlog(fuzz_bit):
+ vlog = code_prefix
+ vlog += inst_pll(fuzz_bit)
+ vlog += "endmodule"
+ return vlog
+
+known_bits = []
+
+# Set to true to continue even if multiple bits are changed (needed because
+# of the issue discusssed below)
+show_all_bits = False #TODO: make this an argument
+
+device = "up5k" #TODO: environment variable?
+
+#HACK: icecube doesn't let you set all of the DIVQ bits to 0,
+#which makes fuzzing early on annoying as there is never a case
+#with just 1 bit set. So a tiny bit of semi-manual work is needed
+#first to discover this (basically run this script with show_all_bits=True
+#and look for the stuck bit)
+#TODO: clever code could get rid of this
+divq_bit0 = {
+ "up5k" : (11, 31, 3)
+}
+
+#Return a list of PLL config bits in the format (x, y, bit)
+def parse_exp(expfile):
+ current_x = 0
+ current_y = 0
+ bits = []
+ with open(expfile, 'r') as f:
+ for line in f:
+ splitline = line.split(' ')
+ if splitline[0] == ".io_tile":
+ current_x = int(splitline[1])
+ current_y = int(splitline[2])
+ elif splitline[0] == "PLL":
+ if splitline[1][:10] == "PLLCONFIG_":
+ bitidx = int(splitline[1][10:])
+ bits.append((current_x, current_y, bitidx))
+ return bits
+
+#Convert a bit tuple as returned from the above to a nice string
+def bit_to_str(bit):
+ return "(%d, %d, \"PLLCONFIG_%d\")" % bit
+
+#The main fuzzing function
+def do_fuzz():
+ if not os.path.exists("./work_pllauto"):
+ os.mkdir("./work_pllauto")
+ known_bits.append(divq_bit0[device])
+ with open("pll_data_" + device + ".txt", 'w') as dat:
+ for fuzz_bit in fuzz_bits:
+ vlog = make_vlog(fuzz_bit)
+ with open("./work_pllauto/pllauto.v", 'w') as f:
+ f.write(vlog)
+ retval = os.system("bash ../../icecube.sh -" + device + " ./work_pllauto/pllauto.v > ./work_pllauto/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_pllauto/pllauto.asc > ./work_pllauto/pllauto.exp")
+ if retval != 0:
+ sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n')
+ sys.exit(1)
+ pll_bits = parse_exp("./work_pllauto/pllauto.exp")
+ new_bits = []
+ for set_bit in pll_bits:
+ if not (set_bit in known_bits):
+ new_bits.append(set_bit)
+ if len(new_bits) == 0:
+ sys.stderr.write('ERROR: no new bits set when setting config bit ' + fuzz_bit + '\n')
+ sys.exit(1)
+ if len(new_bits) > 1:
+ sys.stderr.write('ERROR: multiple new bits set when setting config bit ' + fuzz_bit + '\n')
+ for bit in new_bits:
+ sys.stderr.write('\t' + bit_to_str(bit) + '\n')
+ if not show_all_bits:
+ sys.exit(1)
+ if len(new_bits) == 1:
+ known_bits.append(new_bits[0])
+ #print DIVQ_0 at the right moment, as it's not fuzzed normally
+ if fuzz_bit == "DIVQ_1":
+ print(("\"DIVQ_0\":").ljust(24) + bit_to_str(divq_bit0[device]) + ",")
+ dat.write(("\"DIVQ_0\":").ljust(24) + bit_to_str(divq_bit0[device]) + ",\n")
+ print(("\"" + fuzz_bit + "\":").ljust(24) + bit_to_str(new_bits[0]) + ",")
+ dat.write(("\"" + fuzz_bit + "\":").ljust(24) + bit_to_str(new_bits[0]) + ",\n")
+do_fuzz() \ No newline at end of file
diff --git a/icefuzz/tests/sb_io_od.pcf b/icefuzz/tests/sb_io_od.pcf
new file mode 100644
index 0000000..b613227
--- /dev/null
+++ b/icefuzz/tests/sb_io_od.pcf
@@ -0,0 +1,12 @@
+# set_io pin 1
+set_io pin 39
+
+# set_io pin
+# set_io latch_in
+# set_io clk_in
+# set_io clk_out
+# set_io oen
+# set_io dout_0
+# set_io dout_1
+# set_io din_0
+# set_io din_1
diff --git a/icefuzz/tests/sb_io_od.v b/icefuzz/tests/sb_io_od.v
new file mode 100644
index 0000000..7894741
--- /dev/null
+++ b/icefuzz/tests/sb_io_od.v
@@ -0,0 +1,62 @@
+//`define CONN_INTERNAL_BITS
+
+`define PINTYPE 6'b010001
+// `define IOSTANDARD "SB_LVCMOS"
+`define IOSTANDARD "SB_LVCMOS"
+
+// The following IO standards are just aliases for SB_LVCMOS
+// `define IOSTANDARD "SB_LVCMOS25_16"
+// `define IOSTANDARD "SB_LVCMOS25_12"
+// `define IOSTANDARD "SB_LVCMOS25_8"
+// `define IOSTANDARD "SB_LVCMOS25_4"
+// `define IOSTANDARD "SB_LVCMOS18_10"
+// `define IOSTANDARD "SB_LVCMOS18_8"
+// `define IOSTANDARD "SB_LVCMOS18_4"
+// `define IOSTANDARD "SB_LVCMOS18_2"
+// `define IOSTANDARD "SB_LVCMOS15_4"
+// `define IOSTANDARD "SB_LVCMOS15_2"
+// `define IOSTANDARD "SB_MDDR10"
+// `define IOSTANDARD "SB_MDDR8"
+// `define IOSTANDARD "SB_MDDR4"
+// `define IOSTANDARD "SB_MDDR2"
+
+`ifdef CONN_INTERNAL_BITS
+module top (
+ inout pin,
+ input latch_in,
+ input clk_in,
+ input clk_out,
+ input oen,
+ input dout_0,
+ input dout_1,
+ output din_0,
+ output din_1
+);
+`else
+module top(pin);
+ inout pin;
+ wire latch_in = 0;
+ wire clk_in = 0;
+ wire clk_out = 0;
+ wire oen = 0;
+ wire dout_0 = 0;
+ wire dout_1 = 0;
+ wire din_0;
+ wire din_1;
+`endif
+ SB_IO_OD #(
+ .PIN_TYPE(`PINTYPE),
+ .NEG_TRIGGER(1'b0)
+ ) IO_PIN_I (
+ .PACKAGEPIN(pin),
+ .LATCHINPUTVALUE(latch_in),
+ .CLOCKENABLE(clk_en),
+ .INPUTCLK(clk_in),
+ .OUTPUTCLK(clk_out),
+ .OUTPUTENABLE(oen),
+ .DOUT0(dout_0),
+ .DOUT1(dout_1),
+ .DIN0(din_0),
+ .DIN1(din_1)
+ );
+endmodule
diff --git a/icefuzz/tests/sb_mac16.v b/icefuzz/tests/sb_mac16.v
new file mode 100644
index 0000000..c2fd850
--- /dev/null
+++ b/icefuzz/tests/sb_mac16.v
@@ -0,0 +1,65 @@
+module top(
+ input clk,
+ input rst,
+ input [7:0] a,
+ input [7:0] b,
+ output [15:0] y);
+ wire co;
+ wire [31:0] out;
+ SB_MAC16 i_sbmac16
+ (
+ .A(a),
+ .B(b),
+ .C(8'd0),
+ .D(8'd0),
+ .O(out),
+ .CLK(clk),
+ .IRSTTOP(rst),
+ .IRSTBOT(rst),
+ .ORSTTOP(rst),
+ .ORSTBOT(rst),
+ .AHOLD(1'b0),
+ .BHOLD(1'b0),
+ .CHOLD(1'b0),
+ .DHOLD(1'b0),
+ .OHOLDTOP(1'b0),
+ .OHOLDBOT(1'b0),
+ .OLOADTOP(1'b0),
+ .OLOADBOT(1'b0),
+ .ADDSUBTOP(1'b0),
+ .ADDSUBBOT(1'b0),
+ .CO(co),
+ .CI(1'b0),
+ .ACCUMCI(),
+ .ACCUMCO(),
+ .SIGNEXTIN(),
+ .SIGNEXTOUT()
+ );
+
+//Config: mult_8x8_pipeline_unsigned
+
+defparam i_sbmac16. B_SIGNED = 1'b0;
+defparam i_sbmac16. A_SIGNED = 1'b0;
+defparam i_sbmac16. MODE_8x8 = 1'b1;
+
+defparam i_sbmac16. BOTADDSUB_CARRYSELECT = 2'b00;
+defparam i_sbmac16. BOTADDSUB_UPPERINPUT = 1'b0;
+defparam i_sbmac16. BOTADDSUB_LOWERINPUT = 2'b00;
+defparam i_sbmac16. BOTOUTPUT_SELECT = 2'b10;
+
+defparam i_sbmac16. TOPADDSUB_CARRYSELECT = 2'b00;
+defparam i_sbmac16. TOPADDSUB_UPPERINPUT = 1'b0;
+defparam i_sbmac16. TOPADDSUB_LOWERINPUT = 2'b00;
+defparam i_sbmac16. TOPOUTPUT_SELECT = 2'b10;
+
+defparam i_sbmac16. PIPELINE_16x16_MULT_REG2 = 1'b0;
+defparam i_sbmac16. PIPELINE_16x16_MULT_REG1 = 1'b1;
+defparam i_sbmac16. BOT_8x8_MULT_REG = 1'b1;
+defparam i_sbmac16. TOP_8x8_MULT_REG = 1'b1;
+defparam i_sbmac16. D_REG = 1'b0;
+defparam i_sbmac16. B_REG = 1'b1;
+defparam i_sbmac16. A_REG = 1'b1;
+defparam i_sbmac16. C_REG = 1'b0;
+
+assign y = out[15:0];
+endmodule \ No newline at end of file
diff --git a/icefuzz/tests/sb_rgba_drv.pcf b/icefuzz/tests/sb_rgba_drv.pcf
new file mode 100644
index 0000000..94515d2
--- /dev/null
+++ b/icefuzz/tests/sb_rgba_drv.pcf
@@ -0,0 +1,3 @@
+set_io r_led 39
+set_io g_led 40
+set_io b_led 41
diff --git a/icefuzz/tests/sb_rgba_drv.v b/icefuzz/tests/sb_rgba_drv.v
new file mode 100644
index 0000000..e5a0c36
--- /dev/null
+++ b/icefuzz/tests/sb_rgba_drv.v
@@ -0,0 +1,32 @@
+module top(
+ input r_in,
+ input g_in,
+ input b_in,
+ output r_led,
+ output g_led,
+ output b_led);
+
+ wire curren;
+ wire rgbleden;
+
+ SB_RGBA_DRV RGBA_DRIVER (
+ .CURREN(curren),
+ .RGBLEDEN(rgbleden),
+ .RGB0PWM(r_in),
+ .RGB1PWM(r_in),
+ .RGB2PWM(r_in),
+ .RGB0(r_led),
+ .RGB1(g_led),
+ .RGB2(b_led)
+ );
+
+defparam RGBA_DRIVER.CURRENT_MODE = "0b0";
+defparam RGBA_DRIVER.RGB0_CURRENT = "0b000011";
+defparam RGBA_DRIVER.RGB1_CURRENT = "0b001111";
+defparam RGBA_DRIVER.RGB2_CURRENT = "0b111111";
+
+assign curren = 1'b1;
+assign rgbleden = 1'b1;
+
+
+endmodule \ No newline at end of file
diff --git a/icefuzz/tests/sb_spram256ka.v b/icefuzz/tests/sb_spram256ka.v
new file mode 100644
index 0000000..e1e1403
--- /dev/null
+++ b/icefuzz/tests/sb_spram256ka.v
@@ -0,0 +1,25 @@
+module top(
+ input clk,
+ input [13:0] addr,
+ input [7:0] din,
+ input wren,
+ input cs,
+ output [7:0] dout
+);
+
+SB_SPRAM256KA spram_i
+ (
+ .ADDRESS(addr),
+ .DATAIN(din),
+ .MASKWREN(4'b1111),
+ .WREN(wren),
+ .CHIPSELECT(cs),
+ .CLOCK(clk),
+ .STANDBY(1'b0),
+ .SLEEP(1'b0),
+ .POWEROFF(1'b0),
+ .DATAOUT(dout)
+ );
+
+
+endmodule \ No newline at end of file