ruby: Added clock to ruby system
[gem5.git] / src / mem / ruby / system / System.cc
1
2 /*
3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * RubySystem.cc
32 *
33 * Description: See System.hh
34 *
35 * $Id$
36 *
37 */
38
39
40 #include "mem/ruby/system/System.hh"
41 #include "mem/ruby/common/Address.hh"
42 #include "mem/ruby/profiler/Profiler.hh"
43 #include "mem/ruby/network/Network.hh"
44 #include "mem/ruby/recorder/Tracer.hh"
45 #include "mem/protocol/Protocol.hh"
46 #include "mem/ruby/buffers/MessageBuffer.hh"
47 #include "mem/ruby/system/Sequencer.hh"
48 #include "mem/ruby/system/DMASequencer.hh"
49 #include "mem/ruby/system/MemoryVector.hh"
50 #include "mem/ruby/slicc_interface/AbstractController.hh"
51 #include "mem/ruby/system/CacheMemory.hh"
52 #include "mem/ruby/system/DirectoryMemory.hh"
53 #include "mem/ruby/network/simple/Topology.hh"
54 #include "mem/ruby/network/simple/SimpleNetwork.hh"
55 #include "mem/ruby/system/RubyPort.hh"
56 //#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh"
57 //#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
58 #include "mem/ruby/system/MemoryControl.hh"
59
60 int RubySystem::m_random_seed;
61 bool RubySystem::m_randomization;
62 int RubySystem::m_tech_nm;
63 Tick RubySystem::m_clock;
64 int RubySystem::m_block_size_bytes;
65 int RubySystem::m_block_size_bits;
66 uint64 RubySystem::m_memory_size_bytes;
67 int RubySystem::m_memory_size_bits;
68
69 map< string, RubyPort* > RubySystem::m_ports;
70 map< string, CacheMemory* > RubySystem::m_caches;
71 map< string, DirectoryMemory* > RubySystem::m_directories;
72 map< string, Sequencer* > RubySystem::m_sequencers;
73 map< string, DMASequencer* > RubySystem::m_dma_sequencers;
74 map< string, AbstractController* > RubySystem::m_controllers;
75 map< string, MemoryControl* > RubySystem::m_memorycontrols;
76
77
78 Network* RubySystem::m_network_ptr;
79 map< string, Topology*> RubySystem::m_topologies;
80 Profiler* RubySystem::m_profiler_ptr;
81 Tracer* RubySystem::m_tracer_ptr;
82
83 MemoryVector* RubySystem::m_mem_vec_ptr;
84
85
86 RubySystem::RubySystem(const Params *p)
87 : SimObject(p)
88 {
89 if (g_system_ptr != NULL)
90 fatal("Only one RubySystem object currently allowed.\n");
91
92 m_random_seed = p->random_seed;
93 srandom(m_random_seed);
94 m_randomization = p->randomization;
95 m_tech_nm = p->tech_nm;
96 m_clock = p->clock;
97
98 m_block_size_bytes = p->block_size_bytes;
99 assert(is_power_of_2(m_block_size_bytes));
100 m_block_size_bits = log_int(m_block_size_bytes);
101
102 m_memory_size_bytes = (uint64_t)p->mem_size_mb * 1024 * 1024;
103 m_memory_size_bits = log_int(m_memory_size_bytes);
104
105 m_network_ptr = p->network;
106 g_debug_ptr = p->debug;
107 m_profiler_ptr = p->profiler;
108 m_tracer_ptr = p->tracer;
109
110 g_eventQueue_ptr = new RubyEventQueue(m_clock);
111 g_system_ptr = this;
112 m_mem_vec_ptr = new MemoryVector;
113 m_mem_vec_ptr->setSize(m_memory_size_bytes);
114 }
115
116
117 void RubySystem::init()
118 {
119 }
120
121
122 RubySystem::~RubySystem()
123 {
124
125 }
126
127 void RubySystem::printSystemConfig(ostream & out)
128 {
129 out << "RubySystem config:" << endl;
130 out << " random_seed: " << m_random_seed << endl;
131 out << " randomization: " << m_randomization << endl;
132 out << " tech_nm: " << m_tech_nm << endl;
133 out << " cycle_period: " << m_clock << endl;
134 out << " block_size_bytes: " << m_block_size_bytes << endl;
135 out << " block_size_bits: " << m_block_size_bits << endl;
136 out << " memory_size_bytes: " << m_memory_size_bytes << endl;
137 out << " memory_size_bits: " << m_memory_size_bits << endl;
138
139 }
140
141 void RubySystem::printConfig(ostream& out)
142 {
143 out << "\n================ Begin RubySystem Configuration Print ================\n\n";
144 printSystemConfig(out);
145 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin();
146 it != m_controllers.end(); it++) {
147 (*it).second->printConfig(out);
148 }
149 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin();
150 it != m_caches.end(); it++) {
151 (*it).second->printConfig(out);
152 }
153 DirectoryMemory::printGlobalConfig(out);
154 for (map<string, DirectoryMemory*>::const_iterator it = m_directories.begin();
155 it != m_directories.end(); it++) {
156 (*it).second->printConfig(out);
157 }
158 for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin();
159 it != m_sequencers.end(); it++) {
160 (*it).second->printConfig(out);
161 }
162
163 m_network_ptr->printConfig(out);
164 m_profiler_ptr->printConfig(out);
165
166 out << "\n================ End RubySystem Configuration Print ================\n\n";
167 }
168
169 void RubySystem::printStats(ostream& out)
170 {
171
172 const time_t T = time(NULL);
173 tm *localTime = localtime(&T);
174 char buf[100];
175 strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
176
177 out << "Real time: " << buf << endl;
178
179 m_profiler_ptr->printStats(out);
180 m_network_ptr->printStats(out);
181 for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin();
182 it != m_sequencers.end(); it++) {
183 (*it).second->printStats(out);
184 }
185 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin();
186 it != m_caches.end(); it++) {
187 (*it).second->printStats(out);
188 }
189 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin();
190 it != m_controllers.end(); it++) {
191 (*it).second->printStats(out);
192 }
193 }
194
195 void RubySystem::clearStats() const
196 {
197 m_profiler_ptr->clearStats();
198 m_network_ptr->clearStats();
199 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin();
200 it != m_caches.end(); it++) {
201 (*it).second->clearStats();
202 }
203 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin();
204 it != m_controllers.end(); it++) {
205 (*it).second->clearStats();
206 }
207 }
208
209 void RubySystem::recordCacheContents(CacheRecorder& tr) const
210 {
211
212 }
213
214 #ifdef CHECK_COHERENCE
215 // This code will check for cases if the given cache block is exclusive in
216 // one node and shared in another-- a coherence violation
217 //
218 // To use, the SLICC specification must call sequencer.checkCoherence(address)
219 // when the controller changes to a state with new permissions. Do this
220 // in setState. The SLICC spec must also define methods "isBlockShared"
221 // and "isBlockExclusive" that are specific to that protocol
222 //
223 void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) {
224 /*
225 NodeID exclusive = -1;
226 bool sharedDetected = false;
227 NodeID lastShared = -1;
228
229 for (int i = 0; i < m_chip_vector.size(); i++) {
230
231 if (m_chip_vector[i]->isBlockExclusive(addr)) {
232 if (exclusive != -1) {
233 // coherence violation
234 WARN_EXPR(exclusive);
235 WARN_EXPR(m_chip_vector[i]->getID());
236 WARN_EXPR(addr);
237 WARN_EXPR(g_eventQueue_ptr->getTime());
238 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
239 }
240 else if (sharedDetected) {
241 WARN_EXPR(lastShared);
242 WARN_EXPR(m_chip_vector[i]->getID());
243 WARN_EXPR(addr);
244 WARN_EXPR(g_eventQueue_ptr->getTime());
245 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
246 }
247 else {
248 exclusive = m_chip_vector[i]->getID();
249 }
250 }
251 else if (m_chip_vector[i]->isBlockShared(addr)) {
252 sharedDetected = true;
253 lastShared = m_chip_vector[i]->getID();
254
255 if (exclusive != -1) {
256 WARN_EXPR(lastShared);
257 WARN_EXPR(exclusive);
258 WARN_EXPR(addr);
259 WARN_EXPR(g_eventQueue_ptr->getTime());
260 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
261 }
262 }
263 }
264 */
265 }
266 #endif
267
268
269 RubySystem *
270 RubySystemParams::create()
271 {
272 return new RubySystem(this);
273 }