2014-11-24 02:06:10 +00:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
// THIS MODULE IS PUBLICLY LICENSED
|
|
|
|
//
|
2021-01-01 15:29:54 +00:00
|
|
|
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
2020-03-21 15:24:24 +00:00
|
|
|
// 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
2014-11-24 02:06:10 +00:00
|
|
|
//
|
|
|
|
//=============================================================================
|
|
|
|
///
|
|
|
|
/// \file
|
|
|
|
/// \brief Coverage analysis support
|
|
|
|
///
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#ifndef _VERILATED_COV_H_
|
|
|
|
#define _VERILATED_COV_H_ 1
|
|
|
|
|
|
|
|
#include "verilatedos.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/// Conditionally compile coverage code
|
|
|
|
|
2020-04-14 02:51:35 +00:00
|
|
|
// clang-format off
|
2014-11-24 02:06:10 +00:00
|
|
|
#ifdef VM_COVERAGE
|
2020-04-04 02:31:54 +00:00
|
|
|
# define VL_IF_COVER(stmts) \
|
2020-04-14 02:51:35 +00:00
|
|
|
do { stmts; } while (false)
|
2014-11-24 02:06:10 +00:00
|
|
|
#else
|
2020-04-04 02:31:54 +00:00
|
|
|
# define VL_IF_COVER(stmts) \
|
|
|
|
do { \
|
|
|
|
if (false) { stmts; } \
|
|
|
|
} while (false)
|
2014-11-24 02:06:10 +00:00
|
|
|
#endif
|
2020-04-14 02:51:35 +00:00
|
|
|
// clang-format on
|
2014-11-24 02:06:10 +00:00
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/// Insert a item for coverage analysis.
|
|
|
|
/// The first argument is a pointer to the count to be dumped.
|
|
|
|
/// The remaining arguments occur in pairs: A string key, and a value.
|
|
|
|
/// The value may be a string, or another type which will be auto-converted to a string.
|
|
|
|
///
|
|
|
|
/// Some typical keys:
|
2019-05-08 03:00:52 +00:00
|
|
|
/// filename File the recording occurs in. Defaults to __FILE__
|
|
|
|
/// lineno Line number the recording occurs in. Defaults to __LINE__
|
|
|
|
/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
|
|
|
|
/// hier Hierarchical name. Defaults to name()
|
|
|
|
/// type Type of coverage. Defaults to "user"
|
|
|
|
/// Other types are 'block', 'fsm', 'toggle'.
|
|
|
|
/// comment Description of the coverage event. Should be set by the user.
|
|
|
|
/// Comments for type==block: 'if', 'else', 'elsif', 'case'
|
|
|
|
/// thresh Threshold to consider fully covered.
|
|
|
|
/// If unspecified, downstream tools will determine it.
|
2014-11-24 02:06:10 +00:00
|
|
|
///
|
|
|
|
/// Examples:
|
|
|
|
///
|
2019-05-08 03:00:52 +00:00
|
|
|
/// vluint32_t m_cases[10];
|
|
|
|
/// constructor {
|
|
|
|
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
|
|
|
/// }
|
|
|
|
/// for (int i=0; i<10; ++i) {
|
|
|
|
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
2014-11-24 02:06:10 +00:00
|
|
|
/// }
|
|
|
|
|
2020-04-14 02:51:35 +00:00
|
|
|
#define VL_COVER_INSERT(countp, ...) \
|
|
|
|
VL_IF_COVER(VerilatedCov::_inserti(countp); VerilatedCov::_insertf(__FILE__, __LINE__); \
|
2020-03-29 14:29:12 +00:00
|
|
|
VerilatedCov::_insertp("hier", name(), __VA_ARGS__))
|
2014-11-24 02:06:10 +00:00
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/// Convert VL_COVER_INSERT value arguments to strings
|
|
|
|
|
2020-04-14 02:51:35 +00:00
|
|
|
template <class T> std::string vlCovCvtToStr(const T& t) VL_PURE {
|
|
|
|
std::ostringstream os;
|
|
|
|
os << t;
|
|
|
|
return os.str();
|
2014-11-24 02:06:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
// VerilatedCov
|
2014-11-24 03:00:00 +00:00
|
|
|
/// Verilator coverage global class
|
2014-11-24 02:06:10 +00:00
|
|
|
////
|
|
|
|
/// Global class with methods affecting all coverage data.
|
2017-10-27 01:51:51 +00:00
|
|
|
/// All public methods in this class are thread safe.
|
2014-11-24 02:06:10 +00:00
|
|
|
|
2020-11-19 02:32:16 +00:00
|
|
|
class VerilatedCov final {
|
2017-11-01 22:51:41 +00:00
|
|
|
VL_UNCOPYABLE(VerilatedCov);
|
2020-04-14 02:51:35 +00:00
|
|
|
|
2014-11-24 02:06:10 +00:00
|
|
|
public:
|
|
|
|
// GLOBAL METHODS
|
|
|
|
/// Return default filename
|
2017-10-27 00:05:42 +00:00
|
|
|
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
|
2014-11-24 02:06:10 +00:00
|
|
|
/// Write all coverage data to a file
|
2018-08-25 13:52:45 +00:00
|
|
|
static void write(const char* filenamep = defaultFilename()) VL_MT_SAFE;
|
2014-11-24 02:06:10 +00:00
|
|
|
/// Insert a coverage item
|
|
|
|
/// We accept from 1-30 key/value pairs, all as strings.
|
|
|
|
/// Call _insert1, followed by _insert2 and _insert3
|
|
|
|
/// Do not call directly; use VL_COVER_INSERT or higher level macros instead
|
|
|
|
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
|
2018-08-25 13:52:45 +00:00
|
|
|
static void _inserti(vluint32_t* itemp) VL_MT_SAFE;
|
|
|
|
static void _inserti(vluint64_t* itemp) VL_MT_SAFE;
|
2014-11-24 02:06:10 +00:00
|
|
|
// _insert2: Set default filename and line number
|
2018-08-25 13:52:45 +00:00
|
|
|
static void _insertf(const char* filename, int lineno) VL_MT_SAFE;
|
2014-11-24 02:06:10 +00:00
|
|
|
// _insert3: Set parameters
|
|
|
|
// We could have just the maximum argument version, but this compiles
|
|
|
|
// much slower (nearly 2x) than having smaller versions also. However
|
|
|
|
// there's not much more gain in having a version for each number of args.
|
2020-04-14 02:51:35 +00:00
|
|
|
#define K(n) const char* key##n
|
|
|
|
#define A(n) const char *key##n, const char *valp##n // Argument list
|
2020-08-15 14:12:55 +00:00
|
|
|
#define D(n) const char *key##n = nullptr, const char *valp##n = nullptr // Argument list
|
2020-04-14 02:51:35 +00:00
|
|
|
static void _insertp(D(0), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9));
|
|
|
|
static void _insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), A(9), A(10), D(11),
|
|
|
|
D(12), D(13), D(14), D(15), D(16), D(17), D(18), D(19));
|
|
|
|
static void _insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), A(9), A(10), A(11),
|
|
|
|
A(12), A(13), A(14), A(15), A(16), A(17), A(18), A(19), A(20), D(21),
|
|
|
|
D(22), D(23), D(24), D(25), D(26), D(27), D(28), D(29));
|
2014-11-24 02:06:10 +00:00
|
|
|
// Backward compatibility for Verilator
|
2020-04-14 02:51:35 +00:00
|
|
|
static void _insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4), const std::string& val4,
|
2020-05-31 19:52:17 +00:00
|
|
|
A(5), A(6), A(7));
|
2014-11-24 02:06:10 +00:00
|
|
|
|
|
|
|
#undef K
|
|
|
|
#undef A
|
|
|
|
#undef D
|
|
|
|
/// Clear coverage points (and call delete on all items)
|
2017-10-27 01:51:51 +00:00
|
|
|
static void clear() VL_MT_SAFE;
|
2014-11-24 02:06:10 +00:00
|
|
|
/// Clear items not matching the provided string
|
2018-08-25 13:52:45 +00:00
|
|
|
static void clearNonMatch(const char* matchp) VL_MT_SAFE;
|
2014-11-24 02:06:10 +00:00
|
|
|
/// Zero coverage points
|
2017-10-27 01:51:51 +00:00
|
|
|
static void zero() VL_MT_SAFE;
|
2014-11-24 02:06:10 +00:00
|
|
|
};
|
|
|
|
|
2018-11-29 00:59:10 +00:00
|
|
|
#endif // Guard
|