Beispiel #1
0
def iob(locations, corners):
    cnt = Counter()  # keep track of how many runs are needed
    for ttyp, tiles in locations.items():  # for each tile of this type
        mod = codegen.Module()
        cst = codegen.Constraints()
        # get bels in this ttyp
        bels = {name[-1] for loc in tiles.values() for name in loc}
        locs = tiles.copy()
        for pin in bels:  # [A, B, C, D, ...]
            for typ, conn in iobmap.items():
                # find the next location that has pin
                # or make a new module
                for tile, names in locs.items():
                    name = tile + pin
                    if name in names:
                        del locs[tile]
                        loc = name
                        break
                else:  # no usable tiles
                    yield ttyp, mod, cst, {}
                    cnt[ttyp] += 1
                    locs = tiles.copy()
                    mod = codegen.Module()
                    cst = codegen.Constraints()
                    for tile, names in locs.items():
                        name = tile + pin
                        if name in names:
                            del locs[tile]
                            loc = name
                            break

                name = make_name("IOB", typ)
                iob = codegen.Primitive(typ, name)
                for port in chain.from_iterable(conn.values()):
                    iob.portmap[port] = name + "_" + port

                for direction, wires in conn.items():
                    wnames = [name + "_" + w for w in wires]
                    getattr(mod, direction).update(wnames)
                mod.primitives[name] = iob
                cst.ports[name] = loc

            yield ttyp, mod, cst, {}
            cnt[ttyp] += 1
    # insert dummie in the corners to detect the bank enable bits
    runs = cnt.most_common(1)[0][1]
    for n in range(runs):
        for ttyp in corners:
            mod = codegen.Module()
            cst = codegen.Constraints()
            cfg = {}
            yield ttyp, mod, cst, cfg
Beispiel #2
0
def dff(locations):
    for ttyp in range(12, 17):  # for each tile type
        mod = codegen.Module()
        cst = codegen.Constraints()
        try:
            # get all tiles of this type
            # iter causes the loop to not repeat the same locs per cls
            locs = iter(locations[ttyp])
        except KeyError:
            continue

        for cls in range(3):  # for each cls
            for typ, port in dffmap.items():  # for each bel type
                try:
                    loc = next(locs)  # get the next unused tile
                except StopIteration:
                    yield ttyp, mod, cst, {}
                    locs = iter(locations[ttyp])
                    loc = next(locs)
                    mod = codegen.Module()
                    cst = codegen.Constraints()

                lutname = make_name("DUMMY", "LUT4")
                lut = codegen.Primitive("LUT4", lutname)
                lut.params["INIT"] = "16'hffff"
                lut.portmap['F'] = lutname + "_F"
                lut.portmap['I0'] = lutname + "_I0"
                lut.portmap['I1'] = lutname + "_I1"
                lut.portmap['I2'] = lutname + "_I2"
                lut.portmap['I3'] = lutname + "_I3"

                mod.wires.update(lut.portmap.values())
                mod.primitives[lutname] = lut
                name = make_name("DFF", typ)
                dff = codegen.Primitive(typ, name)
                dff.portmap['CLK'] = name + "_CLK"
                dff.portmap['D'] = lutname + "_F"
                dff.portmap['Q'] = name + "_Q"
                if port:
                    dff.portmap[port] = name + "_" + port
                mod.wires.update(dff.portmap.values())
                mod.primitives[name] = dff

                row = loc[0] + 1
                col = loc[1] + 1
                cst.cells[lutname] = f"R{row}C{col}[{cls}]"
                cst.cells[name] = f"R{row}C{col}[{cls}]"
        yield ttyp, mod, cst, {}
Beispiel #3
0
def iob(locations):
    for ttyp, tiles in locations.items():  # for each tile of this type
        mod = codegen.Module()
        cst = codegen.Constraints()
        # get bels in this ttyp
        bels = {name[-1] for loc in tiles.values() for name in loc}
        locs = tiles.copy()
        for pin in bels:  # [A, B, C, D, ...]
            for typ, conn in iobmap.items():
                # find the next location that has pin
                # or make a new module
                for tile, names in locs.items():
                    name = tile + pin
                    if name in names:
                        del locs[tile]
                        loc = name
                        break
                else:  # no usable tiles
                    yield ttyp, mod, cst
                    locs = tiles.copy()
                    mod = codegen.Module()
                    cst = codegen.Constraints()
                    for tile, names in locs.items():
                        name = tile + pin
                        if name in names:
                            del locs[tile]
                            loc = name
                            break

                name = make_name("IOB", typ)
                iob = codegen.Primitive(typ, name)
                for port in chain.from_iterable(conn.values()):
                    iob.portmap[port] = name + "_" + port

                for direction, wires in conn.items():
                    wnames = [name + "_" + w for w in wires]
                    getattr(mod, direction).update(wnames)
                mod.primitives[name] = iob
                cst.ports[name] = loc

            yield ttyp, mod, cst
Beispiel #4
0
def dualmode(ttyp):
    for pin in dualmode_pins:
        mod = codegen.Module()
        cst = codegen.Constraints()
        cfg = {pin: 'false'}
        yield ttyp, mod, cst, cfg
