sc_main.cc revision 12956
14678SN/A/* 210293SN/A * Copyright 2018 Google, Inc. 310293SN/A * 410293SN/A * Redistribution and use in source and binary forms, with or without 510293SN/A * modification, are permitted provided that the following conditions are 610293SN/A * met: redistributions of source code must retain the above copyright 710293SN/A * notice, this list of conditions and the following disclaimer; 810293SN/A * redistributions in binary form must reproduce the above copyright 910293SN/A * notice, this list of conditions and the following disclaimer in the 1010293SN/A * documentation and/or other materials provided with the distribution; 1110293SN/A * neither the name of the copyright holders nor the names of its 1210293SN/A * contributors may be used to endorse or promote products derived from 1310293SN/A * this software without specific prior written permission. 145465SN/A * 158227SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1611319SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 174678SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 184678SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 194678SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 204678SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 214678SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 224678SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 234678SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 244678SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 254678SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 264678SN/A * 274678SN/A * Authors: Gabe Black 284678SN/A */ 294678SN/A 304678SN/A#include <cstring> 314678SN/A 324678SN/A#include "base/fiber.hh" 334678SN/A#include "base/logging.hh" 344678SN/A#include "base/types.hh" 354678SN/A#include "python/pybind11/pybind.hh" 364678SN/A#include "sim/core.hh" 374678SN/A#include "sim/eventq.hh" 384678SN/A#include "sim/init.hh" 394678SN/A#include "systemc/core/scheduler.hh" 404678SN/A#include "systemc/ext/core/sc_main.hh" 414678SN/A#include "systemc/ext/utils/sc_report_handler.hh" 424678SN/A 4311319SN/A// A weak symbol to detect if sc_main has been defined, and if so where it is. 444678SN/A[[gnu::weak]] int sc_main(int argc, char *argv[]); 4511406Sandreas.sandberg@arm.com 468227SN/Anamespace sc_core 4711406Sandreas.sandberg@arm.com{ 484678SN/A 4911406Sandreas.sandberg@arm.comnamespace 5011406Sandreas.sandberg@arm.com{ 5111406Sandreas.sandberg@arm.com 5211406Sandreas.sandberg@arm.combool scMainCalled = false; 5311406Sandreas.sandberg@arm.com 5411406Sandreas.sandberg@arm.comint _argc = 0; 5511406Sandreas.sandberg@arm.comchar **_argv = NULL; 5610293SN/A 577807SN/Aclass ScMainFiber : public Fiber 588227SN/A{ 598227SN/A void 608227SN/A main() 618227SN/A { 628227SN/A if (::sc_main) { 638227SN/A ::sc_main(_argc, _argv); 648227SN/A } else { 658227SN/A // If python tries to call sc_main but no sc_main was defined... 668227SN/A fatal("sc_main called but not defined.\n"); 678227SN/A } 688227SN/A } 698227SN/A}; 708227SN/A 718227SN/AScMainFiber scMainFiber; 728227SN/A 738227SN/A// This wrapper adapts the python version of sc_main to the c++ version. 748227SN/Avoid 758227SN/Asc_main(pybind11::args args) 768227SN/A{ 778227SN/A panic_if(scMainCalled, "sc_main called more than once."); 788227SN/A 798227SN/A _argc = args.size(); 808227SN/A _argv = new char *[_argc]; 819135SN/A 828227SN/A // Initialize all the _argvs to NULL so we can delete [] them 838227SN/A // unconditionally. 848227SN/A for (int idx = 0; idx < _argc; idx++) 8510293SN/A _argv[idx] = NULL; 8610692SN/A 8710692SN/A // Attempt to convert all the arguments to strings. If that fails, clean 8810692SN/A // up after ourselves. Also don't count this as a call to sc_main since 8910692SN/A // we never got to the c++ version of that function. 9010692SN/A try { 9110692SN/A for (int idx = 0; idx < _argc; idx++) { 9210692SN/A std::string arg = args[idx].cast<std::string>(); 9310692SN/A _argv[idx] = new char[arg.length() + 1]; 9410692SN/A strcpy(_argv[idx], arg.c_str()); 9510692SN/A } 9610692SN/A } catch (...) { 9710692SN/A // If that didn't work for some reason (probably a conversion error) 9810692SN/A // blow away _argv and _argc and pass on the exception. 9910692SN/A for (int idx = 0; idx < _argc; idx++) 10010692SN/A delete [] _argv[idx]; 10110692SN/A delete [] _argv; 10210692SN/A _argc = 0; 10310692SN/A throw; 10410692SN/A } 10510692SN/A 10610692SN/A // At this point we're going to call the c++ sc_main, so we can't try 10710692SN/A // again later. 10810692SN/A scMainCalled = true; 10910692SN/A 11010692SN/A scMainFiber.run(); 11110692SN/A} 11210692SN/A 11310692SN/A// Make our sc_main wrapper available in the internal _m5 python module under 11410692SN/A// the systemc submodule. 11510692SN/Avoid 11610692SN/Asystemc_pybind(pybind11::module &m_internal) 11710692SN/A{ 11810692SN/A pybind11::module m = m_internal.def_submodule("systemc"); 11910692SN/A m.def("sc_main", &sc_main); 12010293SN/A} 12110293SN/AEmbeddedPyBind embed_("systemc", &systemc_pybind); 12210293SN/A 12310293SN/Asc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA; 12410293SN/Asc_status _status = SC_ELABORATION; 12510293SN/A 12610293SN/ATick _max_tick = MaxTick; 12710293SN/Asc_starvation_policy _starvation = SC_EXIT_ON_STARVATION; 12810293SN/A 12910293SN/A} // anonymous namespace 13010293SN/A 13110293SN/Aint 13211319SN/Asc_argc() 13311319SN/A{ 13411319SN/A return _argc; 13511319SN/A} 13611319SN/A 13711319SN/Aconst char *const * 13811319SN/Asc_argv() 13911319SN/A{ 14011319SN/A return _argv; 14111319SN/A} 14211319SN/A 14311319SN/Avoid 14411319SN/Asc_start() 14511319SN/A{ 14611319SN/A _max_tick = MaxTick; 14711319SN/A _starvation = SC_EXIT_ON_STARVATION; 14811319SN/A 14911319SN/A // Switch back gem5. 15011319SN/A Fiber::primaryFiber()->run(); 15111319SN/A} 15211319SN/A 15311319SN/Avoid 15411319SN/Asc_pause() 15511319SN/A{ 15610293SN/A warn("%s not implemented.\n", __PRETTY_FUNCTION__); 15710691SN/A} 15810691SN/A 1595465SN/Avoid 16011319SN/Asc_start(const sc_time &time, sc_starvation_policy p) 16111406Sandreas.sandberg@arm.com{ 1624678SN/A Tick now = curEventQueue() ? curEventQueue()->getCurTick() : 0; 16310692SN/A _max_tick = now + time.value(); 16411319SN/A _starvation = p; 16511406Sandreas.sandberg@arm.com 16610692SN/A // Switch back to gem5. 1674678SN/A Fiber::primaryFiber()->run(); 1684678SN/A} 1694678SN/A 1707807SN/Avoid 1717807SN/Asc_set_stop_mode(sc_stop_mode mode) 1727807SN/A{ 1737807SN/A if (sc_is_running()) { 1747807SN/A SC_REPORT_ERROR("attempt to set sc_stop mode " 17511319SN/A "after start will be ignored", ""); 17611319SN/A return; 1777827SN/A } 1787807SN/A _stop_mode = mode; 1797827SN/A} 1807828SN/A 1817828SN/Asc_stop_mode 1827828SN/Asc_get_stop_mode() 1837828SN/A{ 1847828SN/A return _stop_mode; 1857828SN/A} 1867828SN/A 1877807SN/Avoid 1885465SN/Asc_stop() 1895465SN/A{ 1905465SN/A warn("%s not implemented.\n", __PRETTY_FUNCTION__); 1915465SN/A} 1925465SN/A 1935465SN/Aconst sc_time & 19410692SN/Asc_time_stamp() 19510692SN/A{ 19610692SN/A static sc_time tstamp; 19710692SN/A Tick tick = sc_gem5::scheduler.eventQueue().getCurTick(); 19810692SN/A //XXX We're assuming the systemc time resolution is in ps. 19910692SN/A tstamp = sc_time::from_value(tick / SimClock::Int::ps); 20011319SN/A return tstamp; 20111319SN/A} 20211319SN/A 20311319SN/Asc_dt::uint64 20411319SN/Asc_delta_count() 20511319SN/A{ 20611319SN/A return sc_gem5::scheduler.numCycles(); 20711319SN/A} 20811319SN/A 20911319SN/Abool 21011319SN/Asc_is_running() 21111319SN/A{ 21211319SN/A return _status & (SC_RUNNING | SC_PAUSED); 2135465SN/A} 21410293SN/A 21511319SN/Abool 21610293SN/Asc_pending_activity_at_current_time() 2175465SN/A{ 2187807SN/A warn("%s not implemented.\n", __PRETTY_FUNCTION__); 2194678SN/A return false; 22011406Sandreas.sandberg@arm.com} 22111406Sandreas.sandberg@arm.com 22211406Sandreas.sandberg@arm.combool 223sc_pending_activity_at_future_time() 224{ 225 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 226 return false; 227} 228 229bool 230sc_pending_activity() 231{ 232 return sc_pending_activity_at_current_time() || 233 sc_pending_activity_at_future_time(); 234} 235 236sc_time 237sc_time_to_pending_activity() 238{ 239 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 240 return sc_time(); 241} 242 243sc_status 244sc_get_status() 245{ 246 return _status; 247} 248 249} // namespace sc_core 250