// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Coverage points // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2019 by Wilson Snyder. 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCPOINT_H_ #define _VLCPOINT_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "verilated_cov_key.h" #include #include #include VL_INCLUDE_UNORDERED_MAP //******************************************************************** // VlcPoint - A coverage point (across all tests) class VlcPoint { private: // MEMBERS string m_name; //< Name of the point vluint64_t m_pointNum; //< Point number vluint64_t m_testsCovering; //< Number tests with non-zero coverage of this point vluint64_t m_count; //< Count of hits across all tests public: // CONSTRUCTORS VlcPoint(const string& name, int pointNum) { m_name = name; m_pointNum = pointNum; m_testsCovering = 0; m_count = 0; } ~VlcPoint() {} // ACCESSORS const string& name() const { return m_name; } vluint64_t pointNum() const { return m_pointNum; } vluint64_t testsCovering() const { return m_testsCovering; } void countInc(vluint64_t inc) { m_count += inc; } vluint64_t count() const { return m_count; } void testsCoveringInc() { m_testsCovering++; } // KEY ACCESSORS string filename() const { return keyExtract(VL_CIK_FILENAME); } 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 "" int lineno() const { return atoi(keyExtract(VL_CIK_LINENO).c_str()); } int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); } // METHODS string keyExtract(const char* shortKey) const { // Hot function size_t shortLen = strlen(shortKey); const string namestr = name(); for (const char* cp = namestr.c_str(); *cp; ++cp) { if (*cp == '\001') { if (0==strncmp(cp+1, shortKey, shortLen) && cp[shortLen+1] == '\002') { cp += shortLen+2; // Skip \001+short+\002 const char* ep = cp; while (*ep && *ep != '\001') ++ep; return string(cp, ep-cp); } } } return ""; } static void dumpHeader() { cout<<"Points:\n"; cout<<" Num, TestsCover, Count, Name"< NameMap; // Sorted by name (ordered) NameMap m_nameMap; //< Name to point-number std::vector m_points; //< List of all points vluint64_t m_numPoints; //< Total unique points public: // ITERATORS typedef NameMap ByName; typedef ByName::iterator iterator; ByName::iterator begin() { return m_nameMap.begin(); } ByName::iterator end() { return m_nameMap.end(); } public: // CONSTRUCTORS VlcPoints() { m_numPoints = 0; } ~VlcPoints() {} // METHODS void dump() { UINFO(2,"dumpPoints...\n"); VlcPoint::dumpHeader(); for (VlcPoints::ByName::iterator it=begin(); it!=end(); ++it) { const VlcPoint& point = pointNumber(it->second); point.dump(); } } VlcPoint& pointNumber(vluint64_t num) { return m_points[num]; } vluint64_t findAddPoint(const string& name, vluint64_t count) { vluint64_t pointnum; NameMap::iterator iter = m_nameMap.find(name); if (iter != m_nameMap.end()) { pointnum = iter->second; m_points[pointnum].countInc(count); } else { pointnum = m_numPoints++; VlcPoint point (name, pointnum); point.countInc(count); m_points.push_back(point); m_nameMap.insert(make_pair(point.name(), point.pointNum())); } return pointnum; } }; //###################################################################### #endif // guard