sc_main.cc revision 12949:7014101fea10
12155SN/A/* 22155SN/A * Copyright 2018 Google, Inc. 32155SN/A * 42155SN/A * Redistribution and use in source and binary forms, with or without 52155SN/A * modification, are permitted provided that the following conditions are 62155SN/A * met: redistributions of source code must retain the above copyright 72155SN/A * notice, this list of conditions and the following disclaimer; 82155SN/A * redistributions in binary form must reproduce the above copyright 92155SN/A * notice, this list of conditions and the following disclaimer in the 102155SN/A * documentation and/or other materials provided with the distribution; 112155SN/A * neither the name of the copyright holders nor the names of its 122155SN/A * contributors may be used to endorse or promote products derived from 132155SN/A * this software without specific prior written permission. 142155SN/A * 152155SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162155SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172155SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182155SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192155SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202155SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212155SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222155SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232155SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242155SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252155SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262155SN/A * 272155SN/A * Authors: Gabe Black 282665Ssaidi@eecs.umich.edu */ 292665Ssaidi@eecs.umich.edu 302155SN/A#include <cstring> 314202Sbinkertn@umich.edu 322155SN/A#include "base/fiber.hh" 332178SN/A#include "base/logging.hh" 342178SN/A#include "base/types.hh" 352178SN/A#include "python/pybind11/pybind.hh" 362178SN/A#include "sim/eventq.hh" 372178SN/A#include "sim/init.hh" 382178SN/A#include "systemc/ext/core/sc_main.hh" 392178SN/A#include "systemc/ext/utils/sc_report_handler.hh" 402178SN/A 412178SN/A// A weak symbol to detect if sc_main has been defined, and if so where it is. 422178SN/A[[gnu::weak]] int sc_main(int argc, char *argv[]); 432178SN/A 442155SN/Anamespace sc_core 455865Sksewell@umich.edu{ 466181Sksewell@umich.edu 476181Sksewell@umich.edunamespace 485865Sksewell@umich.edu{ 493918Ssaidi@eecs.umich.edu 505865Sksewell@umich.edubool scMainCalled = false; 512623SN/A 523918Ssaidi@eecs.umich.eduint _argc = 0; 532155SN/Achar **_argv = NULL; 542155SN/A 552292SN/Aclass ScMainFiber : public Fiber 566181Sksewell@umich.edu{ 576181Sksewell@umich.edu void 583918Ssaidi@eecs.umich.edu main() 592292SN/A { 602292SN/A if (::sc_main) { 612292SN/A ::sc_main(_argc, _argv); 623918Ssaidi@eecs.umich.edu } else { 632292SN/A // If python tries to call sc_main but no sc_main was defined... 642292SN/A fatal("sc_main called but not defined.\n"); 652766Sktlim@umich.edu } 662766Sktlim@umich.edu } 672766Sktlim@umich.edu}; 682921Sktlim@umich.edu 692921Sktlim@umich.eduScMainFiber scMainFiber; 702766Sktlim@umich.edu 712766Sktlim@umich.edu// This wrapper adapts the python version of sc_main to the c++ version. 725529Snate@binkert.orgvoid 732766Sktlim@umich.edusc_main(pybind11::args args) 744762Snate@binkert.org{ 752155SN/A panic_if(scMainCalled, "sc_main called more than once."); 762155SN/A 772155SN/A _argc = args.size(); 782155SN/A _argv = new char *[_argc]; 792155SN/A 802155SN/A // Initialize all the _argvs to NULL so we can delete [] them 812766Sktlim@umich.edu // unconditionally. 822155SN/A for (int idx = 0; idx < _argc; idx++) 835865Sksewell@umich.edu _argv[idx] = NULL; 842155SN/A 852155SN/A // Attempt to convert all the arguments to strings. If that fails, clean 862155SN/A // up after ourselves. Also don't count this as a call to sc_main since 872155SN/A // we never got to the c++ version of that function. 882178SN/A try { 892178SN/A for (int idx = 0; idx < _argc; idx++) { 902178SN/A std::string arg = args[idx].cast<std::string>(); 912766Sktlim@umich.edu _argv[idx] = new char[arg.length() + 1]; 922178SN/A strcpy(_argv[idx], arg.c_str()); 932178SN/A } 946994Snate@binkert.org } catch (...) { 952178SN/A // If that didn't work for some reason (probably a conversion error) 962766Sktlim@umich.edu // blow away _argv and _argc and pass on the exception. 972766Sktlim@umich.edu for (int idx = 0; idx < _argc; idx++) 982766Sktlim@umich.edu delete [] _argv[idx]; 992788Sktlim@umich.edu delete [] _argv; 1002178SN/A _argc = 0; 1012733Sktlim@umich.edu throw; 1022733Sktlim@umich.edu } 1032817Sksewell@umich.edu 1042733Sktlim@umich.edu // At this point we're going to call the c++ sc_main, so we can't try 1054486Sbinkertn@umich.edu // again later. 1064486Sbinkertn@umich.edu scMainCalled = true; 1074776Sgblack@eecs.umich.edu 1084776Sgblack@eecs.umich.edu scMainFiber.run(); 1096365Sgblack@eecs.umich.edu} 1104486Sbinkertn@umich.edu 1114202Sbinkertn@umich.edu// Make our sc_main wrapper available in the internal _m5 python module under 1124202Sbinkertn@umich.edu// the systemc submodule. 1134202Sbinkertn@umich.eduvoid 1144202Sbinkertn@umich.edusystemc_pybind(pybind11::module &m_internal) 1154202Sbinkertn@umich.edu{ 1164776Sgblack@eecs.umich.edu pybind11::module m = m_internal.def_submodule("systemc"); 1176365Sgblack@eecs.umich.edu m.def("sc_main", &sc_main); 1184202Sbinkertn@umich.edu} 1194202Sbinkertn@umich.eduEmbeddedPyBind embed_("systemc", &systemc_pybind); 1204202Sbinkertn@umich.edu 1214202Sbinkertn@umich.edusc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA; 1225217Ssaidi@eecs.umich.edusc_status _status = SC_ELABORATION; 1234202Sbinkertn@umich.edu 1242155SN/ATick _max_tick = MaxTick; 1254202Sbinkertn@umich.edusc_starvation_policy _starvation = SC_EXIT_ON_STARVATION; 1264486Sbinkertn@umich.edu 1274486Sbinkertn@umich.eduuint64_t _deltaCycles = 0; 1284202Sbinkertn@umich.edu 1294202Sbinkertn@umich.edu} // anonymous namespace 1302821Sktlim@umich.edu 1314776Sgblack@eecs.umich.eduint 1324776Sgblack@eecs.umich.edusc_argc() 1334776Sgblack@eecs.umich.edu{ 1344776Sgblack@eecs.umich.edu return _argc; 1352766Sktlim@umich.edu} 1364202Sbinkertn@umich.edu 1375192Ssaidi@eecs.umich.educonst char *const * 1382733Sktlim@umich.edusc_argv() 1392733Sktlim@umich.edu{ 1402733Sktlim@umich.edu return _argv; 1412733Sktlim@umich.edu} 1422733Sktlim@umich.edu 1432874Sktlim@umich.eduvoid 1442874Sktlim@umich.edusc_start() 1452874Sktlim@umich.edu{ 1464202Sbinkertn@umich.edu _max_tick = MaxTick; 1472733Sktlim@umich.edu _starvation = SC_EXIT_ON_STARVATION; 1485192Ssaidi@eecs.umich.edu 1495192Ssaidi@eecs.umich.edu // Switch back gem5. 1505192Ssaidi@eecs.umich.edu Fiber::primaryFiber()->run(); 1515217Ssaidi@eecs.umich.edu} 1525192Ssaidi@eecs.umich.edu 1535192Ssaidi@eecs.umich.eduvoid 1545192Ssaidi@eecs.umich.edusc_pause() 1555192Ssaidi@eecs.umich.edu{ 1565192Ssaidi@eecs.umich.edu warn("%s not implemented.\n", __PRETTY_FUNCTION__); 1576667Ssteve.reinhardt@amd.com} 1585192Ssaidi@eecs.umich.edu 1595192Ssaidi@eecs.umich.eduvoid 1605192Ssaidi@eecs.umich.edusc_start(const sc_time &time, sc_starvation_policy p) 1615192Ssaidi@eecs.umich.edu{ 1625192Ssaidi@eecs.umich.edu Tick now = curEventQueue() ? curEventQueue()->getCurTick() : 0; 1635192Ssaidi@eecs.umich.edu _max_tick = now + time.value(); 1645192Ssaidi@eecs.umich.edu _starvation = p; 1655192Ssaidi@eecs.umich.edu 1665784Sgblack@eecs.umich.edu // Switch back to gem5. 1675784Sgblack@eecs.umich.edu Fiber::primaryFiber()->run(); 1685192Ssaidi@eecs.umich.edu} 1695192Ssaidi@eecs.umich.edu 1705192Ssaidi@eecs.umich.eduvoid 1715192Ssaidi@eecs.umich.edusc_set_stop_mode(sc_stop_mode mode) 1725192Ssaidi@eecs.umich.edu{ 1735192Ssaidi@eecs.umich.edu if (sc_is_running()) { 1746667Ssteve.reinhardt@amd.com SC_REPORT_ERROR("attempt to set sc_stop mode " 1756036Sksewell@umich.edu "after start will be ignored", ""); 1766667Ssteve.reinhardt@amd.com return; 177 } 178 _stop_mode = mode; 179} 180 181sc_stop_mode 182sc_get_stop_mode() 183{ 184 return _stop_mode; 185} 186 187void 188sc_stop() 189{ 190 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 191} 192 193const sc_time & 194sc_time_stamp() 195{ 196 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 197 return *(sc_time *)nullptr; 198} 199 200sc_dt::uint64 201sc_delta_count() 202{ 203 return _deltaCycles; 204} 205 206bool 207sc_is_running() 208{ 209 return _status & (SC_RUNNING | SC_PAUSED); 210} 211 212bool 213sc_pending_activity_at_current_time() 214{ 215 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 216 return false; 217} 218 219bool 220sc_pending_activity_at_future_time() 221{ 222 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 223 return false; 224} 225 226bool 227sc_pending_activity() 228{ 229 return sc_pending_activity_at_current_time() || 230 sc_pending_activity_at_future_time(); 231} 232 233sc_time 234sc_time_to_pending_activity() 235{ 236 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 237 return sc_time(); 238} 239 240sc_status 241sc_get_status() 242{ 243 return _status; 244} 245 246} // namespace sc_core 247