| /* |
| * Copyright 2018 Google, Inc. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer; |
| * redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution; |
| * neither the name of the copyright holders nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * Authors: Gabe Black |
| */ |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/logging.hh" |
| #include "systemc/core/kernel.hh" |
| #include "systemc/core/module.hh" |
| #include "systemc/core/process_types.hh" |
| #include "systemc/ext/channel/sc_signal_in_if.hh" |
| #include "systemc/ext/core/sc_module.hh" |
| #include "systemc/ext/core/sc_module_name.hh" |
| #include "systemc/ext/dt/bit/sc_logic.hh" |
| #include "systemc/ext/utils/sc_report_handler.hh" |
| |
| namespace sc_gem5 |
| { |
| |
| Process * |
| newMethodProcess(const char *name, ProcessFuncWrapper *func) |
| { |
| Method *p = new Method(name, func); |
| if (::sc_core::sc_is_running()) { |
| std::string name = p->name(); |
| delete p; |
| SC_REPORT_ERROR("(E541) call to SC_METHOD in sc_module while " |
| "simulation running", name.c_str()); |
| return nullptr; |
| } |
| scheduler.reg(p); |
| return p; |
| } |
| |
| Process * |
| newThreadProcess(const char *name, ProcessFuncWrapper *func) |
| { |
| Thread *p = new Thread(name, func); |
| if (::sc_core::sc_is_running()) { |
| std::string name = p->name(); |
| delete p; |
| SC_REPORT_ERROR("(E542) call to SC_THREAD in sc_module while " |
| "simulation running", name.c_str()); |
| return nullptr; |
| } |
| scheduler.reg(p); |
| return p; |
| } |
| |
| Process * |
| newCThreadProcess(const char *name, ProcessFuncWrapper *func) |
| { |
| CThread *p = new CThread(name, func); |
| if (::sc_core::sc_is_running()) { |
| std::string name = p->name(); |
| delete p; |
| SC_REPORT_ERROR("(E543) call to SC_CTHREAD in sc_module while " |
| "simulation running", name.c_str()); |
| return nullptr; |
| } |
| scheduler.reg(p); |
| p->dontInitialize(true); |
| return p; |
| } |
| |
| UniqueNameGen nameGen; |
| |
| } // namespace sc_gem5 |
| |
| namespace sc_core |
| { |
| |
| sc_bind_proxy::sc_bind_proxy(sc_interface &_interface) : |
| _interface(&_interface), _port(nullptr) |
| {} |
| |
| sc_bind_proxy::sc_bind_proxy(sc_port_base &_port) : |
| _interface(nullptr), _port(&_port) |
| {} |
| |
| const sc_bind_proxy SC_BIND_PROXY_NUL(*(sc_port_base *)nullptr); |
| |
| sc_module::~sc_module() { delete _gem5_module; } |
| |
| const sc_bind_proxy SC_BIND_PROXY_NIL(*(sc_port_base *)nullptr); |
| |
| void |
| sc_module::operator () (const sc_bind_proxy &p001, |
| const sc_bind_proxy &p002, |
| const sc_bind_proxy &p003, |
| const sc_bind_proxy &p004, |
| const sc_bind_proxy &p005, |
| const sc_bind_proxy &p006, |
| const sc_bind_proxy &p007, |
| const sc_bind_proxy &p008, |
| const sc_bind_proxy &p009, |
| const sc_bind_proxy &p010, |
| const sc_bind_proxy &p011, |
| const sc_bind_proxy &p012, |
| const sc_bind_proxy &p013, |
| const sc_bind_proxy &p014, |
| const sc_bind_proxy &p015, |
| const sc_bind_proxy &p016, |
| const sc_bind_proxy &p017, |
| const sc_bind_proxy &p018, |
| const sc_bind_proxy &p019, |
| const sc_bind_proxy &p020, |
| const sc_bind_proxy &p021, |
| const sc_bind_proxy &p022, |
| const sc_bind_proxy &p023, |
| const sc_bind_proxy &p024, |
| const sc_bind_proxy &p025, |
| const sc_bind_proxy &p026, |
| const sc_bind_proxy &p027, |
| const sc_bind_proxy &p028, |
| const sc_bind_proxy &p029, |
| const sc_bind_proxy &p030, |
| const sc_bind_proxy &p031, |
| const sc_bind_proxy &p032, |
| const sc_bind_proxy &p033, |
| const sc_bind_proxy &p034, |
| const sc_bind_proxy &p035, |
| const sc_bind_proxy &p036, |
| const sc_bind_proxy &p037, |
| const sc_bind_proxy &p038, |
| const sc_bind_proxy &p039, |
| const sc_bind_proxy &p040, |
| const sc_bind_proxy &p041, |
| const sc_bind_proxy &p042, |
| const sc_bind_proxy &p043, |
| const sc_bind_proxy &p044, |
| const sc_bind_proxy &p045, |
| const sc_bind_proxy &p046, |
| const sc_bind_proxy &p047, |
| const sc_bind_proxy &p048, |
| const sc_bind_proxy &p049, |
| const sc_bind_proxy &p050, |
| const sc_bind_proxy &p051, |
| const sc_bind_proxy &p052, |
| const sc_bind_proxy &p053, |
| const sc_bind_proxy &p054, |
| const sc_bind_proxy &p055, |
| const sc_bind_proxy &p056, |
| const sc_bind_proxy &p057, |
| const sc_bind_proxy &p058, |
| const sc_bind_proxy &p059, |
| const sc_bind_proxy &p060, |
| const sc_bind_proxy &p061, |
| const sc_bind_proxy &p062, |
| const sc_bind_proxy &p063, |
| const sc_bind_proxy &p064) |
| { |
| std::vector<const ::sc_core::sc_bind_proxy *> proxies; |
| auto insert = [&proxies](const ::sc_core::sc_bind_proxy &p) -> bool { |
| if (!p.port() && !p.interface()) |
| return false; |
| proxies.push_back(&p); |
| return true; |
| }; |
| insert(p001) && insert(p002) && insert(p003) && insert(p004) && |
| insert(p005) && insert(p006) && insert(p007) && insert(p008) && |
| insert(p009) && insert(p010) && insert(p011) && insert(p012) && |
| insert(p013) && insert(p014) && insert(p015) && insert(p016) && |
| insert(p017) && insert(p018) && insert(p019) && insert(p020) && |
| insert(p021) && insert(p022) && insert(p023) && insert(p024) && |
| insert(p025) && insert(p026) && insert(p027) && insert(p028) && |
| insert(p029) && insert(p030) && insert(p031) && insert(p032) && |
| insert(p033) && insert(p034) && insert(p035) && insert(p036) && |
| insert(p037) && insert(p038) && insert(p039) && insert(p040) && |
| insert(p041) && insert(p042) && insert(p043) && insert(p044) && |
| insert(p045) && insert(p046) && insert(p047) && insert(p048) && |
| insert(p049) && insert(p050) && insert(p051) && insert(p052) && |
| insert(p053) && insert(p054) && insert(p055) && insert(p056) && |
| insert(p057) && insert(p058) && insert(p059) && insert(p060) && |
| insert(p061) && insert(p062) && insert(p063) && insert(p064); |
| _gem5_module->bindPorts(proxies); |
| } |
| |
| const std::vector<sc_object *> & |
| sc_module::get_child_objects() const |
| { |
| return _gem5_module->obj()->get_child_objects(); |
| } |
| |
| const std::vector<sc_event *> & |
| sc_module::get_child_events() const |
| { |
| return _gem5_module->obj()->get_child_events(); |
| } |
| |
| sc_module::sc_module() : |
| sc_object(sc_gem5::newModuleChecked()->name()), |
| _gem5_module(sc_gem5::currentModule()) |
| {} |
| |
| sc_module::sc_module(const sc_module_name &) : sc_module() {} |
| sc_module::sc_module(const char *_name) : sc_module(sc_module_name(_name)) |
| { |
| _gem5_module->deprecatedConstructor(); |
| SC_REPORT_WARNING("(W569) sc_module(const char*), " |
| "sc_module(const std::string&) have been deprecated, use " |
| "sc_module(const sc_module_name&)", _name); |
| } |
| sc_module::sc_module(const std::string &_name) : |
| sc_module(sc_module_name(_name.c_str())) |
| { |
| _gem5_module->deprecatedConstructor(); |
| SC_REPORT_WARNING("(W569) sc_module(const char*), " |
| "sc_module(const std::string&) have been deprecated, use " |
| "sc_module(const sc_module_name&)", _name.c_str()); |
| } |
| |
| void |
| sc_module::end_module() |
| { |
| _gem5_module->endModule(); |
| } |
| |
| void |
| sc_module::reset_signal_is(const sc_in<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| void |
| sc_module::reset_signal_is(const sc_inout<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| void |
| sc_module::reset_signal_is(const sc_out<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| void |
| sc_module::reset_signal_is(const sc_signal_in_if<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| |
| void |
| sc_module::async_reset_signal_is(const sc_in<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| void |
| sc_module::async_reset_signal_is(const sc_inout<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| void |
| sc_module::async_reset_signal_is(const sc_out<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| void |
| sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &, bool) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| } |
| |
| |
| void |
| sc_module::dont_initialize() |
| { |
| ::sc_gem5::Process::newest()->dontInitialize(true); |
| } |
| |
| void |
| sc_module::set_stack_size(size_t size) |
| { |
| ::sc_gem5::Process::newest()->setStackSize(size); |
| } |
| |
| |
| void sc_module::next_trigger() { ::sc_core::next_trigger(); } |
| |
| void |
| sc_module::next_trigger(const sc_event &e) |
| { |
| ::sc_core::next_trigger(e); |
| } |
| |
| void |
| sc_module::next_trigger(const sc_event_or_list &eol) |
| { |
| ::sc_core::next_trigger(eol); |
| } |
| |
| void |
| sc_module::next_trigger(const sc_event_and_list &eal) |
| { |
| ::sc_core::next_trigger(eal); |
| } |
| |
| void |
| sc_module::next_trigger(const sc_time &t) |
| { |
| ::sc_core::next_trigger(t); |
| } |
| |
| void |
| sc_module::next_trigger(double d, sc_time_unit u) |
| { |
| ::sc_core::next_trigger(d, u); |
| } |
| |
| void |
| sc_module::next_trigger(const sc_time &t, const sc_event &e) |
| { |
| ::sc_core::next_trigger(t, e); |
| } |
| |
| void |
| sc_module::next_trigger(double d, sc_time_unit u, const sc_event &e) |
| { |
| ::sc_core::next_trigger(d, u, e); |
| } |
| |
| void |
| sc_module::next_trigger(const sc_time &t, const sc_event_or_list &eol) |
| { |
| ::sc_core::next_trigger(t, eol); |
| } |
| |
| void |
| sc_module::next_trigger(double d, sc_time_unit u, const sc_event_or_list &eol) |
| { |
| ::sc_core::next_trigger(d, u, eol); |
| } |
| |
| void |
| sc_module::next_trigger(const sc_time &t, const sc_event_and_list &eal) |
| { |
| ::sc_core::next_trigger(t, eal); |
| } |
| |
| void |
| sc_module::next_trigger(double d, sc_time_unit u, const sc_event_and_list &eal) |
| { |
| ::sc_core::next_trigger(d, u, eal); |
| } |
| |
| |
| bool |
| sc_module::timed_out() |
| { |
| return ::sc_core::timed_out(); |
| } |
| |
| |
| void |
| sc_module::wait() |
| { |
| ::sc_core::wait(); |
| } |
| |
| void |
| sc_module::wait(int i) |
| { |
| ::sc_core::wait(i); |
| } |
| |
| void |
| sc_module::wait(const sc_event &e) |
| { |
| ::sc_core::wait(e); |
| } |
| |
| void |
| sc_module::wait(const sc_event_or_list &eol) |
| { |
| ::sc_core::wait(eol); |
| } |
| |
| void |
| sc_module::wait(const sc_event_and_list &eal) |
| { |
| ::sc_core::wait(eal); |
| } |
| |
| void |
| sc_module::wait(const sc_time &t) |
| { |
| ::sc_core::wait(t); |
| } |
| |
| void |
| sc_module::wait(double d, sc_time_unit u) |
| { |
| ::sc_core::wait(d, u); |
| } |
| |
| void |
| sc_module::wait(const sc_time &t, const sc_event &e) |
| { |
| ::sc_core::wait(t, e); |
| } |
| |
| void |
| sc_module::wait(double d, sc_time_unit u, const sc_event &e) |
| { |
| ::sc_core::wait(d, u, e); |
| } |
| |
| void |
| sc_module::wait(const sc_time &t, const sc_event_or_list &eol) |
| { |
| ::sc_core::wait(t, eol); |
| } |
| |
| void |
| sc_module::wait(double d, sc_time_unit u, const sc_event_or_list &eol) |
| { |
| ::sc_core::wait(d, u, eol); |
| } |
| |
| void |
| sc_module::wait(const sc_time &t, const sc_event_and_list &eal) |
| { |
| ::sc_core::wait(t, eal); |
| } |
| |
| void |
| sc_module::wait(double d, sc_time_unit u, const sc_event_and_list &eal) |
| { |
| ::sc_core::wait(d, u, eal); |
| } |
| |
| |
| void |
| sc_module::halt() |
| { |
| ::sc_core::halt(); |
| } |
| |
| void |
| sc_module::at_posedge(const sc_signal_in_if<bool> &s) |
| { |
| ::sc_core::at_posedge(s); |
| } |
| |
| void |
| sc_module::at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &s) |
| { |
| ::sc_core::at_posedge(s); |
| } |
| |
| void |
| sc_module::at_negedge(const sc_signal_in_if<bool> &s) |
| { |
| ::sc_core::at_negedge(s); |
| } |
| |
| void |
| sc_module::at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &s) |
| { |
| ::sc_core::at_negedge(s); |
| } |
| |
| |
| void |
| next_trigger() |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| p->clearDynamic(); |
| } |
| |
| void |
| next_trigger(const sc_event &e) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| ::sc_gem5::newDynamicSensitivityEvent(p, &e); |
| } |
| |
| void |
| next_trigger(const sc_event_or_list &eol) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); |
| } |
| |
| void |
| next_trigger(const sc_event_and_list &eal) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); |
| } |
| |
| void |
| next_trigger(const sc_time &t) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| p->clearDynamic(); |
| } |
| |
| void |
| next_trigger(double d, sc_time_unit u) |
| { |
| next_trigger(sc_time(d, u)); |
| } |
| |
| void |
| next_trigger(const sc_time &t, const sc_event &e) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| ::sc_gem5::newDynamicSensitivityEvent(p, &e); |
| } |
| |
| void |
| next_trigger(double d, sc_time_unit u, const sc_event &e) |
| { |
| next_trigger(sc_time(d, u), e); |
| } |
| |
| void |
| next_trigger(const sc_time &t, const sc_event_or_list &eol) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); |
| } |
| |
| void |
| next_trigger(double d, sc_time_unit u, const sc_event_or_list &eol) |
| { |
| next_trigger(sc_time(d, u), eol); |
| } |
| |
| void |
| next_trigger(const sc_time &t, const sc_event_and_list &eal) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); |
| } |
| |
| void |
| next_trigger(double d, sc_time_unit u, const sc_event_and_list &eal) |
| { |
| next_trigger(sc_time(d, u), eal); |
| } |
| |
| bool |
| timed_out() |
| { |
| ::sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| if (!p) |
| return false; |
| else |
| return p->timedOut(); |
| } |
| |
| |
| void |
| wait() |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| p->clearDynamic(); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(int n) |
| { |
| if (n <= 0) { |
| std::string msg = csprintf("n = %d", n); |
| SC_REPORT_ERROR("(E525) wait(n) is only valid for n > 0", msg.c_str()); |
| } |
| for (int i = 0; i < n; i++) |
| wait(); |
| } |
| |
| void |
| wait(const sc_event &e) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| ::sc_gem5::newDynamicSensitivityEvent(p, &e); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(const sc_event_or_list &eol) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(const sc_event_and_list &eal) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->cancelTimeout(); |
| ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(const sc_time &t) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| p->clearDynamic(); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(double d, sc_time_unit u) |
| { |
| wait(sc_time(d, u)); |
| } |
| |
| void |
| wait(const sc_time &t, const sc_event &e) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| ::sc_gem5::newDynamicSensitivityEvent(p, &e); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(double d, sc_time_unit u, const sc_event &e) |
| { |
| wait(sc_time(d, u), e); |
| } |
| |
| void |
| wait(const sc_time &t, const sc_event_or_list &eol) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(double d, sc_time_unit u, const sc_event_or_list &eol) |
| { |
| wait(sc_time(d, u), eol); |
| } |
| |
| void |
| wait(const sc_time &t, const sc_event_and_list &eal) |
| { |
| sc_gem5::Process *p = sc_gem5::scheduler.current(); |
| p->setTimeout(t); |
| ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); |
| sc_gem5::scheduler.yield(); |
| } |
| |
| void |
| wait(double d, sc_time_unit u, const sc_event_and_list &eal) |
| { |
| wait(sc_time(d, u), eal); |
| } |
| |
| void |
| halt() |
| { |
| ::sc_core::wait(); |
| throw ::sc_gem5::ScHalt(); |
| } |
| |
| void |
| at_posedge(const sc_signal_in_if<bool> &s) |
| { |
| while (s.read()) |
| wait(); |
| while (!s.read()) |
| wait(); |
| } |
| |
| void |
| at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &s) |
| { |
| while (s.read() == sc_dt::Log_1) |
| wait(); |
| while (s.read() == sc_dt::Log_0) |
| wait(); |
| } |
| |
| void |
| at_negedge(const sc_signal_in_if<bool> &s) |
| { |
| while (!s.read()) |
| wait(); |
| while (s.read()) |
| wait(); |
| } |
| |
| void |
| at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &s) |
| { |
| while (s.read() == sc_dt::Log_0) |
| wait(); |
| while (s.read() == sc_dt::Log_1) |
| wait(); |
| } |
| |
| const char * |
| sc_gen_unique_name(const char *seed) |
| { |
| ::sc_gem5::Module *mod = ::sc_gem5::currentModule(); |
| return mod ? mod->uniqueName(seed) : |
| ::sc_gem5::nameGen.gen(seed); |
| } |
| |
| bool |
| sc_hierarchical_name_exists(const char *name) |
| { |
| warn("%s not implemented.\n", __PRETTY_FUNCTION__); |
| return false; |
| } |
| |
| bool |
| sc_start_of_simulation_invoked() |
| { |
| return ::sc_gem5::kernel->startOfSimulationComplete(); |
| } |
| |
| bool |
| sc_end_of_simulation_invoked() |
| { |
| return ::sc_gem5::kernel->endOfSimulationComplete(); |
| } |
| |
| sc_module * |
| sc_module_sc_new(sc_module *mod) |
| { |
| static std::vector<std::unique_ptr<sc_module> > modules; |
| modules.emplace_back(mod); |
| return mod; |
| } |
| |
| } // namespace sc_core |