Esempio n. 1
0
def run(db_root,
        part,
        filename_in,
        f_out,
        sparse=False,
        roi=None,
        debug=False,
        dump_bits=False):
    db = Database(db_root, part)
    assembler = fasm_assembler.FasmAssembler(db)

    set_features = set()

    def feature_callback(feature):
        set_features.add(feature)

    assembler.set_feature_callback(feature_callback)

    extra_features = []
    if roi:
        with open(roi) as f:
            roi_j = json.load(f)
        x1 = roi_j['info']['GRID_X_MIN']
        x2 = roi_j['info']['GRID_X_MAX']
        y1 = roi_j['info']['GRID_Y_MIN']
        y2 = roi_j['info']['GRID_Y_MAX']

        assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2))

        if 'required_features' in roi_j:
            extra_features = list(
                fasm.parse_fasm_string('\n'.join(roi_j['required_features'])))

    # Get required extra features for the part
    required_features = db.get_required_fasm_features(part)
    extra_features += list(fasm.parse_fasm_string(
        '\n'.join(required_features)))

    assembler.parse_fasm_filename(filename_in, extra_features=extra_features)

    frames = assembler.get_frames(sparse=sparse)

    if debug:
        dump_frames_sparse(frames)

    if dump_bits:
        output_bits(f_out, frames)
    else:
        dump_frm(f_out, frames)
Esempio n. 2
0
def run(db_root, filename_in, f_out, sparse=False, roi=None, debug=False):
    db = Database(db_root)
    assembler = fasm_assembler.FasmAssembler(db)

    extra_features = []
    if roi:
        with open(roi) as f:
            roi_j = json.load(f)
        x1 = roi_j['info']['GRID_X_MIN']
        x2 = roi_j['info']['GRID_X_MAX']
        y1 = roi_j['info']['GRID_Y_MIN']
        y2 = roi_j['info']['GRID_Y_MAX']

        assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2))

        if 'required_features' in roi_j:
            extra_features = fasm.parse_fasm_string('\n'.join(
                roi_j['required_features']))

    assembler.parse_fasm_filename(filename_in, extra_features=extra_features)
    frames = assembler.get_frames(sparse=sparse)

    if debug:
        dump_frames_sparse(frames)

    dump_frm(f_out, frames)
Esempio n. 3
0
def fasm_to_frames(
        db_root,
        part,
        filename_in,
        sparse,
        bits_file,
        frames_file,
):
    db = Database(db_root, part)
    assembler = fasm_assembler.FasmAssembler(db)

    set_features = set()

    def feature_callback(feature):
        set_features.add(feature)

    assembler.set_feature_callback(feature_callback)

    extra_features = []

    # Get required extra features for the part
    required_features = db.get_required_fasm_features(part)
    extra_features += list(
        fasm.parse_fasm_string('\n'.join(required_features)))

    assembler.parse_fasm_filename(filename_in, extra_features=extra_features)

    frames = assembler.get_frames(sparse=sparse)

    print('Have {} frames'.format(len(frames)))

    if bits_file:
        output_bits(bits_file, frames)

    dump_frm(frames_file, frames)
def initlines_to_memfasm(initlines, infile_name):
    print(initlines)
    print("###")
    print(infile_name)
    fasmlines = []
    for tileaddr, tile in initlines.items():
        for yaddr, inits in tile.items():
            for init_type, data in inits.items():
                line_header = '{}.RAMB18_{}.{}_'.format(
                    tileaddr, yaddr, init_type)
                #line_header2 = f'{tileaddr}.RAMB18_{yaddr}.{init_type}_'
                #assert(line_header == line_header2)
                #print(str(len(data)) + "...")
                for count, data in enumerate(data):
                    if int(data) > 0:
                        # print(data)
                        while data[0] == '0':
                            data = data[1:]
                        datalen = len(data)
                        #count2 = count
                        count = hex(count)[2:].upper()
                        l = '{}{}[{}:0] = {}\'b{}'.format(
                            line_header, pad('0', 2, count), datalen - 1,
                            datalen, data)
                        fasmlines.append(l)
                        #l2 = f'{line_header}{count2:02X}[{datalen-1}:0] = {datalen}\'b{data}'
                        #print(l)
                        #print(l2)
                        #assert(l == l2)
                        #fasmlines.append(
                        #    f'{line_header}{count:02X}[{datalen-1}:0] = {datalen}\'b{data}')
    memfasm = (next(fasm.parse_fasm_string(line)) for line in fasmlines)

    return memfasm
