1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 // DESCRIPTION: verilator_coverage: main()
4 //
5 // Code available from: https://verilator.org
6 //
7 //*************************************************************************
8 //
9 // Copyright 2003-2021 by Wilson Snyder. This program is free software; you
10 // can redistribute it and/or modify it under the terms of either the GNU
11 // Lesser General Public License Version 3 or the Perl Artistic License
12 // Version 2.0.
13 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
14 //
15 //*************************************************************************
16 
17 // clang-format off
18 #include "config_build.h"
19 #ifndef HAVE_CONFIG_BUILD
20 # error "Something failed during ./configure as config_build.h is incomplete. Perhaps you used autoreconf, don't."
21 #endif
22 // clang-format on
23 
24 #include "verilatedos.h"
25 
26 // Cheat for speed and compile .cpp files into one object
27 #define V3ERROR_NO_GLOBAL_
28 #include "V3Error.cpp"
29 #include "V3String.cpp"
30 #define V3OPTION_PARSER_NO_VOPTION_BOOL
31 #include "V3OptionParser.cpp"
32 #include "V3Os.cpp"
33 #include "VlcTop.cpp"
34 
35 #include "VlcOptions.h"
36 #include "VlcTop.h"
37 
38 #include <algorithm>
39 #include <fstream>
40 
41 //######################################################################
42 // VlcOptions
43 
addReadFile(const string & filename)44 void VlcOptions::addReadFile(const string& filename) { m_readFiles.insert(filename); }
45 
version()46 string VlcOptions::version() {
47     string ver = DTVERSION;
48     ver += " rev " + cvtToStr(DTVERSION_rev);
49     return ver;
50 }
51 
parseOptsList(int argc,char ** argv)52 void VlcOptions::parseOptsList(int argc, char** argv) {
53     V3OptionParser parser;
54     V3OptionParser::AppendHelper DECL_OPTION{parser};
55     V3OPTION_PARSER_DECL_TAGS;
56 
57     DECL_OPTION("-annotate-all", OnOff, &m_annotateAll);
58     DECL_OPTION("-rank", OnOff, &m_rank);
59     DECL_OPTION("-unlink", OnOff, &m_unlink);
60     DECL_OPTION("-annotate-min", Set, &m_annotateMin);
61     DECL_OPTION("-annotate", Set, &m_annotateOut);
62     DECL_OPTION("-debug", CbCall, []() { V3Error::debugDefault(3); });
63     DECL_OPTION("-debugi", CbVal, [](int v) { V3Error::debugDefault(v); });
64     DECL_OPTION("-V", CbCall, []() {
65         showVersion(true);
66         std::exit(0);
67     });
68     DECL_OPTION("-version", CbCall, []() {
69         showVersion(false);
70         std::exit(0);
71     });
72     DECL_OPTION("-write", Set, &m_writeFile);
73     DECL_OPTION("-write-info", Set, &m_writeInfoFile);
74     parser.finalize();
75 
76     // Parse parameters
77     // Note argc and argv DO NOT INCLUDE the filename in [0]!!!
78     // May be called recursively when there are -f files.
79     for (int i = 0; i < argc;) {
80         UINFO(9, " Option: " << argv[i] << endl);
81         if (argv[i][0] == '-') {
82             if (const int consumed = parser.parse(i, argc, argv)) {
83                 i += consumed;
84             } else {
85                 v3fatal("Invalid option: " << argv[i] << parser.getSuggestion(argv[i]));
86                 ++i;  // LCOV_EXCL_LINE
87             }
88         } else {
89             addReadFile(argv[i]);
90             ++i;
91         }
92     }
93 }
94 
showVersion(bool verbose)95 void VlcOptions::showVersion(bool verbose) {
96     cout << version();
97     cout << endl;
98     if (!verbose) return;
99 
100     cout << endl;
101     cout << "Copyright 2003-2021 by Wilson Snyder.  Verilator is free software; you can\n";
102     cout << "redistribute it and/or modify the Verilator internals under the terms of\n";
103     cout << "either the GNU Lesser General Public License Version 3 or the Perl Artistic\n";
104     cout << "License Version 2.0.\n";
105 
106     cout << endl;
107     cout << "See https://verilator.org for documentation\n";
108 }
109 
110 //######################################################################
111 
main(int argc,char ** argv,char **)112 int main(int argc, char** argv, char** /*env*/) {
113     // General initialization
114     std::ios::sync_with_stdio();
115 
116     VlcTop top;
117 
118     // Command option parsing
119     top.opt.parseOptsList(argc - 1, argv + 1);
120 
121     if (top.opt.readFiles().empty()) top.opt.addReadFile("vlt_coverage.dat");
122 
123     {
124         const VlStringSet& readFiles = top.opt.readFiles();
125         for (const auto& filename : readFiles) top.readCoverage(filename);
126     }
127 
128     if (debug() >= 9) {
129         top.tests().dump(true);
130         top.points().dump();
131     }
132 
133     V3Error::abortIfWarnings();
134     if (!top.opt.annotateOut().empty()) top.annotate(top.opt.annotateOut());
135 
136     if (top.opt.rank()) {
137         top.rank();
138         top.tests().dump(false);
139     }
140 
141     if (!top.opt.writeFile().empty() || !top.opt.writeInfoFile().empty()) {
142         if (!top.opt.writeFile().empty()) top.writeCoverage(top.opt.writeFile());
143         if (!top.opt.writeInfoFile().empty()) top.writeInfo(top.opt.writeInfoFile());
144         V3Error::abortIfWarnings();
145         if (top.opt.unlink()) {
146             const VlStringSet& readFiles = top.opt.readFiles();
147             for (const auto& filename : readFiles) { unlink(filename.c_str()); }
148         }
149     }
150 
151     // Final writing shouldn't throw warnings, but...
152     V3Error::abortIfWarnings();
153 
154     UINFO(1, "Done, Exiting...\n");
155 }
156 
157 // Local Variables:
158 // compile-command: "v4make bin/verilator_coverage --debugi 9 test_regress/t/t_vlcov_data_*.dat"
159 // End:
160