418b31bf031d659c0aeb786f3911c6b2cb8e31f4
2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "base/output.hh"
30 #include "mem/ruby/buffers/MessageBuffer.hh"
31 #include "mem/ruby/common/Address.hh"
32 #include "mem/ruby/network/Network.hh"
33 #include "mem/ruby/profiler/Profiler.hh"
34 #include "mem/ruby/recorder/Tracer.hh"
35 #include "mem/ruby/slicc_interface/AbstractController.hh"
36 #include "mem/ruby/system/MemoryVector.hh"
37 #include "mem/ruby/system/System.hh"
41 int RubySystem::m_random_seed
;
42 bool RubySystem::m_randomization
;
43 Tick
RubySystem::m_clock
;
44 int RubySystem::m_block_size_bytes
;
45 int RubySystem::m_block_size_bits
;
46 uint64
RubySystem::m_memory_size_bytes
;
47 int RubySystem::m_memory_size_bits
;
49 Network
* RubySystem::m_network_ptr
;
50 Profiler
* RubySystem::m_profiler_ptr
;
51 Tracer
* RubySystem::m_tracer_ptr
;
52 MemoryVector
* RubySystem::m_mem_vec_ptr
;
54 RubySystem::RubySystem(const Params
*p
)
57 if (g_system_ptr
!= NULL
)
58 fatal("Only one RubySystem object currently allowed.\n");
60 m_random_seed
= p
->random_seed
;
61 srandom(m_random_seed
);
62 m_randomization
= p
->randomization
;
65 m_block_size_bytes
= p
->block_size_bytes
;
66 assert(is_power_of_2(m_block_size_bytes
));
67 m_block_size_bits
= log_int(m_block_size_bytes
);
69 m_memory_size_bytes
= p
->mem_size
;
70 if (m_memory_size_bytes
== 0) {
71 m_memory_size_bits
= 0;
73 m_memory_size_bits
= log_int(m_memory_size_bytes
);
76 m_network_ptr
= p
->network
;
77 g_debug_ptr
= p
->debug
;
78 m_profiler_ptr
= p
->profiler
;
79 m_tracer_ptr
= p
->tracer
;
81 g_eventQueue_ptr
= new RubyEventQueue(p
->eventq
, m_clock
);
86 m_mem_vec_ptr
= new MemoryVector
;
87 m_mem_vec_ptr
->setSize(m_memory_size_bytes
);
91 // Print ruby configuration and stats at exit
93 RubyExitCallback
* rubyExitCB
= new RubyExitCallback(p
->stats_filename
);
94 registerExitCallback(rubyExitCB
);
100 m_profiler_ptr
->clearStats();
103 RubySystem::~RubySystem()
105 delete m_network_ptr
;
106 delete m_profiler_ptr
;
109 delete m_mem_vec_ptr
;
113 RubySystem::printSystemConfig(ostream
& out
)
115 out
<< "RubySystem config:" << endl
116 << " random_seed: " << m_random_seed
<< endl
117 << " randomization: " << m_randomization
<< endl
118 << " cycle_period: " << m_clock
<< endl
119 << " block_size_bytes: " << m_block_size_bytes
<< endl
120 << " block_size_bits: " << m_block_size_bits
<< endl
121 << " memory_size_bytes: " << m_memory_size_bytes
<< endl
122 << " memory_size_bits: " << m_memory_size_bits
<< endl
;
126 RubySystem::printConfig(ostream
& out
)
128 out
<< "\n================ Begin RubySystem Configuration Print ================\n\n";
129 printSystemConfig(out
);
130 m_network_ptr
->printConfig(out
);
131 m_profiler_ptr
->printConfig(out
);
132 out
<< "\n================ End RubySystem Configuration Print ================\n\n";
136 RubySystem::printStats(ostream
& out
)
138 const time_t T
= time(NULL
);
139 tm
*localTime
= localtime(&T
);
141 strftime(buf
, 100, "%b/%d/%Y %H:%M:%S", localTime
);
143 out
<< "Real time: " << buf
<< endl
;
145 m_profiler_ptr
->printStats(out
);
146 m_network_ptr
->printStats(out
);
150 RubySystem::clearStats() const
152 m_profiler_ptr
->clearStats();
153 m_network_ptr
->clearStats();
157 RubySystem::recordCacheContents(CacheRecorder
& tr
) const
161 #ifdef CHECK_COHERENCE
162 // This code will check for cases if the given cache block is exclusive in
163 // one node and shared in another-- a coherence violation
165 // To use, the SLICC specification must call sequencer.checkCoherence(address)
166 // when the controller changes to a state with new permissions. Do this
167 // in setState. The SLICC spec must also define methods "isBlockShared"
168 // and "isBlockExclusive" that are specific to that protocol
171 RubySystem::checkGlobalCoherenceInvariant(const Address
& addr
)
174 NodeID exclusive
= -1;
175 bool sharedDetected
= false;
176 NodeID lastShared
= -1;
178 for (int i
= 0; i
< m_chip_vector
.size(); i
++) {
179 if (m_chip_vector
[i
]->isBlockExclusive(addr
)) {
180 if (exclusive
!= -1) {
181 // coherence violation
182 WARN_EXPR(exclusive
);
183 WARN_EXPR(m_chip_vector
[i
]->getID());
185 WARN_EXPR(g_eventQueue_ptr
->getTime());
186 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
187 } else if (sharedDetected
) {
188 WARN_EXPR(lastShared
);
189 WARN_EXPR(m_chip_vector
[i
]->getID());
191 WARN_EXPR(g_eventQueue_ptr
->getTime());
192 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
194 exclusive
= m_chip_vector
[i
]->getID();
196 } else if (m_chip_vector
[i
]->isBlockShared(addr
)) {
197 sharedDetected
= true;
198 lastShared
= m_chip_vector
[i
]->getID();
200 if (exclusive
!= -1) {
201 WARN_EXPR(lastShared
);
202 WARN_EXPR(exclusive
);
204 WARN_EXPR(g_eventQueue_ptr
->getTime());
205 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
214 RubySystemParams::create()
216 return new RubySystem(this);
220 * virtual process function that is invoked when the callback
224 RubyExitCallback::process()
226 std::ostream
*os
= simout
.create(stats_filename
);
227 RubySystem::printConfig(*os
);
229 RubySystem::printStats(*os
);