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