在 使用set_handler过滤掉特定的SystemC Wraning &Error Message_123axj的博客-CSDN博客 中 我们使用 sc_report_handler ::set_handler 函数 来 改写 systemc原来的 report 函数,以达到过滤特点systemc warning 或error 的效果。
在查阅 systemC spec的过程中,发现有如下的描述:
An implementation or an application may choose to suppress run-time error checking and diagnostic messages because of considerations of efficiency or practicality. For example, an application may call member function set_actions of class sc_report_handler to take no action for certain categories of report. An application that fails to meet the obligations imposed by this standard remains in error.
尝试用 sc_core::sc_report_handler::set_actions 函数 来达到上述的过滤效果,结果是可行的。
替换代码如下,其中,sc_core::SC_ID_SIMULATION_START_UNEXPECTED_ 这个宏 就是E554的 string描述 : sc_start called unexpectedly。sc_core::SC_DO_NOTHING 表示 遇到 相应error 或 warning 的时候 不做任何处理 (默认情况下,warning 会 打印出提示信息,error 会 停止程序执行)。第2个参数 是 对应error/warning message的sc_severity,如果不想去systemc 源码中查 到底是 error 还是warning,则可以全部使用 sc_core::SC_ERROR,也就是更高level的sc_severity 。
int sc_main(int argc, char **argv)
{
TestPlatform *m_platform;
m_platform = new TestPlatform("TestPlatform");
sc_core::sc_report_handler::set_actions(sc_core::SC_ID_SIMULATION_START_UNEXPECTED_,
sc_core::SC_ERROR,
sc_core::SC_DO_NOTHING); // E554
sc_core::sc_report_handler::set_actions(sc_core::SC_ID_SIMULATION_START_AFTER_STOP_,
sc_core::SC_ERROR,
sc_core::SC_DO_NOTHING); // E546
sc_core::sc_report_handler::set_actions(sc_core::SC_ID_SIMULATION_STOP_CALLED_TWICE_,
sc_core::SC_WARNING,
sc_core::SC_DO_NOTHING); // W545
// sc_report_handler::set_handler(user_handler);
需要注意的是,E554 / E546 / W545 都是在 Simulation阶段的error/warning,调用set_actions函数的位置 可以写在 例化 top module 之后。如果 我们想 过滤掉 一个 elaboration 阶段的error/warning,则必须在例化 top module 之前 调用set_actions函数。
以下是一个 针对 W505 "object already exists" 的warning的 过滤代码。可以看到 如果 例化 top module 在前,调用set_actions在后,则依然会 打印 warning 信息,调换位置后,则不再报warning信息了。
对于W505,一般是 某一个 module 被例化多次造成的,可以使用 sc_core::sc_gen_unique_name(“your_name”) 来解决。
不使用 sc_core::sc_gen_unique_name 情况下,systemc 会自动给 module的不同实例的name赋值,第一个 被例化的实例 name 就是 用户定义的your_name,第二个实例的name会被赋值为 your_name_0,依次类推。如果使用sc_core::sc_gen_unique_name,则 第一个实例的name为 your_name_0,依次类推。
// execute:
// g++ -g -Wall -lsystemc -m64 -pthread main.cpp
// -L/$(your systemc path)/lib-linux64
// -I/$(your systemc path)/include -I/$(your systemc
// path)/src/tlm_utils -o sim
#define SC_INCLUDE_DYNAMIC_PROCESSES // must add this define
#include <systemc>
class MyBasic : public sc_core::sc_module
{
public:
SC_HAS_PROCESS(MyBasic); // must have this line
explicit MyBasic(sc_core::sc_module_name name)
: sc_core::sc_module(name)
{
SC_THREAD(BaiscThread);
}
void BaiscThread()
{
std::cout << this->name() << "\033[34m [" << sc_core::sc_time_stamp() << "]"
<< " \033[0m" << std::endl;
wait(1, sc_core::SC_NS);
}
};
class MyTop : public sc_core::sc_module
{
public:
SC_HAS_PROCESS(MyTop);
explicit MyTop(sc_core::sc_module_name name)
: sc_core::sc_module(name),
m_module("basic"),
m_module_1("basic")
{
}
MyBasic m_module;
MyBasic m_module_1;
};
int sc_main(int argc, char **argv)
{
// here must call set_actions before elaboration (MyTop constructor)
sc_core::sc_report_handler::set_actions(sc_core::SC_ID_INSTANCE_EXISTS_,
sc_core::SC_WARNING,
sc_core::SC_DO_NOTHING);
MyTop m_top_module("my_top_module");
sc_core::sc_start(20, sc_core::SC_NS);
return 0;
}
Warning: (W505) object already exists: my_top_module.basic. Latter declaration will be renamed to my_top_module.basic_0
In file: ../../../src/sysc/kernel/sc_object_manager.cpp:153
my_top_module.basic [0 s]
my_top_module.basic_0 [0 s]