Esempio n. 1
0
    def Orr(in_, out):
        # INVAR: (in = 0) -> (out = 0) & (in != 0) -> (out = 1)
        vars_ = [in_, out]
        comment = "Orr (in, out) = (%s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if (in_.symbol_type() == BOOL) and (out.symbol_type() == BOOL):
            invar = EqualsOrIff(in_, out)
        else:

            if out.symbol_type() == BOOL:
                out0 = Not(out)
                out1 = out
            else:
                out0 = EqualsOrIff(out, BV(0, 1))
                out1 = EqualsOrIff(out, BV(1, 1))

            true_res = Implies(
                EqualsOrIff(in_, BV(0,
                                    in_.symbol_type().width)), out0)
            false_res = Implies(
                Not(EqualsOrIff(in_, BV(0,
                                        in_.symbol_type().width))), out1)

            invar = And(true_res, false_res)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Esempio n. 2
0
    def Mux(in0, in1, sel, out):
        # if Modules.functional
        # INVAR: out' = Ite(sel = 0, in0, in1)
        # else
        # INVAR: ((sel = 0) -> (out = in0)) & ((sel = 1) -> (out = in1))
        vars_ = [in0, in1, sel, out]
        comment = "Mux (in0, in1, sel, out) = (%s, %s, %s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if sel.symbol_type() == BOOL:
            sel0 = Not(sel)
            sel1 = sel
        else:
            sel0 = EqualsOrIff(sel, BV(0, 1))
            sel1 = EqualsOrIff(sel, BV(1, 1))

        if Modules.functional:
            invar = And(EqualsOrIff(out, Ite(sel0, in0, in1)))
        else:
            invar = And(Implies(sel0, EqualsOrIff(in0, out)),
                        Implies(sel1, EqualsOrIff(in1, out)))

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Esempio n. 3
0
    def parse_string(self, contents:str)->HTS:
        '''
        Parses a string representation of an initial state file
        '''
        hts = HTS("INIT")
        ts = TS("TS INIT")

        init = []

        for line in contents.split('\n'):
            line = line.strip()
            if not line:
                continue
            else:
                res = self.parse_line(line)
                if res is not None:
                    init.append(res)

        Logger.msg("Initial state file set concrete values for {} state variables".format(len(init)), 1)

        ts.init = And(init)
        ts.invar = TRUE()
        ts.trans = TRUE()
        hts.add_ts(ts)

        return hts
Esempio n. 4
0
    def Neq(in0, in1, out):
        # INVAR: (((in0 != in1) -> (out = #b1)) & ((in0 == in1) -> (out = #b0)))
        vars_ = [in0, in1, out]
        comment = "Eq (in0, in1, out) = (%s, %s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        # TODO: Create functional encoding
        if Modules.functional:
            if out.symbol_type() == BOOL:
                invar = EqualsOrIff(out, Not(EqualsOrIff(in0, in1)))
            else:
                invar = EqualsOrIff(out, BVNot(BVComp(in0, in1)))
        else:
            eq = EqualsOrIff(in0, in1)

            if out.symbol_type() == BOOL:
                out0 = Not(out)
                out1 = out
            else:
                out0 = EqualsOrIff(out, BV(0, 1))
                out1 = EqualsOrIff(out, BV(1, 1))

            invar = And(Implies(Not(eq), out1), Implies(eq, out0))

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Esempio n. 5
0
    def Zext(in_, out):
        # INVAR: (<op> in) = out)
        vars_ = [in_, out]
        comment = ("ZExt (in, out) = (%s, %s)") % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if (in_.symbol_type() == BOOL) and (out.symbol_type() == BOOL):
            invar = EqualsOrIff(in_, out)

        if (in_.symbol_type() != BOOL) and (out.symbol_type() == BOOL):
            invar = EqualsOrIff(BV2B(in_), out)

        if (in_.symbol_type() == BOOL) and (out.symbol_type() != BOOL):
            length = (out.symbol_type().width) - 1
            if length == 0:
                invar = EqualsOrIff(in_, BV2B(out))
            else:
                invar = EqualsOrIff(BVZExt(B2BV(in_), length), out)

        if (in_.symbol_type() != BOOL) and (out.symbol_type() != BOOL):
            length = (out.symbol_type().width) - (in_.symbol_type().width)
            if length == 0:
                invar = EqualsOrIff(in_, out)
            else:
                invar = EqualsOrIff(BVZExt(in_, length), out)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Esempio n. 6
