| from fuzzconfig import FuzzConfig |
| import nonrouting |
| import nets |
| import pytrellis |
| import re |
| import fuzzloops |
| |
| jobs = [ |
| { |
| "cfg": FuzzConfig(job="PIOL", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R59C0:PICL0", "MIB_R60C0:PICL1", "MIB_R61C0:PICL2"]), |
| "side": "L", |
| "pins": [("M4", "A"), ("N5", "B"), ("N4", "C"), ("P5", "D")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOL_CLR", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R20C0:PICL0", "MIB_R21C0:PICL1", "MIB_R22C0:MIB_CIB_LR", |
| "MIB_R22C0:MIB_CIB_LRC"]), |
| "side": "L", |
| "pins": [("F4", "A"), ("E3", "B"), ("E5", "C"), ("F5", "D")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOL_DQS01", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R14C0:PICL0", "MIB_R15C0:PICL1_DQS0", "MIB_R16C0:PICL2_DQS1"]), |
| "side": "L", |
| "pins": [("C4", "A"), ("B4", "B"), ("A3", "C"), ("B3", "D")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOL_DQS23", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R17C0:PICL0_DQS2", "MIB_R18C0:PICL1_DQS3", "MIB_R19C0:PICL2"]), |
| "side": "L", |
| "pins": [("E4", "A"), ("D5", "B"), ("C3", "C"), ("D3", "D")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOR", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R35C90:PICR0", "MIB_R36C90:PICR1", "MIB_R37C90:PICR2"]), |
| "side": "R", |
| "pins": [("L20", "A"), ("M20", "B"), ("L19", "C"), ("M19", "D")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOR_CLRA", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R32C90:PICR0", "MIB_R33C90:PICR1", "MIB_R34C90:MIB_CIB_LR_A", |
| "MIB_R34C90:MIB_CIB_LRC_A"]), |
| "side": "R", |
| "pins": [("J19", "A"), ("K19", "B"), ("J20", "C"), ("K20", "D")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOT", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R0C4:PIOT0", "MIB_R0C5:PIOT1", "MIB_R1C4:PICT0", |
| "MIB_R1C5:PICT1"]), |
| "side": "T", |
| "pins": [("A6", "A"), ("B6", "B")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOB", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R71C9:PICB0", "MIB_R71C10:PICB1"]), |
| "side": "B", |
| "pins": [("W1", "A"), ("Y2", "B")] |
| }, |
| { |
| "cfg": FuzzConfig(job="PIOB_EFB", family="ECP5", device="LFE5U-45F", ncl="empty.ncl", |
| tiles=["MIB_R71C6:EFB2_PICB0", "MIB_R71C7:EFB3_PICB1"]), |
| "side": "B", |
| "pins": [("U1", "A"), ("V1", "B")] |
| }, |
| ] |
| |
| |
| def get_io_types(dir, pio, side): |
| types = [ |
| "LVTTL33", |
| "LVCMOS33", |
| "LVCMOS25", |
| "LVCMOS18", |
| "LVCMOS15", |
| "LVCMOS12" |
| ] |
| if side in ('L', 'R'): |
| types += [ |
| "SSTL18_I", |
| "SSTL18_II", |
| "SSTL15_I", |
| "SSTL15_II", |
| "SSTL135_I", |
| "SSTL135_II", |
| "HSUL12" |
| ] |
| if pio in ('A', 'C') and side in ('L', 'R'): |
| types += [ |
| "SSTL18D_I", |
| "SSTL18D_II", |
| "SSTL135D_I", |
| "SSTL135D_II", |
| "SSTL15D_I", |
| "SSTL15D_II", |
| "HSUL12D", |
| "LVCMOS33D", |
| "LVCMOS25D", |
| ] |
| if dir == "INPUT": |
| types += [ |
| "LVDS", |
| "BLVDS25", |
| "MLVDS25", |
| "LVPECL33", |
| "SLVS", |
| "SUBLVDS", |
| "LVCMOS18D" |
| ] |
| elif dir == "OUTPUT": |
| if pio == "A": |
| types += ["LVDS", "LVCMOS18D"] |
| types += [ |
| "LVDS25E", |
| "BLVDS25E", |
| "MLVDS25E", |
| "LVPECL33E", |
| ] |
| elif dir == "BIDIR": |
| if pio == "A": |
| types += ["LVDS", "LVCMOS18D"] |
| types += [ |
| "BLVDS25E", |
| "MLVDS25E", |
| ] |
| return types |
| |
| |
| def get_cfg_vccio(iotype): |
| m = re.match(r".*(\d)(\d)$", iotype) |
| if not m: |
| return "3.3" |
| return "{}.{}".format(m.group(1), m.group(2)) |
| |
| |
| def main(): |
| pytrellis.load_database("../../../database") |
| for job in jobs: |
| cfg = job["cfg"] |
| side = job["side"] |
| pins = job["pins"] |
| cfg.setup() |
| empty_bitfile = cfg.build_design(cfg.ncl, {}) |
| cfg.ncl = "pio.v" |
| |
| def per_pin(pin): |
| loc, pio = pin |
| |
| def get_substs(iomode, extracfg=None): |
| if iomode == "NONE": |
| iodir, type = "NONE", "" |
| else: |
| iodir, type = iomode.split("_", 1) |
| substs = { |
| "dir": iodir, |
| "io_type": type, |
| "loc": loc, |
| "extra_attrs": "", |
| "cfg_vio": "3.3" |
| } |
| if extracfg is not None: |
| substs["extra_attrs"] = '(* {}="{}" *)'.format(extracfg[0], extracfg[1]) |
| if side == "B": |
| substs["cfg_vio"] = get_cfg_vccio(type) |
| return substs |
| |
| modes = ["NONE"] |
| for iodir in ("INPUT", "OUTPUT", "BIDIR"): |
| modes += [iodir + "_" + _ for _ in get_io_types(iodir, pio, side)] |
| |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.BASE_TYPE".format(pio), modes, |
| lambda x: get_substs(iomode=x), |
| empty_bitfile, False) |
| |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.PULLMODE".format(pio), ["UP", "DOWN", "NONE"], |
| lambda x: get_substs(iomode="INPUT_LVCMOS33", extracfg=("PULLMODE", x)), |
| empty_bitfile) |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.SLEWRATE".format(pio), ["FAST", "SLOW"], |
| lambda x: get_substs(iomode="OUTPUT_LVCMOS33", extracfg=("SLEWRATE", x)), |
| empty_bitfile) |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.DRIVE".format(pio), ["4", "8", "12", "16"], |
| lambda x: get_substs(iomode="OUTPUT_LVCMOS33", extracfg=("DRIVE", x)), |
| empty_bitfile) |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.HYSTERESIS".format(pio), ["ON", "OFF"], |
| lambda x: get_substs(iomode="INPUT_LVCMOS33", extracfg=("HYSTERESIS", x)), |
| empty_bitfile) |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.OPENDRAIN".format(pio), ["ON", "OFF"], |
| lambda x: get_substs(iomode="OUTPUT_LVCMOS33", extracfg=("OPENDRAIN", x)), |
| empty_bitfile) |
| if loc in ('T', 'B'): |
| nonrouting.fuzz_enum_setting(cfg, "PIO{}.CLAMP".format(pio), ["ON", "OFF"], |
| lambda x: get_substs(iomode="INPUT_LVCMOS33", extracfg=("CLAMP", x)), |
| empty_bitfile) |
| |
| fuzzloops.parallel_foreach(pins, per_pin) |
| |
| |
| if __name__ == "__main__": |
| main() |