예제 #1
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #2
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #3
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #4
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #5
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #6
0
파일: modules.py 프로젝트: danny-boby/CoSA
    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
예제 #7
0
파일: modules.py 프로젝트: pllab/CoSA
 def Undriven(_out):
     '''
     Undriven is a no-op. _out is just undriven
     '''
     vars_ = [_out]
     ts = TS("Undriven wire")
     ts.vars = set(vars_)
     return ts
예제 #8
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
예제 #9
0
파일: modules.py 프로젝트: pllab/CoSA
 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
예제 #10
0
파일: modules.py 프로젝트: pllab/CoSA
 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
예제 #11
0
파일: modules.py 프로젝트: pllab/CoSA
 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
예제 #12
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #13
0
파일: modules.py 프로젝트: pllab/CoSA
    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
예제 #14
0
파일: modules.py 프로젝트: pllab/CoSA
    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
예제 #15
0
파일: modules.py 프로젝트: danny-boby/CoSA
    def Bop(bvop, bop, in0, in1, out):
        # INVAR: (in0 <op> in1) = out
        vars_ = [in0, in1, out]
        comment = (bvop.__name__ + " (in0, in1, out) = (%s, %s, %s)") % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        in0B = in0.symbol_type() == BOOL
        in1B = in1.symbol_type() == BOOL
        outB = out.symbol_type() == BOOL

        bools = (1 if in0B else 0) + (1 if in1B else 0) + (1 if outB else 0)

        if bop == None:
            if in0B:
                in0 = Ite(in0, BV(1, 1), BV(0, 1))
            if in1B:
                in1 = Ite(in1, BV(1, 1), BV(0, 1))
            if outB:
                out = Ite(out, BV(1, 1), BV(0, 1))

            invar = EqualsOrIff(bvop(in0, in1), out)

        else:
            if bools == 3:
                invar = EqualsOrIff(bop(in0, in1), out)
            elif bools == 0:
                invar = EqualsOrIff(bvop(in0, in1), out)
            elif bools == 1:
                if in0B:
                    invar = EqualsOrIff(bvop(B2BV(in0), in1), out)
                if in1B:
                    invar = EqualsOrIff(bvop(in0, B2BV(in1)), out)
                if outB:
                    invar = EqualsOrIff(BV2B(bvop(in0, in1)), out)
            else:
                if not in0B:
                    invar = EqualsOrIff(bop(BV2B(in0), in1), out)
                if not in1B:
                    invar = EqualsOrIff(bop(in0, BV2B(in1)), out)
                if not outB:
                    invar = EqualsOrIff(B2BV(bop(in0, in1)), out)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
