RubySystem.cc revision 6165
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.C 32 * 33 * Description: See RubySystem.h 34 * 35 * $Id$ 36 * 37 */ 38 39 40#include "mem/ruby/system/System.hh" 41#include "mem/ruby/profiler/Profiler.hh" 42#include "mem/ruby/network/Network.hh" 43#include "mem/ruby/tester/Tester.hh" 44#include "mem/ruby/tester/SyntheticDriver.hh" 45#include "mem/ruby/tester/DeterministicDriver.hh" 46#include "mem/protocol/Chip.hh" 47//#include "mem/ruby/recorder/Tracer.hh" 48#include "mem/protocol/Protocol.hh" 49 50RubySystem::RubySystem() 51{ 52 init(); 53 m_preinitialized_driver = false; 54 createDriver(); 55 56 /* gem5:Binkert for decomissiong of tracer 57 m_tracer_ptr = new Tracer; 58 */ 59 60 /* gem5:Arka for decomissiong of log_tm 61 if (XACT_MEMORY) { 62 m_xact_isolation_checker = new XactIsolationChecker; 63 m_xact_commit_arbiter = new XactCommitArbiter; 64 m_xact_visualizer = new XactVisualizer; 65 } 66*/ 67} 68 69RubySystem::RubySystem(Driver* _driver) 70{ 71 init(); 72 m_preinitialized_driver = true; 73 m_driver_ptr = _driver; 74} 75 76RubySystem::~RubySystem() 77{ 78 for (int i = 0; i < m_chip_vector.size(); i++) { 79 delete m_chip_vector[i]; 80 } 81 if (!m_preinitialized_driver) 82 delete m_driver_ptr; 83 delete m_network_ptr; 84 delete m_profiler_ptr; 85 /* gem5:Binkert for decomissiong of tracer 86 delete m_tracer_ptr; 87 */ 88} 89 90void RubySystem::init() 91{ 92 DEBUG_MSG(SYSTEM_COMP, MedPrio,"initializing"); 93 94 m_driver_ptr = NULL; 95 m_profiler_ptr = new Profiler; 96 97 // NETWORK INITIALIZATION 98 // create the network by calling a function that calls new 99 m_network_ptr = Network::createNetwork(RubyConfig::numberOfChips()); 100 101 DEBUG_MSG(SYSTEM_COMP, MedPrio,"Constructed network"); 102 103 // CHIP INITIALIZATION 104 m_chip_vector.setSize(RubyConfig::numberOfChips());// create the vector of pointers to processors 105 for(int i=0; i<RubyConfig::numberOfChips(); i++) { // for each chip 106 // create the chip 107 m_chip_vector[i] = new Chip(i, m_network_ptr); 108 DEBUG_MSG(SYSTEM_COMP, MedPrio,"Constructed a chip"); 109 } 110 111 // These must be after the chips are constructed 112 113#if 0 114 if (!g_SIMICS) { 115 if (g_SYNTHETIC_DRIVER && !g_DETERMINISTIC_DRIVER) { 116 m_driver_ptr = new SyntheticDriver(this); 117 } else if (!g_SYNTHETIC_DRIVER && g_DETERMINISTIC_DRIVER) { 118 m_driver_ptr = new DeterministicDriver(this); 119 } else if (g_SYNTHETIC_DRIVER && g_DETERMINISTIC_DRIVER) { 120 ERROR_MSG("SYNTHETIC and DETERMINISTIC DRIVERS are exclusive and cannot be both enabled"); 121 } else { 122 // normally make tester object, otherwise make an opal interface object. 123 if (!OpalInterface::isOpalLoaded()) { 124 m_driver_ptr = new Tester(this); 125 } else { 126 m_driver_ptr = new OpalInterface(this); 127 } 128 } 129 } else { 130 // detect if opal is loaded or not 131 if (OpalInterface::isOpalLoaded()) { 132 m_driver_ptr = new OpalInterface(this); 133 } else { 134 assert(0); 135 /* Need to allocate a driver here */ 136 // m_driver_ptr = new SimicsDriver(this); 137 } 138 } 139#endif 140 DEBUG_MSG(SYSTEM_COMP, MedPrio,"finished initializing"); 141 DEBUG_NEWLINE(SYSTEM_COMP, MedPrio); 142} 143 144void RubySystem::createDriver() 145{ 146 if (g_SYNTHETIC_DRIVER && !g_DETERMINISTIC_DRIVER) { 147 cerr << "Creating Synthetic Driver" << endl; 148 m_driver_ptr = new SyntheticDriver(this); 149 } else if (!g_SYNTHETIC_DRIVER && g_DETERMINISTIC_DRIVER) { 150 cerr << "Creating Deterministic Driver" << endl; 151 m_driver_ptr = new DeterministicDriver(this); 152 } 153} 154 155void RubySystem::printConfig(ostream& out) const 156{ 157 out << "\n================ Begin RubySystem Configuration Print ================\n\n"; 158 RubyConfig::printConfiguration(out); 159 out << endl; 160 getChip(0)->printConfig(out); 161 m_network_ptr->printConfig(out); 162 m_driver_ptr->printConfig(out); 163 m_profiler_ptr->printConfig(out); 164 out << "\n================ End RubySystem Configuration Print ================\n\n"; 165} 166 167void RubySystem::printStats(ostream& out) 168{ 169 const time_t T = time(NULL); 170 tm *localTime = localtime(&T); 171 char buf[100]; 172 strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); 173 174 out << "Real time: " << buf << endl; 175 176 m_profiler_ptr->printStats(out); 177 for(int i=0; i<RubyConfig::numberOfChips(); i++) { // for each chip 178 for(int p=0; p<RubyConfig::numberOfProcsPerChip(); p++) { 179 m_chip_vector[i]->m_L1Cache_mandatoryQueue_vec[p]->printStats(out); 180 } 181 } 182 m_network_ptr->printStats(out); 183 m_driver_ptr->printStats(out); 184 Chip::printStats(out); 185} 186 187void RubySystem::clearStats() const 188{ 189 m_profiler_ptr->clearStats(); 190 m_network_ptr->clearStats(); 191 m_driver_ptr->clearStats(); 192 Chip::clearStats(); 193 for(int i=0; i<RubyConfig::numberOfChips(); i++) { // for each chip 194 for(int p=0; p<RubyConfig::numberOfProcsPerChip(); p++) { 195 m_chip_vector[i]->m_L1Cache_mandatoryQueue_vec[p]->clearStats(); 196 } 197 } 198} 199 200void RubySystem::recordCacheContents(CacheRecorder& tr) const 201{ 202 for (int i = 0; i < m_chip_vector.size(); i++) { 203 for (int m_version = 0; m_version < RubyConfig::numberOfProcsPerChip(); m_version++) { 204 if (Protocol::m_TwoLevelCache) { 205 m_chip_vector[i]->m_L1Cache_L1IcacheMemory_vec[m_version]->setAsInstructionCache(true); 206 m_chip_vector[i]->m_L1Cache_L1DcacheMemory_vec[m_version]->setAsInstructionCache(false); 207 } else { 208 m_chip_vector[i]->m_L1Cache_cacheMemory_vec[m_version]->setAsInstructionCache(false); 209 } 210 } 211 m_chip_vector[i]->recordCacheContents(tr); 212 } 213} 214 215#ifdef CHECK_COHERENCE 216// This code will check for cases if the given cache block is exclusive in 217// one node and shared in another-- a coherence violation 218// 219// To use, the SLICC specification must call sequencer.checkCoherence(address) 220// when the controller changes to a state with new permissions. Do this 221// in setState. The SLICC spec must also define methods "isBlockShared" 222// and "isBlockExclusive" that are specific to that protocol 223// 224void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) { 225 226 NodeID exclusive = -1; 227 bool sharedDetected = false; 228 NodeID lastShared = -1; 229 230 for (int i = 0; i < m_chip_vector.size(); i++) { 231 232 if (m_chip_vector[i]->isBlockExclusive(addr)) { 233 if (exclusive != -1) { 234 // coherence violation 235 WARN_EXPR(exclusive); 236 WARN_EXPR(m_chip_vector[i]->getID()); 237 WARN_EXPR(addr); 238 WARN_EXPR(g_eventQueue_ptr->getTime()); 239 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); 240 } 241 else if (sharedDetected) { 242 WARN_EXPR(lastShared); 243 WARN_EXPR(m_chip_vector[i]->getID()); 244 WARN_EXPR(addr); 245 WARN_EXPR(g_eventQueue_ptr->getTime()); 246 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 247 } 248 else { 249 exclusive = m_chip_vector[i]->getID(); 250 } 251 } 252 else if (m_chip_vector[i]->isBlockShared(addr)) { 253 sharedDetected = true; 254 lastShared = m_chip_vector[i]->getID(); 255 256 if (exclusive != -1) { 257 WARN_EXPR(lastShared); 258 WARN_EXPR(exclusive); 259 WARN_EXPR(addr); 260 WARN_EXPR(g_eventQueue_ptr->getTime()); 261 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 262 } 263 } 264 } 265} 266#endif 267 268 269 270 271