Esempio n. 1
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. 2
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. 3
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. 4
0
    def add_lemmas(self, hts, prop, lemmas):
        if len(lemmas) == 0:
            return (hts, False)

        self._reset_assertions(self.solver)

        h_init = hts.single_init()
        h_trans = hts.single_trans()

        holding_lemmas = []
        lindex = 1
        nlemmas = len(lemmas)
        tlemmas = 0
        flemmas = 0
        for lemma in lemmas:
            Logger.log("\nChecking Lemma %s/%s" % (lindex, nlemmas), 1)
            invar = hts.single_invar()
            init = And(h_init, invar)
            trans = And(invar, h_trans, TS.to_next(invar))
            if self._check_lemma(hts, lemma, init, trans):
                holding_lemmas.append(lemma)
                hts.add_assumption(lemma)
                hts.reset_formulae()

                Logger.log("Lemma %s holds" % (lindex), 1)
                tlemmas += 1
                if self._suff_lemmas(prop, holding_lemmas):
                    return (hts, True)
            else:
                Logger.log("Lemma %s does not hold" % (lindex), 1)
                flemmas += 1

            msg = "%s T:%s F:%s U:%s" % (status_bar(
                (float(lindex) / float(nlemmas)), False), tlemmas, flemmas,
                                         (nlemmas - lindex))
            Logger.inline(msg, 0, not (Logger.level(1)))
            lindex += 1

        Logger.clear_inline(0, not (Logger.level(1)))

        for lemma in holding_lemmas:
            hts.add_assumption(lemma)
        return (hts, False)
Esempio n. 5
0
File: sugar.py Progetto: pllab/CoSA
 def NoChange(self, x):
     return EqualsOrIff(x, TS.to_next(x))
Esempio n. 6
0
File: sugar.py Progetto: pllab/CoSA
 def Change(self, x):
     return Not(EqualsOrIff(x), TS.to_next(x))