예제 #16
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
예제 #17
0
    def parse_file(self, file_path, config, flags=None):
        # coreir needs a string representing the path
        strfile = str(file_path)

        self.config = config
        self.__reset_structures()

        Logger.msg("Reading CoreIR system... ", 1)
        top_module = self.context.load_from_file(strfile)

        if config.run_coreir_passes:
            self.run_passes()

        Modules.abstract_clock = self.config.abstract_clock
        Modules.symbolic_init = self.config.symbolic_init

        top_def = top_module.definition
        interface = list(top_module.type.items())
        modules = {}
        sym_map = {}

        not_defined_mods = []

        hts = HTS(top_module.name)
        invar_props = []
        ltl_props = []

        Logger.msg("Starting encoding... ", 1)

        count = 0

        def extract_value(x, modname, inst_intr, inst_conf, inst_mod):
            if x in inst_intr:
                return self.BVVar(modname + x, inst_intr[x].size)

            if x in inst_conf:
                xval = inst_conf[x].value
                if type(xval) == bool:
                    xval = 1 if xval else 0
                else:
                    if type(xval) != int:
                        try:
                            xval = xval.as_uint()
                        except:
                            xval = None
                return xval

            if inst_mod.generated:
                inst_args = inst_mod.generator_args
                if x in inst_args:
                    return inst_args[x].value

            return None

        if Logger.level(1):
            timer = Logger.start_timer("IntConvertion", False)
            en_tprinting = False

        if Logger.level(2):
            ttimer = Logger.start_timer("Convertion", False)

        td_instances = top_def.instances
        top_def_instances = [(inst.selectpath, inst.config, inst.module)
                             for inst in td_instances]
        # sorting keeps the behavior deterministic
        top_def_instances.sort()

        totalinst = len(top_def_instances)

        for inst in top_def_instances:
            if Logger.level(1):
                count += 1
                if count % 300 == 0:
                    dtime = Logger.get_timer(timer, False)
                    if dtime > 2:
                        en_tprinting = True
                    if en_tprinting:
                        Logger.inline(
                            "%s" % status_bar(
                                (float(count) / float(totalinst))), 1)
                        timer = Logger.start_timer("IntConvertion", False)

                    if Logger.level(2):
                        Logger.get_timer(timer, False)

            ts = None

            (inst_name, inst_conf, inst_mod) = inst
            inst_type = inst_mod.name
            inst_intr = dict(inst_mod.type.items())
            modname = (SEP.join(inst_name)) + SEP

            values_dic = {}

            for x in self.attrnames:
                values_dic[x] = extract_value(x, modname, inst_intr, inst_conf,
                                              inst_mod)

            def args(ports_list):
                return [values_dic[x] for x in ports_list]

            sym = self.__mod_to_sym(inst_type, args)
            if sym is not None:
                sym_map[sym[0].symbol_name()] = (sym[0], sym[1])
                continue

            ts = self.__mod_to_impl(inst_type, args)

            if ts is not None:

                if flags is not None:
                    if CoreIRModelFlags.NO_INIT in flags:
                        ts.init = TRUE()

                    if CoreIRModelFlags.FC_LEMMAS in flags:
                        for v in ts.vars:
                            v_name = v.symbol_name()
                            if (CR in v_name) or (RCR in v_name):
                                cons_v_name = v_name[:len(
                                    CR)] if CR in v_name else v_name[:len(RCR)]
                                cons_v = Symbol(cons_v_name, v.symbol_type())
                                lemma = EqualsOrIff(
                                    cons_v,
                                    BV(values_dic[self.VALUE],
                                       cons_v.symbol_type().width))
                                hts.add_lemma(lemma)

                        for v in ts.state_vars:
                            lemma = EqualsOrIff(
                                v,
                                BV(values_dic[self.INIT],
                                   v.symbol_type().width))
                            hts.add_lemma(lemma)

                hts.add_ts(ts)
            else:
                if inst_type not in not_defined_mods:
                    intface = ", ".join([
                        "%s" % (v) for v in values_dic
                        if values_dic[v] is not None
                    ])
                    Logger.error(
                        "Module type \"%s\" with interface \"%s\" is not defined"
                        % (inst_type, intface))
                    not_defined_mods.append(inst_type)

        Logger.clear_inline(1)

        # sorting keeps the behavior deterministic
        interface.sort()

        for var in interface:
            varname = SELF + SEP + var[0]
            bvvar = self.BVVar(varname, var[1].size)
            if (var[1].is_input()):
                hts.add_input_var(bvvar)
            else:
                hts.add_output_var(bvvar)

            if var[1].kind == NAMED and var[1].name == COREIR_CLK:
                self.clock_list.add(bvvar)
                if self.config.abstract_clock:
                    self.abstract_clock_list.add(
                        (bvvar, (BV(0, var[1].size), BV(1, var[1].size))))
                else:
                    # add state variable that stores the previous clock value
                    # This is IMPORTANT for model checking soundness, but
                    #    it isn't obvious that this is necessary
                    #
                    # imagine we have an explicit clock encoding (not abstract_clock), e.g.
                    #   next(state_var) = (!clk & next(clk)) ? <state_update> : <old value>
                    # and if we're trying to prove something using k-induction, there's a "loop free"
                    #   constraint that the state and output variables don't repeat (reach the same
                    #   state twice) in the trace
                    #   but on a negedge clock, there can be scenarios where no state or outputs
                    #   can be updated and we'll get a trivial unsat which will be interpreted as
                    #   a converged proof -- uh oh
                    #
                    # adding this state element just ensures that the loop free constraint won't
                    #   be violated trivially
                    # e.g. on a neg-edge clock, this new state element will have changed

                    # make it hidden (won't be printed)
                    # HIDDEN_VAR is a prefix that printers check for
                    trailing_clock_var = self.BVVar(
                        "{}{}__prev".format(HIDDEN_VAR, varname), var[1].size)

                    ts = TS()
                    ts.add_state_var(trailing_clock_var)
                    # the initial state for this trailing variable is unconstrained
                    ts.set_behavior(
                        TRUE(),
                        EqualsOrIff(TS.get_prime(trailing_clock_var), bvvar),
                        TRUE())

                    hts.add_ts(ts)

        varmap = dict([(s.symbol_name(), s) for s in hts.vars])

        def split_paths(path):
            ret = []
            for el in path:
                ret += el.split(CSEP)

            return ret

        def dict_select(dic, el):
            return dic[el] if el in dic else None

        eq_conns = []
        eq_vars = set([])

        td_connections = top_def.connections
        top_def_connections = [
            ((conn.first.selectpath, conn.second.selectpath)
             if conn.first.selectpath < conn.second.selectpath else
             (conn.second.selectpath, conn.first.selectpath), conn)
            for conn in td_connections
        ]
        # sorting keeps the behavior deterministic
        top_def_connections.sort()

        for conn in top_def_connections:

            first_selectpath = split_paths(conn[0][0])
            second_selectpath = split_paths(conn[0][1])

            first = SEP.join(first_selectpath)
            second = SEP.join(second_selectpath)

            firstvar = None
            secondvar = None

            if is_number(first_selectpath[-1]):
                firstname = SEP.join(first_selectpath[:-1])
            else:
                firstname = SEP.join(first_selectpath)

            if is_number(second_selectpath[-1]):
                secondname = SEP.join(second_selectpath[:-1])
            else:
                secondname = SEP.join(second_selectpath)

            first = (dict_select(varmap, self.remap_or2an(firstname)), None)
            second = (dict_select(varmap, self.remap_or2an(secondname)), None)

            firstvar = first[0]
            secondvar = second[0]

            if (firstvar is None) and (self.remap_or2an(firstname) in sym_map):
                firstvar = sym_map[self.remap_or2an(firstname)][1]

            if (secondvar is None) and (self.remap_or2an(secondname)
                                        in sym_map):
                secondvar = sym_map[self.remap_or2an(secondname)][1]

            if (firstvar is None) and (secondvar is not None):
                Logger.error("Symbol \"%s\" is not defined" % firstname)
                first = (Symbol(self.remap_or2an(firstname),
                                secondvar.symbol_type()), None)
            else:
                if firstvar.is_constant():
                    sel = int(first_selectpath[-1]) if (is_number(
                        first_selectpath[-1])) else None
                    first = (firstvar, sel)
                else:
                    if (is_number(first_selectpath[-1])) and (
                            firstvar.symbol_type() !=
                            BOOL) and (firstvar.symbol_type().width > 1):
                        sel = int(first_selectpath[-1])
                        first = (firstvar, sel)

            if (firstvar is not None) and (secondvar is None):
                Logger.error("Symbol \"%s\" is not defined" % secondname)
                second = (Symbol(self.remap_or2an(secondname),
                                 firstvar.symbol_type()), None)
            else:
                if secondvar.is_constant():
                    sel = int(second_selectpath[-1]) if (is_number(
                        second_selectpath[-1])) else None
                    second = (secondvar, sel)
                else:
                    if (is_number(second_selectpath[-1])) and (
                            secondvar.symbol_type() !=
                            BOOL) and (secondvar.symbol_type().width > 1):
                        sel = int(second_selectpath[-1])
                        second = (secondvar, sel)

            assert ((firstvar is not None) and (secondvar is not None))

            eq_conns.append((first, second))

            if firstvar.is_symbol():
                eq_vars.add(firstvar)
            if secondvar.is_symbol():
                eq_vars.add(secondvar)

        conns_len = len(eq_conns)

        if self.pack_connections:
            eq_conns = self.__pack_connections(eq_conns)

        if len(eq_conns) < conns_len:
            Logger.log("Packed %d connections" % (conns_len - len(eq_conns)),
                       1)

        eq_formula = TRUE()

        for eq_conn in eq_conns:

            (fst, snd) = eq_conn

            if fst[1] is None:
                first = fst[0]
            else:
                if len(fst) > 2:
                    first = BVExtract(fst[0], fst[1], fst[2])
                else:
                    first = BVExtract(fst[0], fst[1], fst[1])

            if snd[1] is None:
                second = snd[0]
            else:
                if len(snd) > 2:
                    second = BVExtract(snd[0], snd[1], snd[2])
                else:
                    second = BVExtract(snd[0], snd[1], snd[1])

            if (first.get_type() != BOOL) and (second.get_type() == BOOL):
                second = Ite(second, BV(1, 1), BV(0, 1))

            if (first.get_type() == BOOL) and (second.get_type() != BOOL):
                first = Ite(first, BV(1, 1), BV(0, 1))

            eq_formula = And(eq_formula, EqualsOrIff(first, second))

            Logger.log(str(EqualsOrIff(first, second)), 3)

        ts = TS("Connections")
        ts.invar = eq_formula
        ts.vars = eq_vars

        hts.add_ts(ts)

        if self.enc_map is not None:
            del (self.enc_map)

        if Logger.level(2):
            Logger.get_timer(ttimer)

        # check that clocks were detected if there's any state
        if hts.state_vars:
            assert self.clock_list, "Expecting clocks if there are state variables"

        return (hts, invar_props, ltl_props)