0
    def Uop(bvop, bop, in_, out):
        # INVAR: (<op> in) = out)
        vars_ = [in_, out]
        comment = ""  #(bvop.__name__ + " (in, out) = (%s, %s)")%(tuple([x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        in_B = get_type(in_).is_bool_type()
        outB = get_type(out).is_bool_type()

        bools = (1 if in_B else 0) + (1 if outB else 0)

        if bop == None:
            if in_B:
                in_ = B2BV(in_)
            if outB:
                out = B2BV(out)
            invar = EqualsOrIff(bvop(in_), out)
        else:
            if bools == 2:
                invar = EqualsOrIff(bop(in_), out)
            elif bools == 0:
                invar = EqualsOrIff(bvop(in_), out)
            else:
                if not in_B:
                    invar = EqualsOrIff(bop(BV2B(in_)), out)
                if not outB:
                    invar = EqualsOrIff(bop(in_), BV2B(out))

        ts = TS(comment)
        ts.vars, ts.invar = get_free_variables(invar), invar
        return ts
Esempio n. 7
0
    def all_loopbacks(self, vars, k, heqvar=None):
        lvars = list(vars)
        vars_k = [TS.get_timed(v, k) for v in lvars]
        loopback = FALSE()
        eqvar = None
        heqvars = None

        if heqvar is not None:
            eqvar = Symbol(EQVAR, BOOL)
            heqvars = []

        peqvars = FALSE()

        for i in range(k):
            vars_i = [TS.get_timed(v, i) for v in lvars]
            eq_k_i = And(
                [EqualsOrIff(vars_k[j], vars_i[j]) for j in range(len(lvars))])
            if heqvar is not None:
                eqvar_i = TS.get_timed(eqvar, i)
                peqvars = Or(peqvars, eqvar_i)
                eq_k_i = And(eqvar_i, Iff(eqvar_i, eq_k_i))

                heqvars.append(Iff(TS.get_timed(heqvar, i), peqvars))

            loopback = Or(loopback, eq_k_i)

        if heqvar is not None:
            loopback = And(loopback, And(heqvars))

        return loopback
Esempio n. 8
0
    def MemAcc(self, left, right):
        primed = False
        if TS.is_prime(left):
            primed = True
            left = TS.get_ref_var(left)

        timed_symbol = lambda v: v if not primed else TS.get_prime(v)
            
        memname = left.symbol_name()
        allsymbols = list(get_env().formula_manager.get_all_symbols())
        memsymbols = [(v.symbol_name(), timed_symbol(v)) for v in allsymbols \
                      if (not TS.is_prime(v)) and (not TS.is_timed(v)) and (v.symbol_name()[:len(memname)] == memname) \
                      and v.symbol_name() != memname]
        memsymbols.sort()
        memsize = len(memsymbols)

        if memsize < 1:
            Logger.error("Memory \"%s\" has size 1"%(memname))
        
        if right.is_int_constant():
            location = right.constant_value()
            if location > memsize-1:
                Logger.error("Out of bound access for memory \"%s\", size %d"%(memname, memsize))
            return memsymbols[location][1]
        else:
            if not (right.is_symbol() and right.symbol_type().is_bv_type()):
                Logger.error("Symbolic memory access requires Bitvector indexing")
            width_idx = right.symbol_type().width
            width_mem = min(memsize, width_idx)
            return mem_access(right, [m[1] for m in memsymbols], width_idx)
Esempio n. 9
0
 def Posedge(self, x):
     if get_type(x).is_bool_type():
         if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
             return x
         return And(Not(x), TS.to_next(x))
     if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
         return EqualsOrIff(x, BV(1,1))
     return And(EqualsOrIff(x, BV(0,1)), BV2B(TS.to_next(x)))