Esempio n. 7
0
    def compile_sts(self, name, params):
        sparser = StringParser()
        in_port, max_val, c_push, c_pop = list(params)
        max_val = int(max_val)

        if type(c_push) == str:
            c_push = sparser.parse_formula(c_push)
        if type(c_pop) == str:
            c_pop = sparser.parse_formula(c_pop)

        tracking = Symbol("%s.tracking" % name, BOOL)
        end = Symbol("%s.end" % name, BOOL)
        done = Symbol("%s.done" % name, BOOL)
        packet = Symbol("%s.packet" % name,
                        BVType(in_port.symbol_type().width))
        max_width = math.ceil(math.log(max_val) / math.log(2))

        max_bvval = BV(max_val, max_width)
        zero = BV(0, max_width)
        one = BV(1, max_width)
        count = Symbol("%s.count" % name, BVType(max_width))
        size = Symbol("%s.size" % name, BVType(max_width))

        pos_c_push = BV2B(c_push)
        neg_c_push = Not(BV2B(c_push))

        pos_c_pop = BV2B(c_pop)
        neg_c_pop = Not(BV2B(c_pop))

        init = []
        trans = []
        invar = []

        # INIT DEFINITION #

        # count = 0
        init.append(EqualsOrIff(count, BV(0, max_width)))
        # tracking = False
        init.append(EqualsOrIff(tracking, FALSE()))
        # size = 0
        init.append(EqualsOrIff(size, BV(0, max_width)))
        # end = false
        init.append(EqualsOrIff(end, FALSE()))

        # INVAR DEFINITION #

        # !done -> (end = (tracking & (size = count)))
        invar.append(
            Implies(Not(done),
                    EqualsOrIff(end, And(tracking, EqualsOrIff(size, count)))))

        # count <= size
        invar.append(BVULE(count, size))
        # count <= maxval
        invar.append(BVULE(count, max_bvval))
        # size <= maxval
        invar.append(BVULE(size, max_bvval))

        # done -> (end <-> False);
        invar.append(Implies(done, EqualsOrIff(end, FALSE())))
        # done -> (count = 0_8);
        invar.append(Implies(done, EqualsOrIff(count, BV(0, max_width))))
        # done -> (size = 0_8);
        invar.append(Implies(done, EqualsOrIff(size, BV(0, max_width))))
        # done -> (packet = 0_8);
        invar.append(
            Implies(done,
                    EqualsOrIff(packet, BV(0,
                                           in_port.symbol_type().width))))

        # TRANS DEFINITION #

        # (!end & !done) -> next(!done);
        trans.append(Implies(And(Not(end), Not(done)), TS.to_next(Not(done))))
        # end -> next(done);
        trans.append(Implies(end, TS.to_next(done)))
        # done -> next(done);
        trans.append(Implies(done, TS.to_next(done)))

        # tracking -> next(tracking);
        trans.append(
            Implies(Not(done), Implies(tracking, TS.to_next(tracking))))
        # tracking -> (next(packet) = packet);
        trans.append(
            Implies(Not(done),
                    Implies(tracking, EqualsOrIff(TS.to_next(packet),
                                                  packet))))
        # !tracking & next(tracking) -> c_push;
        trans.append(
            Implies(
                Not(done),
                Implies(And(Not(tracking), TS.to_next(tracking)), pos_c_push)))
        # (c_push & next(tracking)) -> ((packet = in) & (next(packet) = in);
        trans.append(
            Implies(
                Not(done),
                Implies(
                    And(pos_c_push, TS.to_next(tracking)),
                    And(EqualsOrIff(packet, in_port),
                        EqualsOrIff(TS.to_next(packet), in_port)))))
        # (c_push & !c_pop & tracking) -> (next(count) = (count + 1_8));
        trans.append(
            Implies(
                Not(done),
                Implies(
                    And(pos_c_push, neg_c_pop, tracking),
                    EqualsOrIff(TS.to_next(count),
                                BVAdd(count, BV(1, max_width))))))
        # (c_push & size < maxval) -> (next(size) = (size + 1_8));
        trans.append(
            Implies(
                Not(done),
                Implies(
                    And(pos_c_push, BVULT(size, max_bvval)),
                    EqualsOrIff(TS.to_next(size),
                                BVAdd(size, BV(1, max_width))))))
        # (c_pop & size > 0) -> (next(size) = (size - 1_8));
        trans.append(
            Implies(
                Not(done),
                Implies(
                    And(pos_c_pop, BVUGT(size, zero)),
                    EqualsOrIff(TS.to_next(size),
                                BVSub(size, BV(1, max_width))))))
        # (!(c_push | c_pop)) -> (next(count) = count);
        trans.append(
            Implies(
                Not(done),
                Implies(Not(Or(pos_c_push, pos_c_pop)),
                        EqualsOrIff(count, TS.to_next(count)))))
        # ((c_push | c_pop) & !tracking) -> (next(count) = count);
        trans.append(
            Implies(
                Not(done),
                Implies(And(Or(pos_c_push, pos_c_pop), Not(tracking)),
                        EqualsOrIff(count, TS.to_next(count)))))

        # (c_push & size = maxval) -> (next(size) = size);
        trans.append(
            Implies(
                Not(done),
                Implies(And(pos_c_push, EqualsOrIff(size, max_bvval)),
                        EqualsOrIff(TS.to_next(size), size))))
        # (!(c_push | c_pop)) -> (next(size) = size);
        trans.append(
            Implies(
                Not(done),
                Implies(Not(Or(pos_c_push, pos_c_pop)),
                        EqualsOrIff(size, TS.to_next(size)))))
        # (!(c_push | c_pop)) -> (next(count) = count);
        trans.append(
            Implies(
                Not(done),
                Implies(Not(Or(pos_c_push, pos_c_pop)),
                        EqualsOrIff(count, TS.to_next(count)))))
        # (c_pop & size = 0) -> (next(size) = 0);
        trans.append(
            Implies(
                Not(done),
                Implies(And(pos_c_pop, EqualsOrIff(size, zero)),
                        EqualsOrIff(TS.to_next(size), zero))))

        # (!c_push) -> (next(count) = count);
        trans.append(
            Implies(Not(done),
                    Implies(neg_c_push, EqualsOrIff(TS.to_next(count),
                                                    count))))

        init = And(init)
        invar = And(invar)
        trans = And(trans)

        ts = TS()
        ts.vars, ts.init, ts.invar, ts.trans = set(
            [tracking, end, packet, count, size]), init, invar, trans

        return ts
    def generate_STS(self, lines):
        ts = TS("Additional system")
        init = TRUE()
        trans = TRUE()
        invar = TRUE()

        states = {}
        assigns = set([])
        varsmap = {}

        def def_var(name, vtype):
            if name in varsmap:
                return varsmap[name]
            var = Symbol(name, vtype)
            ts.add_state_var(var)
            return var

        for line in lines:
            if line.comment:
                continue
            if line.init:
                if T_I not in states:
                    states[T_I] = TRUE()

                if line.init.varname != "":
                    (value, typev) = self.__get_value(line.init.value)
                    ivar = def_var(line.init.varname, typev)
                    state = EqualsOrIff(ivar, value)
                else:
                    state = TRUE() if line.init.value == T_TRUE else FALSE()

                states[T_I] = And(states[T_I], state)

                # Optimization for the initial state assignment
                init = And(init, state)

            state = TRUE()
            if line.state:
                sname = T_S + line.state.id
                if (line.state.varname != ""):
                    (value, typev) = self.__get_value(line.state.value)
                    ivar = def_var(line.state.varname, typev)
                    state = EqualsOrIff(ivar, value)
                    assval = (sname, line.state.varname)
                    if assval not in assigns:
                        assigns.add(assval)
                    else:
                        Logger.error(
                            "Double assignment for variable \"%s\" at state \"%s\""
                            % (line.state.varname, sname))
                else:
                    state = TRUE() if line.state.value == T_TRUE else FALSE()

                if sname not in states:
                    states[sname] = TRUE()

                states[sname] = And(states[sname], state)

        stateid_width = math.ceil(math.log(len(states)) / math.log(2))
        stateid_var = Symbol(self.new_state_id(), BVType(stateid_width))

        init = And(init, EqualsOrIff(stateid_var, BV(0, stateid_width)))
        invar = And(
            invar,
            Implies(EqualsOrIff(stateid_var, BV(0, stateid_width)),
                    states[T_I]))
        states[T_I] = EqualsOrIff(stateid_var, BV(0, stateid_width))

        count = 1
        state_items = list(states.keys())
        state_items.sort()
        for state in state_items:
            if state == T_I:
                continue
            invar = And(
                invar,
                Implies(EqualsOrIff(stateid_var, BV(count, stateid_width)),
                        states[state]))
            states[state] = EqualsOrIff(stateid_var, BV(count, stateid_width))
            count += 1

        transdic = {}

        for line in lines:
            if line.comment:
                continue

            if line.trans:
                if states[line.trans.start] not in transdic:
                    transdic[states[line.trans.start]] = []
                transdic[states[line.trans.start]].append(
                    states[line.trans.end])

        for transition in transdic:
            (start, end) = (transition, transdic[transition])
            trans = And(trans, Implies(start, TS.to_next(Or(end))))

        vars_ = [v for v in get_free_variables(trans) if not TS.is_prime(v)]
        vars_ += get_free_variables(init)
        vars_ += get_free_variables(invar)

        invar = And(invar, BVULE(stateid_var, BV(count - 1, stateid_width)))
        ts.set_behavior(init, trans, invar)
        ts.add_state_var(stateid_var)

        hts = HTS("ETS")
        hts.add_ts(ts)
        invar_props = []
        ltl_props = []

        return (hts, invar_props, ltl_props)
