示例#1
0
def place_constraints(comps, fab_dims, wire_lengths):
    '''
        place_constraints :: {Component} -> (int, int) -> [int] -> z3.z3.BoolRef
    '''
    nnode = len(comps)

    #build bit mask
    mask, mrows, mcols, mwl = _build_standard_mask(fab_dims, wire_lengths)

    #print bitmask
    #for idx, v in enumerate(mask):
    #    print(v, end='')
    #    if (idx % mcols) == mcols - 1:
    #        print()

    imask = int(~mask)
    mask = int(mask)

    for comp in comps:
        comp.pos = z3.BitVec(comp.name, mrows * mcols)

    constraints = []
    for comp in comps:
        for adj in comp.inputs:
            #should dispatch to fabric to get the rules
            c = []
            for wl in wire_lengths:
                #should probably be comp.pos & (shifted adj.pos) != 0,
                #so that components can have variable size
                c.append(
                    z3.Or(
                        comp.pos == z3.LShR(adj.pos, wl),
                        comp.pos == adj.pos << wl,
                        comp.pos == z3.LShR(adj.pos, wl * mcols),
                        comp.pos == adj.pos << wl * mcols,
                    ))

            constraints.append(z3.Or(c))

        constraints.append(zu.hamming(comp.pos) == __COMP_AREA)
        #The following is insufficient to achieve the previous
        #constraints.append(comp.pos != 0)

        constraints.append(comp.pos & imask == 0)

    u = ft.reduce(lambda x, y: x | y, [c.pos for c in comps])
    constraints.append(zu.hamming(u) == nnode)

    return z3.And(constraints)
示例#2
0
def place_constraints_2d(comps, fab_dims, wire_lengths, pack=True):
    '''
        place_constraints :: {Component} -> (int, int) -> [int] -> Bool? -> z3.z3.BoolRef
    '''
    nnode = len(comps)

    frows, fcols = fab_dims

    constraints = []
    if pack:

        def _get_x(bv):
            return z3.Extract(frows + fcols - 1, frows, bv)

        def _get_y(bv):
            return z3.Extract(frows - 1, 0, bv)

        for comp in comps:
            comp.pos = z3.BitVec(comp.name, frows + fcols)
        constraints.append(
            z3.simplify(z3.Distinct(*(c.pos for c in comps)),
                        ':blast-distinct', True))

    else:

        def _get_x(bv):
            return bv[0]

        def _get_y(bv):
            return bv[1]

        for comp in comps:
            comp.pos = (z3.BitVec(comp.name + '_x',
                                  frows), z3.BitVec(comp.name + '_y', fcols))
        constraints.append(
            z3.simplify(
                z3.Distinct(*(z3.Concat(c.pos[0], c.pos[1]) for c in comps)),
                ':blast-distinct', True))

    for comp in comps:
        constraints.append(zu.hamming(_get_x(comp.pos)) == __COMP_X)
        constraints.append(zu.hamming(_get_y(comp.pos)) == __COMP_Y)

    return z3.And(constraints)
示例#3
0
def place_constraints_opt(comps, fab_dims, distinct_flag=True):
    '''
        place_constraints_opt :: {Component} -> (int, int) -> [int] -> (z3.z3.BoolRef)
    '''
    rows = fab_dims[0]
    cols = fab_dims[1]
    nnode = len(comps)

    constraints = []
    if distinct_flag:
        c = []
        for comp in comps:
            #add a tuple representing the x,y coordinates
            comp.pos = (z3.BitVec(comp.name + '_x',
                                  int(math.ceil(math.log(cols, 2)))),
                        z3.BitVec(comp.name + '_y',
                                  int(math.ceil(math.log(rows, 2)))))
            c.append(z3.Concat(comp.pos[0], comp.pos[1]))
        constraints.append(z3.simplify(z3.Distinct(c), ':blast-distinct',
                                       True))
    else:
        onehot_list = []
        for comp in comps:
            comp.pos = (z3.BitVec(comp.name + '_x',
                                  int(math.ceil(math.log(cols, 2)))),
                        z3.BitVec(comp.name + '_y',
                                  int(math.ceil(math.log(rows, 2)))))
            #one hot representation -- temporary var
            temp_1h = z3.BitVec(comp.name, rows * cols)
            onehot_list.append(temp_1h)
            constraints.append(zu.hamming(temp_1h) == __COMP_AREA)
            constraints.append(
                z3.Extract(
                    0, 0,
                    z3.LShR(temp_1h,
                            find_shift(comp.pos[0], comp.pos[1], rows, cols)))
                == 1)

        u = ft.reduce(lambda x, y: x | y, [bv for bv in onehot_list])
        constraints.append(zu.hamming(u) == nnode)

    #check if number of rows/cols is a power of two (and thus placements can be any bit representation), if not, constrain the placements to be on fabric
    if not math.log(rows, 2).is_integer() and not math.log(cols,
                                                           2).is_integer():
        for comp in comps:
            constraints.append(
                z3.And(z3.ULT(comp.pos[0], cols), z3.ULT(comp.pos[1], rows)))
    elif not math.log(rows, 2).is_integer():
        for comp in comps:
            constraints.append(z3.ULT(comp.pos[1], rows))
    elif not math.log(cols, 2).is_integer():
        for comp in comps:
            constraints.append(z3.ULT(comp.pos[0], cols))

