예제 #1
0
파일: gen-systolic.py 프로젝트: yn224/calyx
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)
예제 #2
0
파일: gen-systolic.py 프로젝트: yn224/calyx
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])
예제 #3
0
파일: gen-systolic.py 프로젝트: yn224/calyx
def instantiate_output_move(row, col, cols, 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}"))
    idx = row * cols + col
    pe = py_ast.CompVar(f"pe_{row}_{col}")
    return py_ast.Group(
        group_name,
        connections=[
            py_ast.Connect(
                py_ast.ConstantPort(idx_bitwidth, idx),
                py_ast.CompPort(OUT_MEM, "addr0"),
            ),
            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")),
        ],
    )
예제 #4
0
파일: gen-systolic.py 프로젝트: yn224/calyx
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