Esempio n. 9
0
 def Next(self, x):
     return TS.to_next(x)
Esempio n. 10
0
    def get_sts(self, name, params):
        in_port, max_val, clk = list(params)
        max_val = int(max_val)

        zero = BV(0, 1)
        one = BV(1, 1)

        tracking = Symbol("%s.tracking" % name, BOOL)
        end = Symbol("%s.end" % name, BOOL)
        packet = Symbol("%s.packet" % name,
                        BVType(in_port.symbol_type().width))
        max_width = math.ceil(math.log(max_val) / math.log(2))

        max_bvval = BV(max_val, max_width)
        count = Symbol("%s.count" % name, BVType(max_width))

        pos_clk = And(EqualsOrIff(clk, zero),
                      EqualsOrIff(TS.to_next(clk), one))
        neg_clk = Not(
            And(EqualsOrIff(clk, zero), EqualsOrIff(TS.to_next(clk), one)))

        init = []
        init.append(EqualsOrIff(count, BV(0, max_width)))
        init.append(EqualsOrIff(tracking, FALSE()))
        init = And(init)

        invar = EqualsOrIff(end, EqualsOrIff(max_bvval, count))

        trans = []
        # tracking -> next(tracking);
        trans.append(Implies(tracking, TS.to_next(tracking)))
        # tracking -> (next(packet) = packet);
        trans.append(Implies(tracking, EqualsOrIff(TS.to_next(packet),
                                                   packet)))
        # !tracking & next(tracking) -> (next(clk) = 0_1);
        trans.append(
            Implies(And(Not(tracking), TS.to_next(tracking)),
                    EqualsOrIff(TS.to_next(clk), zero)))
        # ((clk = 0_1) & (next(clk) = 1_1) & next(tracking)) -> (packet = in);
        trans.append(
            Implies(And(pos_clk, TS.to_next(tracking)),
                    EqualsOrIff(packet, in_port)))
        # ((clk = 0_1) & (next(clk) = 1_1) & tracking) -> (next(count) = (count + 1_8));
        trans.append(
            Implies(
                And(pos_clk, tracking),
                EqualsOrIff(TS.to_next(count), BVAdd(count, BV(1,
                                                               max_width)))))
        # (!((clk = 0_1) & (next(clk) = 1_1))) -> (next(count) = count);
        trans.append(Implies(neg_clk, EqualsOrIff(count, TS.to_next(count))))
        # ((clk = 0_1) & (next(clk) = 1_1) & !tracking) -> (next(count) = count);
        trans.append(
            Implies(And(pos_clk, Not(tracking)),
                    EqualsOrIff(count, TS.to_next(count))))

        trans = And(trans)

        ts = TS()
        ts.vars, ts.init, ts.invar, ts.trans = set(
            [tracking, end, packet, count]), init, invar, trans

        return ts
