sc_module.cc revision 13248
1/* 2 * Copyright 2018 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution; 11 * neither the name of the copyright holders nor the names of its 12 * contributors may be used to endorse or promote products derived from 13 * this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Authors: Gabe Black 28 */ 29 30#include <memory> 31#include <string> 32#include <vector> 33 34#include "base/logging.hh" 35#include "systemc/core/kernel.hh" 36#include "systemc/core/module.hh" 37#include "systemc/core/process_types.hh" 38#include "systemc/ext/channel/sc_signal_in_if.hh" 39#include "systemc/ext/core/sc_module.hh" 40#include "systemc/ext/core/sc_module_name.hh" 41#include "systemc/ext/dt/bit/sc_logic.hh" 42#include "systemc/ext/utils/sc_report_handler.hh" 43 44namespace sc_gem5 45{ 46 47Process * 48newMethodProcess(const char *name, ProcessFuncWrapper *func) 49{ 50 Method *p = new Method(name, func); 51 if (::sc_core::sc_is_running()) { 52 std::string name = p->name(); 53 delete p; 54 SC_REPORT_ERROR("(E541) call to SC_METHOD in sc_module while " 55 "simulation running", name.c_str()); 56 return nullptr; 57 } 58 scheduler.reg(p); 59 return p; 60} 61 62Process * 63newThreadProcess(const char *name, ProcessFuncWrapper *func) 64{ 65 Thread *p = new Thread(name, func); 66 if (::sc_core::sc_is_running()) { 67 std::string name = p->name(); 68 delete p; 69 SC_REPORT_ERROR("(E542) call to SC_THREAD in sc_module while " 70 "simulation running", name.c_str()); 71 return nullptr; 72 } 73 scheduler.reg(p); 74 return p; 75} 76 77Process * 78newCThreadProcess(const char *name, ProcessFuncWrapper *func) 79{ 80 CThread *p = new CThread(name, func); 81 if (::sc_core::sc_is_running()) { 82 std::string name = p->name(); 83 delete p; 84 SC_REPORT_ERROR("(E543) call to SC_CTHREAD in sc_module while " 85 "simulation running", name.c_str()); 86 return nullptr; 87 } 88 scheduler.reg(p); 89 p->dontInitialize(true); 90 return p; 91} 92 93UniqueNameGen nameGen; 94 95} // namespace sc_gem5 96 97namespace sc_core 98{ 99 100sc_bind_proxy::sc_bind_proxy(sc_interface &_interface) : 101 _interface(&_interface), _port(nullptr) 102{} 103 104sc_bind_proxy::sc_bind_proxy(sc_port_base &_port) : 105 _interface(nullptr), _port(&_port) 106{} 107 108const sc_bind_proxy SC_BIND_PROXY_NUL(*(sc_port_base *)nullptr); 109 110sc_module::~sc_module() { delete _gem5_module; } 111 112const sc_bind_proxy SC_BIND_PROXY_NIL(*(sc_port_base *)nullptr); 113 114void 115sc_module::operator () (const sc_bind_proxy &p001, 116 const sc_bind_proxy &p002, 117 const sc_bind_proxy &p003, 118 const sc_bind_proxy &p004, 119 const sc_bind_proxy &p005, 120 const sc_bind_proxy &p006, 121 const sc_bind_proxy &p007, 122 const sc_bind_proxy &p008, 123 const sc_bind_proxy &p009, 124 const sc_bind_proxy &p010, 125 const sc_bind_proxy &p011, 126 const sc_bind_proxy &p012, 127 const sc_bind_proxy &p013, 128 const sc_bind_proxy &p014, 129 const sc_bind_proxy &p015, 130 const sc_bind_proxy &p016, 131 const sc_bind_proxy &p017, 132 const sc_bind_proxy &p018, 133 const sc_bind_proxy &p019, 134 const sc_bind_proxy &p020, 135 const sc_bind_proxy &p021, 136 const sc_bind_proxy &p022, 137 const sc_bind_proxy &p023, 138 const sc_bind_proxy &p024, 139 const sc_bind_proxy &p025, 140 const sc_bind_proxy &p026, 141 const sc_bind_proxy &p027, 142 const sc_bind_proxy &p028, 143 const sc_bind_proxy &p029, 144 const sc_bind_proxy &p030, 145 const sc_bind_proxy &p031, 146 const sc_bind_proxy &p032, 147 const sc_bind_proxy &p033, 148 const sc_bind_proxy &p034, 149 const sc_bind_proxy &p035, 150 const sc_bind_proxy &p036, 151 const sc_bind_proxy &p037, 152 const sc_bind_proxy &p038, 153 const sc_bind_proxy &p039, 154 const sc_bind_proxy &p040, 155 const sc_bind_proxy &p041, 156 const sc_bind_proxy &p042, 157 const sc_bind_proxy &p043, 158 const sc_bind_proxy &p044, 159 const sc_bind_proxy &p045, 160 const sc_bind_proxy &p046, 161 const sc_bind_proxy &p047, 162 const sc_bind_proxy &p048, 163 const sc_bind_proxy &p049, 164 const sc_bind_proxy &p050, 165 const sc_bind_proxy &p051, 166 const sc_bind_proxy &p052, 167 const sc_bind_proxy &p053, 168 const sc_bind_proxy &p054, 169 const sc_bind_proxy &p055, 170 const sc_bind_proxy &p056, 171 const sc_bind_proxy &p057, 172 const sc_bind_proxy &p058, 173 const sc_bind_proxy &p059, 174 const sc_bind_proxy &p060, 175 const sc_bind_proxy &p061, 176 const sc_bind_proxy &p062, 177 const sc_bind_proxy &p063, 178 const sc_bind_proxy &p064) 179{ 180 std::vector<const ::sc_core::sc_bind_proxy *> proxies; 181 auto insert = [&proxies](const ::sc_core::sc_bind_proxy &p) -> bool { 182 if (!p.port() && !p.interface()) 183 return false; 184 proxies.push_back(&p); 185 return true; 186 }; 187 insert(p001) && insert(p002) && insert(p003) && insert(p004) && 188 insert(p005) && insert(p006) && insert(p007) && insert(p008) && 189 insert(p009) && insert(p010) && insert(p011) && insert(p012) && 190 insert(p013) && insert(p014) && insert(p015) && insert(p016) && 191 insert(p017) && insert(p018) && insert(p019) && insert(p020) && 192 insert(p021) && insert(p022) && insert(p023) && insert(p024) && 193 insert(p025) && insert(p026) && insert(p027) && insert(p028) && 194 insert(p029) && insert(p030) && insert(p031) && insert(p032) && 195 insert(p033) && insert(p034) && insert(p035) && insert(p036) && 196 insert(p037) && insert(p038) && insert(p039) && insert(p040) && 197 insert(p041) && insert(p042) && insert(p043) && insert(p044) && 198 insert(p045) && insert(p046) && insert(p047) && insert(p048) && 199 insert(p049) && insert(p050) && insert(p051) && insert(p052) && 200 insert(p053) && insert(p054) && insert(p055) && insert(p056) && 201 insert(p057) && insert(p058) && insert(p059) && insert(p060) && 202 insert(p061) && insert(p062) && insert(p063) && insert(p064); 203 _gem5_module->bindPorts(proxies); 204} 205 206const std::vector<sc_object *> & 207sc_module::get_child_objects() const 208{ 209 return _gem5_module->obj()->get_child_objects(); 210} 211 212const std::vector<sc_event *> & 213sc_module::get_child_events() const 214{ 215 return _gem5_module->obj()->get_child_events(); 216} 217 218sc_module::sc_module() : 219 sc_object(sc_gem5::newModuleChecked()->name()), 220 _gem5_module(sc_gem5::currentModule()) 221{} 222 223sc_module::sc_module(const sc_module_name &) : sc_module() {} 224sc_module::sc_module(const char *_name) : sc_module(sc_module_name(_name)) 225{ 226 _gem5_module->deprecatedConstructor(); 227 SC_REPORT_WARNING("(W569) sc_module(const char*), " 228 "sc_module(const std::string&) have been deprecated, use " 229 "sc_module(const sc_module_name&)", _name); 230} 231sc_module::sc_module(const std::string &_name) : 232 sc_module(sc_module_name(_name.c_str())) 233{ 234 _gem5_module->deprecatedConstructor(); 235 SC_REPORT_WARNING("(W569) sc_module(const char*), " 236 "sc_module(const std::string&) have been deprecated, use " 237 "sc_module(const sc_module_name&)", _name.c_str()); 238} 239 240void 241sc_module::end_module() 242{ 243 _gem5_module->endModule(); 244} 245 246void 247sc_module::reset_signal_is(const sc_in<bool> &, bool) 248{ 249 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 250} 251 252void 253sc_module::reset_signal_is(const sc_inout<bool> &, bool) 254{ 255 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 256} 257 258void 259sc_module::reset_signal_is(const sc_out<bool> &, bool) 260{ 261 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 262} 263 264void 265sc_module::reset_signal_is(const sc_signal_in_if<bool> &, bool) 266{ 267 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 268} 269 270 271void 272sc_module::async_reset_signal_is(const sc_in<bool> &, bool) 273{ 274 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 275} 276 277void 278sc_module::async_reset_signal_is(const sc_inout<bool> &, bool) 279{ 280 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 281} 282 283void 284sc_module::async_reset_signal_is(const sc_out<bool> &, bool) 285{ 286 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 287} 288 289void 290sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &, bool) 291{ 292 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 293} 294 295 296void 297sc_module::dont_initialize() 298{ 299 ::sc_gem5::Process::newest()->dontInitialize(true); 300} 301 302void 303sc_module::set_stack_size(size_t size) 304{ 305 ::sc_gem5::Process::newest()->setStackSize(size); 306} 307 308 309void sc_module::next_trigger() { ::sc_core::next_trigger(); } 310 311void 312sc_module::next_trigger(const sc_event &e) 313{ 314 ::sc_core::next_trigger(e); 315} 316 317void 318sc_module::next_trigger(const sc_event_or_list &eol) 319{ 320 ::sc_core::next_trigger(eol); 321} 322 323void 324sc_module::next_trigger(const sc_event_and_list &eal) 325{ 326 ::sc_core::next_trigger(eal); 327} 328 329void 330sc_module::next_trigger(const sc_time &t) 331{ 332 ::sc_core::next_trigger(t); 333} 334 335void 336sc_module::next_trigger(double d, sc_time_unit u) 337{ 338 ::sc_core::next_trigger(d, u); 339} 340 341void 342sc_module::next_trigger(const sc_time &t, const sc_event &e) 343{ 344 ::sc_core::next_trigger(t, e); 345} 346 347void 348sc_module::next_trigger(double d, sc_time_unit u, const sc_event &e) 349{ 350 ::sc_core::next_trigger(d, u, e); 351} 352 353void 354sc_module::next_trigger(const sc_time &t, const sc_event_or_list &eol) 355{ 356 ::sc_core::next_trigger(t, eol); 357} 358 359void 360sc_module::next_trigger(double d, sc_time_unit u, const sc_event_or_list &eol) 361{ 362 ::sc_core::next_trigger(d, u, eol); 363} 364 365void 366sc_module::next_trigger(const sc_time &t, const sc_event_and_list &eal) 367{ 368 ::sc_core::next_trigger(t, eal); 369} 370 371void 372sc_module::next_trigger(double d, sc_time_unit u, const sc_event_and_list &eal) 373{ 374 ::sc_core::next_trigger(d, u, eal); 375} 376 377 378bool 379sc_module::timed_out() 380{ 381 return ::sc_core::timed_out(); 382} 383 384 385void 386sc_module::wait() 387{ 388 ::sc_core::wait(); 389} 390 391void 392sc_module::wait(int i) 393{ 394 ::sc_core::wait(i); 395} 396 397void 398sc_module::wait(const sc_event &e) 399{ 400 ::sc_core::wait(e); 401} 402 403void 404sc_module::wait(const sc_event_or_list &eol) 405{ 406 ::sc_core::wait(eol); 407} 408 409void 410sc_module::wait(const sc_event_and_list &eal) 411{ 412 ::sc_core::wait(eal); 413} 414 415void 416sc_module::wait(const sc_time &t) 417{ 418 ::sc_core::wait(t); 419} 420 421void 422sc_module::wait(double d, sc_time_unit u) 423{ 424 ::sc_core::wait(d, u); 425} 426 427void 428sc_module::wait(const sc_time &t, const sc_event &e) 429{ 430 ::sc_core::wait(t, e); 431} 432 433void 434sc_module::wait(double d, sc_time_unit u, const sc_event &e) 435{ 436 ::sc_core::wait(d, u, e); 437} 438 439void 440sc_module::wait(const sc_time &t, const sc_event_or_list &eol) 441{ 442 ::sc_core::wait(t, eol); 443} 444 445void 446sc_module::wait(double d, sc_time_unit u, const sc_event_or_list &eol) 447{ 448 ::sc_core::wait(d, u, eol); 449} 450 451void 452sc_module::wait(const sc_time &t, const sc_event_and_list &eal) 453{ 454 ::sc_core::wait(t, eal); 455} 456 457void 458sc_module::wait(double d, sc_time_unit u, const sc_event_and_list &eal) 459{ 460 ::sc_core::wait(d, u, eal); 461} 462 463 464void 465sc_module::halt() 466{ 467 ::sc_core::halt(); 468} 469 470void 471sc_module::at_posedge(const sc_signal_in_if<bool> &s) 472{ 473 ::sc_core::at_posedge(s); 474} 475 476void 477sc_module::at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &s) 478{ 479 ::sc_core::at_posedge(s); 480} 481 482void 483sc_module::at_negedge(const sc_signal_in_if<bool> &s) 484{ 485 ::sc_core::at_negedge(s); 486} 487 488void 489sc_module::at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &s) 490{ 491 ::sc_core::at_negedge(s); 492} 493 494 495void 496next_trigger() 497{ 498 sc_gem5::Process *p = sc_gem5::scheduler.current(); 499 p->cancelTimeout(); 500 p->clearDynamic(); 501} 502 503void 504next_trigger(const sc_event &e) 505{ 506 sc_gem5::Process *p = sc_gem5::scheduler.current(); 507 p->cancelTimeout(); 508 ::sc_gem5::newDynamicSensitivityEvent(p, &e); 509} 510 511void 512next_trigger(const sc_event_or_list &eol) 513{ 514 sc_gem5::Process *p = sc_gem5::scheduler.current(); 515 p->cancelTimeout(); 516 ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); 517} 518 519void 520next_trigger(const sc_event_and_list &eal) 521{ 522 sc_gem5::Process *p = sc_gem5::scheduler.current(); 523 p->cancelTimeout(); 524 ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); 525} 526 527void 528next_trigger(const sc_time &t) 529{ 530 sc_gem5::Process *p = sc_gem5::scheduler.current(); 531 p->setTimeout(t); 532 p->clearDynamic(); 533} 534 535void 536next_trigger(double d, sc_time_unit u) 537{ 538 next_trigger(sc_time(d, u)); 539} 540 541void 542next_trigger(const sc_time &t, const sc_event &e) 543{ 544 sc_gem5::Process *p = sc_gem5::scheduler.current(); 545 p->setTimeout(t); 546 ::sc_gem5::newDynamicSensitivityEvent(p, &e); 547} 548 549void 550next_trigger(double d, sc_time_unit u, const sc_event &e) 551{ 552 next_trigger(sc_time(d, u), e); 553} 554 555void 556next_trigger(const sc_time &t, const sc_event_or_list &eol) 557{ 558 sc_gem5::Process *p = sc_gem5::scheduler.current(); 559 p->setTimeout(t); 560 ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); 561} 562 563void 564next_trigger(double d, sc_time_unit u, const sc_event_or_list &eol) 565{ 566 next_trigger(sc_time(d, u), eol); 567} 568 569void 570next_trigger(const sc_time &t, const sc_event_and_list &eal) 571{ 572 sc_gem5::Process *p = sc_gem5::scheduler.current(); 573 p->setTimeout(t); 574 ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); 575} 576 577void 578next_trigger(double d, sc_time_unit u, const sc_event_and_list &eal) 579{ 580 next_trigger(sc_time(d, u), eal); 581} 582 583bool 584timed_out() 585{ 586 ::sc_gem5::Process *p = sc_gem5::scheduler.current(); 587 if (!p) 588 return false; 589 else 590 return p->timedOut(); 591} 592 593 594namespace 595{ 596 597bool 598waitErrorCheck(sc_gem5::Process *p) 599{ 600 if (p->procKind() == SC_METHOD_PROC_) { 601 SC_REPORT_ERROR( 602 "(E519) wait() is only allowed in SC_THREADs and SC_CTHREADs", 603 "\n in SC_METHODs use next_trigger() instead"); 604 return true; 605 } 606 return false; 607} 608 609} // anonymous namespace 610 611void 612wait() 613{ 614 sc_gem5::Process *p = sc_gem5::scheduler.current(); 615 if (waitErrorCheck(p)) 616 return; 617 p->cancelTimeout(); 618 p->clearDynamic(); 619 sc_gem5::scheduler.yield(); 620} 621 622void 623wait(int n) 624{ 625 if (n <= 0) { 626 std::string msg = csprintf("n = %d", n); 627 SC_REPORT_ERROR("(E525) wait(n) is only valid for n > 0", msg.c_str()); 628 } 629 for (int i = 0; i < n; i++) 630 wait(); 631} 632 633void 634wait(const sc_event &e) 635{ 636 sc_gem5::Process *p = sc_gem5::scheduler.current(); 637 if (waitErrorCheck(p)) 638 return; 639 p->cancelTimeout(); 640 ::sc_gem5::newDynamicSensitivityEvent(p, &e); 641 sc_gem5::scheduler.yield(); 642} 643 644void 645wait(const sc_event_or_list &eol) 646{ 647 sc_gem5::Process *p = sc_gem5::scheduler.current(); 648 if (waitErrorCheck(p)) 649 return; 650 p->cancelTimeout(); 651 ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); 652 sc_gem5::scheduler.yield(); 653} 654 655void 656wait(const sc_event_and_list &eal) 657{ 658 sc_gem5::Process *p = sc_gem5::scheduler.current(); 659 if (waitErrorCheck(p)) 660 return; 661 p->cancelTimeout(); 662 ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); 663 sc_gem5::scheduler.yield(); 664} 665 666void 667wait(const sc_time &t) 668{ 669 sc_gem5::Process *p = sc_gem5::scheduler.current(); 670 if (waitErrorCheck(p)) 671 return; 672 p->setTimeout(t); 673 p->clearDynamic(); 674 sc_gem5::scheduler.yield(); 675} 676 677void 678wait(double d, sc_time_unit u) 679{ 680 wait(sc_time(d, u)); 681} 682 683void 684wait(const sc_time &t, const sc_event &e) 685{ 686 sc_gem5::Process *p = sc_gem5::scheduler.current(); 687 if (waitErrorCheck(p)) 688 return; 689 p->setTimeout(t); 690 ::sc_gem5::newDynamicSensitivityEvent(p, &e); 691 sc_gem5::scheduler.yield(); 692} 693 694void 695wait(double d, sc_time_unit u, const sc_event &e) 696{ 697 wait(sc_time(d, u), e); 698} 699 700void 701wait(const sc_time &t, const sc_event_or_list &eol) 702{ 703 sc_gem5::Process *p = sc_gem5::scheduler.current(); 704 if (waitErrorCheck(p)) 705 return; 706 p->setTimeout(t); 707 ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol); 708 sc_gem5::scheduler.yield(); 709} 710 711void 712wait(double d, sc_time_unit u, const sc_event_or_list &eol) 713{ 714 wait(sc_time(d, u), eol); 715} 716 717void 718wait(const sc_time &t, const sc_event_and_list &eal) 719{ 720 sc_gem5::Process *p = sc_gem5::scheduler.current(); 721 if (waitErrorCheck(p)) 722 return; 723 p->setTimeout(t); 724 ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal); 725 sc_gem5::scheduler.yield(); 726} 727 728void 729wait(double d, sc_time_unit u, const sc_event_and_list &eal) 730{ 731 wait(sc_time(d, u), eal); 732} 733 734void 735halt() 736{ 737 ::sc_core::wait(); 738 throw ::sc_gem5::ScHalt(); 739} 740 741void 742at_posedge(const sc_signal_in_if<bool> &s) 743{ 744 while (s.read()) 745 wait(); 746 while (!s.read()) 747 wait(); 748} 749 750void 751at_posedge(const sc_signal_in_if<sc_dt::sc_logic> &s) 752{ 753 while (s.read() == sc_dt::Log_1) 754 wait(); 755 while (s.read() == sc_dt::Log_0) 756 wait(); 757} 758 759void 760at_negedge(const sc_signal_in_if<bool> &s) 761{ 762 while (!s.read()) 763 wait(); 764 while (s.read()) 765 wait(); 766} 767 768void 769at_negedge(const sc_signal_in_if<sc_dt::sc_logic> &s) 770{ 771 while (s.read() == sc_dt::Log_0) 772 wait(); 773 while (s.read() == sc_dt::Log_1) 774 wait(); 775} 776 777const char * 778sc_gen_unique_name(const char *seed) 779{ 780 ::sc_gem5::Module *mod = ::sc_gem5::currentModule(); 781 return mod ? mod->uniqueName(seed) : 782 ::sc_gem5::nameGen.gen(seed); 783} 784 785bool 786sc_hierarchical_name_exists(const char *name) 787{ 788 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 789 return false; 790} 791 792bool 793sc_start_of_simulation_invoked() 794{ 795 return ::sc_gem5::kernel->startOfSimulationComplete(); 796} 797 798bool 799sc_end_of_simulation_invoked() 800{ 801 return ::sc_gem5::kernel->endOfSimulationComplete(); 802} 803 804sc_module * 805sc_module_sc_new(sc_module *mod) 806{ 807 static std::vector<std::unique_ptr<sc_module> > modules; 808 modules.emplace_back(mod); 809 return mod; 810} 811 812} // namespace sc_core 813