예제 #1
0
def add_tile_bits(tile_db, baseaddr, offset, frames, words, height=None):
    '''
    Record data structure geometry for the given tile baseaddr
    For most tiles there is only one baseaddr, but some like BRAM have multiple
    Notes on multiple block types:
    https://github.com/SymbiFlow/prjxray/issues/145
    '''

    bits = tile_db['bits']
    block_type = util.addr2btype(baseaddr)

    assert 0 <= offset <= 100, offset
    assert 1 <= words <= 101
    assert offset + words <= 101, (
        tile_db, offset + words, offset, words, block_type)

    assert block_type not in bits
    block = bits.setdefault(block_type, {})

    # FDRI address
    block["baseaddr"] = '0x%08X' % baseaddr
    # Number of frames this entry is sretched across
    # that is the following FDRI addresses are used: range(baseaddr, baseaddr + frames)
    block["frames"] = frames

    # Index of first word used within each frame
    block["offset"] = offset

    # related to words...
    # deprecated field? Don't worry about for now
    # DSP has some differences between height and words
    block["words"] = words
    if height is None:
        height = words
    block["height"] = height
예제 #2
0
def add_tile_bits(tile_name,
                  tile_db,
                  baseaddr,
                  offset,
                  frames,
                  words,
                  tile_frames,
                  verbose=False):
    '''
    Record data structure geometry for the given tile baseaddr
    For most tiles there is only one baseaddr, but some like BRAM have multiple
    Notes on multiple block types:
    https://github.com/SymbiFlow/prjxray/issues/145
    '''
    bits = tile_db['bits']
    block_type = util.addr2btype(baseaddr)

    # Extract the information about the maximal number of frames from the part's json
    max_frames = tile_frames.get_tile_frames(baseaddr)
    if frames > max_frames:
        print(
            "Warning: The number of frames specified for the tile {} ({}) exceeds the maximum allowed value ({}). Falling back to the maximum value."
            .format(tile_name, frames, max_frames))
        frames = max_frames
    # If frames count is None then use the maximum
    if frames is None:
        frames = max_frames

    assert offset <= 100, (tile_name, offset)
    # Few rare cases at X=0 for double width tiles split in half => small negative offset
    assert offset >= 0 or "IOB" in tile_name, (tile_name, hex(baseaddr),
                                               offset)
    assert 1 <= words <= 101, words
    assert offset + words <= 101, (tile_name, offset + words, offset, words,
                                   block_type)

    baseaddr_str = '0x%08X' % baseaddr
    block = bits.get(block_type, None)
    if block is not None:
        verbose and print("%s: existing defintion for %s" %
                          (tile_name, block_type))
        assert block["baseaddr"] == baseaddr_str
        assert block["frames"] == frames, (block, frames)
        assert block["offset"] == offset, "%s; orig offset %s, new %s" % (
            tile_name, block["offset"], offset)
        assert block["words"] == words
        return
    block = bits.setdefault(block_type, {})

    # FDRI address
    block["baseaddr"] = baseaddr_str
    # Number of frames this entry is sretched across
    # that is the following FDRI addresses are used: range(baseaddr, baseaddr + frames)
    block["frames"] = frames

    # Index of first word used within each frame
    block["offset"] = offset

    # Number of words used by tile.
    block["words"] = words
예제 #3
0
def make_tile_baseaddrs(tiles, site_baseaddr, verbose=False):
    # Look up a base address by tile name
    tile_baseaddrs = dict()

    verbose and print('')
    verbose and print('%u tiles' % len(tiles))
    verbose and print("%u baseaddrs" % len(site_baseaddr))
    added = 0
    for tile in tiles:
        for site_name in tile["sites"].keys():
            if site_name not in site_baseaddr:
                continue
            framebaseaddr = site_baseaddr[site_name]
            bt = util.addr2btype(framebaseaddr)
            tile_baseaddr = tile_baseaddrs.setdefault(tile["name"], {})
            if bt in tile_baseaddr:
                # actually lets just fail these, better to remove at tcl level to speed up processing
                assert 0, 'duplicate base address'
                assert tile_baseaddr[bt] == [framebaseaddr, 0]
            else:
                tile_baseaddr[bt] = [framebaseaddr, 0]
            verbose and print(
                "baseaddr: %s.%s @ %s.0x%08x" %
                (tile["name"], site_name, bt, framebaseaddr))
            added += 1

    assert added, "Failed to add any base addresses"
    assert added == len(site_baseaddr)
    return tile_baseaddrs
예제 #4
0
def run(fn_in, fn_out, verbose=False):
    database = json.load(open(fn_in, "r"))

    # Load a map of sites to base addresses
    # Need to figure out the
    # FIXME: generate frames from part file (or equivilent)
    # See https://github.com/SymbiFlow/prjxray/issues/327
    # FIXME: generate words from pitch
    tdb_fns = [
        ("iob/build/segbits_tilegrid.tdb", 42, 4),
        # FIXME: height
        ("mmcm/build/segbits_tilegrid.tdb", 30, 101),
        # FIXME: height
        ("pll/build/segbits_tilegrid.tdb", 30, 101),
    ]
    for (tdb_fn, frames, words) in tdb_fns:
        for (tile, frame, wordidx) in load_db(tdb_fn):
            tilej = database[tile]
            bitsj = tilej['bits']
            bt = util.addr2btype(frame)
            verbose and print("Add %s %08X_%03u" % (tile, frame, wordidx))
            add_tile_bits(tilej, frame, wordidx, frames, words)

    # Save
    json.dump(database,
              open(fn_out, "w"),
              sort_keys=True,
              indent=4,
              separators=(",", ": "))