Esempio n. 11
0
    def Mem(clk, wdata, waddr, wen, rdata, raddr):
        # VAR: Array BV(waddr.width) BV(wdata.width)

        # INIT: True (doesn't handle initial value yet)
        # INVAR: (rdata = Select(Array, raddr))

        # do_clk = (!clk & clk')

        # if Modules.functional
        # TRANS: Array' = Ite(do_clk, Ite(wen, Store(Array, waddr, wdata), Array), Array)

        # else
        # act_trans = (Array' = Ite(wen, Store(Array, waddr, wdata), Array))
        # pas_trans = (Array' = Array)

        # TRANS: (do_clk -> act_trans) & (!do_clk -> pas_trans)
        # one cycle delay on write

        vars_ = [clk, wdata, waddr, wen, rdata, raddr]
        comment = "Mem (clk, wdata, waddr, wen, rdata, raddr) = (%s, %s, %s, %s, %s, %s)" % (
            tuple([str(x) for x in vars_]))
        Logger.log(comment, 3)

        init = TRUE()
        trans = TRUE()
        invar = TRUE()

        memname = SEP.join(rdata.symbol_name().split(
            SEP)[:-1]) if SEP in rdata.symbol_name() else rdata.symbol_name()

        arr = Symbol(memname + ".array",
                     ArrayType(waddr.symbol_type(), wdata.symbol_type()))
        vars_.append(arr)

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

        if wen.symbol_type() == BOOL:
            wen1 = wen
        else:
            wen1 = EqualsOrIff(wen, BV(1, 1))

        if Modules.abstract_clock:
            do_clk = TRUE()
        else:
            do_clk = And(TS.to_next(clk1), clk0)

        invar = EqualsOrIff(rdata, Select(arr, raddr))

        if Modules.array_ite:
            next_arr = Ite(wen1, Store(arr, waddr, wdata), arr)
        else:
            next_arr = Store(arr, waddr, Ite(wen1, wdata, Select(arr, waddr)))

        if Modules.functional:
            trans = EqualsOrIff(TS.to_next(arr), Ite(do_clk, next_arr, arr))
        else:
            act_trans = EqualsOrIff(TS.to_next(arr), next_arr)
            pas_trans = EqualsOrIff(TS.to_next(arr), arr)
            trans = And(Implies(do_clk, act_trans),
                        Implies(Not(do_clk), pas_trans))

        trans = simplify(trans)
        ts = TS(comment)
        ts.vars, ts.state_vars, ts.logic = set(
            [v for v in vars_ if v is not None]), set([arr]), L_ABV
        ts.set_behavior(init, trans, invar)
        return ts