Esempio n. 10
0
 def Negedge(self, x):
     if get_type(x).is_bool_type():
         if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
             return Not(x)
         return And(x, Not(TS.to_next(x)))
     if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
         return EqualsOrIff(x, BV(0,1))
     return And(BV2B(x), EqualsOrIff(TS.to_next(x), BV(0,1)))
Esempio n. 11
0
 def Undriven(_out):
     '''
     Undriven is a no-op. _out is just undriven
     '''
     vars_ = [_out]
     ts = TS("Undriven wire")
     ts.vars = set(vars_)
     return ts
Esempio n. 12
0
    def _remap_model_zz(self, vars, model, k):
        retmodel = dict([el for el in dict(model).items() if not TS.is_ptimed(el[0])])

        for var in vars:
            for t in range(int(k/2)+1, k+1, 1):
                retmodel[TS.get_timed(var, t)] = model[TS.get_ptimed(var, k-t)]

        return retmodel
Esempio n. 13
0
    def __encoding_memoization(self, inst_type, args):
        value = 0
        vec_par = []
        actual = []
        for x in args:
            if x is not None:
                if type(x) != int:
                    value += 1
                    vec_par.append(("a%s" % value, x.symbol_type().width))
                    actual.append(x)
            else:
                vec_par.append(x)

        def join(l1, l2):
            ret = []
            for i in range(len(l1)):
                ret.append((l1[i], l2[i]))

            return ret

        def set_remap(in_set, remap):
            ret = set([])

            source = False

            for v in in_set:
                if v in remap:
                    ret.add(remap[v])
                else:
                    if source is False:
                        base_source = ".".join(
                            list(in_set)[0].symbol_name().split(".")[:-1])
                        base_dest = ".".join(remap[list(
                            in_set)[0]].symbol_name().split(".")[:-1])
                        source = True

                    ret.add(
                        Symbol(v.symbol_name().replace(base_source, base_dest),
                               v.symbol_type()))

            return ret

        enc_val = (inst_type, str(vec_par))
        if enc_val in self.enc_map:
            (enc, formal) = self.enc_map[enc_val]
            remap = dict(join(formal, actual))
            self.subwalker.set_substitute_map(remap)
            ts = TS()
            ts.vars = set_remap(enc.vars, remap)
            ts.set_behavior(self.subwalker.walk(enc.init),
                            self.subwalker.walk(enc.trans),
                            self.subwalker.walk(enc.invar))
            return ts

        ret = self.mod_map[inst_type][0](*args)
        self.enc_map[enc_val] = (ret, actual)

        return ret
Esempio n. 14
0
    def _remap_model_bwd(self, vars, model, k):
        retmodel = dict()

        for var in vars:
            for t in range(k + 1):
                retmodel[TS.get_timed(var,
                                      t)] = model[TS.get_ptimed(var, k - t)]

        return retmodel
Esempio n. 15
0
 def Wrap(in_, out):
     # INVAR: (in = out)
     vars_ = [in_,out]
     comment = ("Wrap (in, out) = (%s, %s)")%(tuple([x.symbol_name() for x in vars_]))
     Logger.log(comment, 3)
     invar = EqualsOrIff(in_, out)
     ts = TS(comment)
     ts.vars, ts.invar = set(vars_), invar
     return ts
Esempio n. 16
0
    def _remap_model_zz(self, vars, model, k):
        retmodel = dict(model)

        for var in vars:
            for t in range(int(k / 2) + 1, k + 1, 1):
                retmodel[TS.get_timed(var,
                                      t)] = model[TS.get_ptimed(var, k - t)]

        return retmodel
Esempio n. 17
0
 def Slice(in_, out, low, high):
     # INVAR: (extract low high in) = out
     high -= 1
     vars_ = [in_,out, low, high]
     comment = "Mux (in, out, low, high) = (%s, %s, %s, %s)"%(tuple([str(x) for x in vars_]))
     Logger.log(comment, 3)
     invar = EqualsOrIff(BVExtract(in_, low, high), out)
     ts = TS(comment)
     ts.vars, ts.invar = set([in_, out]), invar
     return ts
