Exemple #1
0
def instantiate_indexor(prefix, width):
    """
    Instantiate an indexor for accessing memory with name `prefix`.
    Generates structure to initialize and update the indexor.

    The initializor starts sets the memories to their maximum value
    because we expect all indices to be incremented once before
    being used.

    Returns (cells, structure)
    """
    stdlib = py_ast.Stdlib()
    name = py_ast.CompVar(NAME_SCHEME["index name"].format(prefix=prefix))
    add_name = py_ast.CompVar(f"{prefix}_add")
    cells = [
        py_ast.Cell(name, stdlib.register(width)),
        py_ast.Cell(add_name, stdlib.op("add", width, signed=False)),
    ]

    init_name = py_ast.CompVar(NAME_SCHEME["index init"].format(prefix=prefix))
    init_group = py_ast.Group(
        init_name,
        connections=[
            py_ast.Connect(py_ast.ConstantPort(width, 2**width - 1),
                           py_ast.CompPort(name, "in")),
            py_ast.Connect(py_ast.ConstantPort(1, 1),
                           py_ast.CompPort(name, "write_en")),
            py_ast.Connect(py_ast.CompPort(name, "done"),
                           py_ast.HolePort(init_name, "done")),
        ],
    )

    upd_name = py_ast.CompVar(
        NAME_SCHEME["index update"].format(prefix=prefix))
    upd_group = py_ast.Group(
        upd_name,
        connections=[
            py_ast.Connect(py_ast.ConstantPort(width, 1),
                           py_ast.CompPort(add_name, "left")),
            py_ast.Connect(py_ast.CompPort(name, "out"),
                           py_ast.CompPort(add_name, "right")),
            py_ast.Connect(py_ast.CompPort(add_name, "out"),
                           py_ast.CompPort(name, "in")),
            py_ast.Connect(py_ast.ConstantPort(1, 1),
                           py_ast.CompPort(name, "write_en")),
            py_ast.Connect(py_ast.CompPort(name, "done"),
                           py_ast.HolePort(upd_name, "done")),
        ],
    )

    return (cells, [init_group, upd_group])
Exemple #2
0
def instantiate_data_move(row, col, right_edge, down_edge):
    """
    Generates groups for "data movers" which are groups that move data
    from the `write` register of the PE at (row, col) to the read register
    of the PEs at (row+1, col) and (row, col+1)
    """
    name = f"pe_{row}_{col}"
    structures = []

    if not right_edge:
        group_name = py_ast.CompVar(
            NAME_SCHEME["register move right"].format(pe=name))
        src_reg = py_ast.CompVar(f"left_{row}_{col}")
        dst_reg = py_ast.CompVar(f"left_{row}_{col + 1}")
        mover = py_ast.Group(
            group_name,
            connections=[
                py_ast.Connect(py_ast.CompPort(src_reg, "out"),
                               py_ast.CompPort(dst_reg, "in")),
                py_ast.Connect(py_ast.ConstantPort(1, 1),
                               py_ast.CompPort(dst_reg, "write_en")),
                py_ast.Connect(
                    py_ast.CompPort(dst_reg, "done"),
                    py_ast.HolePort(group_name, "done"),
                ),
            ],
        )
        structures.append(mover)

    if not down_edge:
        group_name = py_ast.CompVar(
            NAME_SCHEME["register move down"].format(pe=name))
        src_reg = py_ast.CompVar(f"top_{row}_{col}")
        dst_reg = py_ast.CompVar(f"top_{row + 1}_{col}")
        mover = py_ast.Group(
            group_name,
            connections=[
                py_ast.Connect(py_ast.CompPort(src_reg, "out"),
                               py_ast.CompPort(dst_reg, "in")),
                py_ast.Connect(py_ast.ConstantPort(1, 1),
                               py_ast.CompPort(dst_reg, "write_en")),
                py_ast.Connect(
                    py_ast.CompPort(dst_reg, "done"),
                    py_ast.HolePort(group_name, "done"),
                ),
            ],
        )
        structures.append(mover)

    return structures
Exemple #3
0
def instantiate_output_move(row, col, row_idx_bitwidth, col_idx_bitwidth):
    """
    Generates groups to move the final value from a PE into the output array.
    """
    group_name = py_ast.CompVar(
        NAME_SCHEME["out mem move"].format(pe=f"pe_{row}_{col}"))
    pe = py_ast.CompVar(f"pe_{row}_{col}")
    return py_ast.Group(
        group_name,
        connections=[
            py_ast.Connect(
                py_ast.ConstantPort(row_idx_bitwidth, row),
                py_ast.CompPort(OUT_MEM, "addr0"),
            ),
            py_ast.Connect(
                py_ast.ConstantPort(col_idx_bitwidth, col),
                py_ast.CompPort(OUT_MEM, "addr1"),
            ),
            py_ast.Connect(py_ast.CompPort(pe, "out"),
                           py_ast.CompPort(OUT_MEM, "write_data")),
            py_ast.Connect(py_ast.ConstantPort(1, 1),
                           py_ast.CompPort(OUT_MEM, "write_en")),
            py_ast.Connect(py_ast.CompPort(OUT_MEM, "done"),
                           py_ast.HolePort(group_name, "done")),
        ],
    )
Exemple #4
0
def instantiate_memory(top_or_left, idx, size):
    """
    Instantiates:
    - top memory
    - structure to move data from memory to read registers.

    Returns (cells, structure) tuple.
    """
    if top_or_left == "top":
        name = f"t{idx}"
        target_reg = f"top_0_{idx}"
    elif top_or_left == "left":
        name = f"l{idx}"
        target_reg = f"left_{idx}_0"
    else:
        raise f"Invalid top_or_left: {top_or_left}"

    var_name = py_ast.CompVar(f"{name}")
    idx_name = py_ast.CompVar(NAME_SCHEME["index name"].format(prefix=name))
    group_name = py_ast.CompVar(NAME_SCHEME["memory move"].format(prefix=name))
    target_reg = py_ast.CompVar(target_reg)
    structure = py_ast.Group(
        group_name,
        connections=[
            py_ast.Connect(py_ast.CompPort(idx_name, "out"),
                           py_ast.CompPort(var_name, "addr0")),
            py_ast.Connect(
                py_ast.CompPort(var_name, "read_data"),
                py_ast.CompPort(target_reg, "in"),
            ),
            py_ast.Connect(py_ast.ConstantPort(1, 1),
                           py_ast.CompPort(target_reg, "write_en")),
            py_ast.Connect(py_ast.CompPort(target_reg, "done"),
                           py_ast.HolePort(group_name, "done")),
        ],
    )

    idx_width = bits_needed(size)
    # Instantiate the indexor
    (idx_cells, idx_structure) = instantiate_indexor(name, idx_width)
    idx_structure.append(structure)
    # Instantiate the memory
    idx_cells.append(
        py_ast.Cell(
            var_name,
            py_ast.Stdlib().mem_d1(BITWIDTH, size, idx_width),
            is_external=True,
        ))
    return (idx_cells, idx_structure)