From 25ad7a24b96b021c6ab25e275059e20187b4f882 Mon Sep 17 00:00:00 2001 From: David Shah Date: Tue, 14 Nov 2017 14:06:38 +0000 Subject: 5k RGB driver reverse engineered --- icefuzz/tests/rgba_drv_cbit/.gitignore | 1 + icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py | 174 +++++++++++++++++++++ icefuzz/tests/rgba_drv_cbit/rgba_drv_data_up5k.txt | 20 +++ 3 files changed, 195 insertions(+) create mode 100644 icefuzz/tests/rgba_drv_cbit/.gitignore create mode 100755 icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py create mode 100644 icefuzz/tests/rgba_drv_cbit/rgba_drv_data_up5k.txt (limited to 'icefuzz/tests/rgba_drv_cbit') diff --git a/icefuzz/tests/rgba_drv_cbit/.gitignore b/icefuzz/tests/rgba_drv_cbit/.gitignore new file mode 100644 index 0000000..68b6394 --- /dev/null +++ b/icefuzz/tests/rgba_drv_cbit/.gitignore @@ -0,0 +1 @@ +work_rgba_drv/ \ No newline at end of file diff --git a/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py b/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py new file mode 100755 index 0000000..a7e2006 --- /dev/null +++ b/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python3 + +import os, sys +# SB_RGBA_DRV automatic fuzzing script + +device = "up5k" + +# SB_RGBA_DRV 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 + + +fuzz_bits = [ + "RGB0_CURRENT_0", + "RGB0_CURRENT_1", + "RGB0_CURRENT_2", + "RGB0_CURRENT_3", + "RGB0_CURRENT_4", + "RGB0_CURRENT_5", + + "RGB1_CURRENT_0", + "RGB1_CURRENT_1", + "RGB1_CURRENT_2", + "RGB1_CURRENT_3", + "RGB1_CURRENT_4", + "RGB1_CURRENT_5", + + "RGB2_CURRENT_0", + "RGB2_CURRENT_1", + "RGB2_CURRENT_2", + "RGB2_CURRENT_3", + "RGB2_CURRENT_4", + "RGB2_CURRENT_5", + + "CURRENT_MODE" +] + + +# Boilerplate code based on the icefuzz script +code_prefix = """ +module top( + input curren, + input rgbleden, + input r_in, + input g_in, + input b_in, + output r_led, + output g_led, + output b_led); +""" + +def get_param_value(param_name, param_size, fuzz_bit): + param = "\"0b"; + #In the RGB driver, once bit i of a current parameter is set i-1..0 must also be set + is_high = False + for i in range(param_size - 1, -1, -1): + if fuzz_bit == param_name + "_" + str(i) or (i == 0 and fuzz_bit == "CURRENT_MODE") or is_high: + param += '1' + is_high = True + else: + param += '0' + param += "\"" + return param +def inst_rgba(fuzz_bit): + v = "" + v += """SB_RGBA_DRV rgba_inst ( + .CURREN(curren), + .RGBLEDEN(rgbleden), + .RGB0PWM(r_in), + .RGB1PWM(g_in), + .RGB2PWM(b_in), + .RGB0(r_led), + .RGB1(g_led), + .RGB2(b_led) + );""" + + v += "defparam rgba_inst.CURRENT_MODE = " + get_param_value("CURRENT_MODE", 1, fuzz_bit) + ";\n" + v += "defparam rgba_inst.RGB0_CURRENT = " + get_param_value("RGB0_CURRENT", 6, fuzz_bit) + ";\n" + v += "defparam rgba_inst.RGB1_CURRENT = " + get_param_value("RGB1_CURRENT", 6, fuzz_bit) + ";\n" + v += "defparam rgba_inst.RGB2_CURRENT = " + get_param_value("RGB2_CURRENT", 6, fuzz_bit) + ";\n" + + return v; + +def make_vlog(fuzz_bit): + vlog = code_prefix + vlog += inst_rgba(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 config 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 +rgba_drv_en_bit = { + "up5k" : (0, 28, 5) +} + +#Return a list of RGBA_DRIVER 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].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.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, \"CBIT_%d\")" % bit + +#The main fuzzing function +def do_fuzz(): + if not os.path.exists("./work_rgba_drv"): + os.mkdir("./work_rgba_drv") + known_bits.append(rgba_drv_en_bit[device]) + with open("rgba_drv_data_" + device + ".txt", 'w') as dat: + for fuzz_bit in fuzz_bits: + vlog = make_vlog(fuzz_bit) + with open("./work_rgba_drv/rgba_drv.v", 'w') as f: + f.write(vlog) + with open("./work_rgba_drv/rgba_drv.pcf", 'w') as f: + f.write(""" +set_io r_led 39 +set_io g_led 40 +set_io b_led 41 + """) + retval = os.system("bash ../../icecube.sh -" + device + " ./work_rgba_drv/rgba_drv.v > ./work_rgba_drv/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_rgba_drv/rgba_drv.asc > ./work_rgba_drv/rgba_drv.exp") + if retval != 0: + sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n') + sys.exit(1) + rgba_bits = parse_exp("./work_rgba_drv/rgba_drv.exp") + new_bits = [] + for set_bit in rgba_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 == "RGB0_CURRENT_0": + print(("\"RGBA_DRV_EN\":").ljust(24) + bit_to_str(rgba_drv_en_bit[device]) + ",") + dat.write(("\"RGBA_DRV_EN\":").ljust(24) + bit_to_str(rgba_drv_en_bit[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/rgba_drv_cbit/rgba_drv_data_up5k.txt b/icefuzz/tests/rgba_drv_cbit/rgba_drv_data_up5k.txt new file mode 100644 index 0000000..73bfb90 --- /dev/null +++ b/icefuzz/tests/rgba_drv_cbit/rgba_drv_data_up5k.txt @@ -0,0 +1,20 @@ +"RGBA_DRV_EN": (0, 28, "CBIT_5"), +"RGB0_CURRENT_0": (0, 28, "CBIT_6"), +"RGB0_CURRENT_1": (0, 28, "CBIT_7"), +"RGB0_CURRENT_2": (0, 29, "CBIT_0"), +"RGB0_CURRENT_3": (0, 29, "CBIT_1"), +"RGB0_CURRENT_4": (0, 29, "CBIT_2"), +"RGB0_CURRENT_5": (0, 29, "CBIT_3"), +"RGB1_CURRENT_0": (0, 29, "CBIT_4"), +"RGB1_CURRENT_1": (0, 29, "CBIT_5"), +"RGB1_CURRENT_2": (0, 29, "CBIT_6"), +"RGB1_CURRENT_3": (0, 29, "CBIT_7"), +"RGB1_CURRENT_4": (0, 30, "CBIT_0"), +"RGB1_CURRENT_5": (0, 30, "CBIT_1"), +"RGB2_CURRENT_0": (0, 30, "CBIT_2"), +"RGB2_CURRENT_1": (0, 30, "CBIT_3"), +"RGB2_CURRENT_2": (0, 30, "CBIT_4"), +"RGB2_CURRENT_3": (0, 30, "CBIT_5"), +"RGB2_CURRENT_4": (0, 30, "CBIT_6"), +"RGB2_CURRENT_5": (0, 30, "CBIT_7"), +"CURRENT_MODE": (0, 28, "CBIT_4"), -- cgit v1.2.3 From da7a2a9d0db95d6a172286eaddd6e930a27ea752 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 20 Nov 2017 09:43:54 +0000 Subject: Fix whitespace and a couple of typos --- examples/up5k_mac16/mac16.pcf | 2 +- examples/up5k_mac16/mac16.v | 2 +- examples/up5k_rgb/rgb.pcf | 2 +- examples/up5k_rgb/rgb.v | 2 +- icebox/icebox.py | 6 +++--- icefuzz/tests/dsp_cbit/.gitignore | 2 +- icefuzz/tests/rgba_drv_cbit/.gitignore | 2 +- icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py | 2 +- icefuzz/tests/spram/.gitignore | 2 +- icefuzz/tests/spram/fuzz_spram.py | 2 +- icepack/icepack.cc | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) (limited to 'icefuzz/tests/rgba_drv_cbit') diff --git a/examples/up5k_mac16/mac16.pcf b/examples/up5k_mac16/mac16.pcf index 24b9b45..5e21181 100644 --- a/examples/up5k_mac16/mac16.pcf +++ b/examples/up5k_mac16/mac16.pcf @@ -1,4 +1,4 @@ set_io clk 44 set_io rstn 27 set_io LED1 12 -set_io LED2 13 \ No newline at end of file +set_io LED2 13 diff --git a/examples/up5k_mac16/mac16.v b/examples/up5k_mac16/mac16.v index 73740e3..0323fc3 100644 --- a/examples/up5k_mac16/mac16.v +++ b/examples/up5k_mac16/mac16.v @@ -68,4 +68,4 @@ assign LED2 = 1'b0; -endmodule \ No newline at end of file +endmodule diff --git a/examples/up5k_rgb/rgb.pcf b/examples/up5k_rgb/rgb.pcf index cfdb874..0954260 100644 --- a/examples/up5k_rgb/rgb.pcf +++ b/examples/up5k_rgb/rgb.pcf @@ -1,3 +1,3 @@ set_io RGB0 39 set_io RGB1 40 -set_io RGB2 41 \ No newline at end of file +set_io RGB2 41 diff --git a/examples/up5k_rgb/rgb.v b/examples/up5k_rgb/rgb.v index c83b943..81920cb 100644 --- a/examples/up5k_rgb/rgb.v +++ b/examples/up5k_rgb/rgb.v @@ -78,4 +78,4 @@ defparam RGBA_DRIVER.RGB1_CURRENT = "0b000011"; defparam RGBA_DRIVER.RGB2_CURRENT = "0b000011"; -endmodule \ No newline at end of file +endmodule diff --git a/icebox/icebox.py b/icebox/icebox.py index 6b0dfd8..5e94f31 100644 --- a/icebox/icebox.py +++ b/icebox/icebox.py @@ -642,7 +642,7 @@ class iceconfig: if s[0] == 0 and s[1] == 0: if direction == "l": s = (0, 1, vert_net) if direction == "b": s = (1, 0, horz_net) - + if s[0] == self.max_x and s[1] == self.max_y: if direction == "r": s = (self.max_x, self.max_y-1, vert_net) if direction == "t": s = (self.max_x-1, self.max_y, horz_net) @@ -677,11 +677,11 @@ class iceconfig: if s[0] == 0 and s[1] == self.max_y: if direction == "l": s = (0, self.max_y-1, vert_net) if direction == "t": s = (1, self.max_y, horz_net) - + if s[0] == self.max_x and s[1] == 0: if direction == "r": s = (self.max_x, 1, vert_net) if direction == "b": s = (self.max_x-1, 0, horz_net) - + if self.tile_has_net(s[0], s[1], s[2]): neighbours.add((s[0], s[1], s[2])) diff --git a/icefuzz/tests/dsp_cbit/.gitignore b/icefuzz/tests/dsp_cbit/.gitignore index 83d459d..95ff890 100644 --- a/icefuzz/tests/dsp_cbit/.gitignore +++ b/icefuzz/tests/dsp_cbit/.gitignore @@ -1 +1 @@ -work_dsp_cbit/ \ No newline at end of file +work_dsp_cbit/ diff --git a/icefuzz/tests/rgba_drv_cbit/.gitignore b/icefuzz/tests/rgba_drv_cbit/.gitignore index 68b6394..a0beeed 100644 --- a/icefuzz/tests/rgba_drv_cbit/.gitignore +++ b/icefuzz/tests/rgba_drv_cbit/.gitignore @@ -1 +1 @@ -work_rgba_drv/ \ No newline at end of file +work_rgba_drv/ diff --git a/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py b/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py index a7e2006..3d43ba4 100755 --- a/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py +++ b/icefuzz/tests/rgba_drv_cbit/fuzz_rgba_drv_cbit.py @@ -171,4 +171,4 @@ set_io b_led 41 dat.write(("\"RGBA_DRV_EN\":").ljust(24) + bit_to_str(rgba_drv_en_bit[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 +do_fuzz() diff --git a/icefuzz/tests/spram/.gitignore b/icefuzz/tests/spram/.gitignore index c6ebe02..7ce4577 100644 --- a/icefuzz/tests/spram/.gitignore +++ b/icefuzz/tests/spram/.gitignore @@ -1 +1 @@ -work_spram/ \ No newline at end of file +work_spram/ diff --git a/icefuzz/tests/spram/fuzz_spram.py b/icefuzz/tests/spram/fuzz_spram.py index a92a361..05fd828 100755 --- a/icefuzz/tests/spram/fuzz_spram.py +++ b/icefuzz/tests/spram/fuzz_spram.py @@ -171,4 +171,4 @@ with open(device + "_spram_data.txt", "w") as f: for cnet in data[net]: cnets.append("(%d, %d, \"%s\")" % cnet) print("\t\t%s %s, " % (("\"" + net.replace("[","_").replace("]","") + "\":").ljust(24), " ".join(cnets)), file=f) - print("\t},", file=f) \ No newline at end of file + print("\t},", file=f) diff --git a/icepack/icepack.cc b/icepack/icepack.cc index fd3050e..b67241f 100644 --- a/icepack/icepack.cc +++ b/icepack/icepack.cc @@ -1013,7 +1013,7 @@ vector FpgaConfig::chip_cols() const { if (this->device == "384") return vector({18, 54, 54, 54, 54}); if (this->device == "1k") return vector({18, 54, 54, 42, 54, 54, 54}); - // Its ipconect or Mutiplier block, five logic, ram, six logic. + // Its IPConnect or Mutiplier block, five logic, ram, six logic. if (this->device == "5k") return vector({54, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54}); if (this->device == "8k") return vector({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()); @@ -1022,7 +1022,7 @@ vector 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 ipconect or DSP tiles + // The sides on the 5k devices are IPConnect or DSP tiles if (this->device == "5k" && (x == 0 || x == this->chip_width()+1)) { if( (y == 5) || (y == 10) || (y == 15) || (y == 23)) //check ordering here, tile 23-26 might be reversed return "dsp0"; -- cgit v1.2.3