| import pytrellis | |
| import nonrouting | |
| from fuzzconfig import FuzzConfig | |
| import fuzzloops | |
| """ | |
| This fuzzer is ***HORRIBLE***, but the interfaces we have access to mean there is no better option. | |
| CIB interconnect tiles have muxes that allow the connections into special function tiles from the CIB can be driven to | |
| constant 0 or 1, as well as from general routing. But there is no way to specify this directly for the CIB connections | |
| (which are named as LUT inputs [A-D][0-7]). So this horrible hack emerges instead, whereby we trace the CIB->EBR | |
| interconnect and drive constants on the EBR instead. We can't treat this as just an EBR configuration as it applies to | |
| all CIBs, including those where this would be difficult to fuzz and location-dependant. So there's probably not much | |
| choice... | |
| """ | |
| # List of all pins to fuzz | |
| fuzz_pins = [ | |
| "JA0", "JA1", "JA2", "JA3", "JA4", "JA5", "JA6", "JA7", | |
| "JB0", "JB1", "JB2", "JB3", "JB4", "JB5", "JB6", "JB7", | |
| "JC0", "JC1", "JC2", "JC3", "JC4", "JC5", "JC6", "JC7", | |
| "JD0", "JD1", "JD2", "JD3", "JD4", "JD5", "JD6", "JD7", | |
| "JCE0", "JCE1", "JCE2", "JCE3", "JCLK0", "JCLK1", "JLSR0", "JLSR1" | |
| ] | |
| cfg = FuzzConfig(job="CIBCONST", family="ECP5", device="LFE5U-25F", ncl="empty.ncl", | |
| tiles=["CIB_R25C26:CIB_EBR", "CIB_R25C27:CIB_EBR", "CIB_R25C28:CIB_EBR"]) | |
| def main(): | |
| pytrellis.load_database("../../../database") | |
| cfg.setup() | |
| empty_bitfile = cfg.build_design(cfg.ncl, {}) | |
| cfg.ncl = "cibconst.ncl" | |
| def per_pin(pin): | |
| def get_substs(sig, val): | |
| if val == pin: | |
| val = "#SIG" | |
| subs = {"sig": sig, "val": val} | |
| return subs | |
| if pin.startswith("JCE"): | |
| options = [pin, "1"] | |
| elif pin.startswith("JCLK") or pin.startswith("JLSR"): | |
| options = [pin, "0"] | |
| else: | |
| options = [pin, "0", "1"] | |
| # Load the EBR database and find the correct signal | |
| ebrdb = pytrellis.get_tile_bitdata( | |
| pytrellis.TileLocator(cfg.family, cfg.device, "MIB_EBR4")) | |
| fconns = ebrdb.get_fixed_conns() | |
| sig = None | |
| for conn in fconns: | |
| if conn.source.endswith(pin): | |
| sig = conn.sink | |
| break | |
| assert sig is not None | |
| # Convert net name to NCL pin name by stripping extraneous content | |
| if sig[0] == "J": | |
| sig = sig[1:] | |
| sig = sig.replace("_EBR", "") | |
| nonrouting.fuzz_enum_setting(cfg, "CIB.{}MUX".format(pin), options, | |
| lambda x: get_substs(sig=sig, val=x), | |
| empty_bitfile, False) | |
| fuzzloops.parallel_foreach(fuzz_pins, per_pin) | |
| if __name__ == "__main__": | |
| main() |