3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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.
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.
33 * Description: See System.hh
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"
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
;
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
;
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
;
83 MemoryVector
* RubySystem::m_mem_vec_ptr
;
86 RubySystem::RubySystem(const Params
*p
)
89 if (g_system_ptr
!= NULL
)
90 fatal("Only one RubySystem object currently allowed.\n");
92 m_random_seed
= p
->random_seed
;
93 srandom(m_random_seed
);
94 m_randomization
= p
->randomization
;
95 m_tech_nm
= p
->tech_nm
;
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
);
102 m_memory_size_bytes
= (uint64_t)p
->mem_size_mb
* 1024 * 1024;
103 m_memory_size_bits
= log_int(m_memory_size_bytes
);
105 m_network_ptr
= p
->network
;
106 g_debug_ptr
= p
->debug
;
107 m_profiler_ptr
= p
->profiler
;
108 m_tracer_ptr
= p
->tracer
;
110 g_eventQueue_ptr
= new RubyEventQueue(m_clock
);
112 m_mem_vec_ptr
= new MemoryVector
;
113 m_mem_vec_ptr
->setSize(m_memory_size_bytes
);
117 void RubySystem::init()
122 RubySystem::~RubySystem()
127 void RubySystem::printSystemConfig(ostream
& out
)
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
;
141 void RubySystem::printConfig(ostream
& out
)
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
);
149 for (map
<string
, CacheMemory
*>::const_iterator it
= m_caches
.begin();
150 it
!= m_caches
.end(); it
++) {
151 (*it
).second
->printConfig(out
);
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
);
158 for (map
<string
, Sequencer
*>::const_iterator it
= m_sequencers
.begin();
159 it
!= m_sequencers
.end(); it
++) {
160 (*it
).second
->printConfig(out
);
163 m_network_ptr
->printConfig(out
);
164 m_profiler_ptr
->printConfig(out
);
166 out
<< "\n================ End RubySystem Configuration Print ================\n\n";
169 void RubySystem::printStats(ostream
& out
)
172 const time_t T
= time(NULL
);
173 tm
*localTime
= localtime(&T
);
175 strftime(buf
, 100, "%b/%d/%Y %H:%M:%S", localTime
);
177 out
<< "Real time: " << buf
<< endl
;
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
);
185 for (map
<string
, CacheMemory
*>::const_iterator it
= m_caches
.begin();
186 it
!= m_caches
.end(); it
++) {
187 (*it
).second
->printStats(out
);
189 for (map
<string
, AbstractController
*>::const_iterator it
= m_controllers
.begin();
190 it
!= m_controllers
.end(); it
++) {
191 (*it
).second
->printStats(out
);
195 void RubySystem::clearStats() const
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();
203 for (map
<string
, AbstractController
*>::const_iterator it
= m_controllers
.begin();
204 it
!= m_controllers
.end(); it
++) {
205 (*it
).second
->clearStats();
209 void RubySystem::recordCacheContents(CacheRecorder
& tr
) const
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
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
223 void RubySystem::checkGlobalCoherenceInvariant(const Address
& addr
) {
225 NodeID exclusive = -1;
226 bool sharedDetected = false;
227 NodeID lastShared = -1;
229 for (int i = 0; i < m_chip_vector.size(); i++) {
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());
237 WARN_EXPR(g_eventQueue_ptr->getTime());
238 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
240 else if (sharedDetected) {
241 WARN_EXPR(lastShared);
242 WARN_EXPR(m_chip_vector[i]->getID());
244 WARN_EXPR(g_eventQueue_ptr->getTime());
245 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
248 exclusive = m_chip_vector[i]->getID();
251 else if (m_chip_vector[i]->isBlockShared(addr)) {
252 sharedDetected = true;
253 lastShared = m_chip_vector[i]->getID();
255 if (exclusive != -1) {
256 WARN_EXPR(lastShared);
257 WARN_EXPR(exclusive);
259 WARN_EXPR(g_eventQueue_ptr->getTime());
260 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
270 RubySystemParams::create()
272 return new RubySystem(this);