21 #include <sys/types.h>
42 log(
" cover [options] [pattern]\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");
49 log(
" Do not print output to the normal destination (console and/or log file)\n");
52 log(
" Write output to this file, truncate if exists.\n");
55 log(
" Write output to this file, append if exists.\n");
58 log(
" Write output to a newly created file in the specified directory.\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");
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");
67 log(
" YOSYS_COVER_DIR=\"{dir-name}\" yosys {args}\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");
72 log(
" YOSYS_COVER_FILE=\"{file-name}\" yosys {args}\n");
74 log(
" This will append the coverage counters to the specified file.\n");
77 log(
"Hint: Use the following AWK command to consolidate Yosys coverage files:\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");
83 log(
"Coverage counters are only available in debug builds of Yosys for Linux.\n");
88 std::vector<FILE*> out_files;
89 std::vector<std::string> patterns;
93 for (argidx = 1; argidx < args.size(); argidx++)
95 if (args[argidx] ==
"-q") {
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") {
104 log_cmd_error(
"The 'cover -d' option is not supported on win32.\n");
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);
111 FILE *f = fopen(filename.c_str(), open_mode);
113 for (
auto f : out_files)
115 log_cmd_error(
"Can't create file %s.\n", args[argidx].c_str());
117 out_files.push_back(f);
122 while (argidx < args.size() && args[argidx].substr(0, 1) !=
"-")
123 patterns.push_back(args[argidx++]);
127 log_header(
"Printing code coverage counters.\n");
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()))
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());
143 log(
"%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str());
146 for (
auto f : out_files)
149 log_cmd_error(
"This version of Yosys was not built with support for code coverage counters.\n");
152 for (
auto f : out_files)
void log_header(const char *format,...)
bool patmatch(const char *pattern, const char *string)
#define PRIVATE_NAMESPACE_BEGIN
#define PRIVATE_NAMESPACE_END
void log_cmd_error(const char *format,...)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
#define USING_YOSYS_NAMESPACE
void log(const char *format,...)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)