Beispiel #1
0
def init_routing_vars(cgra : MRRG, design : Design, vars : Modeler, solver : Solver) -> Term:
    bv1 = solver.BitVec(1)
    for node in cgra.all_nodes:
        for value in design.values:
            vars.init_var((node, value), bv1)
            for dst in value.dsts:
                vars.init_var((node, value, dst), bv1)
    return solver.TheoryConst(solver.Bool(), True)
Beispiel #2
0
def init_popcount_concat(
        node_filter : NodeFilter,
        cgra : MRRG,
        design : Design,
        vars : Modeler,
        solver : Solver) -> Term:

    nodes = [n for n in cgra.all_nodes if node_filter(n)]
    width = len(nodes).bit_length()
    zero = solver.TheoryConst(solver.BitVec(width - 1), 0)
    zeroExt = ft.partial(solver.Concat, zero)
    expr = ft.reduce(solver.BVAdd,
            map(zeroExt,
                (ft.reduce(solver.BVOr,
                    (vars[n, v] for v in design.values)
                ) for n in nodes)
            )
        )

    pop_count = vars.init_var(node_filter, expr.sort)
    return expr == pop_count
Beispiel #3
0
def init_popcount_ite(
        node_filter : NodeFilter,
        cgra : MRRG,
        design : Design,
        vars : Modeler,
        solver : Solver) -> Term:

    nodes = [n for n in cgra.all_nodes if node_filter(n)]
    bv = solver.BitVec(len(nodes).bit_length())
    zero = solver.TheoryConst(bv, 0)
    one  = solver.TheoryConst(bv, 1)

    expr = ft.reduce(solver.BVAdd,
            map(lambda x : solver.Ite(x == 0, zero, one),
                (ft.reduce(solver.BVOr,
                    (vars[n, v] for v in design.values)
                ) for n in nodes)
            )
        )

    pop_count = vars.init_var(node_filter, bv)
    return expr == pop_count
Beispiel #4
0
def init_popcount_bithack(
        node_filter : NodeFilter,
        cgra : MRRG,
        design : Design,
        vars : Modeler,
        solver : Solver) -> Term:

    def _build_grouped_mask(k, n):
        '''
        build_grouped_mask :: int -> int -> Term
        returns the unique int m of length n that matches the following RE
        ((0{0,k} 1{k}) | (1{0,k})) (0{k} 1{k})*
        '''
        m = 0
        for i in range(k):
            m |= 1 << i
        c = 2*k
        while c < n:
            m |= m << c
            c *= 2
        return solver.TheoryConst(solver.BitVec(n), m)

    def _is_power_of_2(x : int) -> bool:
        return x & (x - 1) == 0

    def _floor_log2(x : int) -> int:
        return x.bit_length() - 1

    def _prev_power_of_2(x : int) -> int:
        return 1 << _floor_log2(x - 1)

    def _next_power_of_2(x : int) -> int:
        return 1 << x.bit_length()


    constraints = []
    vs = [vars[n, v] for n in cgra.all_nodes if node_filter(n) for v in design.values]
    width = len(vs)
    # build a bitvector from the concanation of bits
    bv = vars.anonymous_var(solver.BitVec(width))

    for idx,v in enumerate(vs):
        constraints.append(bv[idx] == v)

    # Boolector can't handle lshr on non power of 2, so zero extend
    if solver.solver_name == 'Boolector' and not _is_power_of_2(width):
        l = _next_power_of_2(width)
        bv = solver.Concat(solver.TheoryConst(solver.BitVec(l - width), 0), bv)

    width = bv.sort.width
    pop_count = vars.init_var(node_filter, bv.sort)

    if width <= 1:
        constraints.append(pop_count == bv)
        return solver.And(constraints)
    elif width == 2:
        constraints.append(pop_count == (bv & 1) + (bv >> 1))
        return solver.And(constraints)

    max_shift = _prev_power_of_2(width)

    def _mask_shift_add(x, shift):
        mask = _build_grouped_mask(shift, width)
        return (x & mask) + ((x >> shift) & mask)

    shifts = it.takewhile(lambda n : n <= max_shift, (1 << i for i in it.count()))
    x = ft.reduce(_mask_shift_add, shifts, bv)

    constraints.append(pop_count == x)
    return solver.And(constraints)
Beispiel #5
0
def init_placement_vars(cgra : MRRG, design : Design, vars : Modeler, solver : Solver) -> Term:
    bv1 = solver.BitVec(1)
    for pe in cgra.functional_units:
        for op in design.operations:
            vars.init_var((pe, op), bv1)
    return solver.TheoryConst(solver.Bool(), True)