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)
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
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
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)
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)