a96daf2c808ce839613a0dcca4ac7dbde817780e
[gem5.git] / util / tlm / sim_control.cc
1 /*
2 * Copyright (c) 2015, University of Kaiserslautern
3 * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
25 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Authors: Matthias Jung
34 * Abdul Mutaal Ahmad
35 * Christian Menard
36 */
37
38 /**
39 * @file
40 *
41 * Example top level file for SystemC-TLM integration with C++-only
42 * instantiation.
43 *
44 */
45
46 #include <systemc>
47 #include <tlm>
48
49 #include "sc_master_port.hh"
50 #include "sc_slave_port.hh"
51 #include "sim/cxx_config_ini.hh"
52 #include "sim/init_signals.hh"
53 #include "sim/stat_control.hh"
54 #include "sim_control.hh"
55 #include "stats.hh"
56
57 // Define global string variable decalred in stats.hh
58 std::string filename = "m5out/stats-systemc.txt";
59
60 namespace Gem5SystemC
61 {
62
63 Gem5SimControl* Gem5SimControl::instance = nullptr;
64
65 Gem5SimControl::Gem5SimControl(sc_core::sc_module_name name,
66 const std::string& configFile,
67 uint64_t simulationEnd,
68 const std::string& gem5DebugFlags)
69 : Gem5SystemC::Module(name),
70 simulationEnd(simulationEnd)
71 {
72 SC_THREAD(run);
73
74 if (instance != nullptr) {
75 panic("Tried to instantiate Gem5SimControl more than once!\n");
76 }
77 instance = this;
78
79 cxxConfigInit();
80
81 // register the systemc slave and master port handler
82 ExternalSlave::registerHandler("tlm_slave", new SCSlavePortHandler(*this));
83 ExternalMaster::registerHandler("tlm_master",
84 new SCMasterPortHandler(*this));
85
86 Trace::setDebugLogger(&logger);
87
88 Gem5SystemC::setTickFrequency();
89 sc_core::sc_set_time_resolution(1, sc_core::SC_PS);
90
91 Gem5SystemC::Module::setupEventQueues(*this);
92 initSignals();
93
94 Stats::initSimStats();
95 Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
96
97 Trace::enable();
98
99 CxxConfigFileBase* conf = new CxxIniFile();
100
101 if (configFile.empty()) {
102 std::cerr << "No gem5 config file specified!\n";
103 std::exit(EXIT_FAILURE);
104 }
105
106 if (!conf->load(configFile.c_str())) {
107 std::cerr << "Can't open config file: " << configFile << '\n';
108 std::exit(EXIT_FAILURE);
109 }
110
111 config_manager = new CxxConfigManager(*conf);
112
113 // parse debug flags string and clear/set flags accordingly
114 std::stringstream ss;
115 ss.str(gem5DebugFlags);
116 std::string flag;
117 while (std::getline(ss, flag, ' ')) {
118 if (flag.at(0) == '-') {
119 flag.erase(0, 1); // remove the '-'
120 clearDebugFlag(flag.c_str());
121 }
122 else {
123 setDebugFlag(flag.c_str());
124 }
125 }
126
127 CxxConfig::statsEnable();
128 getEventQueue(0)->dump();
129
130 try {
131 config_manager->instantiate();
132 } catch (CxxConfigManager::Exception &e) {
133 std::cerr << "Config problem in sim object "
134 << e.name << ": " << e.message << "\n";
135 std::exit(EXIT_FAILURE);
136 }
137 }
138
139 void
140 Gem5SimControl::end_of_elaboration()
141 {
142 try {
143 config_manager->initState();
144 config_manager->startup();
145 } catch (CxxConfigManager::Exception &e) {
146 std::cerr << "Config problem in sim object "
147 << e.name << ": " << e.message << "\n";
148 std::exit(EXIT_FAILURE);
149 }
150 }
151
152 void
153 Gem5SimControl::run()
154 {
155 // notify callback
156 beforeSimulate();
157
158 GlobalSimLoopExitEvent *exit_event = NULL;
159
160 if (simulationEnd == 0) {
161 exit_event = simulate();
162 } else {
163 exit_event = simulate(simulationEnd);
164 }
165
166 std::cerr << "Exit at tick " << curTick()
167 << ", cause: " << exit_event->getCause() << '\n';
168
169 getEventQueue(0)->dump();
170
171 // notify callback
172 afterSimulate();
173
174 #if TRY_CLEAN_DELETE
175 config_manager->deleteObjects();
176 #endif
177 }
178
179 void
180 Gem5SimControl::registerSlavePort(const std::string& name, SCSlavePort* port)
181 {
182 if (slavePorts.find(name) == slavePorts.end()) {
183 slavePorts[name] = port;
184 } else {
185 std::cerr << "Slave Port " << name << " is already registered!\n";
186 std::exit(EXIT_FAILURE);
187 }
188 }
189
190 void
191 Gem5SimControl::registerMasterPort(const std::string& name, SCMasterPort* port)
192 {
193 if (masterPorts.find(name) == masterPorts.end()) {
194 masterPorts[name] = port;
195 } else {
196 std::cerr << "Master Port " << name << " is already registered!\n";
197 std::exit(EXIT_FAILURE);
198 }
199 }
200
201 SCSlavePort*
202 Gem5SimControl::getSlavePort(const std::string& name)
203 {
204 if (slavePorts.find(name) == slavePorts.end()) {
205 std::cerr << "Slave Port " << name << " was not found!\n";
206 std::exit(EXIT_FAILURE);
207 }
208
209 return slavePorts.at(name);
210 }
211
212 SCMasterPort*
213 Gem5SimControl::getMasterPort(const std::string& name)
214 {
215 if (masterPorts.find(name) == masterPorts.end()) {
216 std::cerr << "Master Port " << name << " was not found!\n";
217 std::exit(EXIT_FAILURE);
218 }
219
220 return masterPorts.at(name);
221 }
222
223 }