Esempio n. 5
0
def initlines_to_memfasm(initlines, infile_name):
    fasmlines = []
    for tileaddr, tile in initlines.items():
        for yaddr, inits in tile.items():
            for init_type, data in inits.items():
                line_header = f'{tileaddr}.RAMB18_{yaddr}.{init_type}_'
                for count, data in enumerate(data):
                    # if '1' in data:
                    # fasmlines.append(
                    #     f'{line_header}{count:02X}[255:0] = 256\'b{data}')
                    fasmlines.append(
                        f'{line_header}{count:02X}[255:0] = 256\'b{data}')
        #             print(f'{line_header}{count:02X}[255:0] = 256\'b{data}')
        #     print()
        # print()
    with open(f'{infile_name.split(".")[0]}_check.txt', 'w+') as w:
        for line in fasmlines:
            w.write(f'{line}\n')
            # print(line)
    memfasm = (next(fasm.parse_fasm_string(line)) for line in fasmlines)
    # for mf in memfasm:
    # print(type(mf))
    # print(next(fasm.fasm_line_to_string(mf)))
    return memfasm
Esempio n. 6
0
def fasm2frames(db_root,
                part,
                filename_in,
                f_out=None,
                sparse=False,
                roi=None,
                debug=False,
                emit_pudc_b_pullup=False):
    db = Database(db_root, part)
    assembler = fasm_assembler.FasmAssembler(db)

    set_features = set()

    def feature_callback(feature):
        set_features.add(feature)

    assembler.set_feature_callback(feature_callback)

    # Build mapping of tile to IO bank
    tile_to_bank = {}
    bank_to_tile = defaultdict(lambda: set())

    if part is not None:
        with open(os.path.join(db_root, part, "package_pins.csv"), "r") as fp:
            reader = csv.DictReader(fp)
            package_pins = [l for l in reader]

        with open(os.path.join(db_root, part, "part.json"), "r") as fp:
            part_data = json.load(fp)

        for bank, loc in part_data["iobanks"].items():
            tile = "HCLK_IOI3_" + loc
            bank_to_tile[bank].add(tile)
            tile_to_bank[tile] = bank

        for pin in package_pins:
            bank_to_tile[pin["bank"]].add(pin["tile"])
            tile_to_bank[pin["tile"]] = pin["bank"]

    if emit_pudc_b_pullup:
        pudc_b_in_use = False
        pudc_b_tile_site = find_pudc_b(db)

        def check_for_pudc_b(set_feature):
            feature_callback(set_feature)
            parts = set_feature.feature.split('.')

            if parts[0] == pudc_b_tile_site[0] and parts[
                    1] == pudc_b_tile_site[1]:
                nonlocal pudc_b_in_use
                pudc_b_in_use = True

        if pudc_b_tile_site is not None:
            assembler.set_feature_callback(check_for_pudc_b)

    extra_features = []
    if roi:
        with open(roi) as f:
            roi_j = json.load(f)
        x1 = roi_j['info']['GRID_X_MIN']
        x2 = roi_j['info']['GRID_X_MAX']
        y1 = roi_j['info']['GRID_Y_MIN']
        y2 = roi_j['info']['GRID_Y_MAX']

        assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2))

        if 'required_features' in roi_j:
            extra_features = list(
                fasm.parse_fasm_string('\n'.join(roi_j['required_features'])))

    # Get required extra features for the part
    required_features = db.get_required_fasm_features(part)
    extra_features += list(fasm.parse_fasm_string(
        '\n'.join(required_features)))

    assembler.parse_fasm_filename(filename_in, extra_features=extra_features)

    if emit_pudc_b_pullup and not pudc_b_in_use and pudc_b_tile_site is not None:
        # Enable IN-only and PULLUP on PUDC_B IOB.
        #
        # TODO: The following FASM string only works on Artix 50T and Zynq 10
        # fabrics.  It is known to be wrong for the K70T fabric, but it is
        # unclear how to know which IOSTANDARD to use.
        missing_features = []
        for line in fasm.parse_fasm_string("""
{tile}.{site}.LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135_SSTL15.IN_ONLY
{tile}.{site}.LVCMOS25_LVCMOS33_LVTTL.IN
{tile}.{site}.PULLTYPE.PULLUP
""".format(
                tile=pudc_b_tile_site[0],
                site=pudc_b_tile_site[1],
        )):
            assembler.add_fasm_line(line, missing_features)

        if missing_features:
            raise fasm_assembler.FasmLookupError('\n'.join(missing_features))

    if part is not None:
        # Make a set of all used IOB tiles and sites. Look for the "STEPDOWN"
        # feature. If one is set for an IOB then set it for all other IOBs of
        # the same bank.
        stepdown_tags = defaultdict(lambda: set())
        stepdown_banks = set()
        used_iob_sites = set()

        for set_feature in set_features:
            if set_feature.value == 0:
                continue

            feature = set_feature.feature
            parts = feature.split(".")
            if len(parts) >= 3:
                tile, site, tag = feature.split(".", maxsplit=2)
                if "IOB33" in tile:
                    used_iob_sites.add((
                        tile,
                        site,
                    ))

                # Store STEPDOWN related tags.
                if "STEPDOWN" in tag:
                    bank = tile_to_bank[tile]
                    stepdown_banks.add(bank)
                    stepdown_tags[bank].add(tag)

        # Set the feature for unused IOBs, loop over all banks which were
        # observed to have the STEPDOWN feature set.
        missing_features = []

        for bank in stepdown_banks:
            for tile in bank_to_tile[bank]:

                # This is an IOB33 tile. Set the STEPDOWN feature in it but
                # only if it is unused.
                if "IOB33" in tile:
                    for site in get_iob_sites(db, tile):

                        if (tile, site) in used_iob_sites:
                            continue

                        for tag in stepdown_tags[bank]:
                            feature = "{}.{}.{}".format(tile, site, tag)
                            for line in fasm.parse_fasm_string(feature):
                                assembler.add_fasm_line(line, missing_features)

                # This is a HCLK_IOI3 tile, set the stepdown feature for it
                # too.
                if "HCLK_IOI3" in tile:
                    feature = "{}.STEPDOWN".format(tile)
                    for line in fasm.parse_fasm_string(feature):
                        assembler.add_fasm_line(line, missing_features)

        if missing_features:
            raise fasm_assembler.FasmLookupError('\n'.join(missing_features))

    frames = assembler.get_frames(sparse=sparse)

    if debug:
        dump_frames_sparse(frames)

    if f_out is not None:
        dump_frm(f_out, frames)

    return frames
