1b0eb6649f1616260c01636cd558ddbfd5fd4ee9
2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 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 "libs/sha1/sha1.h"
22 #include "backends/ilang/ilang_backend.h"
34 std::vector
<FILE*> log_files
;
35 std::vector
<std::ostream
*> log_streams
;
36 FILE *log_errfile
= NULL
;
37 SHA1
*log_hasher
= NULL
;
39 bool log_time
= false;
40 bool log_cmd_error_throw
= false;
41 int log_verbose_level
;
43 std::vector
<int> header_count
;
44 std::list
<std::string
> string_buf
;
45 int string_buf_size
= 0;
47 static struct timeval initial_tv
= { 0, 0 };
48 static bool next_print_log
= false;
49 static int log_newline_count
= 0;
51 void logv(const char *format
, va_list ap
)
53 while (format
[0] == '\n' && format
[1] != 0) {
58 std::string str
= vstringf(format
, ap
);
63 size_t nnl_pos
= str
.find_last_not_of('\n');
64 if (nnl_pos
== std::string::npos
)
65 log_newline_count
+= SIZE(str
);
67 log_newline_count
= SIZE(str
) - nnl_pos
- 1;
70 log_hasher
->update(str
);
76 if (next_print_log
|| initial_tv
.tv_sec
== 0) {
77 next_print_log
= false;
79 gettimeofday(&tv
, NULL
);
80 if (initial_tv
.tv_sec
== 0)
82 if (tv
.tv_usec
< initial_tv
.tv_usec
) {
84 tv
.tv_usec
+= 1000000;
86 tv
.tv_sec
-= initial_tv
.tv_sec
;
87 tv
.tv_usec
-= initial_tv
.tv_usec
;
88 time_str
+= stringf("[%05d.%06d] ", int(tv
.tv_sec
), int(tv
.tv_usec
));
91 if (format
[0] && format
[strlen(format
)-1] == '\n')
92 next_print_log
= true;
94 for (auto f
: log_files
)
95 fputs(time_str
.c_str(), f
);
97 for (auto f
: log_streams
)
101 for (auto f
: log_files
)
102 fputs(str
.c_str(), f
);
104 for (auto f
: log_streams
)
108 void logv_header(const char *format
, va_list ap
)
110 bool pop_errfile
= false;
113 if (header_count
.size() > 0)
114 header_count
.back()++;
116 if (int(header_count
.size()) <= log_verbose_level
&& log_errfile
!= NULL
) {
117 log_files
.push_back(log_errfile
);
121 for (int c
: header_count
)
128 log_files
.pop_back();
131 void logv_error(const char *format
, va_list ap
)
133 if (log_errfile
!= NULL
)
134 log_files
.push_back(log_errfile
);
142 void log(const char *format
, ...)
145 va_start(ap
, format
);
150 void log_header(const char *format
, ...)
153 va_start(ap
, format
);
154 logv_header(format
, ap
);
158 void log_error(const char *format
, ...)
161 va_start(ap
, format
);
162 logv_error(format
, ap
);
165 void log_cmd_error(const char *format
, ...)
168 va_start(ap
, format
);
170 if (log_cmd_error_throw
) {
174 throw log_cmd_error_expection();
177 logv_error(format
, ap
);
182 while (log_newline_count
< 2)
188 header_count
.push_back(0);
193 header_count
.pop_back();
199 void log_reset_stack()
201 while (header_count
.size() > 1)
202 header_count
.pop_back();
210 for (auto f
: log_files
)
213 for (auto f
: log_streams
)
217 void log_dump_val_worker(RTLIL::SigSpec v
) {
218 log("%s", log_signal(v
));
221 const char *log_signal(const RTLIL::SigSpec
&sig
, bool autoint
)
223 std::stringstream buf
;
224 ILANG_BACKEND::dump_sigspec(buf
, sig
, autoint
);
226 if (string_buf_size
< 100)
229 string_buf
.pop_front();
230 string_buf
.push_back(buf
.str());
232 return string_buf
.back().c_str();
235 const char *log_id(RTLIL::IdString str
)
237 const char *p
= str
.c_str();
238 log_assert(RTLIL::IdString::global_refcount_storage_
[str
.index_
] > 1);
239 if (p
[0] == '\\' && p
[1] != '$' && p
[1] != 0)
244 void log_cell(RTLIL::Cell
*cell
, std::string indent
)
246 std::stringstream buf
;
247 ILANG_BACKEND::dump_cell(buf
, indent
, cell
);
248 log("%s", buf
.str().c_str());
251 // ---------------------------------------------------
252 // This is the magic behind the code coverage counters
253 // ---------------------------------------------------
256 std::map
<std::string
, std::pair
<std::string
, int>> extra_coverage_data
;
258 void cover_extra(std::string parent
, std::string id
, bool increment
) {
259 if (extra_coverage_data
.count(id
) == 0) {
260 for (CoverData
*p
= __start_yosys_cover_list
; p
!= __stop_yosys_cover_list
; p
++)
262 extra_coverage_data
[id
].first
= stringf("%s:%d:%s", p
->file
, p
->line
, p
->func
);
263 log_assert(extra_coverage_data
.count(id
));
266 extra_coverage_data
[id
].second
++;
269 std::map
<std::string
, std::pair
<std::string
, int>> get_coverage_data()
271 std::map
<std::string
, std::pair
<std::string
, int>> coverage_data
;
273 for (auto &it
: pass_register
) {
274 std::string key
= stringf("passes.%s", it
.first
.c_str());
275 coverage_data
[key
].first
= stringf("%s:%d:%s", __FILE__
, __LINE__
, __FUNCTION__
);
276 coverage_data
[key
].second
+= it
.second
->call_counter
;
279 for (auto &it
: extra_coverage_data
) {
280 if (coverage_data
.count(it
.first
))
281 log("WARNING: found duplicate coverage id \"%s\".\n", it
.first
.c_str());
282 coverage_data
[it
.first
].first
= it
.second
.first
;
283 coverage_data
[it
.first
].second
+= it
.second
.second
;
286 for (CoverData
*p
= __start_yosys_cover_list
; p
!= __stop_yosys_cover_list
; p
++) {
287 if (coverage_data
.count(p
->id
))
288 log("WARNING: found duplicate coverage id \"%s\".\n", p
->id
);
289 coverage_data
[p
->id
].first
= stringf("%s:%d:%s", p
->file
, p
->line
, p
->func
);
290 coverage_data
[p
->id
].second
+= p
->counter
;
293 for (auto &it
: coverage_data
)
294 if (!it
.second
.first
.compare(0, strlen(YOSYS_SRC
"/"), YOSYS_SRC
"/"))
295 it
.second
.first
= it
.second
.first
.substr(strlen(YOSYS_SRC
"/"));
297 return coverage_data
;