def __init__(self, l, it=None, idx=None): self.stmt = None if it is None and idx is None: # Default: use it it = True idx = False else: # One or more are specified if idx is None: idx = False if it is None: it = False if not idx and not it: raise Exception("Neither it nor idx specified") # Form an expression to the array to_expr(l) e = pop_expr() self.arr_ref_e = e self.elem_t = Expr2FieldTypeVisitor().fieldtype(e) self.it = it self.idx = idx if not in_constraint_scope(): raise Exception( "Attempting to use foreach constraint outside constraint scope" ) self.stmt = ConstraintForeachModel(e) if in_srcinfo_mode(): self.stmt.srcinfo = SourceInfo.mk()
def randomize(*args, **kwargs): """Randomize a list of variables""" frame = inspect.stack()[1] fields = [] for v in args: if hasattr(v, "get_model"): fields.append(v.get_model()) else: raise Exception("Parameter \"" + str(v) + " to randomize is not a vsc object") debug = 0 if "debug" in kwargs.keys(): debug = kwargs["debug"] solve_fail_debug = False if "solve_fail_debug" in kwargs: solve_fail_debug = kwargs["solve_fail_debug"] randstate = None if "randstate" in kwargs: randstate = kwargs["randstate"] else: randstate = RandState(random.randint(0, 0xFFFFFFFF)) Randomizer.do_randomize(randstate, SourceInfo(frame.filename, frame.lineno), fields, solve_fail_debug=solve_fail_debug, debug=debug)
def constraint(c): ret = constraint_t(c) # Capture source info, since it's only # captured once during loading ret.srcinfo = SourceInfo.mk() return ret
def visit_expr_bin(self, e:ExprBinModel): # Each side could be # - rand # - resolved ModelVisitor.visit_expr_bin(self, e) lhs_nonrand = IsNonRandExprVisitor().is_nonrand(e.lhs) rhs_nonrand = IsNonRandExprVisitor().is_nonrand(e.rhs) if lhs_nonrand and not rhs_nonrand: lhs_v = e.lhs.val() rhs_w = e.rhs.width() # print("lhs_v=%d rhs_w=%d" % (int(lhs_v), rhs_w)) elif rhs_nonrand and not lhs_nonrand: rhs_v = e.rhs.val() lhs_w = e.lhs.width() lhs_s = e.lhs.is_signed() # print("rhs_v=%d lhs_w=%d lhs_s=%d" % (int(rhs_v), lhs_w, int(lhs_s))) if lhs_s: pass else: lhs_max = (1 << lhs_w) - 1 if rhs_v > lhs_max: self.ret += "%s: %d is out-of-bounds for domain %d..%d\n" % ( SourceInfo.toString(e.srcinfo), int(rhs_v), 0, lhs_max)
def test_incr(self): obj = FieldCompositeModel("obj") arr = obj.add_field( FieldArrayModel( "arr", None, # type_t True, # is_scalar None, # not an enum-type list 32, False, True, False)) for i in range(10): arr.add_field() obj.add_constraint( ConstraintBlockModel("XX", [ ConstraintExprModel( ExprBinModel(ExprFieldRefModel(arr.size), BinExprType.Eq, ExprLiteralModel(10, False, 32))) ])) foreach = ConstraintForeachModel(ExprFieldRefModel(arr)) foreach.addConstraint( ConstraintImpliesModel( ExprBinModel(ExprFieldRefModel(foreach.index), BinExprType.Gt, ExprLiteralModel(0, False, 32)), [ ConstraintExprModel( ExprBinModel( ExprArraySubscriptModel( ExprFieldRefModel(arr), ExprFieldRefModel(foreach.index)), BinExprType.Eq, ExprBinModel( ExprArraySubscriptModel( ExprFieldRefModel(arr), ExprBinModel( ExprFieldRefModel(foreach.index), BinExprType.Sub, ExprLiteralModel(1, False, 32))), BinExprType.Add, ExprLiteralModel( 1, False, 32)))) ])) obj.add_constraint(ConstraintBlockModel("c", [foreach])) # print("Object: " + ModelPrettyPrinter.print(obj)) # # constraints = ArrayConstraintBuilder.build(obj) # for c in constraints: # print("Constraint: " + ModelPrettyPrinter.print(c)) # print("Object(1): " + ModelPrettyPrinter.print(obj)) # # ConstraintOverrideRollbackVisitor.rollback(obj) # print("Object(2): " + ModelPrettyPrinter.print(obj)) randstate = RandState(0) Randomizer.do_randomize(randstate, SourceInfo("", -1), [obj]) for f in arr.field_l: print("" + f.name + ": " + str(int(f.get_val())))
def __init__(self, e): if not in_constraint_scope(): raise Exception( "Attempting to use if_then constraint outside constraint scope" ) to_expr(e) self.stmt = ConstraintImpliesModel(pop_expr()) if in_srcinfo_mode(): self.stmt.srcinfo = SourceInfo.mk()
def unique(*args): expr_l = [] for i in range(-1, -(len(args) + 1), -1): to_expr(args[i]) expr_l.insert(0, pop_expr()) c = ConstraintUniqueModel(expr_l) if in_srcinfo_mode(): c.srcinfo = SourceInfo.mk() push_constraint_stmt(c)
def bin_expr(self, op, rhs): to_expr(rhs) rhs_e = pop_expr() lhs_e = pop_expr() e = ExprBinModel(lhs_e, op, rhs_e) if in_srcinfo_mode(): e.srcinfo = SourceInfo.mk(2) return expr(e)
def test_cross(self): stim = FieldCompositeModel("stim", True) f = FieldScalarModel("a", 16, False, True) stim.add_field(f) f2 = FieldScalarModel("b", 16, False, True) stim.add_field(f2) cg = CovergroupModel("cg") cp = CoverpointModel(ExprFieldRefModel(f), "cp1", CoverageOptionsModel()) cg.add_coverpoint(cp) bn = CoverpointBinArrayModel("cp", 1, 16) cp.add_bin_model(bn) cp2 = CoverpointModel(ExprFieldRefModel(f2), "cp2", CoverageOptionsModel()) cg.add_coverpoint(cp2) bn = CoverpointBinArrayModel("cp", 1, 16) cp2.add_bin_model(bn) cr = CoverpointCrossModel("aXb", CoverageOptionsModel()) cr.add_coverpoint(cp) cr.add_coverpoint(cp2) cg.add_coverpoint(cr) gen = GeneratorModel("top") gen.add_field(stim) gen.add_covergroup(cg) gen.finalize() # Need a special randomizer to deal with generators r = Randomizer(RandState(0)) randstate = RandState(0) count = 0 for i in range(1000): r.do_randomize(randstate, SourceInfo("", -1), [gen]) cg.sample() count += 1 cov = cg.get_coverage() print("Coverage: (" + str(i) + ") " + str(cov)) if cov == 100: break self.assertEqual(cg.get_coverage(), 100) # Ensure that we converge relatively quickly self.assertLessEqual(count, (256 + 16 + 16))
def bin_expr(self, op, rhs): to_expr(rhs) rhs_e = pop_expr() # push_expr(ExprFieldRefModel(self._int_field_info.model)) # Push a reference to this field self.to_expr() lhs_e = pop_expr() e = ExprBinModel(lhs_e, op, rhs_e) if in_srcinfo_mode(): e.srcinfo = SourceInfo.mk(2) return expr(e)
def __exit__(self, t, v, tb): frame = inspect.stack()[1] c = pop_constraint_scope() leave_expr_mode() try: Randomizer.do_randomize(self.randstate, SourceInfo(frame.filename, frame.lineno), self.field_l, [c], debug=debug) except SolveFailure as e: if _solve_fail_debug or self.solve_fail_debug: print("Solve Failure") raise e
def test_smoke(self): obj = FieldCompositeModel("obj") a = obj.add_field(FieldScalarModel("a", 8, False, True)) b = obj.add_field(FieldScalarModel("a", 8, False, True)) obj.add_constraint( ConstraintBlockModel("c", [ ConstraintExprModel( ExprBinModel(a.expr(), BinExprType.Lt, b.expr())) ])) rand = Randomizer(RandState(0)) randstate = RandState(0) rand.do_randomize(randstate, SourceInfo("", -1), [obj]) self.assertLess(a.val, b.val)
def solve_order(before, after): if constraint_scope_depth() != 1: raise Exception( "solve_before can only be used at a constraint top level") before_l = [] after_l = [] if isinstance(before, list): for b in before: to_expr(b) b_e = pop_expr() if not isinstance(b_e, ExprFieldRefModel): raise Exception("Parameter " + str(b) + " is not a field reference") before_l.append(b_e.fm) else: to_expr(before) before_e = pop_expr() if not isinstance(before_e, ExprFieldRefModel): raise Exception("Parameter " + str(before) + " is not a field reference") before_l.append(before_e.fm) if isinstance(after, list): for a in after: to_expr(a) a_e = pop_expr() if not isinstance(a_e, ExprFieldRefModel): raise Exception("Parameter " + str(a) + " is not a field reference") before_l.append(a_e.fm) else: to_expr(after) after_e = pop_expr() if not isinstance(after_e, ExprFieldRefModel): raise Exception("Parameter " + str(after) + " is not a field reference") after_l.append(after_e.fm) c = ConstraintSolveOrderModel(before_l, after_l) if in_srcinfo_mode(): c.srcinfo = SourceInfo.mk() push_constraint_stmt(c)
def test_wide_var(self): obj = FieldCompositeModel("obj") a = obj.add_field(FieldScalarModel("a", 1024, False, True)) obj.add_constraint( ConstraintBlockModel("c", [ ConstraintExprModel( ExprBinModel( a.expr(), BinExprType.Gt, ExprLiteralModel(0x80000000000000000, False, 72))) ])) randstate = RandState(0) rand = Randomizer(randstate) rand.do_randomize(randstate, SourceInfo("", -1), [obj]) print("a=" + hex(int(a.val))) self.assertGreater(a.val, ValueScalar(0x80000000000000000))
def dist(lhs, weights): """Applies distribution weights to the specified field""" to_expr(lhs) lhs_e = pop_expr() weight_l = [] for w in weights: if not isinstance(w, weight): raise Exception( "Weight specifications must of type 'vsc.weight', not " + str(w)) weight_l.append(w.weight_e) c = ConstraintDistModel(lhs_e, weight_l) if in_srcinfo_mode(): c.srcinfo = SourceInfo.mk() push_constraint_stmt(c)
def __init__(self, e): self.stmt = None if not in_constraint_scope(): raise Exception( "Attempting to use if_then constraint outside constraint scope" ) last_stmt = last_constraint_stmt() if last_stmt == None or not isinstance(last_stmt, ConstraintIfElseModel): raise Exception( "Attempting to use else_if where it doesn't follow if_then") to_expr(e) # Need to find where to think this in while last_stmt.false_c != None: last_stmt = last_stmt.false_c self.stmt = ConstraintIfElseModel(pop_expr()) if in_srcinfo_mode(): self.stmt.srcinfo = SourceInfo.mk() last_stmt.false_c = self.stmt
def create_diagnostics_1(self, active_randsets) -> str: ret = "" btor = Boolector() btor.Set_opt(pyboolector.BTOR_OPT_INCREMENTAL, True) btor.Set_opt(pyboolector.BTOR_OPT_MODEL_GEN, True) model_valid = False diagnostic_constraint_l = [] diagnostic_field_l = [] # First, determine how many randsets are actually failing i = 0 while i < len(active_randsets): rs = active_randsets[i] for f in rs.all_fields(): f.build(btor) # Assume that we can omit all soft constraints, since they # will have already been omitted (?) constraint_l = list( map( lambda c: (c, c.build(btor)), filter(lambda c: not isinstance(c, ConstraintSoftModel), rs.constraints()))) for c in constraint_l: btor.Assume(c[1]) if btor.Sat() != btor.SAT: # Save fields and constraints if the randset doesn't # solve on its own diagnostic_constraint_l.extend(constraint_l) diagnostic_field_l.extend(rs.fields()) i += 1 problem_constraints = [] solving_constraints = [] # Okay, now perform a series of solves to identify # constraints that are actually a problem for c in diagnostic_constraint_l: btor.Assume(c[1]) model_valid = False if btor.Sat() != btor.SAT: # This is a problematic constraint # Save it for later problem_constraints.append(c[0]) else: # Not a problem. Assert it now btor.Assert(c[1]) solving_constraints.append(c[0]) model_valid = True # problem_constraints.append(c[0]) if btor.Sat() != btor.SAT: raise Exception("internal error: system should solve") # Okay, we now have a constraint system that solves, and # a list of constraints that are a problem. We want to # resolve the value of all variables referenced by the # solving constraints so and then display the non-solving # constraints. This will (hopefully) help highlight the # reason for the failure for c in solving_constraints: c.accept(RefFieldsPostRandVisitor()) ret += "Problem Constraints:\n" for i, pc in enumerate(problem_constraints): ret += "Constraint %d: %s\n" % (i, SourceInfo.toString(pc.srcinfo)) ret += ModelPrettyPrinter.print(pc, print_values=True) ret += ModelPrettyPrinter.print(pc, print_values=False) for rs in active_randsets: for f in rs.all_fields(): f.dispose() return ret
def create_diagnostics(self, active_randsets) -> str: btor = Boolector() btor.Set_opt(pyboolector.BTOR_OPT_INCREMENTAL, True) btor.Set_opt(pyboolector.BTOR_OPT_MODEL_GEN, True) model_valid = False diagnostic_constraint_l = [] diagnostic_field_l = [] # First, determine how many randsets are actually failing i = 0 while i < len(active_randsets): rs = active_randsets[i] for f in rs.all_fields(): f.build(btor) # Assume that we can omit all soft constraints, since they # will have already been omitted (?) constraint_l = list( map( lambda c: (c, c.build(btor)), filter(lambda c: not isinstance(c, ConstraintSoftModel), rs.constraints()))) for c in constraint_l: btor.Assume(c[1]) if btor.Sat() != btor.SAT: # Save fields and constraints if the randset doesn't # solve on its own diagnostic_constraint_l.extend(constraint_l) diagnostic_field_l.extend(rs.fields()) i += 1 problem_sets = [] degree = 1 while True: init_size = len(diagnostic_constraint_l) tmp_l = [] ret = self._collect_failing_constraints(btor, diagnostic_constraint_l, 0, degree, tmp_l, problem_sets) if len(diagnostic_constraint_l) == init_size and degree > 3: break else: degree += 1 if Randomizer.EN_DEBUG > 0: print("%d constraints remaining ; %d problem sets" % (len(diagnostic_constraint_l), len(problem_sets))) # Assert the remaining constraints for c in diagnostic_constraint_l: btor.Assert(c[1]) if btor.Sat() != btor.SAT: raise Exception("internal error: system should solve") # Okay, we now have a constraint system that solves, and # a list of constraints that are a problem. We want to # resolve the value of all variables referenced by the # solving constraints so and then display the non-solving # constraints. This will (hopefully) help highlight the # reason for the failure ret = "" for ps in problem_sets: ret += ("Problem Set: %d constraints\n" % len(ps)) for pc in ps: ret += " %s:\n" % SourceInfo.toString(pc[0].srcinfo) ret += " %s" % ModelPrettyPrinter.print(pc[0], print_values=False) pc = [] for c in ps: pc.append(c[0]) lint_r = LintVisitor().lint([], pc) if lint_r != "": ret += "Lint Results:\n" + lint_r for rs in active_randsets: for f in rs.all_fields(): f.dispose() return ret