Esempio n. 7
0
def check_round_trip(test, result):
    s = fasm.fasm_tuple_to_string(result)
    test.assertEqual(list(fasm.parse_fasm_string(s)), result)
Esempio n. 8
0
def run(
        db_root,
        filename_in,
        f_out,
        sparse=False,
        roi=None,
        debug=False,
        emit_pudc_b_pullup=False):
    db = Database(db_root)
    assembler = fasm_assembler.FasmAssembler(db)

    if emit_pudc_b_pullup:
        pudc_b_in_use = False
        pudc_b_tile_site = find_pudc_b(db)

        def check_for_pudc_b(set_feature):
            parts = set_feature.feature.split('.')

            if parts[0] == pudc_b_tile_site[0] and parts[
                    1] == pudc_b_tile_site[1]:
                nonlocal pudc_b_in_use
                pudc_b_in_use = True

        if pudc_b_tile_site is not None:
            assembler.set_feature_callback(check_for_pudc_b)

    extra_features = []
    if roi:
        with open(roi) as f:
            roi_j = json.load(f)
        x1 = roi_j['info']['GRID_X_MIN']
        x2 = roi_j['info']['GRID_X_MAX']
        y1 = roi_j['info']['GRID_Y_MIN']
        y2 = roi_j['info']['GRID_Y_MAX']

        assembler.mark_roi_frames(Roi(db=db, x1=x1, x2=x2, y1=y1, y2=y2))

        if 'required_features' in roi_j:
            extra_features = fasm.parse_fasm_string(
                '\n'.join(roi_j['required_features']))

    assembler.parse_fasm_filename(filename_in, extra_features=extra_features)

    if emit_pudc_b_pullup and not pudc_b_in_use and pudc_b_tile_site is not None:
        # Enable IN-only and PULLUP on PUDC_B IOB.
        #
        # TODO: The following FASM string only works on Artix 50T and Zynq 10
        # fabrics.  It is known to be wrong for the K70T fabric, but it is
        # unclear how to know which IOSTANDARD to use.
        missing_features = []
        for line in fasm.parse_fasm_string("""
{tile}.{site}.LVCMOS12_LVCMOS15_LVCMOS18_LVCMOS25_LVCMOS33_LVTTL_SSTL135.IN_ONLY
{tile}.{site}.LVCMOS25_LVCMOS33_LVTTL.IN
{tile}.{site}.PULLTYPE.PULLUP
""".format(
                tile=pudc_b_tile_site[0],
                site=pudc_b_tile_site[1],
        )):
            assembler.add_fasm_line(line, missing_features)

        if missing_features:
            raise fasm_assembler.FasmLookupError('\n'.join(missing_features))

    frames = assembler.get_frames(sparse=sparse)

    if debug:
        dump_frames_sparse(frames)

    dump_frm(f_out, frames)
