diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 8f324ac60..3a41ed65f 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -303,3 +303,4 @@ em2machine emmettifelts Àlex Torregrosa Ícaro Lima +Yogish Sekhar diff --git a/src/VlcMain.cpp b/src/VlcMain.cpp index e5113a966..2226db37e 100644 --- a/src/VlcMain.cpp +++ b/src/VlcMain.cpp @@ -140,6 +140,10 @@ int main(int argc, char** argv) { top.points().dump(); } + if (!top.opt.rank() && top.opt.writeFile().empty() && top.opt.writeInfoFile().empty()) { + top.printTypeSummary(); + } + V3Error::abortIfWarnings(); if (!top.opt.annotateOut().empty()) top.annotate(top.opt.annotateOut()); diff --git a/src/VlcTop.cpp b/src/VlcTop.cpp index aad1f7f0d..708aa68ca 100644 --- a/src/VlcTop.cpp +++ b/src/VlcTop.cpp @@ -269,8 +269,10 @@ void VlcTop::annotateCalcNeeded() { } } const float pct = totCases ? (100 * totOk / totCases) : 0; - std::cout << "Total coverage (" << totOk << "/" << totCases << ") "; - std::cout << std::fixed << std::setw(3) << std::setprecision(2) << pct << "%\n"; + std::cout << "Annotation Summary:\n"; + std::cout << " lines with all attached points covered : "; + std::cout << std::fixed << std::setw(5) << std::setprecision(2) << pct << "% (" << totOk + << "/" << totCases << ")\n"; if (totOk != totCases) cout << "See lines with '%00' in " << opt.annotateOut() << '\n'; } @@ -337,3 +339,45 @@ void VlcTop::annotate(const string& dirname) { annotateCalcNeeded(); annotateOutputFiles(dirname); } + +void VlcTop::printTypeSummary() { + static const std::vector orderedTypes = {"line", "toggle", "branch", "expr"}; + std::map> tally; + for (const auto& i : m_points) { + const VlcPoint& pt = m_points.pointNumber(i.second); + const string type = pt.type().empty() ? "point" : pt.type(); + auto& entry = tally[type]; + if (pt.count() > 0) ++entry.first; + ++entry.second; + } + if (tally.empty()) return; + std::set printed; + size_t typeWidth = 0; + size_t countWidth = 0; + for (const auto& it : tally) { + typeWidth = std::max(typeWidth, it.first.size()); + countWidth = std::max(countWidth, cvtToStr(it.second.first).size()); + countWidth = std::max(countWidth, cvtToStr(it.second.second).size()); + } + std::cout << "Coverage Summary:\n"; + for (const string& type : orderedTypes) { + const auto it = tally.find(type); + if (it == tally.end()) continue; + printed.insert(type); + const uint64_t hit = it->second.first; + const uint64_t total = it->second.second; + const double pct = total ? (100.0 * static_cast(hit) / static_cast(total)) : 0.0; + std::cout << " " << std::left << std::setw(typeWidth) << type << " : " << std::right + << std::fixed << std::setprecision(1) << pct << "% (" << std::setw(countWidth) + << hit << "/" << std::setw(countWidth) << total << ")\n"; + } + for (const auto& it : tally) { + if (printed.count(it.first)) continue; + const uint64_t hit = it.second.first; + const uint64_t total = it.second.second; + const double pct = total ? (100.0 * static_cast(hit) / static_cast(total)) : 0.0; + std::cout << " " << std::left << std::setw(typeWidth) << it.first << " : " << std::right + << std::fixed << std::setprecision(1) << pct << "% (" << std::setw(countWidth) + << hit << "/" << std::setw(countWidth) << total << ")\n"; + } +} diff --git a/src/VlcTop.h b/src/VlcTop.h index 13e0d93d6..a4dd731ee 100644 --- a/src/VlcTop.h +++ b/src/VlcTop.h @@ -55,6 +55,7 @@ public: // METHODS void annotate(const string& dirname); + void printTypeSummary(); void readCoverage(const string& filename, bool nonfatal = false); void writeCoverage(const string& filename); void writeInfo(const string& filename); diff --git a/test_regress/t/t_vlcov_summary_typed.out b/test_regress/t/t_vlcov_summary_typed.out new file mode 100644 index 000000000..a059cd732 --- /dev/null +++ b/test_regress/t/t_vlcov_summary_typed.out @@ -0,0 +1,5 @@ +Coverage Summary: + line : 88.6% ( 39/ 44) + toggle : 33.3% ( 35/105) + branch : 78.1% ( 50/ 64) + expr : 66.7% ( 8/ 12) diff --git a/test_regress/t/t_vlcov_summary_typed.py b/test_regress/t/t_vlcov_summary_typed.py new file mode 100644 index 000000000..41579145f --- /dev/null +++ b/test_regress/t/t_vlcov_summary_typed.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('dist') + +test.run(cmd=[ + os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage", + "t/t_vlcov_data_e.dat", +], + logfile=test.obj_dir + "/vlcov.log", + tee=False, + verilator_run=True) + +test.files_identical(test.obj_dir + "/vlcov.log", test.golden_filename) + +test.passes()