Esempio n. 12
0
    def Reg(in_, clk, clr, rst, arst, out, initval, clk_posedge, arst_posedge):
        # INIT: out = initval

        # do_arst = Ite(arst_posedge, (!arst & arst'), (arst & !arst'))
        # do_clk = Ite(clk_posedge, (!clk & clk'), (clk & !clk'))
        # inr = Ite(clr, 0, Ite(rst, initval, in))

        # if Modules.functional
        # TRANS: out' = Ite(do_clk, Ite(clr, 0, Ite(rst, initval, in)), Ite(rst, initval, in))
        # INVAR: True
        # trans gives priority to clr signal over rst

        # else
        # act_trans = (out' = inr)
        # pas_trans = (out' = out)
        # TRANS: (!do_arst -> ((do_clk -> act_trans) & (!do_clk -> pas_trans))) & (do_arst -> (out' = initval))
        # INVAR: True
        # trans gives priority to clr signal over rst

        vars_ = [in_, clk, clr, rst, arst, out]
        comment = "Reg (in, clk, clr, rst, arst, out) = (%s, %s, %s, %s, %s, %s)" % (
            tuple([str(x) for x in vars_]))
        Logger.log(comment, 3)

        init = TRUE()
        trans = TRUE()
        invar = TRUE()

        initvar = None
        basename = SEP.join(out.symbol_name().split(
            SEP)[:-1]) if SEP in out.symbol_name() else out.symbol_name()
        initname = basename + SEP + INIT

        if initval is not None and not Modules.symbolic_init:
            if out.symbol_type() == BOOL:
                binitval = FALSE() if initval == 0 else TRUE()
            else:
                binitval = BV(initval, out.symbol_type().width)

            initvar = binitval
        else:
            if out.symbol_type() == BOOL:
                initvar = Symbol(initname, BOOL)
            else:
                initvar = Symbol(initname, BVType(out.symbol_type().width))

            trans = And(trans, EqualsOrIff(initvar, TS.get_prime(initvar)))
            vars_.append(initvar)

        init = And(init, EqualsOrIff(out, initvar))

        if arst_posedge is not None:
            arst_posedge0 = False if arst_posedge else True
            arst_posedge1 = True if arst_posedge else False
        else:
            arst_posedge0 = False
            arst_posedge1 = True

        if clk_posedge is not None:
            clk_posedge0 = False if clk_posedge else True
            clk_posedge1 = True if clk_posedge else False
        else:
            clk_posedge0 = False
            clk_posedge1 = True

        if clr is not None:
            if clr.symbol_type() == BOOL:
                clr0 = Not(clr)
                clr1 = clr
            else:
                clr0 = EqualsOrIff(clr, BV(0, 1))
                clr1 = EqualsOrIff(clr, BV(1, 1))
        else:
            clr0 = TRUE()
            clr1 = FALSE()

        if rst is not None:
            if rst.symbol_type() == BOOL:
                rst0 = Not(rst)
                rst1 = rst
            else:
                rst0 = EqualsOrIff(rst, BV(0, 1))
                rst1 = EqualsOrIff(rst, BV(1, 1))
        else:
            rst0 = TRUE()
            rst1 = FALSE()

        if arst is not None:
            if arst.symbol_type() == BOOL:
                arst0 = Not(arst)
                arst1 = arst
            else:
                arst0 = EqualsOrIff(arst, BV(0, 1))
                arst1 = EqualsOrIff(arst, BV(1, 1))
        else:
            arst0 = TRUE()
            arst1 = FALSE()

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

        if Modules.abstract_clock:
            do_clk = TRUE()
        else:
            do_clk = And(TS.to_next(clk1), clk0) if clk_posedge1 else And(
                TS.to_next(clk0), clk1)

        if out.symbol_type() == BOOL:
            out0 = FALSE()
        else:
            out0 = BV(0, out.symbol_type().width)

        inr = Ite(clr1, out0, Ite(rst1, initvar, in_))
        do_arst = And(TS.to_next(arst1), arst0) if arst_posedge1 else And(
            TS.to_next(arst0), arst1)
        ndo_arst = Not(do_arst)
        ndo_clk = Not(do_clk)
        act_trans = EqualsOrIff(inr, TS.get_prime(out))
        pas_trans = EqualsOrIff(out, TS.get_prime(out))

        if Modules.functional:
            f_outr = Ite(rst1, initvar, out)
            f_inr = Ite(rst1, initvar, in_)
            f_clr_rst = Ite(clr1, out0, f_inr)
            trans = And(
                trans,
                EqualsOrIff(TS.get_prime(out), Ite(do_clk, f_clr_rst, f_outr)))
        else:
            trans = And(trans, And(Implies(ndo_arst, And(Implies(do_clk, act_trans), Implies(ndo_clk, pas_trans))), \
                                   Implies(do_arst, EqualsOrIff(TS.get_prime(out), initvar))))

        trans = simplify(trans)
        ts = TS(comment)
        ts.vars, ts.state_vars = set([v for v in vars_
                                      if v is not None]), set([out])
        ts.set_behavior(init, trans, invar)
        return ts