Esempio n. 18
0
def revise_abstract_clock(model, abstract_clock_list):
    newmodel = {}
    abs_clock = dict(abstract_clock_list)
    length = 0
    for var, value in model.items():
        refvar = TS.get_ref_var(var)
        time = TS.get_time(var)

        if time > 0:
            if refvar not in abs_clock:
                newmodel[TS.get_timed(refvar, (time*2)-1)] = value
                newmodel[TS.get_timed(refvar, (time*2))] = value
            else:
                newmodel[TS.get_timed(refvar, (time*2)-1)] = abs_clock[refvar][1]
                if value == abs_clock[refvar][1]:
                    newmodel[TS.get_timed(refvar, (time*2))] = abs_clock[refvar][0]
                else:
                    newmodel[TS.get_timed(refvar, (time*2))] = abs_clock[refvar][1]
                if ((time*2)+1) > length:
                    length = ((time*2))
        else:
            if refvar not in abs_clock:
                newmodel[TS.get_timed(refvar, 0)] = value
            else:
                newmodel[TS.get_timed(refvar, 0)] = abs_clock[refvar][0]

    return (newmodel, length)
Esempio n. 19
0
    def extend_ts(ts, modifier):

        affect_init = False

        if ts.ftrans is None:
            return (ts, [])

        new_ftrans = {}

        vars = []

        for (assign, cond_assign_list) in ts.ftrans.items():
            fv = get_free_variables(assign)
            assert len(fv) == 1
            var = fv.pop()
            is_next = TS.has_next(var)

            refvar = TS.get_ref_var(var)
            nomvar = Symbol(NOMIN % refvar.symbol_name(), var.symbol_type())
            fvar = Symbol(FAULT % refvar.symbol_name(), BOOL)

            vars.append(nomvar)
            vars.append(fvar)

            repldic = dict([(refvar.symbol_name(), nomvar.symbol_name()), \
                            (TS.get_prime(refvar).symbol_name(), TS.get_prime(nomvar).symbol_name())])

            # Remapping nominal behavior to new variable
            new_ftrans[substitute(assign,
                                  repldic)] = [(substitute(c[0], repldic),
                                                substitute(c[1], repldic))
                                               for c in cond_assign_list]

            # Definition of the nominal behavior
            new_ftrans[refvar] = [(Not(fvar), nomvar)]

            # Application of the faulty behavior
            new_ftrans[refvar].append(
                (fvar, modifier.get_behavior(nomvar, refvar)))

            ts.trans = And(ts.trans, Implies(fvar, TS.get_prime(fvar)))

            if affect_init:
                ts.init = substitute(ts.init, repldic)
            else:
                ts.init = And(ts.init, Not(fvar))

        # add the vars to the transition system
        for var in vars:
            ts.add_var(var)

        ts.ftrans = new_ftrans

        return (ts, vars)
Esempio n. 20
0
 def Andr(in_, out):
     # INVAR: (in = 2**width - 1) -> (out = 1) & (in != 2**width - 1) -> (out = 0)
     vars_ = [in_, out]
     comment = "Andr (in, out) = (%s, %s)"%(tuple([x.symbol_name() for x in vars_]))
     Logger.log(comment, 3)
     width = in_.symbol_type().width
     eq_all_ones = EqualsOrIff(in_, BV(2**width - 1,width))
     true_res = Implies(eq_all_ones, EqualsOrIff(out, BV(1,1)))
     false_res = Implies(Not(eq_all_ones), EqualsOrIff(out, BV(0,1)))
     invar = And(true_res, false_res)
     ts = TS(comment)
     ts.vars, ts.invar = set(vars_), invar
     return ts
Esempio n. 21
0
    def MultiOp(op, end_op, out, *inparams):
        cum = inparams[0]
        for el in inparams[1:]:
            cum = op(cum, el)

        if end_op is not None:
            cum = end_op(cum)

        formula = EqualsOrIff(cum, out)

        ts = TS()
        ts.vars, ts.invar = get_free_variables(formula), formula
        return ts