Esempio n. 9
0
    if args.input_pcf is not None:
        pcf_data = parse_pcf(args.input_pcf)

    # Load data from the database
    with open(args.vpr_db, "rb") as fp:
        db = pickle.load(fp)

    f2b = Fasm2Bels(db, args.package_name)

    if args.input_type == 'bitstream':
        qlfasmdb = load_quicklogic_database()
        assembler = QL732BAssembler(qlfasmdb)
        assembler.read_bitstream(args.input_file)
        fasmlines = assembler.disassemble()
        fasmlines = [
            line for line in fasm.parse_fasm_string('\n'.join(fasmlines))
        ]
    else:
        fasmlines = [
            line for line in fasm.parse_fasm_filename(args.input_file)
        ]

    verilog, pcf, qcf = f2b.convert_to_verilog(fasmlines)

    with open(args.output_verilog, 'w') as outv:
        outv.write(verilog)
    if args.output_pcf:
        with open(args.output_pcf, 'w') as outpcf:
            outpcf.write(pcf)
    if args.output_qcf:
        with open(args.output_qcf, 'w') as outqcf:
Esempio n. 10
0
def fasm_to_asc(in_fasm, outf, device):
    """Convert an FASM input to an ASC file

    Set input enable defaults, RAM powerup, and enables all ColBufCtrl (until modeled in VPR see: #464)
    """

    ic = icebox.iceconfig()

    init_method_name = "setup_empty_{}".format(device.lower()[2:])
    assert hasattr(ic,
                   init_method_name), "no icebox method to init empty device"
    getattr(ic, init_method_name)()

    device_1k = ic.device == "1k"

    fasmdb = read_ice_db(ic)
    # TODO: upstream init "default" bitstream
    locs = [(x, y) for x in range(ic.max_x + 1) for y in range(ic.max_y + 1)]
    for tile_loc in locs:
        tile = ic.tile(*tile_loc)
        if tile is None:
            continue
        db = ic.tile_db(*tile_loc)
        tile_type = ic.tile_type(*tile_loc)
        for entry in db:
            if (device_1k and
                ((tile_type == "IO" and entry[-1] in ["IE_0", "IE_1"]) or
                 (tile_type == "RAMB" and entry[-1] == "PowerUp"))
                    or (entry[-2] == "ColBufCtrl")):
                tile_bits = _tile_to_array(tile)
                tile_type = ic.tile_type(*tile_loc)
                bm, bv = _get_iceconfig_bits(tile_bits, entry[0])
                tile_bits[bm] = bv[bm]
                _array_to_tile(tile_bits, tile)

    missing_features = []
    for line in fasm.parse_fasm_string(in_fasm.read()):
        if not line.set_feature:
            continue

        line_strs = tuple(fasm.fasm_line_to_string(line))
        assert len(line_strs) == 1

        feature = Feature.from_fasm_entry(
            FasmEntry(line.set_feature.feature, []))

        def find_ieren(ic, loc, iob):
            tmap = [
                xx[3:] for xx in ic.ieren_db()
                if xx[:3] == (tuple(loc) + (iob, ))
            ]
            assert len(tmap) < 2, "expected 1 IEREN_DB entry found {}".format(
                len(tmap))

            if len(tmap) == 0:
                print("no ieren found for {}".format((tile_loc + (iob, ))))
                return
            return tmap[0]

        # fix up for IO
        if feature.parts[-1] == "SimpleInput":
            iob = int(feature.parts[-2][-1])
            new_ieren = find_ieren(ic, feature.loc, iob)

            feature.parts[-1] = "PINTYPE_0"
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)

            feature.loc = new_ieren[:2]
            feature.parts[-2] = "IoCtrl"
            feature.parts[-1] = "IE_{}".format(new_ieren[2])
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            feature.parts[-1] = "REN_{}".format(new_ieren[2])
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            continue

        if feature.parts[-1] == "SimpleOutput":
            iob = int(feature.parts[-2][-1])
            new_ieren = find_ieren(ic, feature.loc, iob)

            feature.parts[-1] = "PINTYPE_3"
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            feature.parts[-1] = "PINTYPE_4"
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)

            feature.loc = new_ieren[:2]
            feature.parts[-2] = "IoCtrl"
            feature.parts[-1] = "REN_{}".format(new_ieren[2])
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            continue

        ## special case for RAM INIT values
        tile_type, loc = feature.tile_type, feature.loc
        if tile_type == "RAMB" and feature.parts[-1].startswith("INIT"):
            tloc = tuple(loc)
            if tloc not in ic.ram_data:
                ic.ram_data[tloc] = [64 * "0" for _ in range(16)]
            tile = ic.ram_data[tloc]
            tile_bits = _tile_to_array(tile, is_hex=True)
        elif tile_type == "RAMB" and feature.parts[-1].endswith("_MODE"):
            # hack to force modes to the RAMT
            tile = ic.tile(loc[0], loc[1] + 1)
            tile_bits = _tile_to_array(tile)
        else:
            tile = ic.tile(*loc)
            tile_bits = _tile_to_array(tile)

        # lookup feature and convert
        for canonical_feature in fasm.canonical_features(line.set_feature):
            key = fasm.set_feature_to_str(canonical_feature)
            feature = fasmdb[key]
            bm, bv = _get_feature_bits(tile_bits, feature.bit_tuples)

            tile_bits[bm] = bv[bm]

        if tile_type == "RAMB" and feature.parts[-1].startswith("INIT"):
            _array_to_tile(tile_bits, tile, is_hex=True)
        else:
            _array_to_tile(tile_bits, tile)

    # TODO: would be nice to upstream a way to write to non-files
    ic.write_file(outf.name)