示例#1
0
 def visit_scalar_field(self, f: FieldScalarModel):
     if f.is_used_rand:
         self.is_x = True
         self.val = None
     else:
         self.is_x = False
         self.val = f.get_val()
示例#2
0
class FieldArrayModel(FieldCompositeModel):
    """All arrays are processed as if they were variable size."""
    def __init__(self, name, is_scalar, enums, width, is_signed, is_rand,
                 is_rand_sz):
        super().__init__(name, is_rand)
        # width and is_signed only needed for scalar fields
        self.is_enum = (enums is not None)
        self.enums = enums
        self.is_scalar = is_scalar
        self.width = width
        self.is_signed = is_signed
        self.is_rand_sz = is_rand_sz

        # Holds a cached version of the sum constraint
        self.sum_expr_btor = None
        self.sum_expr = None

        # Holds a cached version of the sum constraint
        self.product_expr_btor = None
        self.product_expr = None

        self.size = FieldScalarModel("size", 32, False, is_rand_sz)
        self._set_size(0)

    def append(self, fm):
        super().add_field(fm)
        self._set_size(len(self.field_l))
        fm.is_declared_rand = self.is_declared_rand
        fm.rand_mode = self.is_declared_rand
        self.name_elems()

    def clear(self):
        self.field_l.clear()
        self._set_size(0)

    def pop(self, idx=0):
        self.field_l.pop(idx)
        self._set_size(len(self.field_l))
        self.name_elems()

    def _set_size(self, sz):
        if sz != int(self.size.get_val()):
            self.size.set_val(sz)
            self.sum_expr = None
            self.sum_expr_btor = None
            self.product_expr = None
            self.product_expr_btor = None

    def name_elems(self):
        """Apply an index-based name to all fields"""
        for i, f in enumerate(self.field_l):
            f.name = self.name + "[" + str(i) + "]"

    def pre_randomize(self):
        # Set the size field for arrays that don't
        # have a random size
        if not self.is_rand_sz:
            self._set_size(len(self.field_l))
        FieldCompositeModel.pre_randomize(self)

    def post_randomize(self):
        FieldCompositeModel.post_randomize(self)
        self.sum_expr = None
        self.sum_expr_btor = None

    def add_field(self) -> FieldScalarModel:
        fid = len(self.field_l)
        if self.is_enum:
            ret = super().add_field(
                EnumFieldModel(self.name + "[" + str(fid) + "]", self.enums,
                               self.is_declared_rand))
        else:
            ret = super().add_field(
                FieldScalarModel(self.name + "[" + str(fid) + "]", self.width,
                                 self.is_signed, self.is_declared_rand))
        # Update the size
        self._set_size(len(self.field_l))
        return ret

    def build(self, builder):
        # Called before randomization
        self._set_size(len(self.field_l))
        super().build(builder)

    def get_sum_expr(self):
        if self.sum_expr is None:
            # Build

            # Force the result to be 32-bit, in order to
            # match user expectation
            ret = ExprLiteralModel(0, self.is_signed, 32)
            for i in range(int(self.size.get_val())):
                f = self.field_l[i]
                if ret is None:
                    ret = ExprFieldRefModel(f)
                else:
                    ret = ExprBinModel(ret, BinExprType.Add,
                                       ExprFieldRefModel(f))

            if ret is None:
                ret = ExprLiteralModel(0, self.is_signed, 32)
            self.sum_expr = ret

        return self.sum_expr

    def build_sum_expr(self, btor):
        if self.sum_expr_btor is None:
            self.sum_expr_btor = self.get_sum_expr().build(btor)
        return self.sum_expr_btor

    def get_product_expr(self):
        if self.product_expr is None:
            # Build

            # Force the result to be 32-bit, in order to
            # match user expectation
            if int(self.size.get_val()) == 0:
                ret = ExprLiteralModel(0, self.is_signed, 64)
            else:
                ret = ExprLiteralModel(1, self.is_signed, 64)
            for i in range(int(self.size.get_val())):
                f = self.field_l[i]
                ret = ExprBinModel(ret, BinExprType.Mul, ExprFieldRefModel(f))

            self.product_expr = ret

        return self.product_expr

    def build_product_expr(self, btor):
        if self.product_expr_btor is None:
            self.product_expr_btor = self.get_product_expr().build(btor)
        return self.product_expr_btor

    def accept(self, v):
        v.visit_field_scalar_array(self)