RubySystem.cc revision 6880
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 60int RubySystem::m_random_seed; 61bool RubySystem::m_randomization; 62int RubySystem::m_tech_nm; 63int RubySystem::m_freq_mhz; 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_tech_nm = p->tech_nm; 96 m_freq_mhz = p->freq_mhz; 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_system_ptr = this; 111 m_mem_vec_ptr = new MemoryVector; 112 m_mem_vec_ptr->setSize(m_memory_size_bytes); 113} 114 115 116void RubySystem::init() 117{ 118} 119 120 121RubySystem::~RubySystem() 122{ 123 124} 125 126void RubySystem::printSystemConfig(ostream & out) 127{ 128 out << "RubySystem config:" << endl; 129 out << " random_seed: " << m_random_seed << endl; 130 out << " randomization: " << m_randomization << endl; 131 out << " tech_nm: " << m_tech_nm << endl; 132 out << " freq_mhz: " << m_freq_mhz << endl; 133 out << " block_size_bytes: " << m_block_size_bytes << endl; 134 out << " block_size_bits: " << m_block_size_bits << endl; 135 out << " memory_size_bytes: " << m_memory_size_bytes << endl; 136 out << " memory_size_bits: " << m_memory_size_bits << endl; 137 138} 139 140void RubySystem::printConfig(ostream& out) 141{ 142 out << "\n================ Begin RubySystem Configuration Print ================\n\n"; 143 printSystemConfig(out); 144 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 145 it != m_controllers.end(); it++) { 146 (*it).second->printConfig(out); 147 } 148 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 149 it != m_caches.end(); it++) { 150 (*it).second->printConfig(out); 151 } 152 DirectoryMemory::printGlobalConfig(out); 153 for (map<string, DirectoryMemory*>::const_iterator it = m_directories.begin(); 154 it != m_directories.end(); it++) { 155 (*it).second->printConfig(out); 156 } 157 for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin(); 158 it != m_sequencers.end(); it++) { 159 (*it).second->printConfig(out); 160 } 161 162 m_network_ptr->printConfig(out); 163 m_profiler_ptr->printConfig(out); 164 165 out << "\n================ End RubySystem Configuration Print ================\n\n"; 166} 167 168void RubySystem::printStats(ostream& out) 169{ 170 171 const time_t T = time(NULL); 172 tm *localTime = localtime(&T); 173 char buf[100]; 174 strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); 175 176 out << "Real time: " << buf << endl; 177 178 m_profiler_ptr->printStats(out); 179 m_network_ptr->printStats(out); 180 for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin(); 181 it != m_sequencers.end(); it++) { 182 (*it).second->printStats(out); 183 } 184 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 185 it != m_caches.end(); it++) { 186 (*it).second->printStats(out); 187 } 188 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 189 it != m_controllers.end(); it++) { 190 (*it).second->printStats(out); 191 } 192} 193 194void RubySystem::clearStats() const 195{ 196 m_profiler_ptr->clearStats(); 197 m_network_ptr->clearStats(); 198 for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 199 it != m_caches.end(); it++) { 200 (*it).second->clearStats(); 201 } 202 for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 203 it != m_controllers.end(); it++) { 204 (*it).second->clearStats(); 205 } 206} 207 208void RubySystem::recordCacheContents(CacheRecorder& tr) const 209{ 210 211} 212 213#ifdef CHECK_COHERENCE 214// This code will check for cases if the given cache block is exclusive in 215// one node and shared in another-- a coherence violation 216// 217// To use, the SLICC specification must call sequencer.checkCoherence(address) 218// when the controller changes to a state with new permissions. Do this 219// in setState. The SLICC spec must also define methods "isBlockShared" 220// and "isBlockExclusive" that are specific to that protocol 221// 222void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) { 223 /* 224 NodeID exclusive = -1; 225 bool sharedDetected = false; 226 NodeID lastShared = -1; 227 228 for (int i = 0; i < m_chip_vector.size(); i++) { 229 230 if (m_chip_vector[i]->isBlockExclusive(addr)) { 231 if (exclusive != -1) { 232 // coherence violation 233 WARN_EXPR(exclusive); 234 WARN_EXPR(m_chip_vector[i]->getID()); 235 WARN_EXPR(addr); 236 WARN_EXPR(g_eventQueue_ptr->getTime()); 237 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); 238 } 239 else if (sharedDetected) { 240 WARN_EXPR(lastShared); 241 WARN_EXPR(m_chip_vector[i]->getID()); 242 WARN_EXPR(addr); 243 WARN_EXPR(g_eventQueue_ptr->getTime()); 244 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 245 } 246 else { 247 exclusive = m_chip_vector[i]->getID(); 248 } 249 } 250 else if (m_chip_vector[i]->isBlockShared(addr)) { 251 sharedDetected = true; 252 lastShared = m_chip_vector[i]->getID(); 253 254 if (exclusive != -1) { 255 WARN_EXPR(lastShared); 256 WARN_EXPR(exclusive); 257 WARN_EXPR(addr); 258 WARN_EXPR(g_eventQueue_ptr->getTime()); 259 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 260 } 261 } 262 } 263 */ 264} 265#endif 266 267 268RubySystem * 269RubySystemParams::create() 270{ 271 return new RubySystem(this); 272} 273