Skip to content

Commit f83ae67

Browse files
mballanceCopilot
andcommitted
Fix XML writer: write userAttr on correct per-element scopes
Previously write_user_attrs() was called on coverage container elements (toggleCoverage, blockCoverage, branchCoverage, conditionCoverage, fsmCoverage, assertionCoverage) with the parent INSTANCE scope, which: 1. Duplicated INSTANCE attrs into every coverage container 2. Lost all per-element attrs (TOGGLE/BLOCK/BRANCH/COND/etc. scopes) Deep audit of merged_ncdb.cdb showed 201,883 user attributes in the NCDB model but only 422 in the generated XML — a 99.8% loss. Fix: remove container-level write_user_attrs(container, INSTANCE_scope) calls and instead call write_user_attrs on each individual coverage element using its own scope: - toggleObject ← TOGGLE scope attrs (174,516) - statement in blockCoverage ← BLOCK scope attrs (21,441) - statement in branchCoverage ← BRANCH scope attrs (3,219) - expr in conditionCoverage ← COND scope attrs (2,415) - coverpoint ← COVERPOINT scope attrs (59) - fsm ← FSM scope attrs (16) - assertion ← ASSERT scope attrs (27) - cgInstance ← COVERINSTANCE scope attrs (22) - covergroupCoverage ← COVERGROUP scope attrs (11) After fix: 201,819 userAttr in XML (64 from FSM_STATES/FSM_TRANS container scopes are intentionally unwritten — they have no corresponding element in the UCIS XML schema). XML still validates against ucis.xsd with zero errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 46304c0 commit f83ae67

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

src/ucis/xml/xml_writer.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def write_toggle_coverage(self, inst_elem, scope):
250250
bin_elem = self.mkElem(toggle_elem, "bin")
251251
contents_elem = self.mkElem(bin_elem, "contents")
252252
contents_elem.set("coverageCount", str(bin_item.getCoverData().data))
253-
self.write_user_attrs(tc_elem, scope)
253+
self.write_user_attrs(to_elem, toggle_scope)
254254

255255
def write_block_coverage(self, inst_elem, scope):
256256
block_scopes = list(scope.scopes(ScopeTypeT.BLOCK))
@@ -266,7 +266,7 @@ def write_block_coverage(self, inst_elem, scope):
266266
bin_elem = self.mkElem(stmt_elem, "bin")
267267
contents_elem = self.mkElem(bin_elem, "contents")
268268
contents_elem.set("coverageCount", str(stmt.getCoverData().data))
269-
self.write_user_attrs(bc_elem, scope)
269+
self.write_user_attrs(stmt_elem, block_scope)
270270

271271
def write_branch_coverage(self, inst_elem, scope):
272272
branch_scopes = list(scope.scopes(ScopeTypeT.BRANCH))
@@ -286,7 +286,7 @@ def write_branch_coverage(self, inst_elem, scope):
286286
bb_elem.set("alias", arm.getName()) # use alias to preserve name
287287
contents_elem = self.mkElem(bb_elem, "contents")
288288
contents_elem.set("coverageCount", str(arm.getCoverData().data))
289-
self.write_user_attrs(bc_elem, scope)
289+
self.write_user_attrs(stmt_elem, branch_scope)
290290

291291
def write_fsm_coverage(self, inst_elem, scope):
292292
fsm_scopes = list(scope.scopes(ScopeTypeT.FSM))
@@ -323,7 +323,7 @@ def write_fsm_coverage(self, inst_elem, scope):
323323
tb_elem = self.mkElem(trans_elem, "transitionBin")
324324
contents = self.mkElem(tb_elem, "contents")
325325
contents.set("coverageCount", str(bin_item.getCoverData().data))
326-
self.write_user_attrs(fc_elem, scope)
326+
self.write_user_attrs(fsm_elem, fsm_scope)
327327

328328
def write_assertion_coverage(self, inst_elem, scope):
329329
assert_scopes = (list(scope.scopes(ScopeTypeT.ASSERT))
@@ -360,7 +360,7 @@ def write_assertion_coverage(self, inst_elem, scope):
360360
contents = self.mkElem(bin_elem, "contents")
361361
contents.set("coverageCount",
362362
str(sum(b.getCoverData().data for b in bins)))
363-
self.write_user_attrs(ac_elem, scope)
363+
self.write_user_attrs(asrt_elem, assert_scope)
364364

365365
def write_condition_coverage(self, inst_elem, scope):
366366
cond_scopes = list(scope.scopes(ScopeTypeT.COND))
@@ -398,7 +398,7 @@ def write_condition_coverage(self, inst_elem, scope):
398398
bin_elem.set("alias", bin_item.getName())
399399
contents_elem = self.mkElem(bin_elem, "contents")
400400
contents_elem.set("coverageCount", str(bin_item.getCoverData().data))
401-
self.write_user_attrs(cc_elem, scope)
401+
self.write_user_attrs(expr_elem, cond_scope)
402402

403403
def write_covergroups(self, inst, scope):
404404
for cg in scope.scopes(ScopeTypeT.COVERGROUP):
@@ -417,6 +417,7 @@ def write_covergroups(self, inst, scope):
417417
while cg_inst is not None:
418418
self.write_coverinstance(cgElem, cg.getScopeName(), cg_inst)
419419
cg_inst = next(inst_it, None)
420+
self.write_user_attrs(cgElem, cg)
420421

421422
def write_coverinstance(self, cgElem, cgName, cg : Covergroup):
422423
cgInstElem = self.mkElem(cgElem, "cgInstance")
@@ -446,6 +447,7 @@ def write_coverinstance(self, cgElem, cgName, cg : Covergroup):
446447

447448
for cr in cg.scopes(ScopeTypeT.CROSS):
448449
self.write_cross(cgInstElem, cr)
450+
self.write_user_attrs(cgInstElem, cg)
449451

450452
def write_coverpoint(self, cgInstElem, cp : Coverpoint):
451453
cpElem = self.mkElem(cgInstElem, "coverpoint")
@@ -466,6 +468,7 @@ def write_coverpoint(self, cgInstElem, cp : Coverpoint):
466468
for cs in cp.scopes(_BINSCOPE_MASK):
467469
bins.extend(cs.coverItems(_BIN_MASK))
468470
self.write_coverpoint_bins(cpElem, iter(bins))
471+
self.write_user_attrs(cpElem, cp)
469472

470473
def write_coverpoint_bins(self, cpElem, coveritems : Iterator[CoverIndex]):
471474
# TODO: should probably organize bins into a structure that fits more nicely into the interchage format

0 commit comments

Comments
 (0)