scc 2026.07
SystemC components library
report.cpp
1/*******************************************************************************
2 * Copyright 2017, 2018 MINRES Technologies GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16#include "report.h"
17#include "configurer.h"
18#include <array>
19#include <cci_configuration>
20#include <deque>
21#include <fstream>
22#include <mutex>
23#include <nonstd/optional.hpp>
24#include <spdlog/async.h>
25#include <spdlog/sinks/basic_file_sink.h>
26#include <spdlog/sinks/stdout_color_sinks.h>
27#include <spdlog/spdlog.h>
28#include <sysc/kernel/sc_status.h>
29#include <tuple>
30#include <unordered_map>
31#include <util/logging.h>
32#ifdef WITH_STACKTRACE
33#include <boost/stacktrace.hpp>
34#endif
35#include <cstdlib>
36#ifdef __GNUC__
37#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
38#if GCC_VERSION < 40900
39#define USE_C_REGEX
40#endif
41#define likely(x) __builtin_expect(x, 1)
42#define unlikely(x) __builtin_expect(x, 0)
43#else
44#define likely(x) x
45#define unlikely(x) x
46#endif
47
48#ifdef USE_C_REGEX
49#include <regex.h>
50#else
51#include <regex>
52#endif
53#ifdef ERROR
54#undef ERROR
55#endif
56using namespace std;
57using namespace sc_core;
58using namespace scc;
59
60namespace {
61struct char_equal_to : public std::equal_to<char const*> {
62 bool operator()(char const* __x, char const* __y) const { return strcmp(__x, __y) == 0; }
63};
64
65struct char_hash {
66 // BKDR hash algorithm
67 uint64_t operator()(char const* str) const {
68 constexpr unsigned int seed = 131; // 31 131 1313 13131131313 etc//
69 uint64_t hash = 0;
70 while(*str) {
71 hash = (hash * seed) + (*str);
72 str++;
73 }
74 return hash;
75 }
76};
77static class {
78 std::unordered_map<char const*, sc_core::sc_verbosity, char_hash, char_equal_to> table;
79 std::deque<std::string> cache;
80 std::mutex mtx;
81
82public:
83 std::tuple<bool, sc_core::sc_verbosity> get(char const* key) {
84 std::lock_guard<std::mutex> lock(mtx);
85 auto it = table.find(key);
86 if(it != table.end())
87 return {true, it->second};
88 else
89 return {false, sc_core::SC_DEBUG};
90 }
91 void insert(char const* key, sc_core::sc_verbosity verb) {
92 std::lock_guard<std::mutex> lock(mtx);
93 cache.emplace_back(key);
94 table.insert({cache.back().c_str(), verb});
95 }
96 void clear() {
97 std::lock_guard<std::mutex> lock(mtx);
98 table.clear();
99 cache.clear();
100 }
101} lut;
102#ifdef MTI_SYSTEMC
103static const cci::cci_originator originator;
104#else
105static const cci::cci_originator originator("reporting");
106#endif
107
108bool& inst_based_logging() {
109 thread_local bool active = getenv("SCC_DISABLE_INSTANCE_BASED_LOGGING") == nullptr;
110 return active;
111}
112
113static struct ExtLogConfig : public scc::LogConfig {
114 shared_ptr<spdlog::logger> file_logger;
115 shared_ptr<spdlog::logger> console_logger;
116#ifdef USE_C_REGEX
117 regex_t start_state{};
118#else
119 regex reg_ex;
120#endif
121 sc_time cycle_base{0, SC_NS};
122 auto operator=(const scc::LogConfig& o) -> ExtLogConfig& {
123 scc::LogConfig::operator=(o);
124 return *this;
125 }
126 auto match(const char* type) -> bool {
127#ifdef USE_C_REGEX
128 return regexec(&start_state, type, 0, nullptr, 0) == 0;
129#else
130 return regex_search(type, reg_ex);
131#endif
132 }
133 bool initialized{false};
134 std::mutex mtx;
135 nonstd::optional<cci::cci_broker_handle> broker;
136} log_cfg;
137
138auto get_tuple(const sc_time& t) -> tuple<sc_time::value_type, sc_time_unit> {
139 auto val = t.value();
140 auto tr = (uint64_t)(sc_time::from_value(1).to_seconds() * 1E15);
141 auto scale = 0U;
142 while((tr % 10) == 0) {
143 tr /= 10;
144 scale++;
145 }
146 sc_assert(tr == 1);
147
148 auto tu = scale / 3;
149 while(tu < SC_SEC && (val % 10) == 0) {
150 val /= 10;
151 scale++;
152 tu += (0 == (scale % 3));
153 }
154 for(scale %= 3; scale != 0; scale--)
155 val *= 10;
156 return make_tuple(val, static_cast<sc_time_unit>(tu));
157}
158
159auto time2string(const sc_time& t) -> string {
160 const array<const char*, 6> time_units{"fs", "ps", "ns", "us", "ms", "s "};
161 const array<uint64_t, 6> multiplier{
162 1ULL, 1000ULL, 1000ULL * 1000, 1000ULL * 1000 * 1000, 1000ULL * 1000 * 1000 * 1000, 1000ULL * 1000 * 1000 * 1000 * 1000};
163 ostringstream oss;
164 if(!t.value()) {
165 oss << "0 s ";
166 } else {
167 const auto tt = get_tuple(t);
168 const auto val = get<0>(tt);
169 const auto scale = get<1>(tt);
170 const auto fs_val = val * multiplier[scale];
171 for(int j = multiplier.size() - 1; j >= scale; --j) {
172 if(fs_val >= multiplier[j]) {
173 const auto i = val / multiplier[j - scale];
174 const auto f = val % multiplier[j - scale];
175 oss << i << '.' << setw(3 * (j - scale)) << setfill('0') << right << f << ' ' << time_units[j];
176 break;
177 }
178 }
179 }
180 return oss.str();
181}
182auto compose_message(const sc_report& rep, const scc::LogConfig& cfg) -> const string {
183 if(rep.get_severity() > SC_INFO || cfg.log_filter_regex.length() == 0 || rep.get_verbosity() == sc_core::SC_MEDIUM ||
184 log_cfg.match(rep.get_msg_type())) {
185 stringstream os;
186 if(unlikely(cfg.print_sys_time))
187 os << "<" << logging::now_time() << ">";
188 if(likely(cfg.print_sim_time)) {
189 if(unlikely(log_cfg.cycle_base.value())) {
190 if(unlikely(cfg.print_delta))
191 os << "[" << std::setw(7) << std::setfill(' ') << sc_time_stamp().value() / log_cfg.cycle_base.value() << "(" << setw(5)
192 << sc_delta_count() << ")]";
193 else
194 os << "[" << std::setw(7) << std::setfill(' ') << sc_time_stamp().value() / log_cfg.cycle_base.value() << "]";
195 } else {
196 auto t = time2string(sc_time_stamp());
197 if(unlikely(cfg.print_delta))
198 os << "[" << std::setw(20) << std::setfill(' ') << t << "(" << setw(5) << sc_delta_count() << ")]";
199 else
200 os << "[" << std::setw(20) << std::setfill(' ') << t << "]";
201 }
202 }
203 if(unlikely(rep.get_id() >= 0))
204 os << " ("
205 << "IWEF"[rep.get_severity()] << rep.get_id() << ") " << rep.get_msg_type() << ": ";
206 else if(cfg.msg_type_field_width) {
207 if(cfg.msg_type_field_width == std::numeric_limits<unsigned>::max())
208 os << " " << rep.get_msg_type() << ": ";
209 else
210 os << " " << util::padded(rep.get_msg_type(), cfg.msg_type_field_width) << ": ";
211 }
212 if(*rep.get_msg())
213 os << rep.get_msg();
214 if(rep.get_severity() > SC_INFO) {
215 if(rep.get_line_number())
216 os << "\n [FILE:" << rep.get_file_name() << ":" << rep.get_line_number() << "]";
217 sc_simcontext* simc = sc_get_curr_simcontext();
218 if(simc && sc_is_running()) {
219 const char* proc_name = rep.get_process_name();
220 if(proc_name)
221 os << "\n [PROCESS:" << proc_name << "]";
222 }
223 }
224 return os.str();
225 } else
226 return "";
227}
228
229inline void log2logger(spdlog::logger& logger, const sc_report& rep, const scc::LogConfig& cfg) {
230 auto msg = compose_message(rep, cfg);
231 if(!msg.size())
232 return;
233 switch(rep.get_severity()) {
234 case SC_INFO:
235 switch(rep.get_verbosity()) {
236 case SC_DEBUG:
237 case SC_FULL:
238 logger.trace(msg);
239 break;
240 case SC_HIGH:
241 logger.debug(msg);
242 break;
243 default:
244 logger.info(msg);
245 break;
246 }
247 break;
248 case SC_WARNING:
249 logger.warn(msg);
250 break;
251 case SC_ERROR:
252 logger.error(msg);
253#ifdef WITH_STACKTRACE
254 if(getenv("SCC_PRINT_STACK_ON_ERROR"))
255 logger.error(boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
256#endif
257 break;
258 case SC_FATAL:
259 logger.critical(msg);
260#ifdef WITH_STACKTRACE
261 if(getenv("SCC_PRINT_STACK_ON_ERROR"))
262 logger.error(boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
263#endif
264 break;
265 default:
266 break;
267 }
268}
269
270inline void flush_loggers() {
271 log_cfg.console_logger->flush();
272 if(log_cfg.file_logger)
273 log_cfg.file_logger->flush();
274}
275
276void report_handler(const sc_report& rep, const sc_actions& actions) {
277 thread_local bool sc_stop_called = false;
278 if(actions & SC_DO_NOTHING)
279 return;
280 if(rep.get_severity() == sc_core::SC_INFO || !log_cfg.report_only_first_error || sc_report_handler::get_count(SC_ERROR) < 2) {
281 if((actions & SC_DISPLAY) && (!log_cfg.file_logger || rep.get_verbosity() < SC_HIGH))
282 try {
283 log2logger(*log_cfg.console_logger, rep, log_cfg);
284 } catch(const spdlog::spdlog_ex& e) {
285 }
286 if((actions & SC_LOG) && log_cfg.file_logger) {
287 scc::LogConfig lcfg(log_cfg);
288 lcfg.print_sim_time = true;
289 if(!lcfg.msg_type_field_width)
290 lcfg.msg_type_field_width = 24;
291 log2logger(*log_cfg.file_logger, rep, lcfg);
292 }
293 }
294 if(actions & SC_STOP) {
295 try {
296 flush_loggers();
297 } catch(const spdlog::spdlog_ex& e) {
298 }
299#if SYSTEMC_VERSION < 20241015
300 static const int stop_expr = sc_core::SC_START_OF_SIMULATION | SC_RUNNING | SC_PAUSED;
301#else
302 static constexpr int stop_expr = sc_core::SC_START_OF_SIMULATION | SC_RUNNING | SC_PAUSED | SC_SUSPENDED;
303#endif
304 if((sc_get_status() & stop_expr) && !sc_stop_called) {
305 sc_stop();
306 sc_stop_called = true;
307 }
308 }
309 if(actions & SC_ABORT) {
310 try {
311 flush_loggers();
312 } catch(const spdlog::spdlog_ex& e) {
313 }
314 spdlog::shutdown();
315 abort();
316 }
317 if(actions & SC_THROW) {
318 try {
319 flush_loggers();
320 } catch(const spdlog::spdlog_ex& e) {
321 }
322 throw rep;
323 }
324 if(sc_time_stamp().value() && !sc_is_running()) {
325 try {
326 flush_loggers();
327 } catch(const spdlog::spdlog_ex& e) {
328 }
329 }
330}
331} // namespace
332namespace scc {
333std::mutex verbosity_mtx;
334}
336: os(os)
337, level(level) {
338 old_buf = os.rdbuf(this); // save and redirect
339}
340
342 os.rdbuf(old_buf); // restore
343}
344
346 os.rdbuf(old_buf); // restore
347 old_buf = nullptr;
348}
349
350auto scc::stream_redirection::xsputn(const char_type* s, streamsize n) -> streamsize {
351 auto sz = stringbuf::xsputn(s, n);
352 if(s[n - 1] == '\n') {
353 sync();
354 }
355 return sz;
356}
357
358static const array<sc_severity, 8> severity = {SC_FATAL, // scc::log::NONE
359 SC_FATAL, // scc::log::FATAL
360 SC_ERROR, // scc::log::ERROR
361 SC_WARNING, // scc::log::WARNING
362 SC_INFO, // scc::log::INFO
363 SC_INFO, // scc::log::DEBUG
364 SC_INFO, // scc::log::TRACE
365 SC_INFO}; // scc::log::DBGTRACE
366static const array<sc_verbosity, 8> verbosity = {SC_NONE, // scc::log::NONE
367 SC_LOW, // scc::log::FATAL
368 SC_LOW, // scc::log::ERROR
369 SC_LOW, // scc::log::WARNING
370 SC_MEDIUM, // scc::log::INFO
371 SC_HIGH, // scc::log::DEBUG
372 SC_FULL, // scc::log::TRACE
373 SC_DEBUG}; // scc::log::DBGTRACE
374
375auto scc::stream_redirection::sync() -> int {
376 if(level <= log_cfg.level) {
377 auto timestr = time2string(sc_time_stamp());
378 istringstream buf(str());
379 string line;
380 while(getline(buf, line)) {
381 ::sc_report_handler::report(severity[static_cast<unsigned>(level)], "SystemC", line.c_str(),
382 verbosity[static_cast<unsigned>(level)], "", 0);
383 }
384 str(string(""));
385 }
386 return 0; // Success
387}
388
389static void configure_logging() {
390 std::lock_guard<mutex> lock(log_cfg.mtx);
391 std::lock_guard<mutex> lock2(verbosity_mtx);
392 static bool spdlog_initialized = false;
393 if(!log_cfg.dont_create_broker)
394 scc::init_cci("SCCBroker");
395 log_cfg.broker = cci::cci_get_global_broker(originator);
396 if(log_cfg.install_handler) {
397 if(!log_cfg.instance_based_log_levels || getenv("SCC_DISABLE_INSTANCE_BASED_LOGGING"))
398 inst_based_logging() = false;
399 sc_report_handler::set_verbosity_level(verbosity[static_cast<unsigned>(log_cfg.level)]);
400 sc_report_handler::set_handler(report_handler);
401 if(!spdlog_initialized) {
402 spdlog::init_thread_pool(1024U,
403 log_cfg.log_file_name.size() ? 2U : 1U); // queue with 8k items and 1 backing thread.
404 log_cfg.console_logger = log_cfg.log_async ? spdlog::stdout_color_mt<spdlog::async_factory>("console_logger")
405 : spdlog::stdout_color_mt("console_logger");
406 auto logger_fmt = log_cfg.print_severity ? "[%L] %v" : "%v";
407 if(log_cfg.colored_output) {
408 std::ostringstream os;
409 os << "%^" << logger_fmt << "%$";
410 log_cfg.console_logger->set_pattern(os.str());
411 } else
412 log_cfg.console_logger->set_pattern("[%L] %v");
413 log_cfg.console_logger->flush_on(spdlog::level::err);
414 log_cfg.console_logger->set_level(spdlog::level::level_enum::trace);
415 if(log_cfg.log_file_name.size()) {
416 {
417 ofstream ofs;
418 ofs.open(log_cfg.log_file_name, ios::out | ios::trunc);
419 }
420 log_cfg.file_logger = log_cfg.log_async
421 ? spdlog::basic_logger_mt<spdlog::async_factory>("file_logger", log_cfg.log_file_name)
422 : spdlog::basic_logger_mt("file_logger", log_cfg.log_file_name);
423 if(log_cfg.print_severity)
424 log_cfg.file_logger->set_pattern("[%8l] %v");
425 else
426 log_cfg.file_logger->set_pattern("%v");
427 log_cfg.file_logger->flush_on(spdlog::level::err);
428 log_cfg.file_logger->set_level(spdlog::level::level_enum::trace);
429 }
430 spdlog_initialized = true;
431 } else {
432 log_cfg.console_logger = spdlog::get("console_logger");
433 if(log_cfg.log_file_name.size())
434 log_cfg.file_logger = spdlog::get("file_logger");
435 }
436 if(log_cfg.log_filter_regex.size()) {
437#ifdef USE_C_REGEX
438 regcomp(&log_cfg.start_state, log_cfg.log_filter_regex.c_str(), REG_EXTENDED);
439#else
440 log_cfg.reg_ex = regex(log_cfg.log_filter_regex, regex::extended | regex::icase);
441#endif
442 }
443 logging::LoggerCallbacks::set_output_cb([](logging::log_level lvl, std::string const& msg_type, std::string const& msg) {
444 switch(lvl) {
445 case logging::log_level::FATAL:
446 ::scc ::ScLogger<::sc_core ::SC_FATAL>("", 0, sc_core ::SC_MEDIUM)
447 .type(msg_type.size() ? msg_type : std::string("C++"))
448 .get()
449 << msg;
450 break;
451 case logging::log_level::ERR:
452 ::scc ::ScLogger<::sc_core ::SC_ERROR>("", 0, sc_core ::SC_MEDIUM)
453 .type(msg_type.size() ? msg_type : std::string("C++"))
454 .get()
455 << msg;
456 break;
457 case logging::log_level::WARN:
458 if(::scc ::get_log_verbosity(msg_type) >= sc_core ::SC_LOW)
459 ::scc ::ScLogger<::sc_core ::SC_WARNING>("", 0, sc_core ::SC_MEDIUM)
460 .type(msg_type.size() ? msg_type : std::string("C++"))
461 .get()
462 << msg;
463 break;
464 case logging::log_level::INFO:
465 if(::scc ::get_log_verbosity(msg_type) >= sc_core ::SC_MEDIUM)
466 ::scc ::ScLogger<::sc_core ::SC_INFO>("", 0, sc_core ::SC_MEDIUM)
467 .type(msg_type.size() ? msg_type : std::string("C++"))
468 .get()
469 << msg;
470 break;
471 case logging::log_level::DEBUG:
472 if(::scc ::get_log_verbosity(msg_type) >= sc_core ::SC_HIGH)
473 ::scc ::ScLogger<::sc_core ::SC_INFO>("", 0, sc_core ::SC_HIGH)
474 .type(msg_type.size() ? msg_type : std::string("C++"))
475 .get()
476 << msg;
477 break;
478 case logging::log_level::TRACE:
479 if(::scc ::get_log_verbosity(msg_type) >= sc_core ::SC_FULL)
480 ::scc ::ScLogger<::sc_core ::SC_INFO>("", 0, sc_core ::SC_FULL).type(msg_type).get() << msg;
481 break;
482 case logging::log_level::TRACEALL:
483 if(::scc ::get_log_verbosity(msg_type) >= sc_core ::SC_DEBUG)
484 ::scc ::ScLogger<::sc_core ::SC_INFO>("", 0, sc_core ::SC_DEBUG)
485 .type(msg_type.size() ? msg_type : std::string("C++"))
486 .get()
487 << msg;
488 break;
489 default:
490 break;
491 }
492 });
493 }
494}
495
496void scc::reinit_logging() { reinit_logging(log_cfg.level); }
497
498void scc::reinit_logging(scc::log level) {
499 if(log_cfg.install_handler)
500 sc_report_handler::set_handler(report_handler);
501 log_cfg.level = level;
502 lut.clear();
503 if(!log_cfg.instance_based_log_levels || getenv("SCC_DISABLE_INSTANCE_BASED_LOGGING"))
504 inst_based_logging() = false;
505 log_cfg.initialized = true;
506}
507
508bool scc::is_logging_initialized() { return log_cfg.initialized; }
509
510void scc::init_logging(scc::log level, unsigned type_field_width, bool print_time) {
511 log_cfg.msg_type_field_width = type_field_width;
512 log_cfg.print_sys_time = print_time;
513 log_cfg.level = level;
514 configure_logging();
515 log_cfg.initialized = true;
516}
517
518void scc::init_logging(const scc::LogConfig& log_config) {
519 log_cfg = log_config;
520 configure_logging();
521 log_cfg.initialized = true;
522}
523
525 std::lock_guard<mutex> lock(verbosity_mtx);
526 log_cfg.level = level;
527 sc_report_handler::set_verbosity_level(verbosity[static_cast<unsigned>(level)]);
528 log_cfg.console_logger->set_level(
529 static_cast<spdlog::level::level_enum>(SPDLOG_LEVEL_OFF - min<int>(SPDLOG_LEVEL_OFF, static_cast<int>(log_cfg.level))));
530 log_cfg.initialized = true;
531}
532
533auto scc::get_logging_level() -> scc::log { return log_cfg.level; }
534
535void scc::set_cycle_base(sc_time period) { log_cfg.cycle_base = period; }
536
538 this->level = level;
539 return *this;
540}
541
543 this->msg_type_field_width = width;
544 return *this;
545}
546
548 this->print_sys_time = enable;
549 return *this;
550}
551
553 this->print_sim_time = enable;
554 return *this;
555}
556
558 this->print_delta = enable;
559 return *this;
560}
561
563 this->print_severity = enable;
564 return *this;
565}
566
567auto scc::LogConfig::logFileName(string&& name) -> scc::LogConfig& {
568 this->log_file_name = name;
569 return *this;
570}
571
572auto scc::LogConfig::logFileName(const string& name) -> scc::LogConfig& {
573 this->log_file_name = name;
574 return *this;
575}
576
578 this->colored_output = enable;
579 return *this;
580}
581
582auto scc::LogConfig::logFilterRegex(string&& expr) -> scc::LogConfig& {
583 this->log_filter_regex = expr;
584 return *this;
585}
586
587auto scc::LogConfig::logFilterRegex(const string& expr) -> scc::LogConfig& {
588 this->log_filter_regex = expr;
589 return *this;
590}
591
593 this->log_async = v;
594 return *this;
595}
596
598 this->dont_create_broker = v;
599 return *this;
600}
601
603 this->report_only_first_error = v;
604 return *this;
605}
607 this->instance_based_log_levels = v;
608 return *this;
609}
611 this->install_handler = v;
612 return *this;
613}
614namespace {
615std::mutex mtx;
616auto get_log_verbosity_from_broker(string current_name, char const* str, cci::cci_broker_handle const& broker, sc_core::sc_verbosity verb)
617 -> sc_core::sc_verbosity {
618 std::lock_guard<std::mutex> lk(mtx);
619 while(true) {
620 string param_name = (current_name.empty()) ? SCC_LOG_LEVEL_PARAM_NAME : current_name + "." SCC_LOG_LEVEL_PARAM_NAME;
621 auto h = broker.get_param_handle(param_name);
622 if(h.is_valid()) {
623 sc_core::sc_verbosity ret = verbosity.at(std::min<unsigned>(h.get_cci_value().get_int(), verbosity.size() - 1));
624 lut.insert(str, ret);
625 return ret;
626 } else {
627 auto val = broker.get_preset_cci_value(param_name);
628 if(val.is_int()) {
629 sc_core::sc_verbosity ret = verbosity.at(std::min<unsigned>(val.get_int(), verbosity.size() - 1));
630 lut.insert(str, ret);
631 return ret;
632 } else {
633 if(current_name.empty()) {
634 lut.insert(str, verb);
635 return verb;
636 }
637 auto pos = current_name.rfind(".");
638 if(pos == std::string::npos) {
639 current_name = "";
640 } else {
641 current_name = current_name.substr(0, pos);
642 }
643 }
644 }
645 }
646 return verb;
647}
648} // namespace
649
650auto scc::get_log_verbosity(char const* str) -> sc_core::sc_verbosity {
651 auto global_verb = verbosity[static_cast<unsigned>(log_cfg.level)];
652 if(inst_based_logging()) {
653 auto res = lut.get(str);
654 if(std::get<0>(res))
655 return std::get<1>(res);
656 auto* curr_object = sc_core::sc_get_current_object();
657 if(strchr(str, '.') == nullptr || curr_object) {
658 string current_name = std::string(str);
659 if(log_cfg.broker)
660 return get_log_verbosity_from_broker(current_name, str, log_cfg.broker.value(), global_verb);
661 else {
662 return get_log_verbosity_from_broker(
663 current_name, str, curr_object ? cci::cci_get_broker() : cci::cci_get_global_broker(originator), global_verb);
664 }
665 }
666 }
667 return global_verb;
668}
~stream_redirection()
destructor restoring the output stream buffer
Definition report.cpp:341
void reset()
reset the stream redirection and restore output buffer of the stream
Definition report.cpp:345
stream_redirection(std::ostream &os, log level)
constructor redirecting the given stream to a SystemC log message of given llog level
log_level
enum defining the log levels
Definition logging.h:53
std::string now_time()
Definition logging.h:328
SCC TLM utilities.
void set_logging_level(log level)
sets the SystemC logging level
Definition report.cpp:524
void init_logging(log level=log::WARNING, unsigned type_field_width=24, bool print_time=false)
initializes the SystemC logging system with a particular logging level
Definition report.cpp:510
bool is_logging_initialized()
get the state of the SCC logging system
Definition report.cpp:508
void set_cycle_base(sc_core::sc_time period)
sets the cycle base for cycle based logging
log get_logging_level()
get the SystemC logging level
Definition report.cpp:533
sc_core::sc_verbosity get_log_verbosity()
get the global verbosity level
Definition report.h:326
log
enum defining the log levels
Definition report.h:88
std::mutex verbosity_mtx
a mutex needed to syncronize verbosity manipulations
Definition report.cpp:333
std::string padded(std::string str, size_t width, bool show_ellipsis=true)
pad a string to a given length by either cutting of the overflow or inserting an ellipsis
Definition ities.h:413
the configuration class for the logging setup
Definition report.h:165
LogConfig & printSeverity(bool=true)
Definition report.cpp:562
LogConfig & printSysTime(bool=true)
Definition report.cpp:547
LogConfig & reportOnlyFirstError(bool=true)
Definition report.cpp:602
LogConfig & coloredOutput(bool=true)
Definition report.cpp:577
LogConfig & logFileName(std::string &&)
LogConfig & dontCreateBroker(bool=true)
Definition report.cpp:597
LogConfig & logLevel(log)
Definition report.cpp:537
LogConfig & msgTypeFieldWidth(unsigned)
Definition report.cpp:542
LogConfig & printSimTime(bool=true)
Definition report.cpp:552
LogConfig & logAsync(bool=true)
Definition report.cpp:592
LogConfig & printDelta(bool=true)
Definition report.cpp:557
LogConfig & instanceBasedLogLevels(bool=true)
Definition report.cpp:606
LogConfig & installHandler(bool=true)
Definition report.cpp:610
LogConfig & logFilterRegex(std::string &&)