sc_main.cc revision 12956
17405SAli.Saidi@ARM.com/*
27405SAli.Saidi@ARM.com * Copyright 2018 Google, Inc.
37405SAli.Saidi@ARM.com *
47405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
57405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
67405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
77405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
87405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
97405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
107405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
117405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
127405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
137405SAli.Saidi@ARM.com * this software without specific prior written permission.
147405SAli.Saidi@ARM.com *
157405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
167405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
177405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
187405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
197405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
207405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
217405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
227405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
237405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
247405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
257405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
267405SAli.Saidi@ARM.com *
277405SAli.Saidi@ARM.com * Authors: Gabe Black
287405SAli.Saidi@ARM.com */
297405SAli.Saidi@ARM.com
307405SAli.Saidi@ARM.com#include <cstring>
317405SAli.Saidi@ARM.com
327405SAli.Saidi@ARM.com#include "base/fiber.hh"
337405SAli.Saidi@ARM.com#include "base/logging.hh"
347405SAli.Saidi@ARM.com#include "base/types.hh"
357405SAli.Saidi@ARM.com#include "python/pybind11/pybind.hh"
367405SAli.Saidi@ARM.com#include "sim/core.hh"
377405SAli.Saidi@ARM.com#include "sim/eventq.hh"
387405SAli.Saidi@ARM.com#include "sim/init.hh"
397405SAli.Saidi@ARM.com#include "systemc/core/scheduler.hh"
407405SAli.Saidi@ARM.com#include "systemc/ext/core/sc_main.hh"
417405SAli.Saidi@ARM.com#include "systemc/ext/utils/sc_report_handler.hh"
428232Snate@binkert.org
438232Snate@binkert.org// A weak symbol to detect if sc_main has been defined, and if so where it is.
447678Sgblack@eecs.umich.edu[[gnu::weak]] int sc_main(int argc, char *argv[]);
458059SAli.Saidi@ARM.com
468284SAli.Saidi@ARM.comnamespace sc_core
477405SAli.Saidi@ARM.com{
487405SAli.Saidi@ARM.com
497405SAli.Saidi@ARM.comnamespace
507405SAli.Saidi@ARM.com{
517427Sgblack@eecs.umich.edu
527427Sgblack@eecs.umich.edubool scMainCalled = false;
537427Sgblack@eecs.umich.edu
547427Sgblack@eecs.umich.eduint _argc = 0;
558299Schander.sudanthi@arm.comchar **_argv = NULL;
567427Sgblack@eecs.umich.edu
577427Sgblack@eecs.umich.educlass ScMainFiber : public Fiber
587427Sgblack@eecs.umich.edu{
597427Sgblack@eecs.umich.edu    void
607427Sgblack@eecs.umich.edu    main()
617427Sgblack@eecs.umich.edu    {
627427Sgblack@eecs.umich.edu        if (::sc_main) {
637604SGene.Wu@arm.com            ::sc_main(_argc, _argv);
647427Sgblack@eecs.umich.edu        } else {
657427Sgblack@eecs.umich.edu            // If python tries to call sc_main but no sc_main was defined...
667427Sgblack@eecs.umich.edu            fatal("sc_main called but not defined.\n");
677427Sgblack@eecs.umich.edu        }
687427Sgblack@eecs.umich.edu    }
697427Sgblack@eecs.umich.edu};
707427Sgblack@eecs.umich.edu
717427Sgblack@eecs.umich.eduScMainFiber scMainFiber;
727427Sgblack@eecs.umich.edu
737427Sgblack@eecs.umich.edu// This wrapper adapts the python version of sc_main to the c++ version.
748299Schander.sudanthi@arm.comvoid
758299Schander.sudanthi@arm.comsc_main(pybind11::args args)
768299Schander.sudanthi@arm.com{
777427Sgblack@eecs.umich.edu    panic_if(scMainCalled, "sc_main called more than once.");
787427Sgblack@eecs.umich.edu
797427Sgblack@eecs.umich.edu    _argc = args.size();
807427Sgblack@eecs.umich.edu    _argv = new char *[_argc];
817427Sgblack@eecs.umich.edu
827427Sgblack@eecs.umich.edu    // Initialize all the _argvs to NULL so we can delete [] them
837427Sgblack@eecs.umich.edu    // unconditionally.
847427Sgblack@eecs.umich.edu    for (int idx = 0; idx < _argc; idx++)
857427Sgblack@eecs.umich.edu        _argv[idx] = NULL;
867427Sgblack@eecs.umich.edu
877427Sgblack@eecs.umich.edu    // Attempt to convert all the arguments to strings. If that fails, clean
887427Sgblack@eecs.umich.edu    // up after ourselves. Also don't count this as a call to sc_main since
897427Sgblack@eecs.umich.edu    // we never got to the c++ version of that function.
907427Sgblack@eecs.umich.edu    try {
917427Sgblack@eecs.umich.edu        for (int idx = 0; idx < _argc; idx++) {
927427Sgblack@eecs.umich.edu            std::string arg = args[idx].cast<std::string>();
937427Sgblack@eecs.umich.edu            _argv[idx] = new char[arg.length() + 1];
947427Sgblack@eecs.umich.edu            strcpy(_argv[idx], arg.c_str());
957427Sgblack@eecs.umich.edu        }
967427Sgblack@eecs.umich.edu    } catch (...) {
977427Sgblack@eecs.umich.edu        // If that didn't work for some reason (probably a conversion error)
987427Sgblack@eecs.umich.edu        // blow away _argv and _argc and pass on the exception.
997427Sgblack@eecs.umich.edu        for (int idx = 0; idx < _argc; idx++)
1007427Sgblack@eecs.umich.edu            delete [] _argv[idx];
1017427Sgblack@eecs.umich.edu        delete [] _argv;
1027427Sgblack@eecs.umich.edu        _argc = 0;
1037427Sgblack@eecs.umich.edu        throw;
1047427Sgblack@eecs.umich.edu    }
1057427Sgblack@eecs.umich.edu
1067436Sdam.sunwoo@arm.com    // At this point we're going to call the c++ sc_main, so we can't try
1077436Sdam.sunwoo@arm.com    // again later.
1087436Sdam.sunwoo@arm.com    scMainCalled = true;
1097436Sdam.sunwoo@arm.com
1107436Sdam.sunwoo@arm.com    scMainFiber.run();
1117436Sdam.sunwoo@arm.com}
1127436Sdam.sunwoo@arm.com
1137436Sdam.sunwoo@arm.com// Make our sc_main wrapper available in the internal _m5 python module under
1147436Sdam.sunwoo@arm.com// the systemc submodule.
1157436Sdam.sunwoo@arm.comvoid
1167436Sdam.sunwoo@arm.comsystemc_pybind(pybind11::module &m_internal)
1177436Sdam.sunwoo@arm.com{
1187436Sdam.sunwoo@arm.com    pybind11::module m = m_internal.def_submodule("systemc");
1197436Sdam.sunwoo@arm.com    m.def("sc_main", &sc_main);
1207436Sdam.sunwoo@arm.com}
1217436Sdam.sunwoo@arm.comEmbeddedPyBind embed_("systemc", &systemc_pybind);
1227436Sdam.sunwoo@arm.com
1237436Sdam.sunwoo@arm.comsc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA;
1247436Sdam.sunwoo@arm.comsc_status _status = SC_ELABORATION;
1257436Sdam.sunwoo@arm.com
1267436Sdam.sunwoo@arm.comTick _max_tick = MaxTick;
1277436Sdam.sunwoo@arm.comsc_starvation_policy _starvation = SC_EXIT_ON_STARVATION;
1287436Sdam.sunwoo@arm.com
1297436Sdam.sunwoo@arm.com} // anonymous namespace
1307436Sdam.sunwoo@arm.com
1317436Sdam.sunwoo@arm.comint
1327436Sdam.sunwoo@arm.comsc_argc()
1337436Sdam.sunwoo@arm.com{
1347436Sdam.sunwoo@arm.com    return _argc;
1357436Sdam.sunwoo@arm.com}
1367436Sdam.sunwoo@arm.com
1377436Sdam.sunwoo@arm.comconst char *const *
1387644Sali.saidi@arm.comsc_argv()
1397644Sali.saidi@arm.com{
1408147SAli.Saidi@ARM.com    return _argv;
1418147SAli.Saidi@ARM.com}
1428147SAli.Saidi@ARM.com
1438520SAli.Saidi@ARM.comvoid
1448147SAli.Saidi@ARM.comsc_start()
1458147SAli.Saidi@ARM.com{
1468147SAli.Saidi@ARM.com    _max_tick = MaxTick;
1478147SAli.Saidi@ARM.com    _starvation = SC_EXIT_ON_STARVATION;
1488147SAli.Saidi@ARM.com
1498147SAli.Saidi@ARM.com    // Switch back gem5.
1507427Sgblack@eecs.umich.edu    Fiber::primaryFiber()->run();
1517427Sgblack@eecs.umich.edu}
1527427Sgblack@eecs.umich.edu
1537405SAli.Saidi@ARM.comvoid
1547405SAli.Saidi@ARM.comsc_pause()
1557405SAli.Saidi@ARM.com{
1567405SAli.Saidi@ARM.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1577614Sminkyu.jeong@arm.com}
1587614Sminkyu.jeong@arm.com
1597614Sminkyu.jeong@arm.comvoid
1607614Sminkyu.jeong@arm.comsc_start(const sc_time &time, sc_starvation_policy p)
1617614Sminkyu.jeong@arm.com{
1627614Sminkyu.jeong@arm.com    Tick now = curEventQueue() ? curEventQueue()->getCurTick() : 0;
1637614Sminkyu.jeong@arm.com    _max_tick = now + time.value();
1647614Sminkyu.jeong@arm.com    _starvation = p;
1657614Sminkyu.jeong@arm.com
1667614Sminkyu.jeong@arm.com    // Switch back to gem5.
1677614Sminkyu.jeong@arm.com    Fiber::primaryFiber()->run();
1687405SAli.Saidi@ARM.com}
1697405SAli.Saidi@ARM.com
1707405SAli.Saidi@ARM.comvoid
1717405SAli.Saidi@ARM.comsc_set_stop_mode(sc_stop_mode mode)
1727405SAli.Saidi@ARM.com{
1737405SAli.Saidi@ARM.com    if (sc_is_running()) {
1747405SAli.Saidi@ARM.com        SC_REPORT_ERROR("attempt to set sc_stop mode "
1757405SAli.Saidi@ARM.com                        "after start will be ignored", "");
1767720Sgblack@eecs.umich.edu        return;
1777720Sgblack@eecs.umich.edu    }
1787720Sgblack@eecs.umich.edu    _stop_mode = mode;
1797405SAli.Saidi@ARM.com}
1807405SAli.Saidi@ARM.com
1817757SAli.Saidi@ARM.comsc_stop_mode
1827405SAli.Saidi@ARM.comsc_get_stop_mode()
1837405SAli.Saidi@ARM.com{
1847757SAli.Saidi@ARM.com    return _stop_mode;
1857405SAli.Saidi@ARM.com}
1868284SAli.Saidi@ARM.com
1878284SAli.Saidi@ARM.comvoid
1888284SAli.Saidi@ARM.comsc_stop()
1898468Swade.walker@arm.com{
1908468Swade.walker@arm.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
1918468Swade.walker@arm.com}
1928468Swade.walker@arm.com
1938468Swade.walker@arm.comconst sc_time &
1948284SAli.Saidi@ARM.comsc_time_stamp()
1958284SAli.Saidi@ARM.com{
1968284SAli.Saidi@ARM.com    static sc_time tstamp;
1977405SAli.Saidi@ARM.com    Tick tick = sc_gem5::scheduler.eventQueue().getCurTick();
1987731SAli.Saidi@ARM.com    //XXX We're assuming the systemc time resolution is in ps.
1998468Swade.walker@arm.com    tstamp = sc_time::from_value(tick / SimClock::Int::ps);
2008468Swade.walker@arm.com    return tstamp;
2018468Swade.walker@arm.com}
2027405SAli.Saidi@ARM.com
2037731SAli.Saidi@ARM.comsc_dt::uint64
2047405SAli.Saidi@ARM.comsc_delta_count()
2057405SAli.Saidi@ARM.com{
2067405SAli.Saidi@ARM.com    return sc_gem5::scheduler.numCycles();
2077588SAli.Saidi@arm.com}
2087588SAli.Saidi@arm.com
2097588SAli.Saidi@arm.combool
2108299Schander.sudanthi@arm.comsc_is_running()
2118299Schander.sudanthi@arm.com{
2128299Schander.sudanthi@arm.com    return _status & (SC_RUNNING | SC_PAUSED);
2137583SAli.Saidi@arm.com}
2147583SAli.Saidi@arm.com
2157583SAli.Saidi@arm.combool
2167583SAli.Saidi@arm.comsc_pending_activity_at_current_time()
2177583SAli.Saidi@arm.com{
2187583SAli.Saidi@arm.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2197583SAli.Saidi@arm.com    return false;
2207583SAli.Saidi@arm.com}
2218299Schander.sudanthi@arm.com
2227583SAli.Saidi@arm.combool
2237583SAli.Saidi@arm.comsc_pending_activity_at_future_time()
2248302SAli.Saidi@ARM.com{
2258302SAli.Saidi@ARM.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2267783SGiacomo.Gabrielli@arm.com    return false;
2277783SGiacomo.Gabrielli@arm.com}
2287783SGiacomo.Gabrielli@arm.com
2297783SGiacomo.Gabrielli@arm.combool
2307405SAli.Saidi@ARM.comsc_pending_activity()
2317405SAli.Saidi@ARM.com{
2327405SAli.Saidi@ARM.com    return sc_pending_activity_at_current_time() ||
2337405SAli.Saidi@ARM.com           sc_pending_activity_at_future_time();
2347405SAli.Saidi@ARM.com}
2357405SAli.Saidi@ARM.com
2367405SAli.Saidi@ARM.comsc_time
2377405SAli.Saidi@ARM.comsc_time_to_pending_activity()
2387614Sminkyu.jeong@arm.com{
2397614Sminkyu.jeong@arm.com    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
2407614Sminkyu.jeong@arm.com    return sc_time();
2417614Sminkyu.jeong@arm.com}
2427614Sminkyu.jeong@arm.com
2437614Sminkyu.jeong@arm.comsc_status
2447614Sminkyu.jeong@arm.comsc_get_status()
2457614Sminkyu.jeong@arm.com{
2467614Sminkyu.jeong@arm.com    return _status;
2477614Sminkyu.jeong@arm.com}
2487405SAli.Saidi@ARM.com
2497405SAli.Saidi@ARM.com} // namespace sc_core
2507405SAli.Saidi@ARM.com