2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2014 Clifford Wolf <clifford@clifford.at>
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.
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.
20 #include "kernel/yosys.h"
21 #include <sys/types.h>
29 #include "kernel/register.h"
30 #include "kernel/rtlil.h"
31 #include "kernel/log.h"
34 PRIVATE_NAMESPACE_BEGIN
36 struct CoverPass
: public Pass
{
37 CoverPass() : Pass("cover", "print code coverage counters") { }
38 void help() YS_OVERRIDE
40 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
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 Yosys for Linux.\n");
86 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
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 const std::string
&filename
= args
[++argidx
];
103 if (args
[argidx
-1] == "-d") {
105 log_cmd_error("The 'cover -d' option is not supported on win32.\n");
107 char filename_buffer
[4096];
108 snprintf(filename_buffer
, 4096, "%s/yosys_cover_%d_XXXXXX.txt", filename
.c_str(), getpid());
109 f
= fdopen(mkstemps(filename_buffer
, 4), "w");
112 f
= fopen(filename
.c_str(), open_mode
);
115 for (auto f
: out_files
)
117 log_cmd_error("Can't create file %s%s.\n", args
[argidx
-1] == "-d" ? "in directory " : "", args
[argidx
].c_str());
119 out_files
.push_back(f
);
124 while (argidx
< args
.size() && args
[argidx
].compare(0, 1, "-") != 0)
125 patterns
.push_back(args
[argidx
++]);
126 extra_args(args
, argidx
, design
);
129 log_header(design
, "Printing code coverage counters.\n");
133 #if defined(YOSYS_ENABLE_COVER) && (defined(__linux__) || defined(__FreeBSD__))
134 for (auto &it
: get_coverage_data()) {
135 if (!patterns
.empty()) {
136 for (auto &p
: patterns
)
137 if (patmatch(p
.c_str(), it
.first
.c_str()))
142 for (auto f
: out_files
)
143 fprintf(f
, "%-60s %10d %s\n", it
.second
.first
.c_str(), it
.second
.second
, it
.first
.c_str());
145 log("%-60s %10d %s\n", it
.second
.first
.c_str(), it
.second
.second
, it
.first
.c_str());
148 for (auto f
: out_files
)
151 log_cmd_error("This version of Yosys was not built with support for code coverage counters.\n");
154 for (auto f
: out_files
)
159 PRIVATE_NAMESPACE_END