sc_module.cc revision 13288
112839Sgabeblack@google.com/*
212839Sgabeblack@google.com * Copyright 2018 Google, Inc.
312839Sgabeblack@google.com *
412839Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
512839Sgabeblack@google.com * modification, are permitted provided that the following conditions are
612839Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
712839Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
812839Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
912839Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1012839Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1112839Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1212839Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1312839Sgabeblack@google.com * this software without specific prior written permission.
1412839Sgabeblack@google.com *
1512839Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612839Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712839Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812839Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912839Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012839Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112839Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212839Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312839Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412839Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512839Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612839Sgabeblack@google.com *
2712839Sgabeblack@google.com * Authors: Gabe Black
2812839Sgabeblack@google.com */
2912839Sgabeblack@google.com
3012839Sgabeblack@google.com#include <memory>
3112839Sgabeblack@google.com#include <string>
3212839Sgabeblack@google.com#include <vector>
3312839Sgabeblack@google.com
3412839Sgabeblack@google.com#include "base/logging.hh"
3512839Sgabeblack@google.com#include "systemc/core/event.hh"
3612839Sgabeblack@google.com#include "systemc/core/kernel.hh"
3712839Sgabeblack@google.com#include "systemc/core/module.hh"
3812839Sgabeblack@google.com#include "systemc/core/object.hh"
3912839Sgabeblack@google.com#include "systemc/core/port.hh"
4012839Sgabeblack@google.com#include "systemc/core/process_types.hh"
4112839Sgabeblack@google.com#include "systemc/core/sensitivity.hh"
4212839Sgabeblack@google.com#include "systemc/ext/channel/sc_in.hh"
4312839Sgabeblack@google.com#include "systemc/ext/channel/sc_inout.hh"
4412839Sgabeblack@google.com#include "systemc/ext/channel/sc_out.hh"
4512839Sgabeblack@google.com#include "systemc/ext/channel/sc_signal_in_if.hh"
4612839Sgabeblack@google.com#include "systemc/ext/core/sc_module.hh"
4712839Sgabeblack@google.com#include "systemc/ext/core/sc_module_name.hh"
4812839Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_logic.hh"
4912839Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh"
5012839Sgabeblack@google.com
5112839Sgabeblack@google.comnamespace sc_gem5
5212839Sgabeblack@google.com{
5312839Sgabeblack@google.com
5412839Sgabeblack@google.comProcess *
5512839Sgabeblack@google.comnewMethodProcess(const char *name, ProcessFuncWrapper *func)
5612839Sgabeblack@google.com{
5712839Sgabeblack@google.com    Method *p = new Method(name, func);
5812839Sgabeblack@google.com    if (::sc_core::sc_is_running()) {
5912839Sgabeblack@google.com        std::string name = p->name();
6012839Sgabeblack@google.com        delete p;
6112839Sgabeblack@google.com        SC_REPORT_ERROR("(E541) call to SC_METHOD in sc_module while "
6212839Sgabeblack@google.com                "simulation running", name.c_str());
6312839Sgabeblack@google.com        return nullptr;
6412839Sgabeblack@google.com    }
6512839Sgabeblack@google.com    scheduler.reg(p);
6612839Sgabeblack@google.com    return p;
6712839Sgabeblack@google.com}
6812839Sgabeblack@google.com
6912839Sgabeblack@google.comProcess *
7012839Sgabeblack@google.comnewThreadProcess(const char *name, ProcessFuncWrapper *func)
7112839Sgabeblack@google.com{
7212839Sgabeblack@google.com    Thread *p = new Thread(name, func);
7312839Sgabeblack@google.com    if (::sc_core::sc_is_running()) {
7412839Sgabeblack@google.com        std::string name = p->name();
7512839Sgabeblack@google.com        delete p;
7612839Sgabeblack@google.com        SC_REPORT_ERROR("(E542) call to SC_THREAD in sc_module while "
7712839Sgabeblack@google.com                "simulation running", name.c_str());
7812839Sgabeblack@google.com        return nullptr;
7912839Sgabeblack@google.com    }
8012839Sgabeblack@google.com    scheduler.reg(p);
8112839Sgabeblack@google.com    return p;
8212839Sgabeblack@google.com}
8312839Sgabeblack@google.com
8412839Sgabeblack@google.comProcess *
8512839Sgabeblack@google.comnewCThreadProcess(const char *name, ProcessFuncWrapper *func)
8612839Sgabeblack@google.com{
8712839Sgabeblack@google.com    CThread *p = new CThread(name, func);
8812839Sgabeblack@google.com    if (::sc_core::sc_is_running()) {
8912839Sgabeblack@google.com        std::string name = p->name();
9012839Sgabeblack@google.com        delete p;
9112839Sgabeblack@google.com        SC_REPORT_ERROR("(E543) call to SC_CTHREAD in sc_module while "
9212839Sgabeblack@google.com                "simulation running", name.c_str());
9312839Sgabeblack@google.com        return nullptr;
9412839Sgabeblack@google.com    }
9512839Sgabeblack@google.com    scheduler.reg(p);
9612839Sgabeblack@google.com    p->dontInitialize(true);
9712839Sgabeblack@google.com    return p;
9812839Sgabeblack@google.com}
9912839Sgabeblack@google.com
10012839Sgabeblack@google.comUniqueNameGen nameGen;
10112839Sgabeblack@google.com
10212839Sgabeblack@google.com} // namespace sc_gem5
10312839Sgabeblack@google.com
10412839Sgabeblack@google.comnamespace sc_core
10512839Sgabeblack@google.com{
10612839Sgabeblack@google.com
10712839Sgabeblack@google.comsc_bind_proxy::sc_bind_proxy(sc_interface &_interface) :
10812839Sgabeblack@google.com    _interface(&_interface), _port(nullptr)
10912839Sgabeblack@google.com{}
11012839Sgabeblack@google.com
11112839Sgabeblack@google.comsc_bind_proxy::sc_bind_proxy(sc_port_base &_port) :
11212839Sgabeblack@google.com    _interface(nullptr), _port(&_port)
11312839Sgabeblack@google.com{}
11412839Sgabeblack@google.com
11512839Sgabeblack@google.comconst sc_bind_proxy SC_BIND_PROXY_NUL(*(sc_port_base *)nullptr);
11612839Sgabeblack@google.com
11712839Sgabeblack@google.comsc_module::~sc_module() { delete _gem5_module; }
11812839Sgabeblack@google.com
11912839Sgabeblack@google.comconst sc_bind_proxy SC_BIND_PROXY_NIL(*(sc_port_base *)nullptr);
12012839Sgabeblack@google.com
12112839Sgabeblack@google.comvoid
12212839Sgabeblack@google.comsc_module::operator () (const sc_bind_proxy &p001,
12312839Sgabeblack@google.com                        const sc_bind_proxy &p002,
12412839Sgabeblack@google.com                        const sc_bind_proxy &p003,
12512839Sgabeblack@google.com                        const sc_bind_proxy &p004,
12612839Sgabeblack@google.com                        const sc_bind_proxy &p005,
12712839Sgabeblack@google.com                        const sc_bind_proxy &p006,
12812839Sgabeblack@google.com                        const sc_bind_proxy &p007,
12912839Sgabeblack@google.com                        const sc_bind_proxy &p008,
13012839Sgabeblack@google.com                        const sc_bind_proxy &p009,
13112839Sgabeblack@google.com                        const sc_bind_proxy &p010,
13212839Sgabeblack@google.com                        const sc_bind_proxy &p011,
13312839Sgabeblack@google.com                        const sc_bind_proxy &p012,
13412839Sgabeblack@google.com                        const sc_bind_proxy &p013,
13512839Sgabeblack@google.com                        const sc_bind_proxy &p014,
13612839Sgabeblack@google.com                        const sc_bind_proxy &p015,
13712839Sgabeblack@google.com                        const sc_bind_proxy &p016,
13812839Sgabeblack@google.com                        const sc_bind_proxy &p017,
13912839Sgabeblack@google.com                        const sc_bind_proxy &p018,
14012839Sgabeblack@google.com                        const sc_bind_proxy &p019,
14112839Sgabeblack@google.com                        const sc_bind_proxy &p020,
14212839Sgabeblack@google.com                        const sc_bind_proxy &p021,
14312839Sgabeblack@google.com                        const sc_bind_proxy &p022,
14412839Sgabeblack@google.com                        const sc_bind_proxy &p023,
14512839Sgabeblack@google.com                        const sc_bind_proxy &p024,
14612839Sgabeblack@google.com                        const sc_bind_proxy &p025,
14712839Sgabeblack@google.com                        const sc_bind_proxy &p026,
14812839Sgabeblack@google.com                        const sc_bind_proxy &p027,
14912839Sgabeblack@google.com                        const sc_bind_proxy &p028,
15012839Sgabeblack@google.com                        const sc_bind_proxy &p029,
15112839Sgabeblack@google.com                        const sc_bind_proxy &p030,
15212839Sgabeblack@google.com                        const sc_bind_proxy &p031,
15312839Sgabeblack@google.com                        const sc_bind_proxy &p032,
15412839Sgabeblack@google.com                        const sc_bind_proxy &p033,
15512839Sgabeblack@google.com                        const sc_bind_proxy &p034,
15612839Sgabeblack@google.com                        const sc_bind_proxy &p035,
15712839Sgabeblack@google.com                        const sc_bind_proxy &p036,
15812839Sgabeblack@google.com                        const sc_bind_proxy &p037,
15912839Sgabeblack@google.com                        const sc_bind_proxy &p038,
16012839Sgabeblack@google.com                        const sc_bind_proxy &p039,
16112839Sgabeblack@google.com                        const sc_bind_proxy &p040,
16212839Sgabeblack@google.com                        const sc_bind_proxy &p041,
16312839Sgabeblack@google.com                        const sc_bind_proxy &p042,
164                        const sc_bind_proxy &p043,
165                        const sc_bind_proxy &p044,
166                        const sc_bind_proxy &p045,
167                        const sc_bind_proxy &p046,
168                        const sc_bind_proxy &p047,
169                        const sc_bind_proxy &p048,
170                        const sc_bind_proxy &p049,
171                        const sc_bind_proxy &p050,
172                        const sc_bind_proxy &p051,
173                        const sc_bind_proxy &p052,
174                        const sc_bind_proxy &p053,
175                        const sc_bind_proxy &p054,
176                        const sc_bind_proxy &p055,
177                        const sc_bind_proxy &p056,
178                        const sc_bind_proxy &p057,
179                        const sc_bind_proxy &p058,
180                        const sc_bind_proxy &p059,
181                        const sc_bind_proxy &p060,
182                        const sc_bind_proxy &p061,
183                        const sc_bind_proxy &p062,
184                        const sc_bind_proxy &p063,
185                        const sc_bind_proxy &p064)
186{
187    std::vector<const ::sc_core::sc_bind_proxy *> proxies;
188    auto insert = [&proxies](const ::sc_core::sc_bind_proxy &p) -> bool {
189        if (!p.port() && !p.interface())
190            return false;
191        proxies.push_back(&p);
192        return true;
193    };
194    insert(p001) && insert(p002) && insert(p003) && insert(p004) &&
195    insert(p005) && insert(p006) && insert(p007) && insert(p008) &&
196    insert(p009) && insert(p010) && insert(p011) && insert(p012) &&
197    insert(p013) && insert(p014) && insert(p015) && insert(p016) &&
198    insert(p017) && insert(p018) && insert(p019) && insert(p020) &&
199    insert(p021) && insert(p022) && insert(p023) && insert(p024) &&
200    insert(p025) && insert(p026) && insert(p027) && insert(p028) &&
201    insert(p029) && insert(p030) && insert(p031) && insert(p032) &&
202    insert(p033) && insert(p034) && insert(p035) && insert(p036) &&
203    insert(p037) && insert(p038) && insert(p039) && insert(p040) &&
204    insert(p041) && insert(p042) && insert(p043) && insert(p044) &&
205    insert(p045) && insert(p046) && insert(p047) && insert(p048) &&
206    insert(p049) && insert(p050) && insert(p051) && insert(p052) &&
207    insert(p053) && insert(p054) && insert(p055) && insert(p056) &&
208    insert(p057) && insert(p058) && insert(p059) && insert(p060) &&
209    insert(p061) && insert(p062) && insert(p063) && insert(p064);
210    _gem5_module->bindPorts(proxies);
211}
212
213const std::vector<sc_object *> &
214sc_module::get_child_objects() const
215{
216    return _gem5_module->obj()->get_child_objects();
217}
218
219const std::vector<sc_event *> &
220sc_module::get_child_events() const
221{
222    return _gem5_module->obj()->get_child_events();
223}
224
225sc_module::sc_module() :
226    sc_object(sc_gem5::newModuleChecked()->name()),
227    _gem5_module(sc_gem5::currentModule())
228{
229    if (sc_is_running()) {
230        SC_REPORT_ERROR("(E529) insert module failed", "simulation running");
231        std::cout << "Running!\n";
232    }
233    if (::sc_gem5::scheduler.elaborationDone()) {
234        SC_REPORT_ERROR("(E529) insert module failed", "elaboration done");
235        std::cout << "Elaboration done!\n";
236    }
237}
238
239sc_module::sc_module(const sc_module_name &) : sc_module() {}
240sc_module::sc_module(const char *_name) : sc_module(sc_module_name(_name))
241{
242    _gem5_module->deprecatedConstructor();
243    SC_REPORT_WARNING("(W569) sc_module(const char*), "
244            "sc_module(const std::string&) have been deprecated, use "
245            "sc_module(const sc_module_name&)", _name);
246}
247sc_module::sc_module(const std::string &_name) :
248    sc_module(sc_module_name(_name.c_str()))
249{
250    _gem5_module->deprecatedConstructor();
251    SC_REPORT_WARNING("(W569) sc_module(const char*), "
252            "sc_module(const std::string&) have been deprecated, use "
253            "sc_module(const sc_module_name&)", _name.c_str());
254}
255
256void
257sc_module::end_module()
258{
259    _gem5_module->endModule();
260}
261
262void
263sc_module::reset_signal_is(const sc_in<bool> &port, bool val)
264{
265    ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val);
266}
267
268void
269sc_module::reset_signal_is(const sc_inout<bool> &port, bool val)
270{
271    ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val);
272}
273
274void
275sc_module::reset_signal_is(const sc_out<bool> &port, bool val)
276{
277    ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val);
278}
279
280void
281sc_module::reset_signal_is(const sc_signal_in_if<bool> &signal, bool val)
282{
283    ::sc_gem5::newReset(&signal, ::sc_gem5::Process::newest(), true, val);
284}
285
286
287void
288sc_module::async_reset_signal_is(const sc_in<bool> &port, bool val)
289{
290    ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val);
291}
292
293void
294sc_module::async_reset_signal_is(const sc_inout<bool> &port, bool val)
295{
296    ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val);
297}
298
299void
300sc_module::async_reset_signal_is(const sc_out<bool> &port, bool val)
301{
302    ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val);
303}
304
305void
306sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &signal, bool val)
307{
308    ::sc_gem5::newReset(&signal, ::sc_gem5::Process::newest(), false, val);
309}
310
311
312void
313sc_module::dont_initialize()
314{
315    ::sc_gem5::Process::newest()->dontInitialize(true);
316}
317
318void
319sc_module::set_stack_size(size_t size)
320{
321    ::sc_gem5::Process::newest()->setStackSize(size);
322}
323
324
325void sc_module::next_trigger() { ::sc_core::next_trigger(); }
326
327void
328sc_module::next_trigger(const sc_event &e)
329{
330    ::sc_core::next_trigger(e);
331}
332
333void
334sc_module::next_trigger(const sc_event_or_list &eol)
335{
336    ::sc_core::next_trigger(eol);
337}
338
339void
340sc_module::next_trigger(const sc_event_and_list &eal)
341{
342    ::sc_core::next_trigger(eal);
343}
344
345void
346sc_module::next_trigger(const sc_time &t)
347{
348    ::sc_core::next_trigger(t);
349}
350
351void
352sc_module::next_trigger(double d, sc_time_unit u)
353{
354    ::sc_core::next_trigger(d, u);
355}
356
357void
358sc_module::next_trigger(const sc_time &t, const sc_event &e)
359{
360    ::sc_core::next_trigger(t, e);
361}
362
363void
364sc_module::next_trigger(double d, sc_time_unit u, const sc_event &e)
365{
366    ::sc_core::next_trigger(d, u, e);
367}
368
369void
370sc_module::next_trigger(const sc_time &t, const sc_event_or_list &eol)
371{
372    ::sc_core::next_trigger(t, eol);
373}
374
375void
376sc_module::next_trigger(double d, sc_time_unit u, const sc_event_or_list &eol)
377{
378    ::sc_core::next_trigger(d, u, eol);
379}
380
381void
382sc_module::next_trigger(const sc_time &t, const sc_event_and_list &eal)
383{
384    ::sc_core::next_trigger(t, eal);
385}
386
387void
388sc_module::next_trigger(double d, sc_time_unit u, const sc_event_and_list &eal)
389{
390    ::sc_core::next_trigger(d, u, eal);
391}
392
393
394bool
395sc_module::timed_out()
396{
397    return ::sc_core::timed_out();
398}
399
400
401void
402sc_module::wait()
403{
404    ::sc_core::wait();
405}
406
407void
408sc_module::wait(int i)
409{
410    ::sc_core::wait(i);
411}
412
413void
414sc_module::wait(const sc_event &e)
415{
416    ::sc_core::wait(e);
417}
418
419void
420sc_module::wait(const sc_event_or_list &eol)
421{
422    ::sc_core::wait(eol);
423}
424
425void
426sc_module::wait(const sc_event_and_list &eal)
427{
428    ::sc_core::wait(eal);
429}
430
431void
432sc_module::wait(const sc_time &t)
433{
434    ::sc_core::wait(t);
435}
436
437void
438sc_module::wait(double d, sc_time_unit u)
439{
440    ::sc_core::wait(d, u);
441}
442
443void
444sc_module::wait(const sc_time &t, const sc_event &e)
445{
446    ::sc_core::wait(t, e);
447}
448
449void
450sc_module::wait(double d, sc_time_unit u, const sc_event &e)
451{
452    ::sc_core::wait(d, u, e);
453}
454
455void
456sc_module::wait(const sc_time &t, const sc_event_or_list &eol)
457{
458    ::sc_core::wait(t, eol);
459}
460
461void
462sc_module::wait(double d, sc_time_unit u, const sc_event_or_list &eol)
463{
464    ::sc_core::wait(d, u, eol);
465}
466
467void
468sc_module::wait(const sc_time &t, const sc_event_and_list &eal)
469{
470    ::sc_core::wait(t, eal);
471}
472
473void
474sc_module::wait(double d, sc_time_unit u, const sc_event_and_list &eal)
475{
476    ::sc_core::wait(d, u, eal);
477}
478
479
480void
481sc_module::halt()
482{
483    ::sc_core::halt();
484}
485
486void
487sc_module::at_posedge(const sc_signal_in_if<bool> &s)
488{
489    ::sc_core::at_posedge(s);
490}
491
492void
493sc_module::at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &s)
494{
495    ::sc_core::at_posedge(s);
496}
497
498void
499sc_module::at_negedge(const sc_signal_in_if<bool> &s)
500{
501    ::sc_core::at_negedge(s);
502}
503
504void
505sc_module::at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &s)
506{
507    ::sc_core::at_negedge(s);
508}
509
510
511void
512next_trigger()
513{
514    sc_gem5::Process *p = sc_gem5::scheduler.current();
515    p->cancelTimeout();
516    p->clearDynamic();
517}
518
519void
520next_trigger(const sc_event &e)
521{
522    sc_gem5::Process *p = sc_gem5::scheduler.current();
523    p->cancelTimeout();
524    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
525}
526
527void
528next_trigger(const sc_event_or_list &eol)
529{
530    sc_gem5::Process *p = sc_gem5::scheduler.current();
531    p->cancelTimeout();
532    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
533}
534
535void
536next_trigger(const sc_event_and_list &eal)
537{
538    sc_gem5::Process *p = sc_gem5::scheduler.current();
539    p->cancelTimeout();
540    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
541}
542
543void
544next_trigger(const sc_time &t)
545{
546    sc_gem5::Process *p = sc_gem5::scheduler.current();
547    p->setTimeout(t);
548    p->clearDynamic();
549}
550
551void
552next_trigger(double d, sc_time_unit u)
553{
554    next_trigger(sc_time(d, u));
555}
556
557void
558next_trigger(const sc_time &t, const sc_event &e)
559{
560    sc_gem5::Process *p = sc_gem5::scheduler.current();
561    p->setTimeout(t);
562    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
563}
564
565void
566next_trigger(double d, sc_time_unit u, const sc_event &e)
567{
568    next_trigger(sc_time(d, u), e);
569}
570
571void
572next_trigger(const sc_time &t, const sc_event_or_list &eol)
573{
574    sc_gem5::Process *p = sc_gem5::scheduler.current();
575    p->setTimeout(t);
576    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
577}
578
579void
580next_trigger(double d, sc_time_unit u, const sc_event_or_list &eol)
581{
582    next_trigger(sc_time(d, u), eol);
583}
584
585void
586next_trigger(const sc_time &t, const sc_event_and_list &eal)
587{
588    sc_gem5::Process *p = sc_gem5::scheduler.current();
589    p->setTimeout(t);
590    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
591}
592
593void
594next_trigger(double d, sc_time_unit u, const sc_event_and_list &eal)
595{
596    next_trigger(sc_time(d, u), eal);
597}
598
599bool
600timed_out()
601{
602    ::sc_gem5::Process *p = sc_gem5::scheduler.current();
603    if (!p)
604        return false;
605    else
606        return p->timedOut();
607}
608
609
610namespace
611{
612
613bool
614waitErrorCheck(sc_gem5::Process *p)
615{
616    if (p->procKind() == SC_METHOD_PROC_) {
617        SC_REPORT_ERROR(
618                "(E519) wait() is only allowed in SC_THREADs and SC_CTHREADs",
619                "\n        in SC_METHODs use next_trigger() instead");
620        return true;
621    }
622    return false;
623}
624
625} // anonymous namespace
626
627void
628wait()
629{
630    sc_gem5::Process *p = sc_gem5::scheduler.current();
631    if (waitErrorCheck(p))
632        return;
633    p->cancelTimeout();
634    p->clearDynamic();
635    sc_gem5::scheduler.yield();
636}
637
638void
639wait(int n)
640{
641    if (n <= 0) {
642        std::string msg = csprintf("n = %d", n);
643        SC_REPORT_ERROR("(E525) wait(n) is only valid for n > 0", msg.c_str());
644    }
645    sc_gem5::Process *p = sc_gem5::scheduler.current();
646    p->waitCount(n - 1);
647    wait();
648}
649
650void
651wait(const sc_event &e)
652{
653    sc_gem5::Process *p = sc_gem5::scheduler.current();
654    if (waitErrorCheck(p))
655        return;
656    p->cancelTimeout();
657    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
658    sc_gem5::scheduler.yield();
659}
660
661void
662wait(const sc_event_or_list &eol)
663{
664    sc_gem5::Process *p = sc_gem5::scheduler.current();
665    if (waitErrorCheck(p))
666        return;
667    p->cancelTimeout();
668    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
669    sc_gem5::scheduler.yield();
670}
671
672void
673wait(const sc_event_and_list &eal)
674{
675    sc_gem5::Process *p = sc_gem5::scheduler.current();
676    if (waitErrorCheck(p))
677        return;
678    p->cancelTimeout();
679    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
680    sc_gem5::scheduler.yield();
681}
682
683void
684wait(const sc_time &t)
685{
686    sc_gem5::Process *p = sc_gem5::scheduler.current();
687    if (waitErrorCheck(p))
688        return;
689    p->setTimeout(t);
690    p->clearDynamic();
691    sc_gem5::scheduler.yield();
692}
693
694void
695wait(double d, sc_time_unit u)
696{
697    wait(sc_time(d, u));
698}
699
700void
701wait(const sc_time &t, const sc_event &e)
702{
703    sc_gem5::Process *p = sc_gem5::scheduler.current();
704    if (waitErrorCheck(p))
705        return;
706    p->setTimeout(t);
707    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
708    sc_gem5::scheduler.yield();
709}
710
711void
712wait(double d, sc_time_unit u, const sc_event &e)
713{
714    wait(sc_time(d, u), e);
715}
716
717void
718wait(const sc_time &t, const sc_event_or_list &eol)
719{
720    sc_gem5::Process *p = sc_gem5::scheduler.current();
721    if (waitErrorCheck(p))
722        return;
723    p->setTimeout(t);
724    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
725    sc_gem5::scheduler.yield();
726}
727
728void
729wait(double d, sc_time_unit u, const sc_event_or_list &eol)
730{
731    wait(sc_time(d, u), eol);
732}
733
734void
735wait(const sc_time &t, const sc_event_and_list &eal)
736{
737    sc_gem5::Process *p = sc_gem5::scheduler.current();
738    if (waitErrorCheck(p))
739        return;
740    p->setTimeout(t);
741    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
742    sc_gem5::scheduler.yield();
743}
744
745void
746wait(double d, sc_time_unit u, const sc_event_and_list &eal)
747{
748    wait(sc_time(d, u), eal);
749}
750
751void
752halt()
753{
754    ::sc_core::wait();
755    throw ::sc_gem5::ScHalt();
756}
757
758void
759at_posedge(const sc_signal_in_if<bool> &s)
760{
761    while (s.read())
762        wait();
763    while (!s.read())
764        wait();
765}
766
767void
768at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &s)
769{
770    while (s.read() == sc_dt::Log_1)
771        wait();
772    while (s.read() == sc_dt::Log_0)
773        wait();
774}
775
776void
777at_negedge(const sc_signal_in_if<bool> &s)
778{
779    while (!s.read())
780        wait();
781    while (s.read())
782        wait();
783}
784
785void
786at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &s)
787{
788    while (s.read() == sc_dt::Log_0)
789        wait();
790    while (s.read() == sc_dt::Log_1)
791        wait();
792}
793
794const char *
795sc_gen_unique_name(const char *seed)
796{
797    auto mod = sc_gem5::pickParentModule();
798    if (mod)
799        return mod->uniqueName(seed);
800    sc_gem5::Process *p = sc_gem5::scheduler.current();
801    if (p)
802        return p->uniqueName(seed);
803    return ::sc_gem5::nameGen.gen(seed);
804}
805
806bool
807sc_hierarchical_name_exists(const char *name)
808{
809    return sc_gem5::findEvent(name) != sc_gem5::allEvents.end() ||
810        ::sc_gem5::findObject(name, sc_gem5::allObjects);
811}
812
813bool
814sc_start_of_simulation_invoked()
815{
816    return ::sc_gem5::kernel->startOfSimulationComplete();
817}
818
819bool
820sc_end_of_simulation_invoked()
821{
822    return ::sc_gem5::kernel->endOfSimulationComplete();
823}
824
825sc_module *
826sc_module_sc_new(sc_module *mod)
827{
828    static std::vector<std::unique_ptr<sc_module> > modules;
829    modules.emplace_back(mod);
830    return mod;
831}
832
833} // namespace sc_core
834