#form the manhattan distance
    manhattan_dist = 0
    for comp in comps:
        for adj in comp.inputs:
            manhattan_dist += abs_diff(comp.pos[0], adj.pos[0],
                                       fab_dims) + abs_diff(
                                           comp.pos[1], adj.pos[1], fab_dims)

    return z3.And(constraints), manhattan_dist
示例#4
0
def place_constraints_2d(comps, fab_dims, wire_lengths, pack=True):
    '''
        place_constraints :: {Component} -> (int, int) -> [int] -> Bool? -> z3.z3.BoolRef
    '''
    nnode = len(comps)

    frows, fcols = fab_dims

    constraints = []
    if pack:

        def _get_x(bv):
            return z3.Extract(frows + fcols - 1, frows, bv)

        def _get_y(bv):
            return z3.Extract(frows - 1, 0, bv)

        for comp in comps:
            comp.pos = z3.BitVec(comp.name, frows + fcols)
        constraints.append(z3.Distinct(*(c.pos for c in comps)))

    else:

        def _get_x(bv):
            return bv[0]

        def _get_y(bv):
            return bv[1]

        for comp in comps:
            comp.pos = (z3.BitVec(comp.name + '_x',
                                  frows), z3.BitVec(comp.name + '_y', fcols))
        constraints.append(
            z3.Distinct(*(z3.Concat(c.pos[0], c.pos[1]) for c in comps)))

    for comp in comps:
        for adj in comp.inputs:
            #should dispatch to fabric to get the rules
            c = []
            for wl in wire_lengths:
                #should probably be comp.pos & (shifted adj.pos) != 0,
                #so that components can have variable size
                c.append(
                    z3.Or(
                        z3.And(
                            _get_x(comp.pos) == z3.LShR(_get_x(adj.pos), wl),
                            _get_y(comp.pos) == _get_y(adj.pos)),
                        z3.And(
                            _get_x(comp.pos) == _get_x(adj.pos) << wl,
                            _get_y(comp.pos) == _get_y(adj.pos)),
                        z3.And(
                            _get_y(comp.pos) == z3.LShR(_get_y(adj.pos), wl),
                            _get_x(comp.pos) == _get_x(adj.pos)),
                        z3.And(
                            _get_y(comp.pos) == _get_y(adj.pos) << wl,
                            _get_x(comp.pos) == _get_x(adj.pos)),
                    ))

            constraints.append(z3.Or(c))

        constraints.append(zu.hamming(_get_x(comp.pos)) == __COMP_X)
        constraints.append(zu.hamming(_get_y(comp.pos)) == __COMP_Y)

    return z3.And(constraints)
示例#5
0
def place_constraints_2d(comps, fab_dims, wire_lengths, pack=True):
    '''
        place_constraints :: {Component} -> (int, int) -> [int] -> Bool? -> z3.z3.BoolRef
    '''
    nnode = len(comps)

    frows, fcols = fab_dims

    constraints = []
    if pack:

        def _get_x(bv):
            return z3.Extract(frows + fcols - 1, frows, bv)

        def _get_y(bv):
            return z3.Extract(frows - 1, 0, bv)

        for comp in comps:
            comp.pos = z3.BitVec(comp.name, frows + fcols)
        constraints.append(
            z3.simplify(z3.Distinct(*(c.pos for c in comps)),
                        ':blast-distinct', True))

    else:

        def _get_x(bv):
            return bv[0]

        def _get_y(bv):
            return bv[1]

        #for comp in comps: comp.pos = (z3.BitVec(comp.name + '_x', frows), z3.BitVec(comp.name + '_y', fcols))
        #constraints.append(z3.simplify(z3.Distinct(*(z3.Concat(c.pos[0], c.pos[1]) for c in comps)), ':blast-distinct', True))
        c = []
        for comp in comps:
            #add a tuple representing the x,y coordinates
            comp.pos = (z3.BitVec(comp.name + '_x',
                                  frows), z3.BitVec(comp.name + '_y', fcols))
            c.append(z3.Concat(comp.pos[0], comp.pos[1]))
        constraints.append(z3.simplify(z3.Distinct(c), ':blast-distinct',
                                       True))

    shiftvars = []
    for comp in comps:
        for adj in comp.inputs:
            #should dispatch to fabric to get the rules
            shx = z3.BitVec(comp.name + '-' + adj.name + '_shx', frows)
            shy = z3.BitVec(comp.name + '-' + adj.name + '_shy', fcols)
            shiftvars.append(shx)
            shiftvars.append(shy)
            constraints.append(
                z3.Or(
                    _get_x(comp.pos) == z3.LShR(_get_x(adj.pos), shx),
                    _get_x(comp.pos) == _get_x(adj.pos) << shx))
            constraints.append(
                z3.Or(
                    _get_y(comp.pos) == z3.LShR(_get_y(adj.pos), shy),
                    _get_y(comp.pos) == _get_y(adj.pos) << shy))

        constraints.append(zu.hamming(_get_x(comp.pos)) == __COMP_X)
        constraints.append(zu.hamming(_get_y(comp.pos)) == __COMP_Y)

    return z3.And(constraints), shiftvars
示例#6
0
 def invariants(self):
     return z3.And(zu.hamming(self.x) == 1, zu.hamming(self.y) == 1)