예제 #18
0
    def parse_file(self, strfile, config, flags=None):
        self.config = config
        self.__reset_structures()

        Logger.msg("Reading CoreIR system... ", 1)
        top_module = self.context.load_from_file(strfile)

        if config.run_passes:
            self.run_passes()

        Modules.abstract_clock = self.config.abstract_clock
        Modules.symbolic_init = self.config.symbolic_init

        top_def = top_module.definition
        interface = list(top_module.type.items())
        modules = {}
        sym_map = {}

        not_defined_mods = []

        hts = HTS(top_module.name)
        invar_props = []
        ltl_props = []

        Logger.msg("Starting encoding... ", 1)

        count = 0

        def extract_value(x, modname, inst_intr, inst_conf, inst_mod):
            if x in inst_intr:
                return self.BVVar(modname + x, inst_intr[x].size)

            if x in inst_conf:
                xval = inst_conf[x].value
                if type(xval) == bool:
                    xval = 1 if xval else 0
                else:
                    if type(xval) != int:
                        try:
                            if xval.is_x():
                                xval = None
                            else:
                                xval = xval.as_uint()
                        except:
                            try:
                                xval = xval.val
                            except:
                                xval = xval.unsigned_value
                return xval

            if inst_mod.generated:
                inst_args = inst_mod.generator_args
                if x in inst_args:
                    return inst_args[x].value

            return None

        if Logger.level(1):
            timer = Logger.start_timer("IntConvertion", False)
            en_tprinting = False

        if Logger.level(2):
            ttimer = Logger.start_timer("Convertion", False)

        if self.config.deterministic:
            td_instances = top_def.instances
            top_def_instances = [(inst.selectpath, inst.config, inst.module)
                                 for inst in td_instances]
            top_def_instances.sort()
        else:
            top_def_instances = list(top_def.instances)

        totalinst = len(top_def_instances)

        for inst in top_def_instances:
            if Logger.level(1):
                count += 1
                if count % 300 == 0:
                    dtime = Logger.get_timer(timer, False)
                    if dtime > 2:
                        en_tprinting = True
                    if en_tprinting:
                        Logger.inline(
                            "%s" % status_bar(
                                (float(count) / float(totalinst))), 1)
                        timer = Logger.start_timer("IntConvertion", False)

                    if Logger.level(2):
                        Logger.get_timer(timer, False)

            ts = None

            if self.config.deterministic:
                (inst_name, inst_conf, inst_mod) = inst
            else:
                inst_name = inst.selectpath
                inst_conf = inst.config
                inst_mod = inst.module

            inst_type = inst_mod.name
            inst_intr = dict(inst_mod.type.items())
            modname = (SEP.join(inst_name)) + SEP

            values_dic = {}

            for x in self.attrnames:
                values_dic[x] = extract_value(x, modname, inst_intr, inst_conf,
                                              inst_mod)

            def args(ports_list):
                return [values_dic[x] for x in ports_list]

            sym = self.__mod_to_sym(inst_type, args)
            if sym is not None:
                sym_map[sym[0].symbol_name()] = (sym[0], sym[1])
                continue

            ts = self.__mod_to_impl(inst_type, args)

            if ts is not None:

                if flags is not None:
                    if CoreIRModelFlags.NO_INIT in flags:
                        ts.init = TRUE()

                    if CoreIRModelFlags.FC_LEMMAS in flags:
                        for v in ts.vars:
                            v_name = v.symbol_name()
                            if (CR in v_name) or (RCR in v_name):
                                cons_v_name = v_name[:len(
                                    CR)] if CR in v_name else v_name[:len(RCR)]
                                cons_v = Symbol(cons_v_name, v.symbol_type())
                                lemma = EqualsOrIff(
                                    cons_v,
                                    BV(values_dic[self.VALUE],
                                       cons_v.symbol_type().width))
                                hts.add_lemma(lemma)

                        for v in ts.state_vars:
                            lemma = EqualsOrIff(
                                v,
                                BV(values_dic[self.INIT],
                                   v.symbol_type().width))
                            hts.add_lemma(lemma)

                hts.add_ts(ts)
            else:
                if inst_type not in not_defined_mods:
                    intface = ", ".join([
                        "%s" % (v) for v in values_dic
                        if values_dic[v] is not None
                    ])
                    Logger.error(
                        "Module type \"%s\" with interface \"%s\" is not defined"
                        % (inst_type, intface))
                    not_defined_mods.append(inst_type)

        Logger.clear_inline(1)

        if self.config.deterministic:
            interface.sort()

        for var in interface:
            varname = SELF + SEP + var[0]
            bvvar = self.BVVar(varname, var[1].size)
            if (var[1].is_input()):
                hts.add_input_var(bvvar)
            else:
                hts.add_output_var(bvvar)

            # Adding clock behavior
            if (self.CLK in var[0].lower()) and (var[1].is_input()):
                self.clock_list.add(bvvar)
                if self.config.abstract_clock:
                    self.abstract_clock_list.add(
                        (bvvar, (BV(0, var[1].size), BV(1, var[1].size))))

        varmap = dict([(s.symbol_name(), s) for s in hts.vars])

        def split_paths(path):
            ret = []
            for el in path:
                ret += el.split(CSEP)

            return ret

        def dict_select(dic, el):
            return dic[el] if el in dic else None

        eq_conns = []
        eq_vars = set([])

        if self.config.deterministic:
            td_connections = top_def.connections
            top_def_connections = [
                ((conn.first.selectpath, conn.second.selectpath)
                 if conn.first.selectpath < conn.second.selectpath else
                 (conn.second.selectpath, conn.first.selectpath), conn)
                for conn in td_connections
            ]
            top_def_connections.sort()
        else:
            top_def_connections = list(top_def.connections)

        for conn in top_def_connections:

            if self.config.deterministic:
                first_selectpath = split_paths(conn[0][0])
                second_selectpath = split_paths(conn[0][1])
            else:
                first_selectpath = split_paths(conn.first.selectpath)
                second_selectpath = split_paths(conn.second.selectpath)

            first = SEP.join(first_selectpath)
            second = SEP.join(second_selectpath)

            firstvar = None
            secondvar = None

            if is_number(first_selectpath[-1]):
                firstname = SEP.join(first_selectpath[:-1])
            else:
                firstname = SEP.join(first_selectpath)

            if is_number(second_selectpath[-1]):
                secondname = SEP.join(second_selectpath[:-1])
            else:
                secondname = SEP.join(second_selectpath)

            first = (dict_select(varmap, self.remap_or2an(firstname)), None)
            second = (dict_select(varmap, self.remap_or2an(secondname)), None)

            firstvar = first[0]
            secondvar = second[0]

            if (firstvar is None) and (self.remap_or2an(firstname) in sym_map):
                firstvar = sym_map[self.remap_or2an(firstname)][1]

            if (secondvar is None) and (self.remap_or2an(secondname)
                                        in sym_map):
                secondvar = sym_map[self.remap_or2an(secondname)][1]

            if (firstvar is None) and (secondvar is not None):
                Logger.error("Symbol \"%s\" is not defined" % firstname)
                first = (Symbol(self.remap_or2an(firstname),
                                secondvar.symbol_type()), None)
            else:
                if firstvar.is_constant():
                    sel = int(first_selectpath[-1]) if (is_number(
                        first_selectpath[-1])) else None
                    first = (firstvar, sel)
                else:
                    if (is_number(first_selectpath[-1])) and (
                            firstvar.symbol_type() !=
                            BOOL) and (firstvar.symbol_type().width > 1):
                        sel = int(first_selectpath[-1])
                        first = (firstvar, sel)

            if (firstvar is not None) and (secondvar is None):
                Logger.error("Symbol \"%s\" is not defined" % secondname)
                second = (Symbol(self.remap_or2an(secondname),
                                 firstvar.symbol_type()), None)
            else:
                if secondvar.is_constant():
                    sel = int(second_selectpath[-1]) if (is_number(
                        second_selectpath[-1])) else None
                    second = (secondvar, sel)
                else:
                    if (is_number(second_selectpath[-1])) and (
                            secondvar.symbol_type() !=
                            BOOL) and (secondvar.symbol_type().width > 1):
                        sel = int(second_selectpath[-1])
                        second = (secondvar, sel)

            assert ((firstvar is not None) and (secondvar is not None))

            eq_conns.append((first, second))

            if firstvar.is_symbol():
                eq_vars.add(firstvar)
            if secondvar.is_symbol():
                eq_vars.add(secondvar)

        conns_len = len(eq_conns)

        if self.pack_connections:
            eq_conns = self.__pack_connections(eq_conns)

        if len(eq_conns) < conns_len:
            Logger.log("Packed %d connections" % (conns_len - len(eq_conns)),
                       1)

        eq_formula = TRUE()

        for eq_conn in eq_conns:

            (fst, snd) = eq_conn

            if fst[1] is None:
                first = fst[0]
            else:
                if len(fst) > 2:
                    first = BVExtract(fst[0], fst[1], fst[2])
                else:
                    first = BVExtract(fst[0], fst[1], fst[1])

            if snd[1] is None:
                second = snd[0]
            else:
                if len(snd) > 2:
                    second = BVExtract(snd[0], snd[1], snd[2])
                else:
                    second = BVExtract(snd[0], snd[1], snd[1])

            if (first.get_type() != BOOL) and (second.get_type() == BOOL):
                second = Ite(second, BV(1, 1), BV(0, 1))

            if (first.get_type() == BOOL) and (second.get_type() != BOOL):
                first = Ite(first, BV(1, 1), BV(0, 1))

            eq_formula = And(eq_formula, EqualsOrIff(first, second))

            Logger.log(str(EqualsOrIff(first, second)), 3)

        ts = TS("Connections")
        ts.invar = eq_formula
        ts.vars = eq_vars

        hts.add_ts(ts)

        if self.enc_map is not None:
            del (self.enc_map)

        if Logger.level(2):
            Logger.get_timer(ttimer)

        return (hts, invar_props, ltl_props)