Esempio n. 22
0
    def Const(out, value):
        invar = TRUE()
        if value is not None:
            if out.symbol_type() == BOOL:
                const = TRUE() if value == 1 else FALSE()
            else:
                const = BV(value, out.symbol_type().width)
            invar = EqualsOrIff(out, const)

        comment = "Const (out, val) = (" + out.symbol_name() + ", " + str(value) + ")"
        Logger.log(comment, 3)
        ts = TS(comment)
        ts.vars, ts.invar = set([out]), invar
        return ts
Esempio n. 23
0
    def Clock(clk):
        # INIT: clk = 0
        # TRANS: clk' = !clk
        comment = "Clock (clk) = (" + clk.symbol_name() + ")"

        if clk.symbol_type() == BOOL:
            clk0 = Not(clk)
            clk1 = clk
        else:
            clk0 = EqualsOrIff(clk, BV(0, 1))
            clk1 = EqualsOrIff(clk, BV(1, 1))

        init = clk0

        invar = TRUE()

        if False:
            trans = EqualsOrIff(clk0, TS.to_next(clk1))
        else:
            # Implementation that leverages on the boolean propagation
            trans1 = Implies(clk0, TS.to_next(clk1))
            trans2 = Implies(clk1, TS.to_next(clk0))
            trans = And(trans1, trans2)

        if Modules.abstract_clock:
            invar = clk0
            init = TRUE()
            trans = TRUE()

        ts = TS(comment)
        ts.vars, ts.state_vars = set([clk]), set([clk])
        ts.set_behavior(init, trans, invar)
        return ts
