Skip to content
96 changes: 93 additions & 3 deletions src/ucis/report/coverage_report_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
from ucis.scope_type_t import ScopeTypeT
from ucis.report.coverage_report import CoverageReport
from ucis.coverpoint import Coverpoint
from ucis.cover_data import CoverData
from ucis.cover_type_t import CoverTypeT
from math import ceil
from ucis.cross import Cross
from ucis.mem.mem_cover_index import MemCoverIndex
from collections import defaultdict


class CoverageReportBuilder(object):
Expand All @@ -32,11 +35,57 @@ def build(db : 'UCIS') ->'CoverageReport':

def _build(self)->'CoverageReport':

self.update_coverage()
for iscope in self.db.scopes(ScopeTypeT.INSTANCE):
self.build_covergroups(iscope)

return self.report

def update_coverage(self):
import copy
for inst in self.db.scopes(ScopeTypeT.INSTANCE):
for cg in inst.scopes(ScopeTypeT.COVERGROUP):
cps = dict()
crs = dict()
merged_cps = defaultdict(lambda: defaultdict(lambda: CoverData(CoverTypeT.CVGBIN, 0)))
merged_crs = defaultdict(lambda: defaultdict(lambda: CoverData(CoverTypeT.CVGBIN, 0)))
not_initialized = True
for ci in cg.scopes(ScopeTypeT.COVERINSTANCE):
if ci.getMergeInstances():
if not_initialized:
for cp in ci.scopes(ScopeTypeT.COVERPOINT):
cp_m = cg.createCoverpoint(
cp.m_name, cp.m_srcinfo, cp.m_weight, cp.m_source)
cps[cp.m_name] = cp_m
for ci_n in cp.coverItems(CoverTypeT.CVGBIN):
cp_m.createNextCover(ci_n.name, copy.copy(ci_n.data), ci_n.srcinfo)
merged_cps[cp.m_name][ci_n.name] = copy.copy(ci_n.getCoverData())
merged_cps[cp.m_name][ci_n.name].data = 0
for cr in ci.scopes(ScopeTypeT.CROSS):
cr_m = cg.createCross(
cr.m_name, cr.m_srcinfo, cr.m_weight, cr.m_source,
copy.copy(cr.coverItems))
crs[cr.m_name] = cr_m
for ci_n in cr.coverItems(CoverTypeT.CVGBIN):
cr_m.createNextCover(ci_n.name, copy.copy(ci_n.data), ci_n.srcinfo)
merged_cps[cr.m_name][ci_n.name] = copy.copy(ci_n.getCoverData())
merged_cps[cr.m_name][ci_n.name].data = 0
not_initialized = False
for cp in ci.scopes(ScopeTypeT.COVERPOINT):
for ci_n in cp.coverItems(CoverTypeT.CVGBIN):
merged_cps[cp.m_name][ci_n.name].data+= ci_n.getCoverData().data
for cr in ci.scopes(ScopeTypeT.CROSS):
for ci_n in cr.coverItems(CoverTypeT.CVGBIN):
merged_crs[cr.m_name][ci_n.name].data+= ci_n.getCoverData().data
for cp in cps.values():
for ci_n in cp.coverItems(CoverTypeT.CVGBIN):
ci_n.data.data = merged_cps[cp.m_name][ci_n.name].data
cp.m_name += " (merged)"
for cr in crs.values():
for ci_n in cr.coverItems(CoverTypeT.CVGBIN):
ci_n.data.data = merged_crs[cr.m_name][ci_n.name].data
cr.m_name += " (merged)"


def build_covergroups(self, iscope):

Expand Down Expand Up @@ -65,11 +114,52 @@ def build_covergroup(self, cg_n)->CoverageReport.Covergroup:
for cr_in in cg_n.scopes(ScopeTypeT.CROSS):
cg_r.crosses.append(self.build_cross(cr_in))

unmerged_ci = list()
for cg_in in cg_n.scopes(ScopeTypeT.COVERINSTANCE):
cg_r.covergroups.append(self.build_covergroup(cg_in))

ci = self.build_coverinstance(cg_in)
if cg_in.getPerInstance():
cg_r.covergroups.append(ci)
if not cg_in.getMergeInstances():
unmerged_ci.append(ci)
# Determine the covergroup coverage
coverage = 0.0
div = 0

for cp in cg_r.coverpoints:
if cp.weight > 0:
coverage += cp.coverage * cp.weight
div += cp.weight

for cr in cg_r.crosses:
if cr.weight > 0:
coverage += cr.coverage * cr.weight
div += cr.weight

for cg in unmerged_ci:
if cg.weight > 0:
coverage += cg.coverage * cg.weight
div += cg.weight

if div > 0: coverage /= div

cg_r.coverage = coverage

return cg_r

def build_coverinstance(self, cg_i)->CoverageReport.Covergroup:
cg_r = CoverageReport.Covergroup(
cg_i.getScopeName(),
cg_i.getScopeName())

cg_r.weight = cg_i.getWeight()

for cp_in in cg_i.scopes(ScopeTypeT.COVERPOINT):
cg_r.coverpoints.append(self.build_coverpoint(cp_in))

for cr_in in cg_i.scopes(ScopeTypeT.CROSS):
cg_r.crosses.append(self.build_cross(cr_in))

coverage = 0.0

div = 0
for cp in cg_r.coverpoints:
Expand Down Expand Up @@ -156,4 +246,4 @@ def build_cross(self, cr_n : Cross):





103 changes: 44 additions & 59 deletions src/ucis/xml/xml_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def read(self, file) -> UCIS:
for histN in tree.iter("historyNodes"):
self.readHistoryNode(histN)

