RubySystem.cc revision 6895
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#include "base/output.hh" 60 61int RubySystem::m_random_seed; 62bool RubySystem::m_randomization; 63Tick RubySystem::m_clock; 64int RubySystem::m_block_size_bytes; 65int RubySystem::m_block_size_bits; 66uint64 RubySystem::m_memory_size_bytes; 67int RubySystem::m_memory_size_bits; 68 69map< string, RubyPort* > RubySystem::m_ports; 70map< string, CacheMemory* > RubySystem::m_caches; 71map< string, DirectoryMemory* > RubySystem::m_directories; 72map< string, Sequencer* > RubySystem::m_sequencers; 73map< string, DMASequencer* > RubySystem::m_dma_sequencers; 74map< string, AbstractController* > RubySystem::m_controllers; 75map< string, MemoryControl* > RubySystem::m_memorycontrols; 76 77 78Network* RubySystem::m_network_ptr; 79map< string, Topology*> RubySystem::m_topologies; 80Profiler* RubySystem::m_profiler_ptr; 81Tracer* RubySystem::m_tracer_ptr; 82 83MemoryVector* RubySystem::m_mem_vec_ptr; 84 85 86RubySystem::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_clock = p->clock; 96 97 m_block_size_bytes = p->block_size_bytes; 98 assert(is_power_of_2(m_block_size_bytes)); 99 m_block_size_bits = log_int(m_block_size_bytes); 100 101 m_memory_size_bytes = (uint64_t)p->mem_size_mb * 1024 * 1024; 102 m_memory_size_bits = log_int(m_memory_size_bytes); 103 104 m_network_ptr = p->network; 105 g_debug_ptr = p->debug; 106 m_profiler_ptr = p->profiler; 107 m_tracer_ptr = p->tracer; 108 109 g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock); 110 g_system_ptr = this; 111 m_mem_vec_ptr = new MemoryVector; 112 m_mem_vec_ptr->setSize(m_memory_size_bytes); 113 114 // 115 // Print ruby configuration and stats at exit 116 // 117 RubyExitCallback* rubyExitCB = new RubyExitCallback(p->stats_filename); 118 registerExitCallback(rubyExitCB); 119} 120 121 122void RubySystem::init() 123{ 124 m_profiler_ptr->clearStats(); 125} 126 127 128RubySystem::~RubySystem() 129{ 130 131} 132 133void RubySystem::printSystemConfig(ostream & out) 134{ 135 out << "RubySystem config:" << endl; 136 out << " random_seed: " << m_random_seed << endl; 137 out << " randomization: " << m_randomization << endl; 138 out << " cycle_period: " << m_clock << endl; 139 out << " block_size_bytes: " << m_block_size_bytes << endl; 140 out << " block_size_bits: " << m_block_size_bits << endl; 141 out << " memory_size_bytes: " << m_memory_size_bytes << endl; 142 out << " memory_size_bits: " << m_memory_size_bits << endl; 143 144} 145 146void RubySystem::printConfig(ostream& out) 147{ 148 out << "\n================ Begin RubySystem Configuration Print ================\n\n"; 149 printSystemConfig(out); 150 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 151 it != m_controllers.end(); it++) { 152 (*it).second->printConfig(out); 153 } 154 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 155 it != m_caches.end(); it++) { 156 (*it).second->printConfig(out); 157 } 158 DirectoryMemory::printGlobalConfig(out); 159 for (map<string, DirectoryMemory*>::const_iterator it = m_directories.begin(); 160 it != m_directories.end(); it++) { 161 (*it).second->printConfig(out); 162 } 163 for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin(); 164 it != m_sequencers.end(); it++) { 165 (*it).second->printConfig(out); 166 } 167 168 m_network_ptr->printConfig(out); 169 m_profiler_ptr->printConfig(out); 170 171 out << "\n================ End RubySystem Configuration Print ================\n\n"; 172} 173 174void RubySystem::printStats(ostream& out) 175{ 176 177 const time_t T = time(NULL); 178 tm *localTime = localtime(&T); 179 char buf[100]; 180 strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); 181 182 out << "Real time: " << buf << endl; 183 184 m_profiler_ptr->printStats(out); 185 m_network_ptr->printStats(out); 186 for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin(); 187 it != m_sequencers.end(); it++) { 188 (*it).second->printStats(out); 189 } 190 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 191 it != m_caches.end(); it++) { 192 (*it).second->printStats(out); 193 } 194 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 195 it != m_controllers.end(); it++) { 196 (*it).second->printStats(out); 197 } 198} 199 200void RubySystem::clearStats() const 201{ 202 m_profiler_ptr->clearStats(); 203 m_network_ptr->clearStats(); 204 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 205 it != m_caches.end(); it++) { 206 (*it).second->clearStats(); 207 } 208 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 209 it != m_controllers.end(); it++) { 210 (*it).second->clearStats(); 211 } 212} 213 214void RubySystem::recordCacheContents(CacheRecorder& tr) const 215{ 216 217} 218 219#ifdef CHECK_COHERENCE 220// This code will check for cases if the given cache block is exclusive in 221// one node and shared in another-- a coherence violation 222// 223// To use, the SLICC specification must call sequencer.checkCoherence(address) 224// when the controller changes to a state with new permissions. Do this 225// in setState. The SLICC spec must also define methods "isBlockShared" 226// and "isBlockExclusive" that are specific to that protocol 227// 228void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) { 229 /* 230 NodeID exclusive = -1; 231 bool sharedDetected = false; 232 NodeID lastShared = -1; 233 234 for (int i = 0; i < m_chip_vector.size(); i++) { 235 236 if (m_chip_vector[i]->isBlockExclusive(addr)) { 237 if (exclusive != -1) { 238 // coherence violation 239 WARN_EXPR(exclusive); 240 WARN_EXPR(m_chip_vector[i]->getID()); 241 WARN_EXPR(addr); 242 WARN_EXPR(g_eventQueue_ptr->getTime()); 243 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); 244 } 245 else if (sharedDetected) { 246 WARN_EXPR(lastShared); 247 WARN_EXPR(m_chip_vector[i]->getID()); 248 WARN_EXPR(addr); 249 WARN_EXPR(g_eventQueue_ptr->getTime()); 250 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 251 } 252 else { 253 exclusive = m_chip_vector[i]->getID(); 254 } 255 } 256 else if (m_chip_vector[i]->isBlockShared(addr)) { 257 sharedDetected = true; 258 lastShared = m_chip_vector[i]->getID(); 259 260 if (exclusive != -1) { 261 WARN_EXPR(lastShared); 262 WARN_EXPR(exclusive); 263 WARN_EXPR(addr); 264 WARN_EXPR(g_eventQueue_ptr->getTime()); 265 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 266 } 267 } 268 } 269 */ 270} 271#endif 272 273RubySystem * 274RubySystemParams::create() 275{ 276 return new RubySystem(this); 277} 278 279/** 280 * virtual process function that is invoked when the callback 281 * queue is executed. 282 */ 283void RubyExitCallback::process() 284{ 285 std::ostream *os = simout.create(stats_filename); 286 RubySystem::printConfig(*os); 287 *os << endl; 288 RubySystem::printStats(*os); 289} 290