예제 #19
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #20
0
파일: monitors.py 프로젝트: danny-boby/CoSA
    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
예제 #21
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
예제 #22
0
    def parse_string(self, lines):

        [none, var, state, input, output, init, invar, trans] = range(8)
        section = none

        inits = TRUE()
        invars = TRUE()
        transs = TRUE()

        sparser = StringParser()

        count = 0
        vars = set([])
        states = set([])
        inputs = set([])
        outputs = set([])
        invar_props = []
        ltl_props = []

        for line in lines:
            count += 1

            if line.strip() in ["", "\n"]:
                continue

            if T_VAR == line[:len(T_VAR)]:
                section = var
                continue

            if T_STATE == line[:len(T_STATE)]:
                section = state
                continue

            if T_INPUT == line[:len(T_INPUT)]:
                section = input
                continue

            if T_OUTPUT == line[:len(T_OUTPUT)]:
                section = output
                continue

            if T_INIT == line[:len(T_INIT)]:
                section = init
                continue

            if T_INVAR == line[:len(T_INVAR)]:
                section = invar
                continue

            if T_TRANS == line[:len(T_TRANS)]:
                section = trans
                continue

            if section in [var, state, input, output]:
                line = line[:-2].replace(" ", "").split(":")
                varname, vartype = line[0], (line[1][:-1].split("("))
                if varname[0] == "'":
                    varname = varname[1:-1]
                vardef = self._define_var(varname, vartype)

                vars.add(vardef)
                if section == state:
                    states.add(vardef)
                if section == input:
                    inputs.add(vardef)
                if section == output:
                    outputs.add(vardef)

            if section in [init, invar, trans]:
                qline = quote_names(line[:-2], replace_ops=False)

            if section == init:
                inits = And(inits, sparser.parse_formula(qline))

            if section == invar:
                invars = And(invars, sparser.parse_formula(qline))

            if section == trans:
                transs = And(transs, sparser.parse_formula(qline))

        hts = HTS("STS")
        ts = TS()

        ts.vars = vars
        ts.state_vars = states
        ts.input_vars = inputs
        ts.output_vars = outputs
        ts.init = inits
        ts.invar = invars
        ts.trans = transs

        hts.add_ts(ts)

        return (hts, invar_props, ltl_props)