Beispiel #5
0
        iob(pin_locations, [
            fse['header']['grid'][61][0][0],
            fse['header']['grid'][61][-1][0],
            fse['header']['grid'][61][0][-1],
            fse['header']['grid'][61][-1][-1],
        ]),
        dff(locations),
        dualmode(fse['header']['grid'][61][0][0]),
    )
    for ttyp, mod, cst, cfg in fuzzers:
        modmap.setdefault(ttyp, []).append(mod)
        cstmap.setdefault(ttyp, []).append(cst)
        cfgmap.setdefault(ttyp, []).append(cfg)

    modules = [
        reduce(lambda a, b: a + b, m, codegen.Module())
        for m in zip_longest(*modmap.values(), fillvalue=codegen.Module())
    ]
    constrs = [
        reduce(lambda a, b: a + b, c, codegen.Constraints())
        for c in zip_longest(*cstmap.values(), fillvalue=codegen.Constraints())
    ]
    configs = [
        reduce(lambda a, b: {
            **a,
            **b
        }, c, {}) for c in zip_longest(*cfgmap.values(), fillvalue={})
    ]

    type_re = re.compile(r"inst\d+_([A-Z]+)_([A-Z]+)")
Beispiel #6
0
            mod.primitives[name] = iob

    gnd = codegen.Primitive("GND", "mygnd")
    gnd.portmap["G"] = "VSS"
    mod.primitives["mygnd"] = gnd
    vcc = codegen.Primitive("VCC", "myvcc")
    vcc.portmap["V"] = "VCC"
    mod.primitives["myvcc"] = vcc


if __name__ == "__main__":
    with open(f"{device}.pickle", 'rb') as f:
        db = pickle.load(f)
    bitmap = read_bitstream(sys.argv[1])[0]
    bm = chipdb.tile_bitmap(db, bitmap)
    mod = codegen.Module()
    for idx, t in bm.items():
        row, col = idx
        dbtile = db.grid[row][col]
        print(idx)
        #for bitrow in t:
        #    print(*bitrow, sep='')
        #if idx == (5, 0):
        #    from fuse_h4x import *
        #    fse = readFse(open("/home/pepijn/bin/gowin/IDE/share/device/GW1N-1/GW1N-1.fse", 'rb'))
        #    breakpoint()
        bels, pips = parse_tile_(dbtile, t)
        print(bels)
        #print(pips)
        tile2verilog(row, col, bels, pips, mod, db)
    with open("unpack.v", 'w') as f:
Beispiel #7
0
def run_pnr(fuzzers, bits):
    #TODO generalize/parameterize
    mod = codegen.Module()
    constr = codegen.Constraints()
    start = 0
    for fuzzer in fuzzers:
        cb = bits[start:start + fuzzer.cfg_bits]
        start += fuzzer.cfg_bits
        fuzzer.primitives(mod, cb)
        fuzzer.constraints(constr, cb)

    cfg = codegen.DeviceConfig({
        "JTAG regular_io": "false",
        "SSPI regular_io": "false",
        "MSPI regular_io": "false",
        "READY regular_io": "false",
        "DONE regular_io": "false",
        "RECONFIG_N regular_io": "false",
        "MODE regular_io": "false",
        "CRC_check": "true",
        "compress": "false",
        "encryption": "false",
        "security_bit_enable": "true",
        "bsram_init_fuse_print": "true",
        "download_speed": "250/100",
        "spi_flash_address": "0x00FFF000",
        "format": "txt",
        "background_programming": "false",
        "secure_mode": "false"
    })

    opt = codegen.PnrOptions([])
    #"sdf", "oc", "ibs", "posp", "o",
    #"warning_all", "timing", "reg_not_in_iob"])

    pnr = codegen.Pnr()
    pnr.device = "GW1NR-9-QFN88-6"
    pnr.partnumber = "GW1NR-LV9QN88C6/I5"

    with tempfile.TemporaryDirectory() as tmpdir:
        pnr.outdir = tmpdir
        with open(tmpdir + "/top.v", "w") as f:
            mod.write(f)
        pnr.netlist = tmpdir + "/top.v"
        with open(tmpdir + "/top.cst", "w") as f:
            constr.write(f)
        pnr.cst = tmpdir + "/top.cst"
        with open(tmpdir + "/device.cfg", "w") as f:
            cfg.write(f)
        pnr.cfg = tmpdir + "/device.cfg"
        with open(tmpdir + "/pnr.cfg", "w") as f:
            opt.write(f)
        pnr.opt = tmpdir + "/pnr.cfg"
        with open(tmpdir + "/run.tcl", "w") as f:
            pnr.write(f)
        subprocess.run([gowinhome + "/IDE/bin/gw_sh", tmpdir + "/run.tcl"])
        #print(tmpdir); input()
        try:
            return bslib.read_bitstream(tmpdir + "/impl/pnr/top.fs")[0]
        except FileNotFoundError:
            return None
Beispiel #8
0
        ttyp_pins = pin_locations.setdefault(ttyp, {})
        ttyp_pins.setdefault(name[:-1], set()).add(name)

    modmap = {}
    cstmap = {}
    # Add fuzzers here
    fuzzers = chain(
        iob(pin_locations),
        dff(locations),
    )
    for ttyp, mod, cst in fuzzers:
        modmap.setdefault(ttyp, []).append(mod)
        cstmap.setdefault(ttyp, []).append(cst)

    modules = [
        sum(m, start=codegen.Module())
        for m in zip_longest(*modmap.values(), fillvalue=codegen.Module())
    ]
    constrs = [
        sum(c, start=codegen.Constraints())
        for c in zip_longest(*cstmap.values(), fillvalue=codegen.Constraints())
    ]

    type_re = re.compile(r"inst\d+_([A-Z]+)_([A-Z]+)")

    empty, hdr, ftr, posp = run_pnr(codegen.Module(), codegen.Constraints())
    db.cmd_hdr = hdr
    db.cmd_ftr = ftr
    db.template = empty
    p = Pool()
    pnr_res = p.map(lambda param: run_pnr(*param), zip(modules, constrs))