File: verilated_cov.h

package info (click to toggle)
verilator 5.038-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 162,552 kB
  • sloc: cpp: 139,204; python: 20,931; ansic: 10,222; yacc: 6,000; lex: 1,925; makefile: 1,260; sh: 494; perl: 282; fortran: 22
file content (185 lines) | stat: -rw-r--r-- 7,675 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// Code available from: https://verilator.org
//
// Copyright 2001-2025 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.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//=============================================================================
///
/// \file
/// \brief Verilated coverage analysis support header
///
/// This must be included in user wrapper code that wants to save coverage
/// data.
///
/// It declares the VerilatedCovContext::write() which writes the collected
/// coverage information.
///
//=============================================================================

#ifndef VERILATOR_VERILATED_COV_H_
#define VERILATOR_VERILATED_COV_H_

#include "verilatedos.h"

#include "verilated.h"

#include <iostream>
#include <sstream>
#include <string>

class VerilatedCovImp;

//=============================================================================
/// Insert an 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:
///
///     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.
///     per_instance    If non-zero don't combine all hierarchies into one count
///
/// Example:
///
///     uint32_t m_cases[10];  // Storage for coverage data
///     constructor() {
///         // Initialize
///         for (int i = 0; i < 10; ++i) m_cases[i] = 0;
///         // Insert
///         for (int i = 0; i < 10; ++i)
///             VL_COVER_INSERT(covp, name(), &m_cases[i], "comment", "Coverage Case",
///                             "i", cvtToNumStr(i));
///     }

#define VL_COVER_INSERT(covcontextp, name, countp, ...) \
    do { \
        auto const ccontextp = covcontextp; \
        ccontextp->_inserti(countp); \
        ccontextp->_insertf(__FILE__, __LINE__); \
        ccontextp->_insertp("hier", name, __VA_ARGS__); \
    } while (false)

//=============================================================================
//  VerilatedCov
/// Per-VerilatedContext coverage data class.
/// All public methods in this class are thread safe.
///
/// This structure is accessed and constructed on first access via
/// VerilatedContext::coveragep()

class VerilatedCovContext VL_NOT_FINAL : public VerilatedVirtualBase {
    VL_UNCOPYABLE(VerilatedCovContext);

public:
    // METHODS
    /// Return default filename, may override with +verilator+coverage+file
    std::string defaultFilename() VL_MT_SAFE;
    /// Make all data per_instance, overriding point's per_instance
    void forcePerInstance(bool flag) VL_MT_SAFE;
    /// Write all coverage data to a file
    void write() VL_MT_SAFE { write(defaultFilename()); }
    void write(const std::string& filename) VL_MT_SAFE;
    /// Clear coverage points (and call delete on all items)
    void clear() VL_MT_SAFE;
    /// Clear items not matching the provided string
    void clearNonMatch(const char* matchp) VL_MT_SAFE;
    /// Zero coverage points
    void zero() VL_MT_SAFE;

    // METHODS - public but Internal use only

    // 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)
    void _inserti(uint32_t* itemp) VL_MT_SAFE;
    void _inserti(uint64_t* itemp) VL_MT_SAFE;
    // _insert2: Set default filename and line number
    void _insertf(const char* filename, int lineno) VL_MT_SAFE;
    // _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.
#ifndef DOXYGEN
#define K(n) const char* key##n
#define A(n) const char *key##n, const char *valp##n  // Argument list
#define D(n) const char *key##n = nullptr, const char *valp##n = nullptr  // Argument list
    void _insertp(D(0), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9)) VL_MT_SAFE;
    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)) VL_MT_SAFE;
    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)) VL_MT_SAFE;
    // Backward compatibility for Verilator
    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(7)) VL_MT_SAFE;

#undef K
#undef A
#undef D
#endif  // DOXYGEN

protected:
    friend class VerilatedCovImp;
    // CONSTRUCTORS
    // Internal: Only made as part of VerilatedCovImp
    VerilatedCovContext() = default;
    ~VerilatedCovContext() override = default;

    // METHODS
    // Internal: access to implementation class
    VerilatedCovImp* impp() VL_MT_SAFE { return reinterpret_cast<VerilatedCovImp*>(this); }
};

//=============================================================================
//  VerilatedCov
/// Coverage global class.
///
/// Global class that accesses via current thread's context's
/// VerilatedCovContext.  This class is provided only for
/// backward-compatibility, use VerilatedContext::coveragep() instead.

#ifndef VL_NO_LEGACY
class VerilatedCov final {
    VL_UNCOPYABLE(VerilatedCov);

public:
    // METHODS
    /// Return default filename for the current thread
    static std::string defaultFilename() VL_MT_SAFE { return threadCovp()->defaultFilename(); }
    /// Write all coverage data to a file for the current thread
    static void write() VL_MT_SAFE { write(defaultFilename()); }
    static void write(const std::string& filename) VL_MT_SAFE { threadCovp()->write(filename); }
    /// Clear coverage points (and call delete on all items) for the current thread
    static void clear() VL_MT_SAFE { threadCovp()->clear(); }
    /// Clear items not matching the provided string for the current thread
    static void clearNonMatch(const char* matchp) VL_MT_SAFE {
        threadCovp()->clearNonMatch(matchp);
    }
    /// Zero coverage points for the current thread
    static void zero() VL_MT_SAFE { threadCovp()->zero(); }

private:
    // Current thread's coverage structure
    static VerilatedCovContext* threadCovp() VL_MT_SAFE;
};
#endif  // VL_NO_LEGACY

#endif  // Guard