yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cover.cc
Go to the documentation of this file.
1 /*
2  * yosys -- Yosys Open SYnthesis Suite
3  *
4  * Copyright (C) 2014 Clifford Wolf <clifford@clifford.at>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 
20 #include "kernel/yosys.h"
21 #include <sys/types.h>
22 
23 #ifndef _WIN32
24 # include <unistd.h>
25 #else
26 # include <io.h>
27 #endif
28 
29 #include "kernel/register.h"
30 #include "kernel/rtlil.h"
31 #include "kernel/log.h"
32 
35 
36 struct CoverPass : public Pass {
37  CoverPass() : Pass("cover", "print code coverage counters") { }
38  virtual void help()
39  {
40  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
41  log("\n");
42  log(" cover [options] [pattern]\n");
43  log("\n");
44  log("Print the code coverage counters collected using the cover() macro in the Yosys\n");
45  log("C++ code. This is useful to figure out what parts of Yosys are utilized by a\n");
46  log("test bench.\n");
47  log("\n");
48  log(" -q\n");
49  log(" Do not print output to the normal destination (console and/or log file)\n");
50  log("\n");
51  log(" -o file\n");
52  log(" Write output to this file, truncate if exists.\n");
53  log("\n");
54  log(" -a file\n");
55  log(" Write output to this file, append if exists.\n");
56  log("\n");
57  log(" -d dir\n");
58  log(" Write output to a newly created file in the specified directory.\n");
59  log("\n");
60  log("When one or more pattern (shell wildcards) are specified, then only counters\n");
61  log("matching at least one pattern are printed.\n");
62  log("\n");
63  log("\n");
64  log("It is also possible to instruct Yosys to print the coverage counters on program\n");
65  log("exit to a file using environment variables:\n");
66  log("\n");
67  log(" YOSYS_COVER_DIR=\"{dir-name}\" yosys {args}\n");
68  log("\n");
69  log(" This will create a file (with an auto-generated name) in this\n");
70  log(" directory and write the coverage counters to it.\n");
71  log("\n");
72  log(" YOSYS_COVER_FILE=\"{file-name}\" yosys {args}\n");
73  log("\n");
74  log(" This will append the coverage counters to the specified file.\n");
75  log("\n");
76  log("\n");
77  log("Hint: Use the following AWK command to consolidate Yosys coverage files:\n");
78  log("\n");
79  log(" gawk '{ p[$3] = $1; c[$3] += $2; } END { for (i in p)\n");
80  log(" printf \"%%-60s %%10d %%s\\n\", p[i], c[i], i; }' {files} | sort -k3\n");
81  log("\n");
82  log("\n");
83  log("Coverage counters are only available in debug builds of Yosys for Linux.\n");
84  log("\n");
85  }
86  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
87  {
88  std::vector<FILE*> out_files;
89  std::vector<std::string> patterns;
90  bool do_log = true;
91 
92  size_t argidx;
93  for (argidx = 1; argidx < args.size(); argidx++)
94  {
95  if (args[argidx] == "-q") {
96  do_log = false;
97  continue;
98  }
99  if ((args[argidx] == "-o" || args[argidx] == "-a" || args[argidx] == "-d") && argidx+1 < args.size()) {
100  const char *open_mode = args[argidx] == "-a" ? "a+" : "w";
101  std::string filename = args[++argidx];
102  if (args[argidx-1] == "-d") {
103  #ifdef _WIN32
104  log_cmd_error("The 'cover -d' option is not supported on win32.\n");
105  #else
106  char filename_buffer[4096];
107  snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", filename.c_str(), getpid());
108  filename = mkstemps(filename_buffer, 4);
109  #endif
110  }
111  FILE *f = fopen(filename.c_str(), open_mode);
112  if (f == NULL) {
113  for (auto f : out_files)
114  fclose(f);
115  log_cmd_error("Can't create file %s.\n", args[argidx].c_str());
116  }
117  out_files.push_back(f);
118  continue;
119  }
120  break;
121  }
122  while (argidx < args.size() && args[argidx].substr(0, 1) != "-")
123  patterns.push_back(args[argidx++]);
124  extra_args(args, argidx, design);
125 
126  if (do_log) {
127  log_header("Printing code coverage counters.\n");
128  log("\n");
129  }
130 
131 #ifdef YOSYS_ENABLE_COVER
132  for (auto &it : get_coverage_data()) {
133  if (!patterns.empty()) {
134  for (auto &p : patterns)
135  if (patmatch(p.c_str(), it.first.c_str()))
136  goto pattern_match;
137  continue;
138  }
139  pattern_match:
140  for (auto f : out_files)
141  fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str());
142  if (do_log)
143  log("%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str());
144  }
145 #else
146  for (auto f : out_files)
147  fclose(f);
148 
149  log_cmd_error("This version of Yosys was not built with support for code coverage counters.\n");
150 #endif
151 
152  for (auto f : out_files)
153  fclose(f);
154  }
155 } CoverPass;
156 
CoverPass CoverPass
void log_header(const char *format,...)
Definition: log.cc:188
bool patmatch(const char *pattern, const char *string)
Definition: yosys.cc:144
virtual void help()
Definition: cover.cc:38
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
void log_cmd_error(const char *format,...)
Definition: log.cc:211
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: cover.cc:86
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
#define NULL
CoverPass()
Definition: cover.cc:37
void log(const char *format,...)
Definition: log.cc:180
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128