Esempio n. 13
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]
        cyclestr = params[1]

        try:
            cycle = int(cyclestr)
        except:
            Logger.error(
                "Clock cycle should be an integer number instead of \"%s\"" %
                cyclestr)

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

        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 cycle < 1:
            Logger.error(
                "Deterministic clock requires at least a cycle of size 1")

        if cycle == 1:
            init.append(neg_clk)
            trans.append(Iff(neg_clk, TS.to_next(pos_clk)))

        if cycle > 1:
            statesize = math.ceil(math.log(cycle) / math.log(2))
            counter = Symbol("%s%s" % (clk.symbol_name(), CLOCK_COUNTER),
                             BVType(statesize))
            # 0 counts
            cycle -= 1

            # counter = 0 & clk = 0
            init.append(EqualsOrIff(counter, BV(0, statesize)))
            init.append(neg_clk)

            # counter <= cycle
            invar.append(BVULE(counter, BV(cycle, statesize)))

            # (counter < cycle) -> next(counter) = counter + 1
            trans.append(
                Implies(
                    BVULT(counter, BV(cycle, statesize)),
                    EqualsOrIff(TS.to_next(counter),
                                BVAdd(counter, BV(1, statesize)))))

            # (counter >= cycle) -> next(counter) = 0
            trans.append(
                Implies(BVUGE(counter, BV(cycle, statesize)),
                        EqualsOrIff(TS.to_next(counter), BV(0, statesize))))

            # (!clk) & (counter < cycle) -> next(!clk)
            trans.append(
                Implies(And(neg_clk, BVULT(counter, BV(cycle, statesize))),
                        TS.to_next(neg_clk)))
            # (!clk) & (counter >= cycle) -> next(clk)
            trans.append(
                Implies(And(neg_clk, BVUGE(counter, BV(cycle, statesize))),
                        TS.to_next(pos_clk)))

            # (clk) & (counter < cycle) -> next(clk)
            trans.append(
                Implies(And(pos_clk, BVULT(counter, BV(cycle, statesize))),
                        TS.to_next(pos_clk)))
            # (clk) & (counter >= cycle) -> next(!clk)
            trans.append(
                Implies(And(pos_clk, BVUGE(counter, BV(cycle, statesize))),
                        TS.to_next(neg_clk)))

            vars.add(counter)

        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
Esempio n. 14
0
 def Negedge(self, x):
     if get_type(x).is_bool_type():
         return And(x, Not(TS.to_next(x)))
     return And(BV2B(x), EqualsOrIff(TS.to_next(x), BV(0, 1)))
Esempio n. 15
0
 def Posedge(self, x):
     if get_type(x).is_bool_type():
         return And(Not(x), TS.to_next(x))
     return And(EqualsOrIff(x, BV(0, 1)), BV2B(TS.to_next(x)))
