def _build_standard_mask(fab_dims, wire_lengths): ''' _build_standard_mask :: (int, int) -> [int] -> (Mask, int, int, int) The return value is MASK, MASK_ROWS, MASK_COLS, MWL where MASK:= MWL COLS MWL 0...0 1....1 0...0 . . ROWS . . . . 0...0 1....1 0...0 MWL := max(wire_lengths) ROWS := fab_dims[0] COLS := fab_dims[1] MASK_ROWS := ROWS MASK_COLS := MWL + COLS + MWL ''' mwl = max(wire_lengths) mrows = fab_dims[0] mcols = fab_dims[1] + 2 * mwl mask = zu.Mask(value=[0] * mwl + [1] * fab_dims[1] + [0] * mwl, size=mrows * mcols) for i in range(mrows.bit_length()): mask |= mask << (mcols * 2**i) return mask, mrows, mcols, mwl
def check_model(model, comps, fab_dims, wire_lengths, printer=print, *pargs, **kwargs): correct = [True, True, True] mask, mrows, mcols, mwl = _build_standard_mask(fab_dims, wire_lengths) #mask formatting functions def row_formatter(size, value, idx, v): if idx % mcols == mcols - 1: return '\n' else: return '' spacing = max(len(x.name) for x in comps) + 1 def choose_between(masks, overlap_c, none_c, w=spacing): def elem_f(size, value, idx, v): for m, n in masks: if m[idx] and not any(other[idx] for other, _ in masks if other is not m): return '{n: ^{w}}'.format(n=n, w=w) elif m[idx]: return '{n: ^{w}}'.format(n=overlap_c, w=w) return '{n: ^{w}}'.format(n=none_c, w=w) return elem_f #check correctness of placement printer("Checking validity of placement...", *pargs, **kwargs) for comp in comps: p = zu.Mask(model.evaluate(comp.pos).as_long(), size=mask.size) if p.hamming != __COMP_AREA: correct[0] = False printer( '{} has incorrect size, expected {} has {}'.format( comp.name, __COMP_AREA, p.hamming), *pargs, **kwargs) printer(p.to_formatted_string(post_f=row_formatter), *pargs, **kwargs) if p & ~mask != 0: correct[0] = False printer('{} was placed in the masked region'.format(comp.name, p), *pargs, **kwargs) elem_f = choose_between([(p, 'X'), (mask, '1')], overlap_c='C', none_c='0') printer(p.to_formatted_string(elem_f=elem_f, post_f=row_formatter), *pargs, **kwargs) if correct[0]: printer("Pass", *pargs, **kwargs) #check adjacency is satisfied printer("Checking adjacency rules are satisfied...", *pargs, **kwargs) for comp in comps: p = zu.Mask(model.evaluate(comp.pos).as_long(), size=mask.size) for adj in comp.inputs: adj_p = zu.Mask(model.evaluate(adj.pos).as_long(), size=mask.size) c = [] for wl in wire_lengths: c.extend([ p == adj_p << wl, p == adj_p >> wl, p == adj_p << wl * mcols, p == adj_p >> wl * mcols, ]) if not any(c): correct[1] = False printer( '{} and {} are not adjacent'.format(comp.name, adj.name), *pargs, **kwargs) elem_f = choose_between([(p, comp.name), (adj_p, adj.name)], overlap_c='X', none_c='-') printer( p.to_formatted_string(elem_f=elem_f, post_f=row_formatter), *pargs, **kwargs) if correct[1]: printer("Pass", *pargs, **kwargs) #check uniqueness of placement printer("Checking uniqueness of placement...", *pargs, **kwargs) unmarked = set(c for c in comps) for comp in comps: unmarked.remove(comp) p = zu.Mask(model.evaluate(comp.pos).as_long(), size=mask.size) for other in unmarked: other_p = zu.Mask(model.evaluate(other.pos).as_long(), size=mask.size) if p & other_p != 0: correct[2] = False printer('{} and {} overlap'.format(comp.name, other.name), *pargs, **kwargs) elem_f = choose_between([(p, comp.name), (other_p, other.name)], overlap_c='X', none_c='-') printer( p.to_formatted_string(elem_f=elem_f, post_f=row_formatter), *pargs, **kwargs) if correct[2]: printer("Pass", *pargs, **kwargs) return correct