예제 #23
0
파일: modules.py 프로젝트: yuex1994/CoSA
    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
예제 #24
0
    def combine_systems(hts,
                        hts2,
                        k,
                        symbolic_init,
                        eqprop=None,
                        inc=True,
                        non_deterministic=False):
        htseq = HTS("eq")

        hts1_varnames = [v.symbol_name() for v in hts.vars]
        hts2_varnames = [v.symbol_name() for v in hts2.vars]

        map1 = dict([(v, TS.get_prefix_name(v, S1)) for v in hts1_varnames]+\
                    [(TS.get_prime_name(v), TS.get_prefix_name(TS.get_prime_name(v), S1)) for v in hts1_varnames])
        map2 = dict([(v, TS.get_prefix_name(v, S2)) for v in hts2_varnames]+\
                    [(TS.get_prime_name(v), TS.get_prefix_name(TS.get_prime_name(v), S2)) for v in hts2_varnames])

        ts1_init = TRUE()
        ts2_init = TRUE()

        if not symbolic_init:
            ts1_init = substitute(hts.single_init(), map1)
            ts2_init = substitute(hts2.single_init(), map2)

        ts1 = TS()
        ts1.vars = set([TS.get_prefix(v, S1) for v in hts.vars])
        ts1.set_behavior(ts1_init,\
                         substitute(hts.single_trans(), map1),\
                         substitute(hts.single_invar(), map1))
        ts1.state_vars = set([TS.get_prefix(v, S1) for v in hts.state_vars])

        ts2 = TS()
        ts2.vars = set([TS.get_prefix(v, S2) for v in hts2.vars])
        ts2.set_behavior(ts2_init,\
                         substitute(hts2.single_trans(), map2),\
                         substitute(hts2.single_invar(), map2))
        ts2.state_vars = set([TS.get_prefix(v, S2) for v in hts2.state_vars])

        htseq.add_ts(ts1)
        htseq.add_ts(ts2)

        assumptions = []
        lemmas = []

        def sets_intersect(set1, set2):
            for el in set1:
                if not el in set2:
                    return False
            return True

        if hts.assumptions is not None:
            for assumption in hts.assumptions:
                assumptions.append(assumption)

        if hts.lemmas is not None:
            for lemma in hts.lemmas:
                lemmas.append(lemma)

        if hts2.assumptions is not None:
            for assumption in hts2.assumptions:
                assumptions.append(assumption)

        if hts2.lemmas is not None:
            for lemma in hts2.lemmas:
                lemmas.append(lemma)

        for assumption in assumptions:
            fv_assumption = get_free_variables(assumption)
            c_assumption = TRUE()

            if sets_intersect(fv_assumption, hts.vars):
                c_assumption = And(c_assumption, substitute(assumption, map1))
            if sets_intersect(fv_assumption, hts2.vars):
                c_assumption = And(c_assumption, substitute(assumption, map2))

            if c_assumption != TRUE():
                htseq.add_assumption(c_assumption)

        for lemma in lemmas:
            fv_lemma = get_free_variables(lemma)
            c_lemma = TRUE()

            if sets_intersect(fv_lemma, hts.vars):
                c_lemma = And(c_lemma, substitute(lemma, map1))
            if sets_intersect(fv_lemma, hts2.vars):
                c_lemma = And(c_lemma, substitute(lemma, map2))

            if c_lemma != TRUE():
                htseq.add_lemma(c_lemma)

        miter_out = Symbol(EQS, BOOL)

        inputs = hts.input_vars.intersection(hts2.input_vars)
        outputs = hts.output_vars.intersection(hts2.output_vars)

        htseq.input_vars = set([
            TS.get_prefix(v, S1) for v in hts.input_vars
        ]).union(set([TS.get_prefix(v, S2) for v in hts2.input_vars]))
        htseq.output_vars = set([
            TS.get_prefix(v, S1) for v in hts.output_vars
        ]).union(set([TS.get_prefix(v, S2) for v in hts2.output_vars]))

        if symbolic_init or (not non_deterministic):
            states = hts.state_vars.intersection(hts2.state_vars)
        else:
            states = []

        eqinputs = TRUE()
        eqoutputs = TRUE()
        eqstates = TRUE()

        for inp in inputs:
            eqinputs = And(
                eqinputs,
                EqualsOrIff(TS.get_prefix(inp, S1), TS.get_prefix(inp, S2)))

        for out in outputs:
            eqoutputs = And(
                eqoutputs,
                EqualsOrIff(TS.get_prefix(out, S1), TS.get_prefix(out, S2)))

        for svar in states:
            eqstates = And(
                eqstates,
                EqualsOrIff(TS.get_prefix(svar, S1), TS.get_prefix(svar, S2)))

        if eqprop is None:
            if symbolic_init or (not non_deterministic):
                invar = And(eqinputs,
                            Iff(miter_out, Implies(eqstates, eqoutputs)))
            else:
                invar = And(eqinputs, Iff(miter_out, eqoutputs))

            Logger.log('Inferring equivalence property: {}'.format(invar), 2)
        else:
            sparser = StringParser()
            eqprop = sparser.parse_formulae(eqprop)
            if len(eqprop) > 1:
                Logger.error("Expecting a single equivalence property")
            eqprop = eqprop[0][1]
            invar = Iff(miter_out, eqprop)
            Logger.log('Using provided equivalence property: {}'.format(invar),
                       2)

        tsmo = TS()
        tsmo.vars = set([miter_out])
        tsmo.invar = invar
        htseq.add_ts(tsmo)

        return (htseq, miter_out)