Esempio n. 16
0
    def parametric_safety(self,
                          prop,
                          k_max,
                          k_min,
                          parameters,
                          monotonic=True,
                          at_most=-1):
        if len(parameters) == 0:
            Logger.error("Parameters size cannot be 0")

        lemmas = self.hts.lemmas
        self._init_at_time(self.hts.vars, k_max)

        monotonic = True

        # if monotonic:
        #     for p in parameters:
        #         self.set_preferred((p, False))

        self.region = FALSE()

        generalize = lambda model, t: self._get_param_assignments(
            model, t, parameters, monotonic)

        if at_most == -1:
            cardinality = len(parameters)
        else:
            cardinality = at_most

        prev_cs_count = 0

        prove = self.config.prove

        step = 5
        same_res_counter = 0
        k = step
        end = False
        has_next = TS.has_next(prop)

        # Strategy selection
        increase_k = False

        if cardinality == -2:
            (t, status) = self.solve_safety_inc_fwd(self.hts,
                                                    prop,
                                                    k_max,
                                                    k_min,
                                                    all_vars=False,
                                                    generalize=generalize)
        else:
            sn = SortingNetwork.sorting_network(parameters)

            if increase_k:
                # Approach with incremental increase of bmc k
                while k < k_max + 1:
                    for at in range(cardinality):
                        Logger.msg("[%d,%d]" % ((at + 1), k), 0,
                                   not (Logger.level(1)))

                        sn_k = sn[at + 1] if at + 1 < len(sn) else FALSE()
                        bound_constr = Or(sn_k, self.region)
                        bound_constr = bound_constr if not has_next else Or(
                            bound_constr, TS.to_next(bound_constr))

                        self.config.prove = False
                        (t, status) = self.solve_safety_inc_bwd(
                            self.hts,
                            Or(prop, bound_constr),
                            k,
                            generalize=generalize)

                        if (prev_cs_count == self.cs_count):
                            same_res_counter += 1
                        else:
                            same_res_counter = 0

                        prev_cs_count = self.cs_count

                        if (prove == True) and ((same_res_counter > 1) or
                                                (at == cardinality - 1)):
                            Logger.msg("[>%d,%d]" % ((at + 1), k), 0,
                                       not (Logger.level(1)))

                            if (at_most > -1) and (at_most < cardinality):
                                sn_k = sn[at_most - 1]
                            else:
                                sn_k = FALSE()
                            bound_constr = Or(sn_k, self.region)
                            bound_constr = bound_constr if not has_next else Or(
                                bound_constr, TS.to_next(bound_constr))

                            self.config.prove = True
                            (t, status) = self.solve_safety(
                                self.hts, Or(prop, bound_constr), k,
                                max(k_min, k - step))

                            if status == True:
                                end = True
                                break

                        if (same_res_counter > 2) and (k < k_max):
                            break

                    if end:
                        break
                    k += step
            else:
                # Approach with fixed bmc k
                for at in range(cardinality):
                    Logger.msg("[%d]" % ((at + 1)), 0, not (Logger.level(1)))

                    sn_k = sn[at + 1] if at + 1 < len(sn) else FALSE()
                    bound_constr = Or(sn_k, self.region)
                    bound_constr = bound_constr if not has_next else Or(
                        bound_constr, TS.to_next(bound_constr))

                    self.config.prove = False
                    (t, status) = self.solve_safety_inc_bwd(
                        self.hts,
                        Or(prop, bound_constr),
                        k_max,
                        generalize=generalize)

                    if simplify(self.region) == TRUE():
                        break

                    if (prev_cs_count == self.cs_count):
                        same_res_counter += 1
                    else:
                        same_res_counter = 0

                    prev_cs_count = self.cs_count

                    if (prove == True) and ((same_res_counter > 1) or
                                            (at == cardinality - 1)):
                        Logger.msg("[>%d]" % ((at + 1)), 0,
                                   not (Logger.level(1)))

                        if (at_most > -1) and (at_most < cardinality):
                            sn_k = sn[at_most - 1]
                        else:
                            sn_k = FALSE()
                        bound_constr = Or(sn_k, self.region)
                        bound_constr = bound_constr if not has_next else Or(
                            bound_constr, TS.to_next(bound_constr))

                        self.config.prove = True
                        (t,
                         status) = self.solve_safety(self.hts,
                                                     Or(prop, bound_constr),
                                                     k_max, k_min)
                        if status == True:
                            break

        traces = None
        if (self.models is not None) and (simplify(self.region)
                                          not in [TRUE(), FALSE()]):
            traces = []
            for (model, time) in self.models:
                model = self._remap_model(self.hts.vars, model, time)
                trace = self.generate_trace(model, time,
                                            get_free_variables(prop))
                traces.append(trace)

        region = []
        dass = {}

        # Sorting result by size
        for ass in list(disjunctive_partition(self.region)):
            cp = list(conjunctive_partition(ass))
            size = len(cp)
            if size not in dass:
                dass[size] = []
            dass[size].append(ass)

        indexes = list(dass.keys())
        indexes.sort()
        for size in indexes:
            region += dass[size]

        if status == True:
            return (VerificationStatus.TRUE, traces, region)
        elif status is not None:
            return (VerificationStatus.FALSE, traces, region)
        else:
            return (VerificationStatus.UNK, traces, region)