Esempio n. 24
0
    def BopBool(op, in0, in1, out):
        # INVAR: (in0 <op> in1) = out
        vars_ = [in0,in1,out]
        comment = (op.__name__ + " (in0, in1, out) = (%s, %s, %s)")%(tuple([x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if out.symbol_type() == BOOL:
            bout = out
        else:
            bout = EqualsOrIff(out, BV(1, 1))

        invar = Iff(op(in0,in1), bout)
        ts = TS(comment)
        ts.vars, ts.invar = get_free_variables(invar), invar
        return ts
Esempio n. 25
0
    def parse_formulae(self, strforms):
        formulae = []

        if strforms is None:
            return formulae

        for strform in strforms:
            if ("#" not in strform) and (strform != ""):
                formula = self.parse_formula(strform)
                formula_fv = get_free_variables(formula)
                nextvars = [v for v in formula_fv if TS.is_prime(v)] != []
                prevvars = [v for v in formula_fv if TS.is_prev(v)] != []
                formulae.append((strform, formula, (nextvars, prevvars)))

        return formulae
Esempio n. 26
0
    def _get_param_assignments(self, model, time, parameters, monotonic=True):
        p_ass = []

        fwd = False

        for p in parameters:
            # search the trace for any enabled faults
            ever_true = False
            for t in range(time + 1):
                p_time = model[TS.get_ptimed(p, 0)]
                if p.symbol_type() == BOOL:
                    if p_time == TRUE():
                        ever_true = True
                        break

            if ever_true:
                p_ass.append(p)
            elif not monotonic:
                p_ass.append(EqualsOrIff(p, FALSE()))

        p_ass = And(p_ass)
        self.region = simplify(Or(self.region, p_ass))

        if self.models is None:
            self.models = []
        self.models.append((model, time))

        Logger.msg("+", 0, not (Logger.level(1)))
        self.cs_count += 1
        Logger.log(
            "Found assignment \"%s\"" % (p_ass.serialize(threshold=100)), 1)

        return (p_ass, False)
Esempio n. 27
0
    def solve_safety_inc_zz(self, hts, prop, k):
        self._reset_assertions(self.solver)

        if TS.has_next(prop):
            Logger.error(
                "Invariant checking with next variables only supports FWD strategy"
            )

        init = hts.single_init()
        trans = hts.single_trans()
        invar = hts.single_invar()

        initt = self.at_time(And(init, invar), 0)
        Logger.log("Add init at_0", 2)
        self._add_assertion(self.solver, initt)

        propt = self.at_ptime(And(Not(prop), invar), -1)
        Logger.log("Add property pat_%d" % 0, 2)
        self._add_assertion(self.solver, propt)

        t = 0
        while (t < k + 1):
            self._push(self.solver)
            even = (t % 2) == 0
            th = int(t / 2)

            if even:
                eq = And([
                    EqualsOrIff(self.at_time(v, th), self.at_ptime(v, th - 1))
                    for v in hts.vars
                ])
            else:
                eq = And([
                    EqualsOrIff(self.at_time(v, th + 1),
                                self.at_ptime(v, th - 1)) for v in hts.vars
                ])

            Logger.log("Add equivalence time %d" % t, 2)
            self._add_assertion(self.solver, eq)

            if self._solve(self.solver):
                Logger.log("Counterexample found with k=%s" % (t), 1)
                model = self._get_model(self.solver)
                return (t, model)
            else:
                Logger.log("No counterexample found with k=%s" % (t), 1)
                Logger.msg(".", 0, not (Logger.level(1)))

            self._pop(self.solver)

            if even:
                trans_t = self.unroll(trans, invar, th + 1, th)
            else:
                trans_t = self.unroll(trans, invar, th, th + 1)

            self._add_assertion(self.solver, trans_t)

            t += 1

        return (t - 1, None)
Esempio n. 28
0
    def _get_param_assignments(self, model, time, parameters, monotonic=True):
        p_ass = []

        fwd = False

        for p in parameters:
            p_time = model[TS.get_ptimed(p, 0)]
            if p.symbol_type() == BOOL:
                if monotonic:
                    if p_time == TRUE():
                        p_ass.append(p)
                else:
                    p_ass.append(p if p_time == TRUE() else Not(p))
            else:
                p_ass.append(EqualsOrIff(p, p_time))

        p_ass = And(p_ass)
        self.region = simplify(Or(self.region, p_ass))

        if self.models is None:
            self.models = []
        self.models.append((model, time))

        Logger.msg("+", 0, not (Logger.level(1)))
        self.cs_count += 1
        Logger.log(
            "Found assignment \"%s\"" % (p_ass.serialize(threshold=100)), 1)

        return (p_ass, False)
Esempio n. 29
0
 def Term(_in):
     '''
     Term is a no-op. Just terminates a coreir wireable
     '''
     vars_ = [_in]
     ts = TS("Terminate wire")
     return ts
Esempio n. 30
0
    def get_sts(self, params):
        if len(params) != len(self.interface.split()):
            Logger.error("Invalid parameters for clock behavior \"%s\"" %
                         (self.name))
        clk = params[0]
        valuepar = params[1]

        if (not type(clk) == FNode) or (not clk.is_symbol()):
            Logger.error("Clock symbol \"%s\" not found" % (str(clk)))

        if (type(valuepar) == FNode) and (valuepar.is_bv_constant()):
            value = valuepar.constant_value()
        else:
            try:
                value = int(valuepar)
            except:
                Logger.error(
                    "Clock value should be an integer number instead of \"%s\""
                    % valuepar)

        init = []
        invar = []
        trans = []
        vars = set([])

        if clk.symbol_type().is_bv_type():
            pos_clk = EqualsOrIff(clk, BV(1, 1))
            neg_clk = EqualsOrIff(clk, BV(0, 1))
        else:
            pos_clk = clk
            neg_clk = Not(clk)

        if value == 1:
            invar.append(pos_clk)
        else:
            invar.append(neg_clk)

        ts = TS("Clock Behavior")
        ts.vars, ts.init, ts.invar, ts.trans = vars, And(init), And(
            invar), And(trans)

        Logger.log(
            "Adding clock behavior \"%s(%s)\"" %
            (self.name, ", ".join([str(p) for p in params])), 1)

        return ts