Esempio n. 1
0
 def _fresh_output(self):
     # Change bit level names.
     outputs = dict(self.aigbv.output_map)
     relabels = {n: cmn._fresh() for n in outputs[self.output]}
     aig = self.aigbv.aig['o', relabels]
     circ = attr.evolve(self.aigbv,
                        aig=aig,
                        output_map=frozenset([(self.output, aig.outputs)]))
     # Change word level name.
     return type(self)(circ['o', {self.output: cmn._fresh()}])
Esempio n. 2
0
def atom(wordlen: int, val: Val, signed: bool = True) -> Expr:
    output = cmn._fresh()
    if val is None:
        val = cmn._fresh()

    if isinstance(val, str):
        aig = cmn.identity_gate(wordlen, val, output)
    else:
        aig = cmn.source(wordlen, val, output, signed)

    return (SignedBVExpr if signed else UnsignedBVExpr)(aig)
Esempio n. 3
0
 def concat(self, other):
     combiner = cmn.combine_gate(
         output=cmn._fresh(),
         left_wordlen=self.size,
         left=self.output,
         right_wordlen=other.size,
         right=other.output,
     )
     circ = self.aigbv | other.aigbv
     return type(self)(circ >> combiner)
Esempio n. 4
0
    def __or__(self, other):
        assert not self.outputs & other.outputs
        assert not self.latches & other.latches

        shared_inputs = self.inputs & other.inputs
        input_map = dict(self.input_map)
        if shared_inputs:
            relabels1 = {n: common._fresh() for n in shared_inputs}
            relabels2 = {n: common._fresh() for n in shared_inputs}
            self, other = self['i', relabels1], other['i', relabels2]

        circ = AIGBV(aig=self.aig | other.aig,
                     input_map=self.input_map | other.input_map,
                     output_map=self.output_map | other.output_map,
                     latch_map=self.latch_map | other.latch_map)

        if shared_inputs:
            for orig in shared_inputs:
                new1, new2 = relabels1[orig], relabels2[orig]
                circ <<= common.tee(len(input_map[orig]), {orig: [new1, new2]})

        return circ
Esempio n. 5
0
def _binary_gate(gate, expr1, expr2, same_circ=None):
    if isinstance(expr2, int):
        expr2 = atom(expr1.size, expr2, signed=isinstance(expr1, SignedBVExpr))

    assert expr1.size == expr2.size
    if expr1.aigbv == expr2.aigbv and same_circ is not None:
        return type(expr1)(same_circ(expr1))
    elif expr1.aigbv.aig.outputs & expr2.aigbv.aig.outputs:
        expr2 = expr2._fresh_output()

    circ3 = expr1.aigbv | expr2.aigbv
    circ3 >>= gate(wordlen=expr1.size,
                   output=cmn._fresh(),
                   left=expr1.output,
                   right=expr2.output)
    return type(expr1)(aigbv=circ3)
Esempio n. 6
0
 def repeat(self, times):
     # TODO: support size != 1 via self concatenation.
     assert self.size == 1
     repeater = cmn.repeat(times, self.output, cmn._fresh())
     return type(self)(self.aigbv >> repeater)
Esempio n. 7
0
 def _indexer(idx):
     return cmn.index_gate(self.size, idx, self.output, cmn._fresh())
Esempio n. 8
0
def _unary_gate(gate, expr):
    circ = gate(expr.size, input=expr.output, output=cmn._fresh())
    return type(expr)(aigbv=expr.aigbv >> circ)