for instN in tree.iter("instanceCoverages"):
self.readInstanceCoverage(instN)
for instX in tree.iter("instanceCoverages"):
self.readInstanceCoverage(instX)

return self.db

Expand Down Expand Up @@ -114,17 +114,14 @@ def readHistoryNode(self, histN):

return ret

def readInstanceCoverage(self, instN):
name = instN.attrib["name"]
stmt_id = None
for stmt_idN in instN.iter("id"):
stmt_id = self.readStatementId(stmt_idN)

def readInstanceCoverage(self, instX):
name = instX.attrib["name"]
stmt_id = self.readStatementId(instX.find('id'))
srcinfo = None

# TODO: Creating a coverage instance depends on
# having a du_type
module_scope_name = self.getAttr(instN, "moduleName", "default")
module_scope_name = self.getAttr(instX, "moduleName", "default")

type_scope = self.getScope(
module_scope_name,
Expand All @@ -137,58 +134,46 @@ def readInstanceCoverage(self, instN):
UCIS_OTHER,
type_scope)

for cg in instN.iter("covergroupCoverage"):
self.readCovergroup(cg, inst_scope, module_scope_name)
for cgX in instX.iter("covergroupCoverage"):
self.readCovergroup(cgX, inst_scope, module_scope_name)

# self.setIntIfEx(instN, ret.setAli, name)

def readCovergroup(self, cg, inst_scope, module_scope_name):
# This entry is for a given covergroup type

cg_typescope = None
covergroup_scope = None

instances = [i for i in cg.iter("cgInstance")]
if len(instances) == 1:
cg_typescope = inst_scope.createCovergroup(
self.getAttr(instances[0], "name", "default"),
None,
1,
UCIS_OTHER)
else:
cg_typescope = inst_scope.createCovergroup(
module_scope_name, None, 1, UCIS_OTHER)
def readCovergroup(self, cgX, inst_scope, module_scope_name):

cg = inst_scope.createCovergroup(
module_scope_name, None, 1, UCIS_OTHER)

for cgN in instances:
for ciX in cgX.iter("cgInstance"):
srcinfo = None
if len(instances) == 1:
covergroup_scope = cg_typescope
else:
covergroup_scope = cg_typescope.createCoverInstance(
self.getAttr(cgN, "name", "default"),
srcinfo,
1,
UCIS_OTHER)
ci = cg.createCoverInstance(
self.getAttr(ciX, "name", "default"),
srcinfo,
1,
UCIS_OTHER)
ciX_options = ciX.find("options")
ci.m_per_instance = self.getAttrBool(ciX_options, 'per_instance')
ci.m_merge_instances = self.getAttrBool(ciX_options, 'merge_instances')

cp_m = {}

for cpN in cgN.iter("coverpoint"):
cp = self.readCoverpoint(cpN, covergroup_scope)
cp_m[self.getAttr(cpN, "name", "default")] = cp
for cpX in ciX.iter("coverpoint"):
cp = self.readCoverpoint(cpX, ci)
cp_m[self.getAttr(cpX, "name", "default")] = cp

for crN in cgN.iter("cross"):
self.readCross(crN, cp_m, covergroup_scope)
for crX in ciX.iter("cross"):
self.readCross(crX, cp_m, ci)

def readCoverpoint(self, cpN, covergroup_scope):
def readCoverpoint(self, cpX, ci):
srcinfo = None

cp = covergroup_scope.createCoverpoint(
self.getAttr(cpN, "name", "default"),
cp = ci.createCoverpoint(
self.getAttr(cpX, "name", "default"),
srcinfo,
1, # weight
UCIS_OTHER)

for cpBin in cpN.iter("coverpointBin"):
for cpBin in cpX.iter("coverpointBin"):
self.readCoverpointBin(cpBin, cp)

return cp
Expand Down Expand Up @@ -226,9 +211,9 @@ def readCoverpointBin(self, cpBin : Element, cp):
self.getAttr(cpBin, "name", "default"),
kind)

def readCross(self, crN, cp_m, covergroup_scope):
crossExpr = next(crN.iter("crossExpr"))
name = self.getAttr(crN, "name", "default")
def readCross(self, crX, cp_m, ci):
crossExpr = next(crX.iter("crossExpr"))
name = self.getAttr(crX, "name", "default")

cp_l = []
for cp_n in crossExpr.text.split(','):
Expand All @@ -240,22 +225,22 @@ def readCross(self, crN, cp_m, covergroup_scope):

srcinfo = None

cr = covergroup_scope.createCross(
cr = ci.createCross(
name,
srcinfo,
1, # weight
UCIS_OTHER,
cp_l)

for crB in crN.iter("crossBin"):
self.readCrossBin(crB, cr)
for crbX in crX.iter("crossBin"):
self.readCrossBin(crbX, cr)

return cr

def readCrossBin(self, crB, cr):
name = self.getAttr(crB, "name", "default")
def readCrossBin(self, crbX, cr):
name = self.getAttr(crbX, "name", "default")
srcinfo = None
contentsN = next(crB.iter("contents"))
contentsN = next(crbX.iter("contents"))

cr.createBin(
name,
Expand All @@ -265,10 +250,10 @@ def readCrossBin(self, crB, cr):
"") # TODO:


def readStatementId(self, stmt_idN):
file_id = int(stmt_idN.attrib["file"])
line = int(stmt_idN.attrib["line"])
item = int(stmt_idN.attrib["inlineCount"])
def readStatementId(self, stmt_idX):
file_id = int(stmt_idX.attrib["file"])
line = int(stmt_idX.attrib["line"])
item = int(stmt_idX.attrib["inlineCount"])
file = self.file_m[file_id]
return StatementId(file, line, item)

Expand Down