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 <cstring> 31 32#include "base/fiber.hh" 33#include "base/logging.hh" 34#include "base/types.hh" 35#include "python/pybind11/pybind.hh" 36#include "sim/eventq.hh" 37#include "sim/init.hh" 38#include "systemc/ext/core/sc_main.hh" 39#include "systemc/ext/utils/sc_report_handler.hh" 40
| 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 <cstring> 31 32#include "base/fiber.hh" 33#include "base/logging.hh" 34#include "base/types.hh" 35#include "python/pybind11/pybind.hh" 36#include "sim/eventq.hh" 37#include "sim/init.hh" 38#include "systemc/ext/core/sc_main.hh" 39#include "systemc/ext/utils/sc_report_handler.hh" 40
|
41// A default version of this function in case one isn't otherwise defined. 42// This ensures everything will link properly whether or not the user defined 43// a custom sc_main function. If they didn't but still try to call it, throw 44// an error and die. 45[[gnu::weak]] int 46sc_main(int argc, char *argv[]) 47{ 48 // If python attempts to call sc_main but no sc_main was defined... 49 fatal("sc_main called but not defined.\n"); 50}
| 41// A weak symbol to detect if sc_main has been defined, and if so where it is. 42[[gnu::weak]] int sc_main(int argc, char *argv[]);
|
51 52namespace sc_core 53{ 54 55namespace 56{ 57 58bool scMainCalled = false; 59 60int _argc = 0; 61char **_argv = NULL; 62 63class ScMainFiber : public Fiber 64{ 65 void 66 main() 67 {
| 43 44namespace sc_core 45{ 46 47namespace 48{ 49 50bool scMainCalled = false; 51 52int _argc = 0; 53char **_argv = NULL; 54 55class ScMainFiber : public Fiber 56{ 57 void 58 main() 59 {
|
68 ::sc_main(_argc, _argv);
| 60 if (::sc_main) { 61 ::sc_main(_argc, _argv); 62 } else { 63 // If python tries to call sc_main but no sc_main was defined... 64 fatal("sc_main called but not defined.\n"); 65 }
|
69 } 70}; 71 72ScMainFiber scMainFiber; 73 74// This wrapper adapts the python version of sc_main to the c++ version. 75void 76sc_main(pybind11::args args) 77{ 78 panic_if(scMainCalled, "sc_main called more than once."); 79 80 _argc = args.size(); 81 _argv = new char *[_argc]; 82 83 // Initialize all the _argvs to NULL so we can delete [] them 84 // unconditionally. 85 for (int idx = 0; idx < _argc; idx++) 86 _argv[idx] = NULL; 87 88 // Attempt to convert all the arguments to strings. If that fails, clean 89 // up after ourselves. Also don't count this as a call to sc_main since 90 // we never got to the c++ version of that function. 91 try { 92 for (int idx = 0; idx < _argc; idx++) { 93 std::string arg = args[idx].cast<std::string>(); 94 _argv[idx] = new char[arg.length() + 1]; 95 strcpy(_argv[idx], arg.c_str()); 96 } 97 } catch (...) { 98 // If that didn't work for some reason (probably a conversion error) 99 // blow away _argv and _argc and pass on the exception. 100 for (int idx = 0; idx < _argc; idx++) 101 delete [] _argv[idx]; 102 delete [] _argv; 103 _argc = 0; 104 throw; 105 } 106 107 // At this point we're going to call the c++ sc_main, so we can't try 108 // again later. 109 scMainCalled = true; 110 111 scMainFiber.run(); 112} 113 114// Make our sc_main wrapper available in the internal _m5 python module under 115// the systemc submodule. 116void 117systemc_pybind(pybind11::module &m_internal) 118{ 119 pybind11::module m = m_internal.def_submodule("systemc"); 120 m.def("sc_main", &sc_main); 121} 122EmbeddedPyBind embed_("systemc", &systemc_pybind); 123 124sc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA; 125sc_status _status = SC_ELABORATION; 126 127Tick _max_tick = MaxTick; 128sc_starvation_policy _starvation = SC_EXIT_ON_STARVATION; 129 130uint64_t _deltaCycles = 0; 131 132} // anonymous namespace 133 134int 135sc_argc() 136{ 137 return _argc; 138} 139 140const char *const * 141sc_argv() 142{ 143 return _argv; 144} 145 146void 147sc_start() 148{ 149 _max_tick = MaxTick; 150 _starvation = SC_EXIT_ON_STARVATION; 151 152 // Switch back gem5. 153 Fiber::primaryFiber()->run(); 154} 155 156void 157sc_pause() 158{ 159 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 160} 161 162void 163sc_start(const sc_time &time, sc_starvation_policy p) 164{ 165 Tick now = curEventQueue() ? curEventQueue()->getCurTick() : 0; 166 _max_tick = now + time.value(); 167 _starvation = p; 168 169 // Switch back to gem5. 170 Fiber::primaryFiber()->run(); 171} 172 173void 174sc_set_stop_mode(sc_stop_mode mode) 175{ 176 if (sc_is_running()) { 177 SC_REPORT_ERROR("attempt to set sc_stop mode " 178 "after start will be ignored", ""); 179 return; 180 } 181 _stop_mode = mode; 182} 183 184sc_stop_mode 185sc_get_stop_mode() 186{ 187 return _stop_mode; 188} 189 190void 191sc_stop() 192{ 193 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 194} 195 196const sc_time & 197sc_time_stamp() 198{ 199 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 200 return *(sc_time *)nullptr; 201} 202 203sc_dt::uint64 204sc_delta_count() 205{ 206 return _deltaCycles; 207} 208 209bool 210sc_is_running() 211{ 212 return _status & (SC_RUNNING | SC_PAUSED); 213} 214 215bool 216sc_pending_activity_at_current_time() 217{ 218 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 219 return false; 220} 221 222bool 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
| 66 } 67}; 68 69ScMainFiber scMainFiber; 70 71// This wrapper adapts the python version of sc_main to the c++ version. 72void 73sc_main(pybind11::args args) 74{ 75 panic_if(scMainCalled, "sc_main called more than once."); 76 77 _argc = args.size(); 78 _argv = new char *[_argc]; 79 80 // Initialize all the _argvs to NULL so we can delete [] them 81 // unconditionally. 82 for (int idx = 0; idx < _argc; idx++) 83 _argv[idx] = NULL; 84 85 // Attempt to convert all the arguments to strings. If that fails, clean 86 // up after ourselves. Also don't count this as a call to sc_main since 87 // we never got to the c++ version of that function. 88 try { 89 for (int idx = 0; idx < _argc; idx++) { 90 std::string arg = args[idx].cast<std::string>(); 91 _argv[idx] = new char[arg.length() + 1]; 92 strcpy(_argv[idx], arg.c_str()); 93 } 94 } catch (...) { 95 // If that didn't work for some reason (probably a conversion error) 96 // blow away _argv and _argc and pass on the exception. 97 for (int idx = 0; idx < _argc; idx++) 98 delete [] _argv[idx]; 99 delete [] _argv; 100 _argc = 0; 101 throw; 102 } 103 104 // At this point we're going to call the c++ sc_main, so we can't try 105 // again later. 106 scMainCalled = true; 107 108 scMainFiber.run(); 109} 110 111// Make our sc_main wrapper available in the internal _m5 python module under 112// the systemc submodule. 113void 114systemc_pybind(pybind11::module &m_internal) 115{ 116 pybind11::module m = m_internal.def_submodule("systemc"); 117 m.def("sc_main", &sc_main); 118} 119EmbeddedPyBind embed_("systemc", &systemc_pybind); 120 121sc_stop_mode _stop_mode = SC_STOP_FINISH_DELTA; 122sc_status _status = SC_ELABORATION; 123 124Tick _max_tick = MaxTick; 125sc_starvation_policy _starvation = SC_EXIT_ON_STARVATION; 126 127uint64_t _deltaCycles = 0; 128 129} // anonymous namespace 130 131int 132sc_argc() 133{ 134 return _argc; 135} 136 137const char *const * 138sc_argv() 139{ 140 return _argv; 141} 142 143void 144sc_start() 145{ 146 _max_tick = MaxTick; 147 _starvation = SC_EXIT_ON_STARVATION; 148 149 // Switch back gem5. 150 Fiber::primaryFiber()->run(); 151} 152 153void 154sc_pause() 155{ 156 warn("%s not implemented.\n", __PRETTY_FUNCTION__); 157} 158 159void 160sc_start(const sc_time &time, sc_starvation_policy p) 161{ 162 Tick now = curEventQueue() ? curEventQueue()->getCurTick() : 0; 163 _max_tick = now + time.value(); 164 _starvation = p; 165 166 // Switch back to gem5. 167 Fiber::primaryFiber()->run(); 168} 169 170void 171sc_set_stop_mode(sc_stop_mode mode) 172{ 173 if (sc_is_running()) { 174 SC_REPORT_ERROR("attempt to set sc_stop mode " 175 "after start will be ignored", ""); 176 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
|