예제 #25
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
예제 #26
0
    def parse_string(self, lines):

        [none, var, state, input, output, init, invar, trans,
         ftrans] = range(9)
        section = none

        inits = TRUE()
        invars = TRUE()
        transs = TRUE()
        ftranss = {}

        sparser = StringParser()

        count = 0
        vars = set([])
        states = set([])
        inputs = set([])
        outputs = set([])
        invar_props = []
        ltl_props = []

        for line in lines:
            count += 1

            if (line.strip() in ["", "\n"]) or line[0] == T_COM:
                continue

            if T_VAR == line[:len(T_VAR)]:
                section = var
                continue

            if T_STATE == line[:len(T_STATE)]:
                section = state
                continue

            if T_INPUT == line[:len(T_INPUT)]:
                section = input
                continue

            if T_OUTPUT == line[:len(T_OUTPUT)]:
                section = output
                continue

            if T_INIT == line[:len(T_INIT)]:
                section = init
                continue

            if T_INVAR == line[:len(T_INVAR)]:
                section = invar
                continue

            if T_TRANS == line[:len(T_TRANS)]:
                section = trans
                continue

            if T_FTRANS == line[:len(T_FTRANS)]:
                section = ftrans
                continue

            if section in [var, state, input, output]:
                varname, vartype = line[:-2].replace(" ", "").split(":")
                if varname[0] == "'":
                    varname = varname[1:-1]
                vartype = parse_typestr(vartype)
                vardef = self._define_var(varname, vartype)

                vars.add(vardef)
                if section == state:
                    states.add(vardef)
                if section == input:
                    inputs.add(vardef)
                if section == output:
                    outputs.add(vardef)

            if section in [init, invar, trans]:
                line = line.replace(T_SC, "").strip()
                qline = quote_names(line, replace_ops=False)

            if section == init:
                inits = And(inits, sparser.parse_formula(qline))

            if section == invar:
                invars = And(invars, sparser.parse_formula(qline))

            if section == trans:
                transs = And(transs, sparser.parse_formula(qline))

            if section == ftrans:
                strvar = line[:line.find(":=")]
                var = sparser.parse_formula(
                    quote_names(strvar, replace_ops=False))
                cond_ass = line[line.find(":=") + 2:].strip()
                ftranss[var] = []

                for cond_as in cond_ass.split("{"):
                    if cond_as == "":
                        continue
                    cond = cond_as[:cond_as.find(",")]
                    ass = cond_as[cond_as.find(",") + 1:cond_as.find("}")]
                    ftranss[var].append((sparser.parse_formula(
                        quote_names(cond, replace_ops=False)),
                                         sparser.parse_formula(
                                             quote_names(ass,
                                                         replace_ops=False))))

        hts = HTS("STS")
        ts = TS()

        ts.vars = vars
        ts.state_vars = states
        ts.input_vars = inputs
        ts.output_vars = outputs
        ts.init = inits
        ts.invar = invars
        ts.trans = transs
        ts.ftrans = ftranss

        hts.add_ts(ts)

        return (hts, invar_props, ltl_props)
