From a57826b125da79f2f002892f1e01b5da56aea3a9 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 31 May 2020 15:52:17 -0400 Subject: [PATCH] Line Coverage now tracks all statement lines, not just branch lines. --- Changes | 1 + include/verilated_cov.cpp | 4 +- include/verilated_cov.h | 2 +- include/verilated_cov_key.h | 3 + src/V3AstNodes.cpp | 2 + src/V3AstNodes.h | 13 +- src/V3Coverage.cpp | 293 +++++++++--- src/V3EmitC.cpp | 13 +- src/V3FileLine.h | 9 +- src/VlcPoint.h | 1 + src/VlcTop.cpp | 32 +- test_regress/driver.pl | 6 +- test_regress/t/t_cover_line.out | 241 ++++++---- test_regress/t/t_cover_line.v | 177 +++++--- test_regress/t/t_cover_line.vlt | 3 +- test_regress/t/t_cover_line_trace.out | 615 +++++++++++++++++++++----- 16 files changed, 1070 insertions(+), 345 deletions(-) diff --git a/Changes b/Changes index 389c8a9b0..beeaeed8d 100644 --- a/Changes +++ b/Changes @@ -15,6 +15,7 @@ The contributors that suggested a given feature are shown in []. Thanks! waivers to the warnings emitted during a Verilator run. *** Support verilator_coverage --write-info for lcov HTML reports. + Line Coverage now tracks all statement lines, not just branch lines. **** Support multi channel descriptor I/O (#2190) [Stephen Henry] diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index aca0ad304..ba9dc9b8e 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -475,11 +475,11 @@ void VerilatedCov::_insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8) } // Backward compatibility for Verilator void VerilatedCov::_insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4), - const std::string& val4, A(5), A(6)) VL_MT_SAFE { + const std::string& val4, A(5), A(6), A(7)) VL_MT_SAFE { std::string val2str = vlCovCvtToStr(val2); std::string val3str = vlCovCvtToStr(val3); _insertp(C(0), C(1), key2, val2str.c_str(), key3, val3str.c_str(), key4, val4.c_str(), C(5), - C(6), N(7), N(8), N(9), N(10), N(11), N(12), N(13), N(14), N(15), N(16), N(17), N(18), + C(6), C(7), N(8), N(9), N(10), N(11), N(12), N(13), N(14), N(15), N(16), N(17), N(18), N(19), N(20), N(21), N(22), N(23), N(24), N(25), N(26), N(27), N(28), N(29)); } #undef A diff --git a/include/verilated_cov.h b/include/verilated_cov.h index a7efa51cd..f9d036758 100644 --- a/include/verilated_cov.h +++ b/include/verilated_cov.h @@ -121,7 +121,7 @@ public: D(22), D(23), D(24), D(25), D(26), D(27), D(28), D(29)); // Backward compatibility for Verilator static void _insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4), const std::string& val4, - A(5), A(6)); + A(5), A(6), A(7)); #undef K #undef A diff --git a/include/verilated_cov_key.h b/include/verilated_cov_key.h index a2807eb5d..46c9311dd 100644 --- a/include/verilated_cov_key.h +++ b/include/verilated_cov_key.h @@ -38,6 +38,7 @@ VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ") +VLCOVGEN_ITEM("name=>'linescov', short=>'L', group=>1, default=>'', descr=>'List of comma-separated lines covered'") VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'") VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'") VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ") @@ -80,6 +81,7 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr #define VL_CIK_HIER "h" #define VL_CIK_LIMIT "L" #define VL_CIK_LINENO "l" +#define VL_CIK_LINESCOV "L" #define VL_CIK_PER_INSTANCE "P" #define VL_CIK_ROW0 "r0" #define VL_CIK_ROW0_NAME "R0" @@ -121,6 +123,7 @@ public: if (key == "hier") return VL_CIK_HIER; if (key == "limit") return VL_CIK_LIMIT; if (key == "lineno") return VL_CIK_LINENO; + if (key == "linescov") return VL_CIK_LINESCOV; if (key == "per_instance") return VL_CIK_PER_INSTANCE; if (key == "row0") return VL_CIK_ROW0; if (key == "row0_name") return VL_CIK_ROW0_NAME; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index b1041f601..ba94046f2 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1519,6 +1519,8 @@ void AstBegin::dump(std::ostream& str) const { } void AstCoverDecl::dump(std::ostream& str) const { this->AstNode::dump(str); + if (!page().empty()) str << " page="< "; this->dataDeclNullp()->dump(str); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 84bce7844..f9c9c648a 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3322,12 +3322,17 @@ private: string m_page; string m_text; string m_hier; + string m_linescov; + int m_offset; // Offset column numbers to uniq-ify IFs int m_binNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: - AstCoverDecl(FileLine* fl, const string& page, const string& comment) + AstCoverDecl(FileLine* fl, const string& page, const string& comment, const string& linescov, + int offset) : ASTGEN_SUPER(fl) { m_page = page; m_text = comment; + m_linescov = linescov; + m_offset = offset; m_binNum = 0; m_dataDeclp = NULL; } @@ -3347,7 +3352,9 @@ public: virtual bool maybePointedTo() const { return true; } void binNum(int flag) { m_binNum = flag; } int binNum() const { return m_binNum; } + int offset() const { return m_offset; } const string& comment() const { return m_text; } // text to insert in code + const string& linescov() const { return m_linescov; } const string& page() const { return m_page; } const string& hier() const { return m_hier; } void hier(const string& flag) { m_hier = flag; } @@ -3355,8 +3362,8 @@ public: virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { const AstCoverDecl* asamep = static_cast(samep); - return (fileline() == asamep->fileline() && hier() == asamep->hier() - && comment() == asamep->comment()); + return (fileline() == asamep->fileline() && linescov() == asamep->linescov() + && hier() == asamep->hier() && comment() == asamep->comment()); } virtual bool isPredictOptimizable() const { return false; } void dataDeclp(AstCoverDecl* nodep) { m_dataDeclp = nodep; } diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 9a0306f27..11bfaa140 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -32,6 +32,7 @@ #include "V3Ast.h" #include +#include VL_INCLUDE_UNORDERED_MAP //###################################################################### // Coverage state, as a visitor of each AstNode @@ -39,7 +40,9 @@ class CoverageVisitor : public AstNVisitor { private: // TYPES - typedef std::map VarNameMap; + typedef vl_unordered_map VarNameMap; + typedef std::set LinenoSet; + typedef vl_unordered_map HandleLines; struct ToggleEnt { string m_comment; // Comment for coverage dump @@ -56,18 +59,37 @@ private: } }; + struct CheckState { // State save-restored on each new coverage scope/block + bool m_on; // Should this block get covered? + bool m_inModOff; // In module with no coverage + int m_handle; // Opaque handle for index into line tracking + const AstNode* m_nodep; // Node establishing this state + CheckState() + : m_on(false) + , m_inModOff(false) + , m_handle(0) + , m_nodep(NULL) {} + bool lineCoverageOn(const AstNode* nodep) { + return m_on && !m_inModOff && nodep->fileline()->coverageOn() + && v3Global.opt.coverageLine(); + } + }; + int m_nextHandle; + // NODE STATE // Entire netlist: // AstIf::user1() -> bool. True indicates ifelse processed AstUser1InUse m_inuser1; // STATE - bool m_checkBlock; // Should this block get covered? + CheckState m_state; // State save-restored on each new coverage scope/block AstNodeModule* m_modp; // Current module to add statement to bool m_inToggleOff; // In function/task etc - bool m_inModOff; // In module with no coverage VarNameMap m_varnames; // Uniquification of inserted variable names string m_beginHier; // AstBegin hier name for user coverage points + typedef vl_unordered_map NameMap; + NameMap m_varNames; // Variable names made for uniq + HandleLines m_handleLines; // All line numbers for a given m_stateHandle // METHODS VL_DEBUG_FUNC; // Declare debug() @@ -90,14 +112,8 @@ private: } AstCoverInc* newCoverInc(FileLine* fl, const string& hier, const string& page_prefix, - const string& comment, const string& trace_var_name) { - // For line coverage, we may have multiple if's on one line, so disambiguate if - // everything is otherwise identical - // (Don't set column otherwise as it may result in making bins not match up with - // different types of coverage enabled.) - string key = fl->filename() + "\001" + cvtToStr(fl->lineno()) + "\001" + hier + "\001" - + page_prefix + "\001" + comment; - + const string& comment, const string& linescov, int offset, + const string& trace_var_name) { // We could use the basename of the filename to the page, but seems // better for code from an include file to be listed under the // module using it rather than the include file. @@ -106,9 +122,10 @@ private: // Someday the user might be allowed to specify a different page suffix string page = page_prefix + "/" + m_modp->prettyName(); - AstCoverDecl* declp = new AstCoverDecl(fl, page, comment); + AstCoverDecl* declp = new AstCoverDecl(fl, page, comment, linescov, offset); declp->hier(hier); m_modp->addStmtp(declp); + UINFO(9, "new " << declp << endl); AstCoverInc* incp = new AstCoverInc(fl, declp); if (!trace_var_name.empty() && v3Global.opt.traceCoverage()) { @@ -138,32 +155,120 @@ private: } return name; } + + // Line tracking + void createHandle(const AstNode* nodep) { + // Start tracking lines for the given handling node + // If and if's else have separate handles for same nodep, + // so nodep cannot have a pointer to a unique handle + m_state.m_on = true; + m_state.m_handle = ++m_nextHandle; + // Ensure line numbers we track are in the same file as this block + // so track via nodep + m_state.m_nodep = nodep; + UINFO(9, "line create h" << m_state.m_handle << " " << nodep << endl); + } + void lineTrack(const AstNode* nodep) { + if (m_state.lineCoverageOn(nodep) + && m_state.m_nodep->fileline()->filenameno() == nodep->fileline()->filenameno()) { + for (int lineno = nodep->fileline()->firstLineno(); + lineno <= nodep->fileline()->lastLineno(); ++lineno) { + UINFO(9, "line track " << lineno << " for h" << m_state.m_handle << " " + << m_state.m_nodep << endl); + m_handleLines[m_state.m_handle].insert(lineno); + } + } + } + static string linesFirstLast(const int first, const int last) { + if (first && first == last) { + return cvtToStr(first); + } else if (first && last) { + return cvtToStr(first) + "-" + cvtToStr(last); + } else { + return ""; + } + } + string linesCov(const CheckState& state, const AstNode* nodep) { + // Return comma separated list of ranged numbers + string out; + const LinenoSet& lines = m_handleLines[state.m_handle]; + int first = 0; + int last = 0; + for (LinenoSet::iterator it = lines.begin(); it != lines.end(); ++it) { + if (!first) { + first = last = *it; + } else if (*it == last + 1) { + ++last; + } else { + if (!out.empty()) out += ","; + out += linesFirstLast(first, last); + first = last = *it; + } + } + if (first) { + if (!out.empty()) out += ","; + out += linesFirstLast(first, last); + } + UINFO(9, "lines out " << out << " for h" << state.m_handle << " " << nodep << endl); + return out; + } + // VISITORS - BOTH virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { AstNodeModule* origModp = m_modp; - bool origInModOff = m_inModOff; + CheckState lastState = m_state; { + createHandle(nodep); m_modp = nodep; - m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created - if (!origModp) m_varnames.clear(); + m_state.m_inModOff + = nodep->isTop(); // Ignore coverage on top module; it's a shell we created + if (!origModp) { + // No blocks cross (non-nested) modules, so save some memory + m_varnames.clear(); + m_handleLines.clear(); + } iterateChildren(nodep); } m_modp = origModp; - m_inModOff = origInModOff; + m_state = lastState; } - // VISITORS - TOGGLE COVERAGE + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { iterateProcedure(nodep); } + virtual void visit(AstWhile* nodep) VL_OVERRIDE { iterateProcedure(nodep); } virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE { + if (!nodep->dpiImport()) iterateProcedure(nodep); + } + void iterateProcedure(AstNode* nodep) { + CheckState lastState = m_state; bool oldtog = m_inToggleOff; { m_inToggleOff = true; + createHandle(nodep); iterateChildren(nodep); + if (m_state.lineCoverageOn(nodep)) { + lineTrack(nodep); + AstNode* newp + = newCoverInc(nodep->fileline(), "", "v_line", "block", + linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block")); + if (AstNodeProcedure* itemp = VN_CAST(nodep, NodeProcedure)) { + itemp->addStmtp(newp); + } else if (AstNodeFTask* itemp = VN_CAST(nodep, NodeFTask)) { + itemp->addStmtsp(newp); + } else if (AstWhile* itemp = VN_CAST(nodep, While)) { + itemp->addBodysp(newp); + } else { + nodep->v3fatalSrc("Bad node type"); + } + } } + m_state = lastState; m_inToggleOff = oldtog; } + + // VISITORS - TOGGLE COVERAGE virtual void visit(AstVar* nodep) VL_OVERRIDE { iterateChildren(nodep); - if (m_modp && !m_inModOff && !m_inToggleOff && nodep->fileline()->coverageOn() + if (m_modp && !m_inToggleOff && !m_state.m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) { const char* disablep = varIgnoreToggle(nodep); if (disablep) { @@ -203,7 +308,8 @@ private: void toggleVarBottom(const ToggleEnt& above, const AstVar* varp) { AstCoverToggle* newp = new AstCoverToggle( varp->fileline(), - newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, ""), + newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0, + ""), above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true)); m_modp->addStmtp(newp); } @@ -282,78 +388,133 @@ private: } // VISITORS - LINE COVERAGE - virtual void - visit(AstIf* nodep) VL_OVERRIDE { // Note not AstNodeIf; other types don't get covered + // Note not AstNodeIf; other types don't get covered + virtual void visit(AstIf* nodep) VL_OVERRIDE { UINFO(4, " IF: " << nodep << endl); - if (m_checkBlock) { + if (m_state.m_on) { // An else-if. When we iterate the if, use "elsif" marking - bool elsif = (VN_IS(nodep->elsesp(), If) && !VN_CAST(nodep->elsesp(), If)->nextp()); + bool elsif = nodep->ifsp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp(); if (elsif) VN_CAST(nodep->elsesp(), If)->user1(true); + bool first_elsif = !nodep->user1() && elsif; + bool cont_elsif = nodep->user1() && elsif; + bool final_elsif = nodep->user1() && !elsif && nodep->elsesp(); // - iterateAndNextNull(nodep->ifsp()); - if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() - && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it - UINFO(4, " COVER: " << nodep << endl); - if (nodep->user1()) { + // Considered: If conditional is on a different line from if/else then we + // can show it as part of line coverage of the statement + // above. Otherwise show it based on what is inside. + // But: Seemed too complicated, and fragile. + CheckState lastState = m_state; + CheckState ifState; + CheckState elseState; + { + createHandle(nodep); + iterateAndNextNull(nodep->ifsp()); + lineTrack(nodep); + ifState = m_state; + } + m_state = lastState; + { + createHandle(nodep); + iterateAndNextNull(nodep->elsesp()); + elseState = m_state; + } + m_state = lastState; + // + // If both if and else are "on", and we're not in an if/else, then + // we do branch coverage + if (!(first_elsif || cont_elsif || final_elsif) && ifState.lineCoverageOn(nodep) + && elseState.lineCoverageOn(nodep)) { + // Normal if. Linecov shows what's inside the if (not condition that is + // always executed) + UINFO(4, " COVER-branch: " << nodep << endl); + nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_branch", "if", + linesCov(ifState, nodep), 0, + traceNameForLine(nodep, "if"))); + // The else has a column offset of 1 to uniquify it relative to the if + // As "if" and "else" are more than one character wide, this won't overlap + // another token + nodep->addElsesp(newCoverInc(nodep->fileline(), "", "v_branch", "else", + linesCov(elseState, nodep), 1, + traceNameForLine(nodep, "else"))); + } + // If/else attributes to each block as non-branch coverage + else if (first_elsif || cont_elsif) { + UINFO(4, " COVER-elsif: " << nodep << endl); + if (ifState.lineCoverageOn(nodep)) { nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif", + linesCov(ifState, nodep), 0, traceNameForLine(nodep, "elsif"))); - } else { + } + // and we don't insert the else as the child if-else will do so + } else { + // Cover as separate blocks (not a branch as is not two-legged) + if (ifState.lineCoverageOn(nodep)) { + UINFO(4, " COVER-half-if: " << nodep << endl); nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if", + linesCov(ifState, nodep), 0, traceNameForLine(nodep, "if"))); } - } - // Don't do empty else's, only empty if/case's - if (nodep->elsesp()) { - m_checkBlock = true; - iterateAndNextNull(nodep->elsesp()); - if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() - && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it - UINFO(4, " COVER: " << nodep << endl); - if (!elsif) { // elsif done inside if() - nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", - "else", traceNameForLine(nodep, "else"))); - } + if (elseState.lineCoverageOn(nodep)) { + UINFO(4, " COVER-half-el: " << nodep << endl); + nodep->addElsesp(newCoverInc(nodep->fileline(), "", "v_line", "else", + linesCov(elseState, nodep), 1, + traceNameForLine(nodep, "else"))); } } - m_checkBlock = true; // Reset as a child may have cleared it + m_state = lastState; } + UINFO(9, " done HANDLE " << m_state.m_handle << " for " << nodep << endl); } virtual void visit(AstCaseItem* nodep) VL_OVERRIDE { + // We don't add an explicit "default" coverage if not provided, + // as we already have a warning when there is no default. UINFO(4, " CASEI: " << nodep << endl); - if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() - && v3Global.opt.coverageLine()) { - iterateAndNextNull(nodep->bodysp()); - if (m_checkBlock) { // if the case body didn't disable it - UINFO(4, " COVER: " << nodep << endl); - nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case", - traceNameForLine(nodep, "case"))); + if (m_state.lineCoverageOn(nodep)) { + CheckState lastState = m_state; + { + createHandle(nodep); + iterateAndNextNull(nodep->bodysp()); + if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it + lineTrack(nodep); + UINFO(4, " COVER: " << nodep << endl); + nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case", + linesCov(m_state, nodep), 0, + traceNameForLine(nodep, "case"))); + } } - m_checkBlock = true; // Reset as a child may have cleared it + m_state = lastState; } } virtual void visit(AstCover* nodep) VL_OVERRIDE { UINFO(4, " COVER: " << nodep << endl); - m_checkBlock = true; // Always do cover blocks, even if there's a $stop - iterateChildren(nodep); - if (!nodep->coverincp()) { - // Note the name may be overridden by V3Assert processing - nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", - m_beginHier + "_vlCoverageUserTrace")); + CheckState lastState = m_state; + { + m_state.m_on = true; // Always do cover blocks, even if there's a $stop + createHandle(nodep); + iterateChildren(nodep); + if (!nodep->coverincp() && v3Global.opt.coverageUser()) { + // Note the name may be overridden by V3Assert processing + lineTrack(nodep); + nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", + linesCov(m_state, nodep), 0, + m_beginHier + "_vlCoverageUserTrace")); + } } - m_checkBlock = true; // Reset as a child may have cleared it + m_state = lastState; } virtual void visit(AstStop* nodep) VL_OVERRIDE { UINFO(4, " STOP: " << nodep << endl); - m_checkBlock = false; + m_state.m_on = false; } virtual void visit(AstPragma* nodep) VL_OVERRIDE { if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) { // Skip all NEXT nodes under this block, and skip this if/case branch - UINFO(4, " OFF: " << nodep << endl); - m_checkBlock = false; + UINFO(4, " OFF: h" << m_state.m_handle << " " << nodep << endl); + m_state.m_on = false; VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { - if (m_checkBlock) iterateChildren(nodep); + if (m_state.m_on) iterateChildren(nodep); + lineTrack(nodep); } } virtual void visit(AstBegin* nodep) VL_OVERRIDE { @@ -370,6 +531,7 @@ private: m_beginHier = m_beginHier + (m_beginHier != "" ? "." : "") + nodep->name(); } iterateChildren(nodep); + lineTrack(nodep); } m_beginHier = oldHier; m_inToggleOff = oldtog; @@ -377,21 +539,18 @@ private: // VISITORS - BOTH virtual void visit(AstNode* nodep) VL_OVERRIDE { - if (m_checkBlock) { - iterateChildren(nodep); - m_checkBlock = true; // Reset as a child may have cleared it - } + iterateChildren(nodep); + lineTrack(nodep); } public: // CONSTRUCTORS explicit CoverageVisitor(AstNetlist* rootp) { // Operate on all modules - m_checkBlock = true; + m_nextHandle = 0; m_modp = NULL; m_beginHier = ""; m_inToggleOff = false; - m_inModOff = true; iterateChildren(rootp); } virtual ~CoverageVisitor() {} diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index fff5d2798..19f8939a3 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -398,7 +398,7 @@ public: puts(", "); puts(cvtToStr(nodep->fileline()->lineno())); puts(", "); - puts(cvtToStr(nodep->fileline()->firstColumn())); + puts(cvtToStr(nodep->offset() + nodep->fileline()->firstColumn())); puts(", "); putsQuoted((!nodep->hier().empty() ? "." : "") + protectWordsIf(nodep->hier(), nodep->protect())); @@ -406,6 +406,8 @@ public: putsQuoted(protectWordsIf(nodep->page(), nodep->protect())); puts(", "); putsQuoted(protectWordsIf(nodep->comment(), nodep->protect())); + puts(", "); + putsQuoted(nodep->linescov()); puts(");\n"); } virtual void visit(AstCoverInc* nodep) VL_OVERRIDE { @@ -2249,7 +2251,8 @@ void EmitCImp::emitCoverageDecl(AstNodeModule* modp) { puts("void __vlCoverInsert("); puts(v3Global.opt.threads() ? "std::atomic" : "uint32_t"); puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n"); - puts("const char* hierp, const char* pagep, const char* commentp);\n"); + puts("const char* hierp, const char* pagep, const char* commentp, const char* " + "linescovp);\n"); } } @@ -2372,7 +2375,8 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) { puts("void " + prefixNameProtect(m_modp) + "::__vlCoverInsert("); puts(v3Global.opt.threads() ? "std::atomic" : "uint32_t"); puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n"); - puts("const char* hierp, const char* pagep, const char* commentp) {\n"); + puts("const char* hierp, const char* pagep, const char* commentp, const char* linescovp) " + "{\n"); if (v3Global.opt.threads()) { puts("assert(sizeof(uint32_t) == sizeof(std::atomic));\n"); puts("uint32_t* count32p = reinterpret_cast(countp);\n"); @@ -2392,7 +2396,8 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) { // puts( "\"hier\",std::string(__VlSymsp->name())+hierp,"); puts("\"hier\",std::string(name())+hierp,"); puts(" \"page\",pagep,"); - puts(" \"comment\",commentp);\n"); + puts(" \"comment\",commentp,"); + puts(" (linescovp[0] ? \"linescov\" : \"\"), linescovp);\n"); puts("}\n"); splitSizeInc(10); } diff --git a/src/V3FileLine.h b/src/V3FileLine.h index 6603ae0df..2a5e2e1ad 100644 --- a/src/V3FileLine.h +++ b/src/V3FileLine.h @@ -164,7 +164,7 @@ public: m_lastLineno = num; m_firstColumn = m_lastColumn = 1; } - void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } + void language(V3LangCode lang) { singleton().numberToLang(filenameno(), lang); } void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } void parent(FileLine* fileline) { m_parent = fileline; } void lineDirective(const char* textp, int& enterExitRef); @@ -190,14 +190,15 @@ public: string source() const; string prettySource() const; // Source, w/stripped unprintables and newlines FileLine* parent() const { return m_parent; } - V3LangCode language() const { return singleton().numberToLang(m_filenameno); } + V3LangCode language() const { return singleton().numberToLang(filenameno()); } string ascii() const; string asciiLineCol() const; - const string filename() const { return singleton().numberToName(m_filenameno); } + int filenameno() const { return m_filenameno; } + const string filename() const { return singleton().numberToName(filenameno()); } bool filenameIsGlobal() const { return (filename() == commandLineFilename() || filename() == builtInFilename()); } - const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); } + const string filenameLetters() const { return singleton().filenameLetters(filenameno()); } const string filebasename() const; const string filebasenameNoExt() const; const string firstColumnLetters() const; diff --git a/src/VlcPoint.h b/src/VlcPoint.h index 90c42e7fc..0cd57317e 100644 --- a/src/VlcPoint.h +++ b/src/VlcPoint.h @@ -58,6 +58,7 @@ public: string comment() const { return keyExtract(VL_CIK_COMMENT); } string type() const { return keyExtract(VL_CIK_TYPE); } string thresh() const { return keyExtract(VL_CIK_THRESH); } // string as maybe "" + string linescov() const { return keyExtract(VL_CIK_LINESCOV); } int lineno() const { return atoi(keyExtract(VL_CIK_LINENO).c_str()); } int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); } // METHODS diff --git a/src/VlcTop.cpp b/src/VlcTop.cpp index ad02fc61d..67f74570c 100644 --- a/src/VlcTop.cpp +++ b/src/VlcTop.cpp @@ -203,14 +203,38 @@ void VlcTop::annotateCalc() { string filename = point.filename(); int lineno = point.lineno(); if (!filename.empty() && lineno != 0) { - int column = point.column(); VlcSource& source = sources().findNewSource(filename); string threshStr = point.thresh(); unsigned thresh = (!threshStr.empty()) ? atoi(threshStr.c_str()) : opt.annotateMin(); bool ok = (point.count() >= thresh); - UINFO(9, - "AnnoCalc count " << filename << " " << lineno << " " << point.count() << endl); - source.incCount(lineno, column, point.count(), ok); + UINFO(9, "AnnoCalc count " << filename << ":" << lineno << ":" << point.column() << " " + << point.count() << " " << point.linescov() << endl); + // Base coverage + source.incCount(lineno, point.column(), point.count(), ok); + // Additional lines covered by this statement + bool range = false; + int start = 0; + int end = 0; + string linescov = point.linescov(); + for (const char* covp = linescov.c_str(); true; ++covp) { + if (!*covp || *covp == ',') { // Ending + for (int lni = start; start && lni <= end; ++lni) { + source.incCount(lni, point.column(), point.count(), ok); + } + if (!*covp) { break; } + start = 0; // Prep for next + end = 0; + range = false; + } else if (*covp == '-') { + range = true; + } else if (isdigit(*covp)) { + const char* digitsp = covp; + while (isdigit(*covp)) ++covp; + --covp; // Will inc in for loop + if (!range) start = atoi(digitsp); + end = atoi(digitsp); + } + } } } } diff --git a/test_regress/driver.pl b/test_regress/driver.pl index 53ea86716..149310b84 100755 --- a/test_regress/driver.pl +++ b/test_regress/driver.pl @@ -1331,10 +1331,10 @@ sub inline_checks { while (defined(my $line = $fh->getline)) { if ($line =~ /CHECK/) { if ($line =~ /CHECK_COVER *\( *([---0-9]+) *, *"([^"]+)" *, *("([^"]+)" *,|) *(\d+) *\)/) { - my $lineno=($. + $1); my $hier=$2; my $comment=$4; my $count=$5; + my $lineno = ($. + $1); my $hier=$2; my $comment=$4; my $count=$5; my $regexp = "\001l\002".$lineno; $regexp .= ".*\001o\002".quotemeta($comment) if $comment; - $regexp .= ".*\001h\002".quotemeta($hier); + $regexp .= ".*\001h\002".quotemeta($hier) if $hier; $regexp .= ".*' ".$count; if ($contents !~ /$regexp/) { $self->error("CHECK_COVER: $covfn: Regexp not found: $regexp\n". @@ -1342,7 +1342,7 @@ sub inline_checks { } } elsif ($line =~ /CHECK_COVER_MISSING *\( *([---0-9]+) *\)/) { - my $lineno=($. + $1); + my $lineno = ($. + $1); my $regexp = "\001l\002".$lineno; if ($contents =~ /$regexp/) { $self->error("CHECK_COVER_MISSING: $covfn: Regexp found: $regexp\n". diff --git a/test_regress/t/t_cover_line.out b/test_regress/t/t_cover_line.out index 567dd70ca..579327102 100644 --- a/test_regress/t/t_cover_line.out +++ b/test_regress/t/t_cover_line.out @@ -12,60 +12,136 @@ input clk; - reg toggle; initial toggle=0; + reg toggle; +%000002 initial toggle=0; + + integer cyc; +%000002 initial cyc=1; - integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); alpha a2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); tsk t1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); off o1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); - always @ (posedge clk) begin - 000010 if (cyc!=0) begin - cyc <= cyc + 1; - toggle <= '0; -%000001 if (cyc==3) begin - toggle <= '1; - end -%000001 else if (cyc==5) begin + 000020 always @ (posedge clk) begin + 000020 if (cyc!=0) begin +%000000 verilator_coverage: (next point on previous line) + + 000010 cyc <= cyc + 1; + 000010 toggle <= '0; + // Single and multiline if +%000002 if (cyc==3) $write(""); +%000009 verilator_coverage: (next point on previous line) + +%000002 if (cyc==3) +%000009 verilator_coverage: (next point on previous line) + +%000001 begin +%000001 $write(""); + end + // Single and multiline else +%000002 if (cyc==3) ; else $write(""); +%000018 verilator_coverage: (next point on previous line) + +%000002 if (cyc==3) ; +%000009 verilator_coverage: (next point on previous line) + + else +%000009 begin +%000009 $write(""); + end + // Single and multiline if else +%000002 if (cyc==3) $write(""); else $write(""); +%000018 verilator_coverage: (next point on previous line) + +%000002 if (cyc==3) +%000009 verilator_coverage: (next point on previous line) + +%000001 begin +%000001 $write(""); + end + else +%000009 begin +%000009 $write(""); + end + // multiline elseif +%000002 if (cyc==3) +%000001 begin +%000001 $write(""); + end +%000002 else if (cyc==4) +%000001 begin +%000001 $write(""); + end +%000002 else if (cyc==5) +%000007 verilator_coverage: (next point on previous line) + +%000001 begin +%000001 $write(""); + end + else +%000007 begin +%000007 $write(""); + end + // Single and multiline while +%000000 while (0); +%000000 while (0) begin +%000000 $write(""); + end +%000000 do ; while (0); + 000010 do begin +%000000 verilator_coverage: (next point on previous line) + + 000010 $write(""); +%000000 verilator_coverage: (next point on previous line) + +%000000 end while (0); + //=== + // Task and complicated +%000002 if (cyc==3) begin +%000001 toggle <= '1; + end +%000002 else if (cyc==5) begin `ifdef VERILATOR - $c("call_task();"); +%000001 $c("call_task();"); `else - call_task(); + call_task(); `endif - end -%000001 else if (cyc==10) begin - $write("*-* All Finished *-*\n"); - $finish; - end + end +%000002 else if (cyc==10) begin +%000007 verilator_coverage: (next point on previous line) + +%000001 $write("*-* All Finished *-*\n"); +%000001 $finish; + end end end - task call_task; +%000002 task call_task; /* verilator public */ - t1.center_task(1'b1); +%000001 t1.center_task(1'b1); endtask endmodule @@ -76,18 +152,19 @@ ); input clk; input toggle; - always @ (posedge clk) begin -%000002 if (toggle) begin - // CHECK_COVER(-1,"top.t.a*",2) - // t.a1 and t.a2 collapse to a count of 2 + 000040 always @ (posedge clk) begin +%000004 if (toggle) begin // CHECK_COVER(0,"top.t.a*",2) + 000018 verilator_coverage: (next point on previous line) + +%000002 $write(""); + // t.a1 and t.a2 collapse to a count of 2 end - if (toggle) begin - // CHECK_COVER_MISSING(-1) - // This doesn't even get added + 000018 if (toggle) begin + $write(""); // CHECK_COVER_MISSING(0) + // This doesn't even get added `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); end end endmodule @@ -101,22 +178,28 @@ /* verilator public_module */ - always @ (posedge clk) begin -%000000 if (0) begin - // CHECK_COVER(-1,"top.t.b*",0) - // Make sure that we don't optimize away zero buckets + 000040 always @ (posedge clk) begin + 000020 $write(""); // Always covered +%000000 if (0) begin // CHECK_COVER(0,"top.t.b*",0) + 000020 verilator_coverage: (next point on previous line) + + // Make sure that we don't optimize away zero buckets +%000000 $write(""); end -%000002 if (toggle) begin - // CHECK_COVER(-1,"top.t.b*",2) - // t.b1 and t.b2 collapse to a count of 2 +%000004 if (toggle) begin // CHECK_COVER(0,"top.t.b*",2) + 000018 verilator_coverage: (next point on previous line) + + // t.b1 and t.b2 collapse to a count of 2 +%000002 $write(""); end - if (toggle) begin : block - // CHECK_COVER_MISSING(-1) - // This doesn't + 000018 if (toggle) begin : block + // This doesn't `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); + begin end // Needed for .vlt to attach coverage_block_off + if (1) begin end // CHECK_COVER_MISSING(0) + $write(""); // CHECK_COVER_MISSING(0) end end endmodule @@ -130,20 +213,23 @@ /* verilator public_module */ - always @ (posedge clk) begin - center_task(1'b0); + 000020 always @ (posedge clk) begin + 000010 center_task(1'b0); end - task center_task; + 000022 task center_task; input external; - begin -%000001 if (toggle) begin - // CHECK_COVER(-1,"top.t.t1",1) - end -%000001 if (external) begin - // CHECK_COVER(-1,"top.t.t1",1) - $write("[%0t] Got external pulse\n", $time); - end + 000011 begin +%000002 if (toggle) begin // CHECK_COVER(0,"top.t.t1",1) + 000010 verilator_coverage: (next point on previous line) + +%000001 $write(""); + end +%000002 if (external) begin // CHECK_COVER(0,"top.t.t1",1) + 000010 verilator_coverage: (next point on previous line) + +%000001 $write("[%0t] Got external pulse\n", $time); + end end endtask @@ -159,15 +245,20 @@ // verilator coverage_off always @ (posedge clk) begin if (toggle) begin - // CHECK_COVER_MISSING(-1) - // because under coverage_module_off + $write(""); // CHECK_COVER_MISSING(0) + // because under coverage_module_off end end // verilator coverage_on - always @ (posedge clk) begin -%000001 if (toggle) begin - // CHECK_COVER(-1,"top.t.o1",1) - // because under coverage_module_off + 000020 always @ (posedge clk) begin +%000002 if (toggle) begin +%000009 verilator_coverage: (next point on previous line) + + // because under coverage_module_off +%000001 $write(""); +%000000 if (0) ; // CHECK_COVER(0,"top.t.o1",1) +%000001 verilator_coverage: (next point on previous line) + end end diff --git a/test_regress/t/t_cover_line.v b/test_regress/t/t_cover_line.v index 887c02c14..580e31061 100644 --- a/test_regress/t/t_cover_line.v +++ b/test_regress/t/t_cover_line.v @@ -11,54 +11,108 @@ module t (/*AUTOARG*/ input clk; - reg toggle; initial toggle=0; + reg toggle; + initial toggle=0; + + integer cyc; + initial cyc=1; - integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); alpha a2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); tsk t1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); off o1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); always @ (posedge clk) begin if (cyc!=0) begin - cyc <= cyc + 1; - toggle <= '0; - if (cyc==3) begin - toggle <= '1; - end - else if (cyc==5) begin + cyc <= cyc + 1; + toggle <= '0; + // Single and multiline if + if (cyc==3) $write(""); + if (cyc==3) + begin + $write(""); + end + // Single and multiline else + if (cyc==3) ; else $write(""); + if (cyc==3) ; + else + begin + $write(""); + end + // Single and multiline if else + if (cyc==3) $write(""); else $write(""); + if (cyc==3) + begin + $write(""); + end + else + begin + $write(""); + end + // multiline elseif + if (cyc==3) + begin + $write(""); + end + else if (cyc==4) + begin + $write(""); + end + else if (cyc==5) + begin + $write(""); + end + else + begin + $write(""); + end + // Single and multiline while + while (0); + while (0) begin + $write(""); + end + do ; while (0); + do begin + $write(""); + end while (0); + //=== + // Task and complicated + if (cyc==3) begin + toggle <= '1; + end + else if (cyc==5) begin `ifdef VERILATOR - $c("call_task();"); + $c("call_task();"); `else - call_task(); + call_task(); `endif - end - else if (cyc==10) begin - $write("*-* All Finished *-*\n"); - $finish; - end + end + else if (cyc==10) begin + $write("*-* All Finished *-*\n"); + $finish; + end end end @@ -76,17 +130,16 @@ module alpha (/*AUTOARG*/ input clk; input toggle; always @ (posedge clk) begin - if (toggle) begin - // CHECK_COVER(-1,"top.t.a*",2) - // t.a1 and t.a2 collapse to a count of 2 + if (toggle) begin // CHECK_COVER(0,"top.t.a*",2) + $write(""); + // t.a1 and t.a2 collapse to a count of 2 end if (toggle) begin - // CHECK_COVER_MISSING(-1) - // This doesn't even get added + $write(""); // CHECK_COVER_MISSING(0) + // This doesn't even get added `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); end end endmodule @@ -101,21 +154,23 @@ module beta (/*AUTOARG*/ /* verilator public_module */ always @ (posedge clk) begin - if (0) begin - // CHECK_COVER(-1,"top.t.b*",0) - // Make sure that we don't optimize away zero buckets + $write(""); // Always covered + if (0) begin // CHECK_COVER(0,"top.t.b*",0) + // Make sure that we don't optimize away zero buckets + $write(""); end - if (toggle) begin - // CHECK_COVER(-1,"top.t.b*",2) - // t.b1 and t.b2 collapse to a count of 2 + if (toggle) begin // CHECK_COVER(0,"top.t.b*",2) + // t.b1 and t.b2 collapse to a count of 2 + $write(""); end if (toggle) begin : block - // CHECK_COVER_MISSING(-1) - // This doesn't + // This doesn't `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); + begin end // Needed for .vlt to attach coverage_block_off + if (1) begin end // CHECK_COVER_MISSING(0) + $write(""); // CHECK_COVER_MISSING(0) end end endmodule @@ -136,13 +191,12 @@ module tsk (/*AUTOARG*/ task center_task; input external; begin - if (toggle) begin - // CHECK_COVER(-1,"top.t.t1",1) - end - if (external) begin - // CHECK_COVER(-1,"top.t.t1",1) - $write("[%0t] Got external pulse\n", $time); - end + if (toggle) begin // CHECK_COVER(0,"top.t.t1",1) + $write(""); + end + if (external) begin // CHECK_COVER(0,"top.t.t1",1) + $write("[%0t] Got external pulse\n", $time); + end end endtask @@ -158,15 +212,16 @@ module off (/*AUTOARG*/ // verilator coverage_off always @ (posedge clk) begin if (toggle) begin - // CHECK_COVER_MISSING(-1) - // because under coverage_module_off + $write(""); // CHECK_COVER_MISSING(0) + // because under coverage_module_off end end // verilator coverage_on always @ (posedge clk) begin if (toggle) begin - // CHECK_COVER(-1,"top.t.o1",1) - // because under coverage_module_off + // because under coverage_module_off + $write(""); + if (0) ; // CHECK_COVER(0,"top.t.o1",1) end end diff --git a/test_regress/t/t_cover_line.vlt b/test_regress/t/t_cover_line.vlt index 898f27d9c..a7303b6b5 100644 --- a/test_regress/t/t_cover_line.vlt +++ b/test_regress/t/t_cover_line.vlt @@ -6,5 +6,6 @@ `verilator_config -coverage_block_off -file "t/t_cover_line.v" -lines 83 +coverage_block_off -file "t/t_cover_line.v" -lines 137 +coverage_block_off -file "t/t_cover_line.v" -lines 171 coverage_block_off -module "beta" -block "block" diff --git a/test_regress/t/t_cover_line_trace.out b/test_regress/t/t_cover_line_trace.out index d328b8b1b..56c0bd1d1 100644 --- a/test_regress/t/t_cover_line_trace.out +++ b/test_regress/t/t_cover_line_trace.out @@ -1,51 +1,99 @@ $version Generated by VerilatedVcd $end -$date Thu Mar 19 18:37:02 2020 +$date Sun May 31 15:48:42 2020 $end $timescale 1ps $end $scope module top $end - $var wire 1 5! clk $end + $var wire 1 W clk $end $scope module t $end - $var wire 1 5! clk $end - $var wire 32 + cyc [31:0] $end - $var wire 8 3 cyc_copy [7:0] $end - $var wire 1 # toggle $end - $var wire 32 S vlCoverageLineTrace_t_cover_line__45_if [31:0] $end - $var wire 32 ; vlCoverageLineTrace_t_cover_line__48_if [31:0] $end - $var wire 32 C vlCoverageLineTrace_t_cover_line__51_elsif [31:0] $end - $var wire 32 K vlCoverageLineTrace_t_cover_line__58_elsif [31:0] $end + $var wire 1 W clk $end + $var wire 32 & cyc [31:0] $end + $var wire 8 ' cyc_copy [7:0] $end + $var wire 1 % toggle $end + $var wire 32 ; vlCoverageLineTrace_t_cover_line__102_elsif [31:0] $end + $var wire 32 : vlCoverageLineTrace_t_cover_line__105_elsif [31:0] $end + $var wire 32 9 vlCoverageLineTrace_t_cover_line__112_else [31:0] $end + $var wire 32 8 vlCoverageLineTrace_t_cover_line__112_if [31:0] $end + $var wire 32 X vlCoverageLineTrace_t_cover_line__119_block [31:0] $end + $var wire 32 # vlCoverageLineTrace_t_cover_line__15_block [31:0] $end + $var wire 32 $ vlCoverageLineTrace_t_cover_line__18_block [31:0] $end + $var wire 32 > vlCoverageLineTrace_t_cover_line__47_block [31:0] $end + $var wire 32 = vlCoverageLineTrace_t_cover_line__48_else [31:0] $end + $var wire 32 < vlCoverageLineTrace_t_cover_line__48_if [31:0] $end + $var wire 32 ) vlCoverageLineTrace_t_cover_line__52_else [31:0] $end + $var wire 32 ( vlCoverageLineTrace_t_cover_line__52_if [31:0] $end + $var wire 32 + vlCoverageLineTrace_t_cover_line__53_else [31:0] $end + $var wire 32 * vlCoverageLineTrace_t_cover_line__53_if [31:0] $end + $var wire 32 - vlCoverageLineTrace_t_cover_line__58_else [31:0] $end + $var wire 32 , vlCoverageLineTrace_t_cover_line__58_if [31:0] $end + $var wire 32 / vlCoverageLineTrace_t_cover_line__59_else [31:0] $end + $var wire 32 . vlCoverageLineTrace_t_cover_line__59_if [31:0] $end + $var wire 32 1 vlCoverageLineTrace_t_cover_line__65_else [31:0] $end + $var wire 32 0 vlCoverageLineTrace_t_cover_line__65_if [31:0] $end + $var wire 32 3 vlCoverageLineTrace_t_cover_line__66_else [31:0] $end + $var wire 32 2 vlCoverageLineTrace_t_cover_line__66_if [31:0] $end + $var wire 32 7 vlCoverageLineTrace_t_cover_line__75_elsif [31:0] $end + $var wire 32 6 vlCoverageLineTrace_t_cover_line__79_elsif [31:0] $end + $var wire 32 5 vlCoverageLineTrace_t_cover_line__83_else [31:0] $end + $var wire 32 4 vlCoverageLineTrace_t_cover_line__83_if [31:0] $end + $var wire 32 ] vlCoverageLineTrace_t_cover_line__92_block [31:0] $end + $var wire 32 ^ vlCoverageLineTrace_t_cover_line__93_block [31:0] $end + $var wire 32 _ vlCoverageLineTrace_t_cover_line__96_block [31:0] $end + $var wire 32 ` vlCoverageLineTrace_t_cover_line__97_block [31:0] $end $scope module a1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 [ vlCoverageLineTrace_t_cover_line__79_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 B vlCoverageLineTrace_t_cover_line__132_block [31:0] $end + $var wire 32 @ vlCoverageLineTrace_t_cover_line__133_else [31:0] $end + $var wire 32 ? vlCoverageLineTrace_t_cover_line__133_if [31:0] $end + $var wire 32 A vlCoverageLineTrace_t_cover_line__137_else [31:0] $end $upscope $end $scope module a2 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 c vlCoverageLineTrace_t_cover_line__79_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 F vlCoverageLineTrace_t_cover_line__132_block [31:0] $end + $var wire 32 D vlCoverageLineTrace_t_cover_line__133_else [31:0] $end + $var wire 32 C vlCoverageLineTrace_t_cover_line__133_if [31:0] $end + $var wire 32 E vlCoverageLineTrace_t_cover_line__137_else [31:0] $end $upscope $end $scope module b1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 =! vlCoverageLineTrace_t_cover_line__104_if [31:0] $end - $var wire 32 s vlCoverageLineTrace_t_cover_line__108_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 O vlCoverageLineTrace_t_cover_line__156_block [31:0] $end + $var wire 32 K vlCoverageLineTrace_t_cover_line__158_else [31:0] $end + $var wire 32 b vlCoverageLineTrace_t_cover_line__158_if [31:0] $end + $var wire 32 M vlCoverageLineTrace_t_cover_line__162_else [31:0] $end + $var wire 32 L vlCoverageLineTrace_t_cover_line__162_if [31:0] $end + $var wire 32 N vlCoverageLineTrace_t_cover_line__166_else [31:0] $end $upscope $end $scope module b2 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 E! vlCoverageLineTrace_t_cover_line__104_if [31:0] $end - $var wire 32 { vlCoverageLineTrace_t_cover_line__108_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 T vlCoverageLineTrace_t_cover_line__156_block [31:0] $end + $var wire 32 P vlCoverageLineTrace_t_cover_line__158_else [31:0] $end + $var wire 32 c vlCoverageLineTrace_t_cover_line__158_if [31:0] $end + $var wire 32 R vlCoverageLineTrace_t_cover_line__162_else [31:0] $end + $var wire 32 Q vlCoverageLineTrace_t_cover_line__162_if [31:0] $end + $var wire 32 S vlCoverageLineTrace_t_cover_line__166_else [31:0] $end $upscope $end $scope module o1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 k vlCoverageLineTrace_t_cover_line__167_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 J vlCoverageLineTrace_t_cover_line__220_block [31:0] $end + $var wire 32 I vlCoverageLineTrace_t_cover_line__221_else [31:0] $end + $var wire 32 H vlCoverageLineTrace_t_cover_line__221_if [31:0] $end + $var wire 32 G vlCoverageLineTrace_t_cover_line__224_else [31:0] $end + $var wire 32 a vlCoverageLineTrace_t_cover_line__224_if [31:0] $end $upscope $end $scope module t1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 %! vlCoverageLineTrace_t_cover_line__139_if [31:0] $end - $var wire 32 -! vlCoverageLineTrace_t_cover_line__142_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 U vlCoverageLineTrace_t_cover_line__187_block [31:0] $end + $var wire 32 \ vlCoverageLineTrace_t_cover_line__191_block [31:0] $end + $var wire 32 Z vlCoverageLineTrace_t_cover_line__194_else [31:0] $end + $var wire 32 Y vlCoverageLineTrace_t_cover_line__194_if [31:0] $end + $var wire 32 V vlCoverageLineTrace_t_cover_line__197_else [31:0] $end + $var wire 32 [ vlCoverageLineTrace_t_cover_line__197_if [31:0] $end $upscope $end $upscope $end $upscope $end @@ -53,100 +101,427 @@ $enddefinitions $end #0 -0# -b00000000000000000000000000000001 + -b00000001 3 +b00000000000000000000000000000001 # +b00000000000000000000000000000001 $ +0% +b00000000000000000000000000000001 & +b00000001 ' +b00000000000000000000000000000000 ( +b00000000000000000000000000000000 ) +b00000000000000000000000000000000 * +b00000000000000000000000000000000 + +b00000000000000000000000000000000 , +b00000000000000000000000000000000 - +b00000000000000000000000000000000 . +b00000000000000000000000000000000 / +b00000000000000000000000000000000 0 +b00000000000000000000000000000000 1 +b00000000000000000000000000000000 2 +b00000000000000000000000000000000 3 +b00000000000000000000000000000000 4 +b00000000000000000000000000000000 5 +b00000000000000000000000000000000 6 +b00000000000000000000000000000000 7 +b00000000000000000000000000000000 8 +b00000000000000000000000000000000 9 +b00000000000000000000000000000000 : b00000000000000000000000000000000 ; +b00000000000000000000000000000000 < +b00000000000000000000000000000000 = +b00000000000000000000000000000000 > +b00000000000000000000000000000000 ? +b00000000000000000000000000000000 @ +b00000000000000000000000000000000 A +b00000000000000000000000000000000 B b00000000000000000000000000000000 C +b00000000000000000000000000000000 D +b00000000000000000000000000000000 E +b00000000000000000000000000000000 F +b00000000000000000000000000000000 G +b00000000000000000000000000000000 H +b00000000000000000000000000000000 I +b00000000000000000000000000000000 J b00000000000000000000000000000000 K +b00000000000000000000000000000000 L +b00000000000000000000000000000000 M +b00000000000000000000000000000000 N +b00000000000000000000000000000000 O +b00000000000000000000000000000000 P +b00000000000000000000000000000000 Q +b00000000000000000000000000000000 R b00000000000000000000000000000000 S +b00000000000000000000000000000000 T +b00000000000000000000000000000000 U +b00000000000000000000000000000000 V +0W +b00000000000000000000000000000000 X +b00000000000000000000000000000000 Y +b00000000000000000000000000000000 Z b00000000000000000000000000000000 [ +b00000000000000000000000000000000 \ +b00000000000000000000000000000000 ] +b00000000000000000000000000000000 ^ +b00000000000000000000000000000000 _ +b00000000000000000000000000000000 ` +b00000000000000000000000000000000 a +b00000000000000000000000000000000 b b00000000000000000000000000000000 c -b00000000000000000000000000000000 k -b00000000000000000000000000000000 s -b00000000000000000000000000000000 { -b00000000000000000000000000000000 %! -b00000000000000000000000000000000 -! -05! -b00000000000000000000000000000000 =! -b00000000000000000000000000000000 E! #10 -b00000000000000000000000000000010 + -b00000010 3 -b00000000000000000000000000000001 S -15! -#15 -05! -#20 -b00000000000000000000000000000011 + -b00000011 3 -b00000000000000000000000000000010 S -15! -#25 -05! -#30 -1# -b00000000000000000000000000000100 + -b00000100 3 -b00000000000000000000000000000001 ; -b00000000000000000000000000000011 S -15! -#35 -05! -#40 -0# -b00000000000000000000000000000101 + -b00000101 3 -b00000000000000000000000000000100 S -b00000000000000000000000000000001 [ -b00000000000000000000000000000001 c -b00000000000000000000000000000001 k -b00000000000000000000000000000001 s -b00000000000000000000000000000001 { -b00000000000000000000000000000001 %! -15! -#45 -05! -#50 -b00000000000000000000000000000110 + -b00000110 3 -b00000000000000000000000000000001 C -b00000000000000000000000000000101 S -b00000000000000000000000000000001 -! -15! -#55 -05! -#60 -b00000000000000000000000000000111 + -b00000111 3 -b00000000000000000000000000000110 S -15! -#65 -05! -#70 -b00000000000000000000000000001000 + -b00001000 3 -b00000000000000000000000000000111 S -15! -#75 -05! -#80 -b00000000000000000000000000001001 + -b00001001 3 -b00000000000000000000000000001000 S -15! -#85 -05! -#90 -b00000000000000000000000000001010 + -b00001010 3 -b00000000000000000000000000001001 S -15! -#95 -05! -#100 -b00000000000000000000000000001011 + -b00001011 3 +b00000000000000000000000000000010 & +b00000010 ' +b00000000000000000000000000000001 ) +b00000000000000000000000000000001 + +b00000000000000000000000000000001 - +b00000000000000000000000000000001 / +b00000000000000000000000000000001 1 +b00000000000000000000000000000001 3 +b00000000000000000000000000000001 5 +b00000000000000000000000000000001 9 +b00000000000000000000000000000001 < +b00000000000000000000000000000001 > +b00000000000000000000000000000001 @ +b00000000000000000000000000000001 A +b00000000000000000000000000000001 B +b00000000000000000000000000000001 D +b00000000000000000000000000000001 E +b00000000000000000000000000000001 F +b00000000000000000000000000000001 I +b00000000000000000000000000000001 J b00000000000000000000000000000001 K -b00000000000000000000000000001010 S -15! +b00000000000000000000000000000001 M +b00000000000000000000000000000001 N +b00000000000000000000000000000001 O +b00000000000000000000000000000001 P +b00000000000000000000000000000001 R +b00000000000000000000000000000001 S +b00000000000000000000000000000001 T +b00000000000000000000000000000001 U +b00000000000000000000000000000001 V +1W +b00000000000000000000000000000001 Z +b00000000000000000000000000000001 \ +#15 +0W +#20 +b00000000000000000000000000000011 & +b00000011 ' +b00000000000000000000000000000010 ) +b00000000000000000000000000000010 + +b00000000000000000000000000000010 - +b00000000000000000000000000000010 / +b00000000000000000000000000000010 1 +b00000000000000000000000000000010 3 +b00000000000000000000000000000010 5 +b00000000000000000000000000000010 9 +b00000000000000000000000000000010 < +b00000000000000000000000000000010 > +b00000000000000000000000000000010 @ +b00000000000000000000000000000010 A +b00000000000000000000000000000010 B +b00000000000000000000000000000010 D +b00000000000000000000000000000010 E +b00000000000000000000000000000010 F +b00000000000000000000000000000010 I +b00000000000000000000000000000010 J +b00000000000000000000000000000010 K +b00000000000000000000000000000010 M +b00000000000000000000000000000010 N +b00000000000000000000000000000010 O +b00000000000000000000000000000010 P +b00000000000000000000000000000010 R +b00000000000000000000000000000010 S +b00000000000000000000000000000010 T +b00000000000000000000000000000010 U +b00000000000000000000000000000010 V +1W +b00000000000000000000000000000010 Z +b00000000000000000000000000000010 \ +#25 +0W +#30 +1% +b00000000000000000000000000000100 & +b00000100 ' +b00000000000000000000000000000001 ( +b00000000000000000000000000000001 * +b00000000000000000000000000000001 , +b00000000000000000000000000000001 . +b00000000000000000000000000000001 0 +b00000000000000000000000000000001 2 +b00000000000000000000000000000001 7 +b00000000000000000000000000000001 ; +b00000000000000000000000000000011 < +b00000000000000000000000000000011 > +b00000000000000000000000000000011 @ +b00000000000000000000000000000011 A +b00000000000000000000000000000011 B +b00000000000000000000000000000011 D +b00000000000000000000000000000011 E +b00000000000000000000000000000011 F +b00000000000000000000000000000011 I +b00000000000000000000000000000011 J +b00000000000000000000000000000011 K +b00000000000000000000000000000011 M +b00000000000000000000000000000011 N +b00000000000000000000000000000011 O +b00000000000000000000000000000011 P +b00000000000000000000000000000011 R +b00000000000000000000000000000011 S +b00000000000000000000000000000011 T +b00000000000000000000000000000011 U +b00000000000000000000000000000011 V +1W +b00000000000000000000000000000011 Z +b00000000000000000000000000000011 \ +#35 +0W +#40 +0% +b00000000000000000000000000000101 & +b00000101 ' +b00000000000000000000000000000011 ) +b00000000000000000000000000000011 + +b00000000000000000000000000000011 - +b00000000000000000000000000000011 / +b00000000000000000000000000000011 1 +b00000000000000000000000000000011 3 +b00000000000000000000000000000001 6 +b00000000000000000000000000000011 9 +b00000000000000000000000000000100 < +b00000000000000000000000000000100 > +b00000000000000000000000000000001 ? +b00000000000000000000000000000100 B +b00000000000000000000000000000001 C +b00000000000000000000000000000100 F +b00000000000000000000000000000001 G +b00000000000000000000000000000001 H +b00000000000000000000000000000100 J +b00000000000000000000000000000100 K +b00000000000000000000000000000001 L +b00000000000000000000000000000100 O +b00000000000000000000000000000100 P +b00000000000000000000000000000001 Q +b00000000000000000000000000000100 T +b00000000000000000000000000000100 U +b00000000000000000000000000000100 V +1W +b00000000000000000000000000000001 Y +b00000000000000000000000000000100 \ +#45 +0W +#50 +b00000000000000000000000000000110 & +b00000110 ' +b00000000000000000000000000000100 ) +b00000000000000000000000000000100 + +b00000000000000000000000000000100 - +b00000000000000000000000000000100 / +b00000000000000000000000000000100 1 +b00000000000000000000000000000100 3 +b00000000000000000000000000000001 4 +b00000000000000000000000000000001 : +b00000000000000000000000000000101 < +b00000000000000000000000000000101 > +b00000000000000000000000000000100 @ +b00000000000000000000000000000100 A +b00000000000000000000000000000101 B +b00000000000000000000000000000100 D +b00000000000000000000000000000100 E +b00000000000000000000000000000101 F +b00000000000000000000000000000100 I +b00000000000000000000000000000101 J +b00000000000000000000000000000101 K +b00000000000000000000000000000100 M +b00000000000000000000000000000100 N +b00000000000000000000000000000101 O +b00000000000000000000000000000101 P +b00000000000000000000000000000100 R +b00000000000000000000000000000100 S +b00000000000000000000000000000101 T +b00000000000000000000000000000101 U +b00000000000000000000000000000101 V +1W +b00000000000000000000000000000001 X +b00000000000000000000000000000101 Z +b00000000000000000000000000000001 [ +b00000000000000000000000000000110 \ +#55 +0W +#60 +b00000000000000000000000000000111 & +b00000111 ' +b00000000000000000000000000000101 ) +b00000000000000000000000000000101 + +b00000000000000000000000000000101 - +b00000000000000000000000000000101 / +b00000000000000000000000000000101 1 +b00000000000000000000000000000101 3 +b00000000000000000000000000000011 5 +b00000000000000000000000000000100 9 +b00000000000000000000000000000110 < +b00000000000000000000000000000110 > +b00000000000000000000000000000101 @ +b00000000000000000000000000000101 A +b00000000000000000000000000000110 B +b00000000000000000000000000000101 D +b00000000000000000000000000000101 E +b00000000000000000000000000000110 F +b00000000000000000000000000000101 I +b00000000000000000000000000000110 J +b00000000000000000000000000000110 K +b00000000000000000000000000000101 M +b00000000000000000000000000000101 N +b00000000000000000000000000000110 O +b00000000000000000000000000000110 P +b00000000000000000000000000000101 R +b00000000000000000000000000000101 S +b00000000000000000000000000000110 T +b00000000000000000000000000000110 U +b00000000000000000000000000000110 V +1W +b00000000000000000000000000000110 Z +b00000000000000000000000000000111 \ +#65 +0W +#70 +b00000000000000000000000000001000 & +b00001000 ' +b00000000000000000000000000000110 ) +b00000000000000000000000000000110 + +b00000000000000000000000000000110 - +b00000000000000000000000000000110 / +b00000000000000000000000000000110 1 +b00000000000000000000000000000110 3 +b00000000000000000000000000000100 5 +b00000000000000000000000000000101 9 +b00000000000000000000000000000111 < +b00000000000000000000000000000111 > +b00000000000000000000000000000110 @ +b00000000000000000000000000000110 A +b00000000000000000000000000000111 B +b00000000000000000000000000000110 D +b00000000000000000000000000000110 E +b00000000000000000000000000000111 F +b00000000000000000000000000000110 I +b00000000000000000000000000000111 J +b00000000000000000000000000000111 K +b00000000000000000000000000000110 M +b00000000000000000000000000000110 N +b00000000000000000000000000000111 O +b00000000000000000000000000000111 P +b00000000000000000000000000000110 R +b00000000000000000000000000000110 S +b00000000000000000000000000000111 T +b00000000000000000000000000000111 U +b00000000000000000000000000000111 V +1W +b00000000000000000000000000000111 Z +b00000000000000000000000000001000 \ +#75 +0W +#80 +b00000000000000000000000000001001 & +b00001001 ' +b00000000000000000000000000000111 ) +b00000000000000000000000000000111 + +b00000000000000000000000000000111 - +b00000000000000000000000000000111 / +b00000000000000000000000000000111 1 +b00000000000000000000000000000111 3 +b00000000000000000000000000000101 5 +b00000000000000000000000000000110 9 +b00000000000000000000000000001000 < +b00000000000000000000000000001000 > +b00000000000000000000000000000111 @ +b00000000000000000000000000000111 A +b00000000000000000000000000001000 B +b00000000000000000000000000000111 D +b00000000000000000000000000000111 E +b00000000000000000000000000001000 F +b00000000000000000000000000000111 I +b00000000000000000000000000001000 J +b00000000000000000000000000001000 K +b00000000000000000000000000000111 M +b00000000000000000000000000000111 N +b00000000000000000000000000001000 O +b00000000000000000000000000001000 P +b00000000000000000000000000000111 R +b00000000000000000000000000000111 S +b00000000000000000000000000001000 T +b00000000000000000000000000001000 U +b00000000000000000000000000001000 V +1W +b00000000000000000000000000001000 Z +b00000000000000000000000000001001 \ +#85 +0W +#90 +b00000000000000000000000000001010 & +b00001010 ' +b00000000000000000000000000001000 ) +b00000000000000000000000000001000 + +b00000000000000000000000000001000 - +b00000000000000000000000000001000 / +b00000000000000000000000000001000 1 +b00000000000000000000000000001000 3 +b00000000000000000000000000000110 5 +b00000000000000000000000000000111 9 +b00000000000000000000000000001001 < +b00000000000000000000000000001001 > +b00000000000000000000000000001000 @ +b00000000000000000000000000001000 A +b00000000000000000000000000001001 B +b00000000000000000000000000001000 D +b00000000000000000000000000001000 E +b00000000000000000000000000001001 F +b00000000000000000000000000001000 I +b00000000000000000000000000001001 J +b00000000000000000000000000001001 K +b00000000000000000000000000001000 M +b00000000000000000000000000001000 N +b00000000000000000000000000001001 O +b00000000000000000000000000001001 P +b00000000000000000000000000001000 R +b00000000000000000000000000001000 S +b00000000000000000000000000001001 T +b00000000000000000000000000001001 U +b00000000000000000000000000001001 V +1W +b00000000000000000000000000001001 Z +b00000000000000000000000000001010 \ +#95 +0W +#100 +b00000000000000000000000000001011 & +b00001011 ' +b00000000000000000000000000001001 ) +b00000000000000000000000000001001 + +b00000000000000000000000000001001 - +b00000000000000000000000000001001 / +b00000000000000000000000000001001 1 +b00000000000000000000000000001001 3 +b00000000000000000000000000000111 5 +b00000000000000000000000000000001 8 +b00000000000000000000000000001010 < +b00000000000000000000000000001010 > +b00000000000000000000000000001001 @ +b00000000000000000000000000001001 A +b00000000000000000000000000001010 B +b00000000000000000000000000001001 D +b00000000000000000000000000001001 E +b00000000000000000000000000001010 F +b00000000000000000000000000001001 I +b00000000000000000000000000001010 J +b00000000000000000000000000001010 K +b00000000000000000000000000001001 M +b00000000000000000000000000001001 N +b00000000000000000000000000001010 O +b00000000000000000000000000001010 P +b00000000000000000000000000001001 R +b00000000000000000000000000001001 S +b00000000000000000000000000001010 T +b00000000000000000000000000001010 U +b00000000000000000000000000001010 V +1W +b00000000000000000000000000001010 Z +b00000000000000000000000000001011 \