From 4476b835dbccf912c8c0f02b6c13520490891a1c Mon Sep 17 00:00:00 2001 From: Matthew Ballance Date: Sun, 22 Sep 2024 22:52:53 +0000 Subject: [PATCH] 0.9.3 - () - Properly apply ignore bins to single-value bins Signed-off-by: Matthew Ballance --- doc/Changelog.md | 3 + etc/ivpm.info | 2 +- setup.py | 2 +- src/vsc/coverage.py | 18 ++-- ve/unit/test_coverage_bin_model.py | 2 + ve/unit/test_coverage_igore_bins.py | 143 ++++++++++++++++++++++++++++ 6 files changed, 162 insertions(+), 8 deletions(-) diff --git a/doc/Changelog.md b/doc/Changelog.md index 39d2465..cf13298 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -1,4 +1,7 @@ +## 0.9.3 +- () - Properly apply ignore bins to single-value bins + ## 0.9.2 - (#224) - Ensure fields within expressions can be referenced diff --git a/etc/ivpm.info b/etc/ivpm.info index c63f0d9..3044157 100644 --- a/etc/ivpm.info +++ b/etc/ivpm.info @@ -1,4 +1,4 @@ name=pyvsc -version=0.9.1 +version=0.9.3 diff --git a/setup.py b/setup.py index 46d4040..c072a42 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ def get_version(): ], install_requires=[ 'pyboolector>=3.2.2', - 'pyucis>=0.1.3', + 'pyucis>=0.1.4', 'toposort' ], ) diff --git a/src/vsc/coverage.py b/src/vsc/coverage.py index e70409f..679440c 100644 --- a/src/vsc/coverage.py +++ b/src/vsc/coverage.py @@ -358,9 +358,12 @@ def build_cov_model(self, parent, name, exclude_bins : RangelistModel): if exclude_bins is not None and len(exclude_bins.range_l) > 0: # Apply exclusions range_l.intersect(exclude_bins) - - ret = CoverpointBinSingleBagModel(name, range_l) - ret.srcinfo_decl = self.srcinfo_decl + + if len(range_l.range_l) > 0: + ret = CoverpointBinSingleBagModel(name, range_l) + ret.srcinfo_decl = self.srcinfo_decl + else: + ret = None return ret @@ -847,7 +850,8 @@ def build_cov_model(self, parent, name): if not hasattr(bin_spec, "build_cov_model"): raise Exception("Bin specification doesn't have a build_cov_model method") bin_m = bin_spec.build_cov_model(self.model, bin_name, exclude_bins) - self.model.add_bin_model(bin_m) + if bin_m is not None: + self.model.add_bin_model(bin_m) if self.ignore_bins is not None and len(self.ignore_bins) != 0: # Build dedicated ignore_bins @@ -855,14 +859,16 @@ def build_cov_model(self, parent, name): if not hasattr(bin_spec, "build_cov_model"): raise Exception("Bin specification doesn't have a build_cov_model method") bin_m = bin_spec.build_cov_model(self.model, bin_name, None) - self.model.add_ignore_bin_model(bin_m) + if bin_m is not None: + self.model.add_ignore_bin_model(bin_m) if self.illegal_bins is not None and len(self.illegal_bins) != 0: # Build dedicated ignore_bins for bin_name,bin_spec in self.illegal_bins.items(): if not hasattr(bin_spec, "build_cov_model"): raise Exception("Bin specification doesn't have a build_cov_model method") bin_m = bin_spec.build_cov_model(self.model, bin_name, None) - self.model.add_illegal_bin_model(bin_m) + if bin_m is not None: + self.model.add_illegal_bin_model(bin_m) return self.model diff --git a/ve/unit/test_coverage_bin_model.py b/ve/unit/test_coverage_bin_model.py index 689f772..f412934 100644 --- a/ve/unit/test_coverage_bin_model.py +++ b/ve/unit/test_coverage_bin_model.py @@ -109,3 +109,5 @@ def test_partition_mixed_nonconsecutive_values(self): bins.finalize(0) self.assertEqual(4, len(bins.bin_l)) self.assertEqual(4, bins.get_n_bins()) + + diff --git a/ve/unit/test_coverage_igore_bins.py b/ve/unit/test_coverage_igore_bins.py index 40b6668..fb202d8 100644 --- a/ve/unit/test_coverage_igore_bins.py +++ b/ve/unit/test_coverage_igore_bins.py @@ -211,4 +211,147 @@ def __init__(self): self.assertEqual(coverage_model.covergroups[0].coverpoints[0].ignore_bins[0].count, 1) self.assertEqual(coverage_model.covergroups[0].coverpoints[0].illegal_bins[0].count, 1) + def test_record_ignore(self): + import sys + import vsc + from io import StringIO + from ucis.xml.xml_factory import XmlFactory + from ucis.report.text_coverage_report_formatter import TextCoverageReportFormatter + from ucis.report.coverage_report_builder import CoverageReportBuilder + + @vsc.covergroup + class cg_t(object): + def __init__(self): + self.with_sample(dict( + a=vsc.int8_t())) + self.cp = vsc.coverpoint(self.a, + bins=dict(rng=vsc.bin_array([], [0,20])), + ignore_bins=dict(ignore=vsc.bin(0))) + + cg = cg_t() + cg.sample(0) + cg.sample(1) + + out = StringIO() + vsc.write_coverage_db(out) +# vsc.report_coverage(details=True) + db = XmlFactory.read(StringIO(out.getvalue())) + report = CoverageReportBuilder(db).build(db) + # Confirm that the ignore bin was properly saved/restored + self.assertEqual( + len(report.covergroups[0].covergroups[0].coverpoints[0].ignore_bins), 1) + reporter = TextCoverageReportFormatter(report, sys.stdout) + reporter.details = True + reporter.report() + + def test_ignore_single_val_bin(self): + import sys + import vsc + from io import StringIO + from ucis.xml.xml_factory import XmlFactory + from ucis.report.text_coverage_report_formatter import TextCoverageReportFormatter + from ucis.report.coverage_report_builder import CoverageReportBuilder + + @vsc.covergroup + class cg_t(object): + def __init__(self): + self.with_sample(dict( + a=vsc.int8_t())) + self.cp = vsc.coverpoint(self.a, + bins=dict( + ign=vsc.bin(0), + rng=vsc.bin_array([], [1,20])), + ignore_bins=dict(ignore=vsc.bin(0))) + + cg = cg_t() + cg.sample(0) + cg.sample(1) + + out = StringIO() + vsc.write_coverage_db(out) + vsc.report_coverage(details=True) + db = XmlFactory.read(StringIO(out.getvalue())) + report = CoverageReportBuilder(db).build(db) + # Confirm that the ignore bin was properly saved/restored + self.assertEqual( + len(report.covergroups[0].covergroups[0].coverpoints[0].bins), 20) + self.assertEqual( + len(report.covergroups[0].covergroups[0].coverpoints[0].ignore_bins), 1) + reporter = TextCoverageReportFormatter(report, sys.stdout) + reporter.details = True + reporter.report() + + # def test_ignore_full_array_bin(self): + # import sys + # import vsc + # from io import StringIO + # from ucis.xml.xml_factory import XmlFactory + # from ucis.report.text_coverage_report_formatter import TextCoverageReportFormatter + # from ucis.report.coverage_report_builder import CoverageReportBuilder + + # @vsc.covergroup + # class cg_t(object): + # def __init__(self): + # self.with_sample(dict( + # a=vsc.int8_t())) + # self.cp = vsc.coverpoint(self.a, + # bins=dict( + # single=vsc.bin(0), + # rng=vsc.bin_array([], [1,20])), + # ignore_bins=dict(ignore=vsc.bin(1,20))) + + # cg = cg_t() + # cg.sample(0) + # cg.sample(1) + + # out = StringIO() + # vsc.write_coverage_db(out) + # vsc.report_coverage(details=True) + # db = XmlFactory.read(StringIO(out.getvalue())) + # report = CoverageReportBuilder(db).build(db) + # # Confirm that the ignore bin was properly saved/restored + # self.assertEqual( + # len(report.covergroups[0].covergroups[0].coverpoints[0].bins), 1) + # self.assertEqual( + # len(report.covergroups[0].covergroups[0].coverpoints[0].ignore_bins), 1) + # reporter = TextCoverageReportFormatter(report, sys.stdout) + # reporter.details = True + # reporter.report() + + # def test_example(self): + # import vsc + # DATA_WIDTH = 4 + + # @vsc.covergroup + # class my_covergroup(object): + # def __init__(self,a,b,op): + # super().__init__() + # self.options.weight = 1 + # self.operation_cvg = vsc.coverpoint(op, + # bins={"Ops.ADD":vsc.bin(0), "Ops.SUB":vsc.bin(1), "Ops.NOT":vsc.bin(2), "Ops.NOR":vsc.bin(3), "Ops.NAND":vsc.bin(4), "Ops.AND":vsc.bin(5), "Ops.OR":vsc.bin(6), "Ops.XOR":vsc.bin(7)}, + # name="alu_op" + # ) + + # self.operanda_cvg = vsc.coverpoint(a, + # bins = {"illegal/ignore": vsc.bin(0), "low": vsc.bin_array([],[1,int(2**DATA_WIDTH/2)]), "high": vsc.bin_array([],[int(2**DATA_WIDTH/2)+1,2**DATA_WIDTH-1])}, + # options=dict(weight=2), + # ignore_bins=dict(invalid_value=vsc.bin(1,2)), + # name="alu_operand_a") + # self.operandb_cvg = vsc.coverpoint(b, + # bins = {"low": vsc.bin_array([],[0,int(2**DATA_WIDTH/2)]), "high": vsc.bin_array([],[int(2**DATA_WIDTH/2)+1,2**DATA_WIDTH-1])}, + # name="alu_operand_b") + # self.cross_a_b = vsc.cross([self.operanda_cvg,self.operandb_cvg]) + + + # a = 0 + # b = 0 + # op = 0 + # cg = my_covergroup(lambda:a, lambda:b, lambda:op) + # for i in range(1,16): + # a = i + # b = i + # cg.sample() + # vsc.report_coverage(details=True) + # vsc.write_coverage_db("pyvsc_coverage_result.xml") + \ No newline at end of file