Beispiel #1
0
    def __init__(self, 
                 target : ExprModel, 
                 name : str,
                 options,
                 iff : ExprModel = None):
        super().__init__()
        self.parent = None
        self.target = target
        self.iff = iff

        # Cached value Target-ref field. This is used to retrieve values for
        # type covergroups
        self.iff_val_cache = True
        self.target_val_cache = 0

        self.name = name
        self.n_bins = 0
        self.unhit_s : Set[int] = set()
        self.hit_l : List[int] = []
        self.bin_model_l = []
        
        self.srcinfo_decl = None
        self.bin_expr = None
        # Tracks 
        self.coverage = 0.0
        self.coverage_calc_valid = False

        if options is None:        
            self.options = CoverageOptionsModel()
        else:
            self.options = options
Beispiel #2
0
    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", 0, 1, 16)
        cp.add_bin_model(bn)
        
        cp2 = CoverpointModel(ExprFieldRefModel(f2), "cp2",
                              CoverageOptionsModel())
        cg.add_coverpoint(cp2)
        bn = CoverpointBinArrayModel("cp", 0, 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()

        count = 0        
        for i in range(1000):
            r.do_randomize([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))
Beispiel #3
0
    def test_coverpoint_array_bin(self):

        cg = CovergroupModel("cg")

        a = 0
        a_cp = CoverpointModel(ExprRefModel(lambda: a, 32, False), "a_cp",
                               CoverageOptionsModel())
        cg.add_coverpoint(a_cp)

        bins = a_cp.add_bin_model(CoverpointBinArrayModel("a", 0, 15))

        cg.finalize()

        for i in range(8):
            a = i
            cg.sample()

        for i in range(16):
            if (i < 8):
                self.assertEqual(a_cp.get_bin_hits(i), 1)
            else:
                self.assertEqual(a_cp.get_bin_hits(i), 0)

        self.assertEqual(a_cp.get_coverage(), 50.0)
        self.assertEqual(cg.get_coverage(), 50.0)
Beispiel #4
0
    def test_coverpoint_bins(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)
        cp.add_bin_model(CoverpointBinArrayModel("bn1", 0, 1, 16))
        cp.add_bin_model(CoverpointBinCollectionModel.mk_collection("bn2", RangelistModel([
            [17,65535-16-1]
            ]), 16))
        cp.add_bin_model(CoverpointBinArrayModel("bn3", 0, 65535-16, 65535))
        
        cp2 = CoverpointModel(ExprFieldRefModel(f2), "cp2",
                              CoverageOptionsModel())
        cg.add_coverpoint(cp2)
        bn = CoverpointBinArrayModel("cp", 0, 1, 16)
        cp2.add_bin_model(bn)
        
        gen = GeneratorModel("top")
        gen.add_field(stim)
        gen.add_covergroup(cg)
        
        gen.finalize()

        # Need a special randomizer to deal with generators        
        r = Randomizer()

        count = 0        
        for i in range(1000):
            r.do_randomize([gen])
            cg.sample()
            count += 1
            cov = cg.get_coverage()
            if cov == 100:
                break
            
        self.assertEqual(cg.get_coverage(), 100)
        # Ensure that we converge relatively quickly
        self.assertLessEqual(count, 64)
Beispiel #5
0
    def test_smoke(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)

        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()
            if cov == 100:
                break

        self.assertEqual(cg.get_coverage(), 100)
        # Ensure that we converge relatively quickly
        self.assertLessEqual(count, 32)
Beispiel #6
0
    def __init__(self, name: str):
        super().__init__(name)

        # Handle to the type covergroup this instance is associated with
        self.type_cg: CovergroupModel = None

        # List of covergroup instances of this type
        self.cg_inst_l: List[CovergroupModel] = []

        self.coverpoint_l = []
        self.cross_l = []
        self.typename = None  # Typename of this covergroup
        self.du_name = None  # Design-unit typename in which this covergroup is instanced
        self.instname = None  # Design-unit instance name in which this covergroup is instanced

        self.coverage = 0.0
        self.coverage_calc_valid = False

        self.options = CoverageOptionsModel()
Beispiel #7
0
    def create_model(self, parent=None):
        ret = CoverageOptionsModel()
        
        if self.weight is not None:
            ret.weight = self.weight
        elif parent is not None:
            ret.weight = parent.weight
            
        if self.goal is not None:
            ret.goal = self.goal
        elif parent is not None:
            ret.goal = parent.goal

        # Comment doesn't cascade        
        if self.comment is not None:
            ret.comment = self.comment
            
        if self.at_least is not None:
            ret.at_least = self.at_least
        elif parent is not None:
            ret.at_least = parent.at_least
            
        if self.auto_bin_max is not None:
            ret.auto_bin_max = self.auto_bin_max
        elif parent is not None:
            ret.auto_bin_max = parent.auto_bin_max
            
        return ret
Beispiel #8
0
class CoverpointModel(CoverItemBase):
    def __init__(self,
                 target: ExprModel,
                 name: str,
                 options,
                 iff: ExprModel = None):
        super().__init__()
        self.parent = None
        self.target = target
        self.iff = iff

        # Cached value Target-ref field. This is used to retrieve values for
        # type covergroups
        self.iff_val_cache = True
        self.target_val_cache = 0

        self.name = name
        self.n_bins = 0
        self.n_ignore_bins = 0
        self.n_illegal_bins = 0
        self.unhit_s: Set[int] = set()
        self.hit_l: List[int] = []
        self.hit_ignore_l: List[int] = []
        self.hit_illegal_l: List[int] = []
        self.bin_model_l = []
        self.ignore_bin_model_l = []
        self.illegal_bin_model_l = []

        self.srcinfo_decl = None
        self.bin_expr = None
        # Tracks
        self.coverage = 0.0
        self.coverage_calc_valid = False

        if options is None:
            self.options = CoverageOptionsModel()
        else:
            self.options = options

    def add_bin_model(self, bin_m):
        bin_m.parent = self
        self.bin_model_l.append(bin_m)
        return bin_m

    def add_ignore_bin_model(self, bin_m):
        bin_m.parent = self
        bin_m.set_bin_type(CoverpointBinType.Ignore)
        self.ignore_bin_model_l.append(bin_m)
        return bin_m

    def add_illegal_bin_model(self, bin_m):
        bin_m.parent = self
        bin_m.set_bin_type(CoverpointBinType.Illegal)
        self.illegal_bin_model_l.append(bin_m)
        return bin_m

    def finalize(self):
        self.n_bins = 0
        self.n_ignore_bins = 0
        self.n_illegal_bins = 0

        for b in self.bin_model_l:
            self.n_bins += b.finalize(self.n_bins)
        for b in self.ignore_bin_model_l:
            self.n_ignore_bins += b.finalize(self.n_ignore_bins)
        for b in self.illegal_bin_model_l:
            self.n_illegal_bins += b.finalize(self.n_illegal_bins)

        # Track unhit bins within this coverpoint
        self.unhit_s.update(range(self.n_bins))
        self.hit_l = [0] * self.n_bins
        self.hit_ignore_l = [0] * self.n_ignore_bins
        self.hit_illegal_l = [0] * self.n_illegal_bins

    def get_bin_expr(self, bin_idx):
        b = None

        # First, find the bin this index applies to
        for i in range(len(self.bin_model_l)):
            b = self.bin_model_l[i]
            if b.get_n_bins() > bin_idx:
                break
            bin_idx -= b.get_n_bins()

        # Now, return the actual expression
        return b.get_bin_expr(bin_idx)

    def _get_target_bin(self, bin_idx) -> Tuple['CoverpointBinModelBase', int]:
        b = None

        # First, find the bin this index applies to
        for i in range(len(self.bin_model_l)):
            b = self.bin_model_l[i]
            if b.get_n_bins() > bin_idx:
                break
            bin_idx -= b.get_n_bins()

        return (b, bin_idx)

    def _get_target_ignore_bin(
            self, bin_idx) -> Tuple['CoverpointBinModelBase', int]:
        b = None

        # First, find the bin this index applies to
        for i in range(len(self.ignore_bin_model_l)):
            b = self.ignore_bin_model_l[i]
            if b.get_n_bins() > bin_idx:
                break
            bin_idx -= b.get_n_bins()

        return (b, bin_idx)

    def _get_target_illegal_bin(
            self, bin_idx) -> Tuple['CoverpointBinModelBase', int]:
        b = None

        # First, find the bin this index applies to
        for i in range(len(self.illegal_bin_model_l)):
            b = self.illegal_bin_model_l[i]
            if b.get_n_bins() > bin_idx:
                break
            bin_idx -= b.get_n_bins()

        return (b, bin_idx)

    def get_coverage(self) -> float:
        if not self.coverage_calc_valid:
            self.coverage = (len(self.hit_l) - len(self.unhit_s)) / len(
                self.hit_l) * 100.0
            self.coverage_calc_valid = True

        return self.coverage

    def get_inst_coverage(self):
        raise Exception("get_inst_coverage unimplemented")

    def sample(self):

        if self.iff is not None:
            self.iff_val_cache = bool(self.iff.val())

        if self.iff_val_cache:
            for b in self.bin_model_l:
                b.sample()
            for b in self.ignore_bin_model_l:
                b.sample()
            for b in self.illegal_bin_model_l:
                b.sample()

    def select_unhit_bin(self, r: RandIF) -> int:
        if len(self.unhit_s) > 0:
            return r.sample(self.unhit_s, 1)[0]
#            return random.sample(self.unhit_s,1)[0]
        else:
            return -1

    def get_bin_range(self, bin_idx) -> RangelistModel:
        b, off = self._get_target_bin(bin_idx)

        return b.get_bin_range(off)
        pass

    def coverage_ev(self, bin_idx, bin_type):
        """Called by a bin to signal that an uncovered bin has been covered"""
        self.coverage_calc_valid = False
        if bin_type == CoverpointBinType.Bins:
            if bin_idx in self.unhit_s:
                self.parent.coverage_ev(self, bin_idx)
                self.unhit_s.remove(bin_idx)
            self.hit_l[bin_idx] += 1
            self.coverage_calc_valid = False
        elif bin_type == CoverpointBinType.Ignore:
            self.hit_ignore_l[bin_idx] += 1
        elif bin_type == CoverpointBinType.Illegal:
            self.hit_illegal_l[bin_idx] += 1

    def get_val(self):
        if self.target is not None:
            self.target_val_cache = self.target.val()
        return self.target_val_cache

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

    def dump(self, ind=""):
        print(ind + "Coverpoint: " + self.name)
        for b in self.bin_model_l:
            b.dump(ind + "    ")

    def get_n_bins(self):
        return self.n_bins

    def get_n_ignore_bins(self):
        return self.n_ignore_bins

    def get_n_illegal_bins(self):
        return self.n_illegal_bins

    def get_n_hit_bins(self):
        return len(self.hit_l) - len(self.unhit_s)

    def get_bin_hits(self, bin_idx):
        return self.hit_l[bin_idx]

    def get_ignore_bin_hits(self, bin_idx):
        return self.hit_ignore_l[bin_idx]

    def get_illegal_bin_hits(self, bin_idx):
        return self.hit_illegal_l[bin_idx]

    def get_bin_name(self, bin_idx) -> str:
        b, idx = self._get_target_bin(bin_idx)
        return b.get_bin_name(idx)

    def get_ignore_bin_name(self, bin_idx) -> str:
        b, idx = self._get_target_ignore_bin(bin_idx)
        return b.get_bin_name(idx)

    def get_illegal_bin_name(self, bin_idx) -> str:
        b, idx = self._get_target_illegal_bin(bin_idx)
        return b.get_bin_name(idx)

    def get_hit_bins(self, bin_l):
        bin_idx = 0
        for b in self.bin_model_l:
            if b.hit_idx() != -1:
                bin_l.append(bin_idx + b.hit_idx())
            bin_idx += b.n_bins()

    def equals(self, oth: 'CoverpointModel') -> bool:
        eq = True

        eq &= self.name == oth.name

        if len(self.bin_model_l) == len(oth.bin_model_l):
            for s, o in zip(self.bin_model_l, oth.bin_model_l):
                eq &= s.equals(o)
        else:
            eq = False

        if len(self.ignore_bin_model_l) == len(oth.ignore_bin_model_l):
            for s, o in zip(self.ignore_bin_model_l, oth.ignore_bin_model_l):
                eq &= s.equals(o)
        else:
            eq = False

        if len(self.illegal_bin_model_l) == len(oth.illegal_bin_model_l):
            for s, o in zip(self.illegal_bin_model_l, oth.illegal_bin_model_l):
                eq &= s.equals(o)
        else:
            eq = False

        return eq

    def clone(self) -> 'CoverpointModel':
        ret = CoverpointModel(self.target, self.name, self.options.clone())
        ret.srcinfo_decl = None if self.srcinfo_decl is None else self.srcinfo_decl.clone(
        )

        for bn in self.bin_model_l:
            ret.add_bin_model(bn.clone())

        for bn in self.ignore_bin_model_l:
            ret.add_ignore_bin_model(bn.clone())

        for bn in self.illegal_bin_model_l:
            ret.add_illegal_bin_model(bn.clone())

        return ret