1from fuzzconfig import FuzzConfig
2import nonrouting
3import pytrellis
4import fuzzloops
5
6jobs = [
7    ("R25C22", "EBR0", FuzzConfig(job="EBROUTE0", family="ECP5", device="LFE5U-25F", ncl="empty.ncl",
8                                  tiles=["MIB_R25C22:MIB_EBR0", "MIB_R25C23:MIB_EBR1"])),
9    ("R25C24", "EBR1", FuzzConfig(job="EBROUTE1", family="ECP5", device="LFE5U-25F", ncl="empty.ncl",
10                                  tiles=["MIB_R25C24:MIB_EBR2", "MIB_R25C25:MIB_EBR3", "MIB_R25C26:MIB_EBR4"])),
11    ("R25C26", "EBR2", FuzzConfig(job="EBROUTE2", family="ECP5", device="LFE5U-25F", ncl="empty.ncl",
12                                  tiles=["MIB_R25C26:MIB_EBR4", "MIB_R25C27:MIB_EBR5", "MIB_R25C28:MIB_EBR6"])),
13    ("R25C28", "EBR3", FuzzConfig(job="EBROUTE3", family="ECP5", device="LFE5U-25F", ncl="empty.ncl",
14                                  tiles=["MIB_R25C28:MIB_EBR6", "MIB_R25C29:MIB_EBR7", "MIB_R25C30:MIB_EBR8"])),
15
16]
17
18
19def main():
20    pytrellis.load_database("../../../database")
21
22    def per_job(job):
23        def get_substs(mode, settings, muxes = None):
24            ebrloc = loc
25            if mode == "NONE":
26                # easier to move EBR out the way than remove it
27                ebrloc = "R25C60"
28                mode = "PDPW16KD"
29            if mode == "PDPW16KD" and "DATA_WIDTH_R" not in settings:
30                settings["DATA_WIDTH_R"] = "18"
31            if mode == "PDPW16KD" and "DATA_WIDTH_W" not in settings:
32                settings["DATA_WIDTH_W"] = "36"
33            if mode == "PDPW16KD" and "CSDECODE_W" not in settings:
34                settings["CSDECODE_W"] = "0b111"
35            if mode == "PDPW16KD" and "CSDECODE_R" not in settings:
36                settings["CSDECODE_R"] = "0b111"
37            if mode == "DP16KD" and "CSDECODE_A" not in settings:
38                settings["CSDECODE_A"] = "0b111"
39            if mode == "DP16KD" and "CSDECODE_B" not in settings:
40                settings["CSDECODE_B"] = "0b111"
41            setting_text = ",".join(["{}={}".format(k, v) for k, v in settings.items()])
42            if muxes is not None:
43                setting_text += ":" + ",".join(["{}={}".format(k, v) for k, v in muxes.items()])
44            return dict(loc=ebrloc, mode=mode, settings=setting_text)
45
46        def get_muxval(sig, val):
47            if val == sig:
48                return None
49            elif val == "INV":
50                return {sig: "#INV"}
51            else:
52                assert False
53        loc, ebr, cfg = job
54        cfg.setup()
55        empty_bitfile = cfg.build_design(cfg.ncl, {})
56        cfg.ncl = "ebr.ncl"
57
58        nonrouting.fuzz_enum_setting(cfg, "{}.CLKAMUX".format(ebr), ["CLKA", "INV"],
59                                     lambda x: get_substs("DP16KD", {}, get_muxval("CLKA", x)), empty_bitfile)
60        nonrouting.fuzz_enum_setting(cfg, "{}.CLKBMUX".format(ebr), ["CLKB", "INV"],
61                                     lambda x: get_substs("DP16KD", {}, get_muxval("CLKB", x)), empty_bitfile)
62        nonrouting.fuzz_enum_setting(cfg, "{}.RSTAMUX".format(ebr), ["RSTA", "INV"],
63                                     lambda x: get_substs("DP16KD", {}, get_muxval("RSTA", x)), empty_bitfile)
64        nonrouting.fuzz_enum_setting(cfg, "{}.RSTBMUX".format(ebr), ["RSTB", "INV"],
65                                     lambda x: get_substs("DP16KD", {}, get_muxval("RSTB", x)), empty_bitfile)
66        nonrouting.fuzz_enum_setting(cfg, "{}.OCEAMUX".format(ebr), ["OCEA", "INV"],
67                                     lambda x: get_substs("DP16KD", {}, get_muxval("OCEA", x)), empty_bitfile)
68        nonrouting.fuzz_enum_setting(cfg, "{}.OCEBMUX".format(ebr), ["OCEB", "INV"],
69                                     lambda x: get_substs("DP16KD", {}, get_muxval("OCEB", x)), empty_bitfile)
70        nonrouting.fuzz_enum_setting(cfg, "{}.WEAMUX".format(ebr), ["WEA", "INV"],
71                                     lambda x: get_substs("DP16KD", {}, get_muxval("WEA", x)), empty_bitfile)
72        nonrouting.fuzz_enum_setting(cfg, "{}.WEBMUX".format(ebr), ["WEB", "INV"],
73                                     lambda x: get_substs("DP16KD", {}, get_muxval("WEB", x)), empty_bitfile)
74        nonrouting.fuzz_enum_setting(cfg, "{}.CEAMUX".format(ebr), ["CEA", "INV"],
75                                     lambda x: get_substs("DP16KD", {}, get_muxval("CEA", x)), empty_bitfile)
76        nonrouting.fuzz_enum_setting(cfg, "{}.CEBMUX".format(ebr), ["CEB", "INV"],
77                                     lambda x: get_substs("DP16KD", {}, get_muxval("CEB", x)), empty_bitfile)
78        for p in ("A", "B"):
79            for i in range(4 if p == "A" else 2):
80                sig = "AD{}{}".format(p, i)
81                nonrouting.fuzz_enum_setting(cfg, "{}.{}MUX".format(ebr, sig), [sig, "INV"],
82                                         lambda x: get_substs("DP16KD", {}, get_muxval(sig, x)), empty_bitfile)
83    fuzzloops.parallel_foreach(jobs, per_job)
84
85
86if __name__ == "__main__":
87    main()
88