From ecfe0283e290ddab2ca11047f4b7acc009ade64b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 29 Oct 2013 20:15:01 -0400 Subject: [PATCH] Fix crash with coverage of structures, bug691. --- Changes | 2 ++ src/V3Coverage.cpp | 46 ++++++++++++++++++++++++++++++++- test_regress/t/t_cover_toggle.v | 17 +++++++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index cecf20c8b..2bceb7247 100644 --- a/Changes +++ b/Changes @@ -21,6 +21,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix vpi_remove_cb inside callback, bug689. [Varun Koyyalagunta] +**** Fix crash with coverage of structures, bug691. [Eivind Liland] + * Verilator 3.853 2013-09-30 diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 8e63fc25f..b5af0e1c8 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -213,7 +213,7 @@ private: } } else if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) { - for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb()+1; ++index_docs) { + for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) { int index_code = index_docs - adtypep->lsb(); ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", new AstArraySel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code), @@ -224,6 +224,50 @@ private: newent.cleanup(); } } + else if (AstPackArrayDType* adtypep = dtypep->castPackArrayDType()) { + for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) { + AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp(); + int index_code = index_docs - adtypep->lsb(); + ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", + new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), + index_code*subtypep->width(), subtypep->width()), + new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true), + index_code*subtypep->width(), subtypep->width())); + toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1, + newent, + varp, chgVarp); + newent.cleanup(); + } + } + else if (AstStructDType* adtypep = dtypep->castStructDType()) { + // For now it's packed, so similar to array + for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { + AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); + int index_code = itemp->lsb(); + ToggleEnt newent (above.m_comment+string(".")+itemp->name(), + new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), + index_code, subtypep->width()), + new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true), + index_code, subtypep->width())); + toggleVarRecurse(subtypep, depth+1, + newent, + varp, chgVarp); + newent.cleanup(); + } + } + else if (AstUnionDType* adtypep = dtypep->castUnionDType()) { + // Arbitrarially handle only the first member of the union + if (AstMemberDType* itemp = adtypep->membersp()) { + AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); + ToggleEnt newent (above.m_comment+string(".")+itemp->name(), + above.m_varRefp->cloneTree(true), + above.m_chgRefp->cloneTree(true)); + toggleVarRecurse(subtypep, depth+1, + newent, + varp, chgVarp); + newent.cleanup(); + } + } else { dtypep->v3fatalSrc("Unexpected node data type in toggle coverage generation: "<prettyTypeName()); } diff --git a/test_regress/t/t_cover_toggle.v b/test_regress/t/t_cover_toggle.v index 21d8ed66e..fab11247a 100644 --- a/test_regress/t/t_cover_toggle.v +++ b/test_regress/t/t_cover_toggle.v @@ -10,7 +10,19 @@ module t (/*AUTOARG*/ input clk; - reg toggle; initial toggle=0; + typedef struct packed { + union packed { + logic ua; + logic ub; + } u; + logic b; + } str_t; + + reg toggle; initial toggle='0; + + str_t stoggle; initial stoggle='0; + + reg [1:0][1:0] ptoggle; initial ptoggle=0; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; @@ -51,6 +63,9 @@ module t (/*AUTOARG*/ cyc <= cyc + 1; memory[cyc + 'd100] <= memory[cyc + 'd100] + 2'b1; toggle <= '0; + stoggle.u <= toggle; + stoggle.b <= toggle; + ptoggle[0][0] <= toggle; if (cyc==3) begin toggle <= '1; end