예제 #27
0
파일: coi.py 프로젝트: yuex1994/CoSA
    def compute(self, hts, prop):
        Logger.log("Building COI", 1)

        self._build_var_deps(hts)

        coi_vars = set(self._free_variables(prop))

        if (len(coi_vars) < 1) or (self.var_deps == {}):
            return hts

        if hts.assumptions is not None:
            for assumption in hts.assumptions:
                for v in self._free_variables(assumption):
                    coi_vars.add(v)

        if hts.lemmas is not None:
            for lemma in hts.lemmas:
                for v in self._free_variables(lemma):
                    coi_vars.add(v)

        coits = TS("COI")

        coi_vars = list(coi_vars)
        i = 0
        visited = set([])
        while i < len(coi_vars):
            var = coi_vars[i]
            if (var in visited) or (var not in self.var_deps):
                i += 1
                continue

            coi_vars = coi_vars[:i + 1] + list(
                self.var_deps[var]) + coi_vars[i + 1:]

            visited.add(var)
            i += 1

        coi_vars = frozenset(coi_vars)

        trans = list(
            conjunctive_partition(hts.single_trans(include_ftrans=True)))
        invar = list(
            conjunctive_partition(hts.single_invar(include_ftrans=True)))
        init = list(conjunctive_partition(hts.single_init()))

        coits.trans = [
            f for f in trans
            if self._intersect(coi_vars, self._free_variables(f))
        ]
        coits.invar = [
            f for f in invar
            if self._intersect(coi_vars, self._free_variables(f))
        ]
        coits.init = [
            f for f in init
            if self._intersect(coi_vars, self._free_variables(f))
        ]

        Logger.log("COI statistics:", 1)
        Logger.log("  Vars:  %s -> %s" % (len(hts.vars), len(coi_vars)), 1)
        Logger.log("  Init:  %s -> %s" % (len(init), len(coits.init)), 1)
        Logger.log("  Invar: %s -> %s" % (len(invar), len(coits.invar)), 1)
        Logger.log("  Trans: %s -> %s" % (len(trans), len(coits.trans)), 1)

        coits.trans = And(coits.trans)
        coits.invar = And(coits.invar)
        coits.init = And(coits.init)

        coits.vars = set([])
        for bf in [init, invar, trans]:
            for f in bf:
                for v in self._free_variables(f):
                    coits.vars.add(v)

        coits.input_vars = set([v for v in coi_vars if v in hts.input_vars])
        coits.output_vars = set([v for v in coi_vars if v in hts.output_vars])
        coits.state_vars = set([v for v in coi_vars if v in hts.state_vars])

        new_hts = HTS("COI")
        new_hts.add_ts(coits)

        if self.save_model:
            printer = HTSPrintersFactory.printer_by_name("STS")
            with open("/tmp/coi_model.ssts", "w") as f:
                f.write(printer.print_hts(new_hts, []))

        return new_hts