diff options
author | Nils Albartus <nils.albartus@rub.de> | 2020-12-04 16:47:05 +0100 |
---|---|---|
committer | Nils Albartus <nils.albartus@rub.de> | 2020-12-04 16:47:05 +0100 |
commit | d969c333d036e7f9f6fb62e1d3d5a0a77bcf1432 (patch) | |
tree | 93c141c007aadb8c6715160f2611f9f436411ff2 /icefuzz | |
parent | da52117ccd5b4147f64dc7345357ec5439cd7543 (diff) | |
download | icestorm-d969c333d036e7f9f6fb62e1d3d5a0a77bcf1432.tar.gz icestorm-d969c333d036e7f9f6fb62e1d3d5a0a77bcf1432.tar.bz2 icestorm-d969c333d036e7f9f6fb62e1d3d5a0a77bcf1432.zip |
added I2C and SPI for u4k to database
Diffstat (limited to 'icefuzz')
-rwxr-xr-x | icefuzz/tests/ip/trace_ip_u4k.py | 347 | ||||
-rw-r--r-- | icefuzz/tests/ip/u4k_I2C_data.txt | 84 | ||||
-rw-r--r-- | icefuzz/tests/ip/u4k_SPI_data.txt | 108 |
3 files changed, 539 insertions, 0 deletions
diff --git a/icefuzz/tests/ip/trace_ip_u4k.py b/icefuzz/tests/ip/trace_ip_u4k.py new file mode 100755 index 0000000..8e94faf --- /dev/null +++ b/icefuzz/tests/ip/trace_ip_u4k.py @@ -0,0 +1,347 @@ +#!/usr/bin/env python3 + +import os, sys, re + +device = "u4k" + +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".split() +#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 is the master IP reverse engineering script for three similar IPs: I2C, SPI +ip_types = ["I2C", "SPI"] +ip_locs = { } +ip_locs["I2C"] = [(0, 21, 0), (25, 21, 0)] +ip_locs["SPI"] = [(0, 0, 0), (25, 0, 1)] +#spram_locs = [(0, 0, 1)] +ip_data = { } + +#up5k +# ip_types = ["I2C", "SPI", "LEDDA_IP"] +# ip_locs = { } +# ip_locs["I2C"] = [(0, 31, 0), (25, 31, 0)] +# ip_locs["SPI"] = [(0, 0, 0), (25, 0, 1)] +# ip_locs["LEDDA_IP"] = [(0, 31, 2)] +# #spram_locs = [(0, 0, 1)] +# ip_data = { } + +#signals[x][0] -> inputs, signals[x][1] ->outputs +ip_signals = {} +ip_signals["I2C"] = [["SBCLKI", "SBRWI", "SBSTBI", "SCLI", "SDAI"], + ["SBACKO", "I2CIRQ", "I2CWKUP", "SCLO", "SCLOE", "SDAO", "SDAOE"]] +ip_signals["SPI"] = [["SBCLKI", "SBRWI", "SBSTBI", "MI", "SI", "SCKI", "SCSNI"], + ["SBACKO", "SPIIRQ", "SPIWKUP", "SO", "SOE", "MO", "MOE", "SCKO", "SCKOE"]] + +fixed_cbits = {} + +fixed_cbits[("I2C", (0, 21, 0))] = ["BUS_ADDR74_0", "I2C_SLAVE_INIT_ADDR_0"] +fixed_cbits[("I2C", (25, 21, 0))] = ["BUS_ADDR74_0", "BUS_ADDR74_1", "I2C_SLAVE_INIT_ADDR_1"] + +fixed_cbits[("SPI", (0, 0, 0))] = [] +fixed_cbits[("SPI", (25, 0, 1))] = ["BUS_ADDR74_1"] # WARNING: this is documented as BUS_ADDR74_0, but this is wrong and will cause icecube to fail. May be the same across devices + +#up5k +# fixed_cbits[("I2C", (0, 31, 0))] = ["BUS_ADDR74_0", "I2C_SLAVE_INIT_ADDR_0"] +# fixed_cbits[("I2C", (25, 31, 0))] = ["BUS_ADDR74_0", "BUS_ADDR74_1", "I2C_SLAVE_INIT_ADDR_1"] + +# fixed_cbits[("SPI", (0, 10, 0))] = [] +# fixed_cbits[("SPI", (25, 10, 1))] = ["BUS_ADDR74_1"] # WARNING: this is documented as BUS_ADDR74_0, but this is wrong and will cause icecube to fail. May be the same across devices + +fuzz_cbits = {} +fuzz_cbits["I2C"] = ["SDA_INPUT_DELAYED", "SDA_OUTPUT_DELAYED"] + +# Don't add slave address to the list, despite confusing primitive declaration, +# it's only set in registers not the bitstream + +#for i in range(2, 10): + #fuzz_cbits["I2C"].append("I2C_SLAVE_INIT_ADDR_%d" % i) + +for i in range(8): + ip_signals["I2C"][0].append("SBADRI%d" % i) + ip_signals["SPI"][0].append("SBADRI%d" % i) + +for i in range(8): + ip_signals["I2C"][0].append("SBDATI%d" % i) + ip_signals["SPI"][0].append("SBDATI%d" % i) + +for i in range(8): + ip_signals["I2C"][1].append("SBDATO%d" % i) + ip_signals["SPI"][1].append("SBDATO%d" % i) + +for i in range(4): + ip_signals["SPI"][1].append("MCSNO%d" % i) + ip_signals["SPI"][1].append("MCSNOE%d" % i) + +fuzz_net_options = {} +fuzz_net_options["I2C"] = ["SBADRI", "SBDATI", "SBDATO"] +fuzz_net_options["SPI"] = ["SBADRI", "SBDATI", "SBDATO", "MCSN"] + +available_cbits = {} +available_cbits["I2C"] = [("BUS_ADDR74", 4), ("I2C_SLAVE_INIT_ADDR", 10)] +available_cbits["SPI"] = [("BUS_ADDR74", 4)] + +# Return a param value in "Lattice style" +def get_param_value(param_size, param_name, set_cbits): + val = "\"0b" + for i in range(param_size): + if param_name + "_" + str((param_size - 1) - i) in set_cbits: + val += "1" + else: + val += "0" + val += "\"" + return val + +# Build the output files for a given IP and config, returning +# the pin2net map +def make_ip(ip_type, ip_loc, fuzz_opt, set_cbits): + used_inputs = [ ] + used_outputs = [ ] + for insig in ip_signals[ip_type][0]: + ignore = False + for o in fuzz_net_options[ip_type]: + if o != fuzz_opt and insig.startswith(o): + ignore = True + if not ignore: + used_inputs.append(insig) + for outsig in ip_signals[ip_type][1]: + ignore = False + for o in fuzz_net_options[ip_type]: + if o != fuzz_opt and outsig.startswith(o): + ignore = True + if not ignore: + used_outputs.append(outsig) + all_sigs = used_inputs + used_outputs + all_cbits = set() + all_cbits.update(set_cbits) + if (ip_type, ip_loc) in fixed_cbits: + all_cbits.update(fixed_cbits[(ip_type, ip_loc)]) + with open("./work_ip/ip.v", "w") as f: + print("module top(", file=f) + for s in used_inputs: + print("input %s," % s, file=f) + for s in used_outputs[:-1]: + print("output %s," % s, file=f) + print("output %s);" % used_outputs[-1], file=f) + print("SB_%s" % ip_type, file=f) + if ip_type in available_cbits: + print("\t#(", file=f) + for p in available_cbits[ip_type]: + name, width = p + comma = "," if p != available_cbits[ip_type][-1] else "" + print("\t\t.%s(%s)%s" % (name, get_param_value(width, name, all_cbits), comma), file=f) + print("\t)", file=f) + print("\tip_inst (",file=f) + for sig in all_sigs[:-1]: + print("\t\t.%s(%s)," % (sig, sig), file=f) + print("\t\t.%s(%s)" % (all_sigs[-1], all_sigs[-1]), file=f) + print("\t)", file=f) + if "SDA_INPUT_DELAYED" in all_cbits: + print("\t/* synthesis SDA_INPUT_DELAYED=1 */", file=f) + else: + print("\t/* synthesis SDA_INPUT_DELAYED=0 */", file=f) + if "SDA_OUTPUT_DELAYED" in all_cbits: + print("\t/* synthesis SDA_OUTPUT_DELAYED=1 */", file=f) + else: + print("\t/* synthesis SDA_OUTPUT_DELAYED=0 */", file=f) + print(";", file=f) + print("endmodule", file=f) + pin2net = {} + with open("./work_ip/ip.pcf","w") as f: + temp_pins = list(pins) + for sig in all_sigs: + 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 ip_inst %d %d %d" % ip_loc, file=f) + return pin2net + +def check_for_pin_assignment(pin): + out = None + with open("./work_ip/ip.vlog", "r") as f: + for l in f: + if l.startswith("assign pin_{}".format(pin)): + rhs = l.split("=") + o_cen = rhs[1].split(" ")[1] + out = rhs[1].split(" ")[3] + + return out + +#Parse the output of an icebox vlog file to determine connectivity +def parse_vlog(f, pin2net, net_map): + wires_to_check = dict() + + current_net = None + + for line in f: + if line == "\n": + current_net = None + + 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 + + #search for assignment + data_input = check_for_pin_assignment(pin) + if data_input: + wires_to_check[data_input] = pin + + 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)) + + f.seek(0) + for line in f: + if line == "\n": + current_net = None + + m = re.match(r"wire ([a-zA-Z0-9]+);", line) + if m: + net = m.group(1) + if net in wires_to_check: + pin = wires_to_check[net] + 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": + bits.add((current_x, current_y, splitline[1].strip())) + return bits + +if not os.path.exists("./work_ip"): + os.mkdir("./work_ip") +for ip in ip_types: + ip_data[ip] = {} + for loc in ip_locs[ip]: + x, y, z = loc + net_cbit_map = {} + init_cbits = [] + for sig in ip_signals[ip][0]: + net_cbit_map[sig] = set() + for sig in ip_signals[ip][1]: + net_cbit_map[sig] = set() + first = True + for state in ["FUZZ_NETS", "FUZZ_CBITS"]: + fuzz_options = None + if state == "FUZZ_NETS": + fuzz_options = fuzz_net_options[ip] + else: + if ip in fuzz_cbits: + fuzz_options = fuzz_cbits[ip] + else: + fuzz_options = [] + for n in fuzz_options: + # if n != "SBDATO": + # continue + print("Fuzzing %s (%d, %d, %d) %s" % (ip, x, y, z, n)) + fuzz_nets = fuzz_net_options[ip][0] + if state == "FUZZ_NETS": + fuzz_nets = n + set_cbits = set() + if state == "FUZZ_CBITS": + set_cbits.add(n) + pin2net = make_ip(ip, loc, fuzz_nets, set_cbits) + retval = os.system("bash ../../icecube.sh -" + device + " ./work_ip/ip.v > ./work_ip/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_ip/ip.asc > ./work_ip/ip.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_ip/ip.asc > ./work_ip/ip.vlog") + if retval != 0: + sys.stderr.write('ERROR: icebox_vlog returned non-zero error code\n') + sys.exit(1) + with open("./work_ip/ip.vlog", "r") as f: + parse_vlog(f, pin2net, net_cbit_map) + bits = [] + with open("./work_ip/ip.exp", "r") as f: + bits = parse_exp(f) + if first: + idx = 0 + for bit in bits: + init_cbits.append(bit) + if len(bits) == 1: + net_cbit_map[ip + "_ENABLE"] = [bit] + else: + net_cbit_map[ip + "_ENABLE_" + str(idx)] = [bit] + idx += 1 + for bit in init_cbits: + if bit not in bits: + bx, by, bn = bit + print('WARNING: while fuzzing %s (%d, %d, %d) bit (%d, %d, %s) has unknown function (not always set)' % + (ip, x, y, z, bx, by, bn)) + new_bits = [] + for bit in bits: + if bit not in init_cbits: + new_bits.append(bit) + if state == "FUZZ_NETS" and len(new_bits) != 0: + for bit in new_bits: + bx, by, bn = bit + print('WARNING: while fuzzing %s (%d, %d, %d) bit (%d, %d, %s) has unknown function (not always set)' % + (ip, x, y, z, bx, by, bn)) + elif state == "FUZZ_CBITS": + if len(new_bits) == 0: + print('WARNING: while fuzzing %s (%d, %d, %d) param %s causes no change' % + (ip, x, y, z, n)) + else: + idx = 0 + for bit in new_bits: + if len(new_bits) == 1: + net_cbit_map[n] = [bit] + else: + net_cbit_map[n + "_" + str(idx)] = [bit] + idx += 1 + first = False + # if n == "SBDATO": + # exit() + ip_data[ip][loc] = net_cbit_map + + with open(device + "_" + ip + "_data.txt", "w") as f: + for loc in ip_data[ip]: + x, y, z = loc + print("\t(\"%s\", (%d, %d, %d)): {" % (ip, x, y, z), file=f) + data = ip_data[ip][loc] + for net in sorted(data): + cnets = [] + 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) diff --git a/icefuzz/tests/ip/u4k_I2C_data.txt b/icefuzz/tests/ip/u4k_I2C_data.txt new file mode 100644 index 0000000..6338608 --- /dev/null +++ b/icefuzz/tests/ip/u4k_I2C_data.txt @@ -0,0 +1,84 @@ + ("I2C", (0, 21, 0)): { + "I2CIRQ": (0, 20, "slf_op_7"), + "I2CWKUP": (0, 19, "slf_op_5"), + "I2C_ENABLE_0": (13, 21, "cbit2usealt_in_0"), + "I2C_ENABLE_1": (12, 21, "cbit2usealt_in_1"), + "SBACKO": (0, 20, "slf_op_6"), + "SBADRI0": (0, 20, "lutff_1/in_0"), + "SBADRI1": (0, 20, "lutff_2/in_0"), + "SBADRI2": (0, 20, "lutff_3/in_0"), + "SBADRI3": (0, 20, "lutff_4/in_0"), + "SBADRI4": (0, 20, "lutff_5/in_0"), + "SBADRI5": (0, 20, "lutff_6/in_0"), + "SBADRI6": (0, 20, "lutff_7/in_0"), + "SBADRI7": (0, 19, "lutff_2/in_0"), + "SBCLKI": (0, 20, "clk"), + "SBDATI0": (0, 19, "lutff_5/in_0"), + "SBDATI1": (0, 19, "lutff_6/in_0"), + "SBDATI2": (0, 19, "lutff_7/in_0"), + "SBDATI3": (0, 20, "lutff_0/in_3"), + "SBDATI4": (0, 20, "lutff_5/in_1"), + "SBDATI5": (0, 20, "lutff_6/in_1"), + "SBDATI6": (0, 20, "lutff_7/in_1"), + "SBDATI7": (0, 20, "lutff_0/in_0"), + "SBDATO0": (0, 19, "slf_op_6"), + "SBDATO1": (0, 19, "slf_op_7"), + "SBDATO2": (0, 20, "slf_op_0"), + "SBDATO3": (0, 20, "slf_op_1"), + "SBDATO4": (0, 20, "slf_op_2"), + "SBDATO5": (0, 20, "slf_op_3"), + "SBDATO6": (0, 20, "slf_op_4"), + "SBDATO7": (0, 20, "slf_op_5"), + "SBRWI": (0, 19, "lutff_4/in_0"), + "SBSTBI": (0, 19, "lutff_3/in_0"), + "SCLI": (0, 19, "lutff_2/in_1"), + "SCLO": (0, 19, "slf_op_3"), + "SCLOE": (0, 19, "slf_op_4"), + "SDAI": (0, 19, "lutff_1/in_1"), + "SDAO": (0, 19, "slf_op_1"), + "SDAOE": (0, 19, "slf_op_2"), + "SDA_INPUT_DELAYED": (12, 21, "SDA_input_delay"), + "SDA_OUTPUT_DELAYED": (12, 21, "SDA_output_delay"), + }, + ("I2C", (25, 21, 0)): { + "I2CIRQ": (25, 20, "slf_op_7"), + "I2CWKUP": (25, 19, "slf_op_5"), + "I2C_ENABLE_0": (19, 21, "cbit2usealt_in_1"), + "I2C_ENABLE_1": (19, 21, "cbit2usealt_in_0"), + "SBACKO": (25, 20, "slf_op_6"), + "SBADRI0": (25, 20, "lutff_1/in_0"), + "SBADRI1": (25, 20, "lutff_2/in_0"), + "SBADRI2": (25, 20, "lutff_3/in_0"), + "SBADRI3": (25, 20, "lutff_4/in_0"), + "SBADRI4": (25, 20, "lutff_5/in_0"), + "SBADRI5": (25, 20, "lutff_6/in_0"), + "SBADRI6": (25, 20, "lutff_7/in_0"), + "SBADRI7": (25, 19, "lutff_2/in_0"), + "SBCLKI": (25, 20, "clk"), + "SBDATI0": (25, 19, "lutff_5/in_0"), + "SBDATI1": (25, 19, "lutff_6/in_0"), + "SBDATI2": (25, 19, "lutff_7/in_0"), + "SBDATI3": (25, 20, "lutff_0/in_3"), + "SBDATI4": (25, 20, "lutff_5/in_1"), + "SBDATI5": (25, 20, "lutff_6/in_1"), + "SBDATI6": (25, 20, "lutff_7/in_1"), + "SBDATI7": (25, 20, "lutff_0/in_0"), + "SBDATO0": (25, 19, "slf_op_6"), + "SBDATO1": (25, 19, "slf_op_7"), + "SBDATO2": (25, 20, "slf_op_0"), + "SBDATO3": (25, 20, "slf_op_1"), + "SBDATO4": (25, 20, "slf_op_2"), + "SBDATO5": (25, 20, "slf_op_3"), + "SBDATO6": (25, 20, "slf_op_4"), + "SBDATO7": (25, 20, "slf_op_5"), + "SBRWI": (25, 19, "lutff_4/in_0"), + "SBSTBI": (25, 19, "lutff_3/in_0"), + "SCLI": (25, 19, "lutff_2/in_1"), + "SCLO": (25, 19, "slf_op_3"), + "SCLOE": (25, 19, "slf_op_4"), + "SDAI": (25, 19, "lutff_1/in_1"), + "SDAO": (25, 19, "slf_op_1"), + "SDAOE": (25, 19, "slf_op_2"), + "SDA_INPUT_DELAYED": (19, 21, "SDA_input_delay"), + "SDA_OUTPUT_DELAYED": (19, 21, "SDA_output_delay"), + }, diff --git a/icefuzz/tests/ip/u4k_SPI_data.txt b/icefuzz/tests/ip/u4k_SPI_data.txt new file mode 100644 index 0000000..b6463a7 --- /dev/null +++ b/icefuzz/tests/ip/u4k_SPI_data.txt @@ -0,0 +1,108 @@ + ("SPI", (0, 0, 0)): { + "MCSNO0": (0, 3, "slf_op_1"), + "MCSNO1": (0, 3, "slf_op_3"), + "MCSNO2": (0, 3, "slf_op_6"), + "MCSNO3": (0, 4, "slf_op_0"), + "MCSNOE0": (0, 3, "slf_op_2"), + "MCSNOE1": (0, 3, "slf_op_4"), + "MCSNOE2": (0, 3, "slf_op_7"), + "MCSNOE3": (0, 4, "slf_op_1"), + "MI": (0, 2, "lutff_0/in_1"), + "MO": (0, 2, "slf_op_5"), + "MOE": (0, 2, "slf_op_6"), + "SBACKO": (0, 2, "slf_op_0"), + "SBADRI0": (0, 1, "lutff_1/in_1"), + "SBADRI1": (0, 1, "lutff_2/in_1"), + "SBADRI2": (0, 2, "lutff_0/in_3"), + "SBADRI3": (0, 2, "lutff_1/in_3"), + "SBADRI4": (0, 2, "lutff_2/in_3"), + "SBADRI5": (0, 2, "lutff_3/in_3"), + "SBADRI6": (0, 2, "lutff_4/in_3"), + "SBADRI7": (0, 2, "lutff_5/in_3"), + "SBCLKI": (0, 1, "clk"), + "SBDATI0": (0, 1, "lutff_1/in_3"), + "SBDATI1": (0, 1, "lutff_2/in_3"), + "SBDATI2": (0, 1, "lutff_3/in_3"), + "SBDATI3": (0, 1, "lutff_4/in_3"), + "SBDATI4": (0, 1, "lutff_5/in_3"), + "SBDATI5": (0, 1, "lutff_6/in_3"), + "SBDATI6": (0, 1, "lutff_7/in_3"), + "SBDATI7": (0, 1, "lutff_0/in_1"), + "SBDATO0": (0, 1, "slf_op_0"), + "SBDATO1": (0, 1, "slf_op_1"), + "SBDATO2": (0, 1, "slf_op_2"), + "SBDATO3": (0, 1, "slf_op_3"), + "SBDATO4": (0, 1, "slf_op_4"), + "SBDATO5": (0, 1, "slf_op_5"), + "SBDATO6": (0, 1, "slf_op_6"), + "SBDATO7": (0, 1, "slf_op_7"), + "SBRWI": (0, 1, "lutff_0/in_3"), + "SBSTBI": (0, 2, "lutff_6/in_3"), + "SCKI": (0, 2, "lutff_1/in_1"), + "SCKO": (0, 2, "slf_op_7"), + "SCKOE": (0, 3, "slf_op_0"), + "SCSNI": (0, 2, "lutff_2/in_1"), + "SI": (0, 2, "lutff_7/in_3"), + "SO": (0, 2, "slf_op_3"), + "SOE": (0, 2, "slf_op_4"), + "SPIIRQ": (0, 2, "slf_op_1"), + "SPIWKUP": (0, 2, "slf_op_2"), + "SPI_ENABLE_0": (7, 0, "cbit2usealt_in_0"), + "SPI_ENABLE_1": (6, 0, "cbit2usealt_in_0"), + "SPI_ENABLE_2": (7, 0, "cbit2usealt_in_1"), + "SPI_ENABLE_3": (6, 0, "cbit2usealt_in_1"), + }, + ("SPI", (25, 0, 1)): { + "MCSNO0": (25, 3, "slf_op_1"), + "MCSNO1": (25, 3, "slf_op_3"), + "MCSNO2": (25, 3, "slf_op_6"), + "MCSNO3": (25, 4, "slf_op_0"), + "MCSNOE0": (25, 3, "slf_op_2"), + "MCSNOE1": (25, 3, "slf_op_4"), + "MCSNOE2": (25, 3, "slf_op_7"), + "MCSNOE3": (25, 4, "slf_op_1"), + "MI": (25, 2, "lutff_0/in_1"), + "MO": (25, 2, "slf_op_5"), + "MOE": (25, 2, "slf_op_6"), + "SBACKO": (25, 2, "slf_op_0"), + "SBADRI0": (25, 1, "lutff_1/in_1"), + "SBADRI1": (25, 1, "lutff_2/in_1"), + "SBADRI2": (25, 2, "lutff_0/in_3"), + "SBADRI3": (25, 2, "lutff_1/in_3"), + "SBADRI4": (25, 2, "lutff_2/in_3"), + "SBADRI5": (25, 2, "lutff_3/in_3"), + "SBADRI6": (25, 2, "lutff_4/in_3"), + "SBADRI7": (25, 2, "lutff_5/in_3"), + "SBCLKI": (25, 1, "clk"), + "SBDATI0": (25, 1, "lutff_1/in_3"), + "SBDATI1": (25, 1, "lutff_2/in_3"), + "SBDATI2": (25, 1, "lutff_3/in_3"), + "SBDATI3": (25, 1, "lutff_4/in_3"), + "SBDATI4": (25, 1, "lutff_5/in_3"), + "SBDATI5": (25, 1, "lutff_6/in_3"), + "SBDATI6": (25, 1, "lutff_7/in_3"), + "SBDATI7": (25, 1, "lutff_0/in_1"), + "SBDATO0": (25, 1, "slf_op_0"), + "SBDATO1": (25, 1, "slf_op_1"), + "SBDATO2": (25, 1, "slf_op_2"), + "SBDATO3": (25, 1, "slf_op_3"), + "SBDATO4": (25, 1, "slf_op_4"), + "SBDATO5": (25, 1, "slf_op_5"), + "SBDATO6": (25, 1, "slf_op_6"), + "SBDATO7": (25, 1, "slf_op_7"), + "SBRWI": (25, 1, "lutff_0/in_3"), + "SBSTBI": (25, 2, "lutff_6/in_3"), + "SCKI": (25, 2, "lutff_1/in_1"), + "SCKO": (25, 2, "slf_op_7"), + "SCKOE": (25, 3, "slf_op_0"), + "SCSNI": (25, 2, "lutff_2/in_1"), + "SI": (25, 2, "lutff_7/in_3"), + "SO": (25, 2, "slf_op_3"), + "SOE": (25, 2, "slf_op_4"), + "SPIIRQ": (25, 2, "slf_op_1"), + "SPIWKUP": (25, 2, "slf_op_2"), + "SPI_ENABLE_0": (24, 0, "cbit2usealt_in_0"), + "SPI_ENABLE_1": (24, 0, "cbit2usealt_in_1"), + "SPI_ENABLE_2": (23, 0, "cbit2usealt_in_0"), + "SPI_ENABLE_3": (23, 0, "cbit2usealt_in_1"), + }, |