RubySystem.cc revision 6895
12623SN/A 22623SN/A/* 32623SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 42623SN/A * All rights reserved. 52623SN/A * 62623SN/A * Redistribution and use in source and binary forms, with or without 72623SN/A * modification, are permitted provided that the following conditions are 82623SN/A * met: redistributions of source code must retain the above copyright 92623SN/A * notice, this list of conditions and the following disclaimer; 102623SN/A * redistributions in binary form must reproduce the above copyright 112623SN/A * notice, this list of conditions and the following disclaimer in the 122623SN/A * documentation and/or other materials provided with the distribution; 132623SN/A * neither the name of the copyright holders nor the names of its 142623SN/A * contributors may be used to endorse or promote products derived from 152623SN/A * this software without specific prior written permission. 162623SN/A * 172623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu */ 292623SN/A 302623SN/A/* 313170Sstever@eecs.umich.edu * RubySystem.cc 322623SN/A * 332623SN/A * Description: See System.hh 342623SN/A * 353348Sbinkertn@umich.edu * $Id$ 363348Sbinkertn@umich.edu * 372623SN/A */ 382901Ssaidi@eecs.umich.edu 392623SN/A 402623SN/A#include "mem/ruby/system/System.hh" 412623SN/A#include "mem/ruby/common/Address.hh" 422623SN/A#include "mem/ruby/profiler/Profiler.hh" 432856Srdreslin@umich.edu#include "mem/ruby/network/Network.hh" 442856Srdreslin@umich.edu#include "mem/ruby/recorder/Tracer.hh" 452856Srdreslin@umich.edu#include "mem/protocol/Protocol.hh" 462856Srdreslin@umich.edu#include "mem/ruby/buffers/MessageBuffer.hh" 472856Srdreslin@umich.edu#include "mem/ruby/system/Sequencer.hh" 482856Srdreslin@umich.edu#include "mem/ruby/system/DMASequencer.hh" 492856Srdreslin@umich.edu#include "mem/ruby/system/MemoryVector.hh" 502856Srdreslin@umich.edu#include "mem/ruby/slicc_interface/AbstractController.hh" 512856Srdreslin@umich.edu#include "mem/ruby/system/CacheMemory.hh" 522856Srdreslin@umich.edu#include "mem/ruby/system/DirectoryMemory.hh" 532623SN/A#include "mem/ruby/network/simple/Topology.hh" 542623SN/A#include "mem/ruby/network/simple/SimpleNetwork.hh" 552623SN/A#include "mem/ruby/system/RubyPort.hh" 562623SN/A//#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" 572623SN/A//#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" 582623SN/A#include "mem/ruby/system/MemoryControl.hh" 592680Sktlim@umich.edu#include "base/output.hh" 602680Sktlim@umich.edu 612623SN/Aint RubySystem::m_random_seed; 622623SN/Abool RubySystem::m_randomization; 632680Sktlim@umich.eduTick RubySystem::m_clock; 642623SN/Aint RubySystem::m_block_size_bytes; 652623SN/Aint RubySystem::m_block_size_bits; 662623SN/Auint64 RubySystem::m_memory_size_bytes; 672623SN/Aint RubySystem::m_memory_size_bits; 682623SN/A 692630SN/Amap< string, RubyPort* > RubySystem::m_ports; 702623SN/Amap< string, CacheMemory* > RubySystem::m_caches; 712623SN/Amap< string, DirectoryMemory* > RubySystem::m_directories; 722623SN/Amap< string, Sequencer* > RubySystem::m_sequencers; 732623SN/Amap< string, DMASequencer* > RubySystem::m_dma_sequencers; 742623SN/Amap< string, AbstractController* > RubySystem::m_controllers; 752623SN/Amap< string, MemoryControl* > RubySystem::m_memorycontrols; 762630SN/A 772623SN/A 783184Srdreslin@umich.eduNetwork* RubySystem::m_network_ptr; 793184Srdreslin@umich.edumap< string, Topology*> RubySystem::m_topologies; 802623SN/AProfiler* RubySystem::m_profiler_ptr; 812623SN/ATracer* RubySystem::m_tracer_ptr; 822623SN/A 832623SN/AMemoryVector* RubySystem::m_mem_vec_ptr; 842623SN/A 852631SN/A 862631SN/ARubySystem::RubySystem(const Params *p) 872631SN/A : SimObject(p) 882623SN/A{ 892623SN/A if (g_system_ptr != NULL) 902623SN/A fatal("Only one RubySystem object currently allowed.\n"); 912948Ssaidi@eecs.umich.edu 922948Ssaidi@eecs.umich.edu m_random_seed = p->random_seed; 932948Ssaidi@eecs.umich.edu srandom(m_random_seed); 942948Ssaidi@eecs.umich.edu m_randomization = p->randomization; 952948Ssaidi@eecs.umich.edu m_clock = p->clock; 962948Ssaidi@eecs.umich.edu 972948Ssaidi@eecs.umich.edu m_block_size_bytes = p->block_size_bytes; 982948Ssaidi@eecs.umich.edu assert(is_power_of_2(m_block_size_bytes)); 992623SN/A m_block_size_bits = log_int(m_block_size_bytes); 1003170Sstever@eecs.umich.edu 1013170Sstever@eecs.umich.edu m_memory_size_bytes = (uint64_t)p->mem_size_mb * 1024 * 1024; 1022623SN/A m_memory_size_bits = log_int(m_memory_size_bytes); 1032623SN/A 1042623SN/A m_network_ptr = p->network; 1052839Sktlim@umich.edu g_debug_ptr = p->debug; 1062867Sktlim@umich.edu m_profiler_ptr = p->profiler; 1073222Sktlim@umich.edu m_tracer_ptr = p->tracer; 1082901Ssaidi@eecs.umich.edu 1092623SN/A g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock); 1102623SN/A g_system_ptr = this; 1112623SN/A m_mem_vec_ptr = new MemoryVector; 1122623SN/A m_mem_vec_ptr->setSize(m_memory_size_bytes); 1132623SN/A 1142623SN/A // 1152623SN/A // Print ruby configuration and stats at exit 1162623SN/A // 1172623SN/A RubyExitCallback* rubyExitCB = new RubyExitCallback(p->stats_filename); 1182623SN/A registerExitCallback(rubyExitCB); 1192915Sktlim@umich.edu} 1202915Sktlim@umich.edu 1212623SN/A 1222623SN/Avoid RubySystem::init() 1232623SN/A{ 1242623SN/A m_profiler_ptr->clearStats(); 1252623SN/A} 1262623SN/A 1272915Sktlim@umich.edu 1282915Sktlim@umich.eduRubySystem::~RubySystem() 1292623SN/A{ 1302798Sktlim@umich.edu 1312798Sktlim@umich.edu} 1322901Ssaidi@eecs.umich.edu 1332839Sktlim@umich.eduvoid RubySystem::printSystemConfig(ostream & out) 1342798Sktlim@umich.edu{ 1352839Sktlim@umich.edu out << "RubySystem config:" << endl; 1362798Sktlim@umich.edu out << " random_seed: " << m_random_seed << endl; 1372798Sktlim@umich.edu out << " randomization: " << m_randomization << endl; 1382901Ssaidi@eecs.umich.edu out << " cycle_period: " << m_clock << endl; 1392901Ssaidi@eecs.umich.edu out << " block_size_bytes: " << m_block_size_bytes << endl; 1402798Sktlim@umich.edu out << " block_size_bits: " << m_block_size_bits << endl; 1412839Sktlim@umich.edu out << " memory_size_bytes: " << m_memory_size_bytes << endl; 1422839Sktlim@umich.edu out << " memory_size_bits: " << m_memory_size_bits << endl; 1432901Ssaidi@eecs.umich.edu 1442798Sktlim@umich.edu} 1452623SN/A 1462623SN/Avoid RubySystem::printConfig(ostream& out) 1472623SN/A{ 1482798Sktlim@umich.edu out << "\n================ Begin RubySystem Configuration Print ================\n\n"; 1492623SN/A printSystemConfig(out); 1502798Sktlim@umich.edu for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 1513201Shsul@eecs.umich.edu it != m_controllers.end(); it++) { 1523201Shsul@eecs.umich.edu (*it).second->printConfig(out); 1532867Sktlim@umich.edu } 1542867Sktlim@umich.edu for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 1552915Sktlim@umich.edu it != m_caches.end(); it++) { 1562915Sktlim@umich.edu (*it).second->printConfig(out); 1572915Sktlim@umich.edu } 1582867Sktlim@umich.edu DirectoryMemory::printGlobalConfig(out); 1592867Sktlim@umich.edu for (map<string, DirectoryMemory*>::const_iterator it = m_directories.begin(); 1602867Sktlim@umich.edu it != m_directories.end(); it++) { 1612867Sktlim@umich.edu (*it).second->printConfig(out); 1622867Sktlim@umich.edu } 1632867Sktlim@umich.edu for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin(); 1642623SN/A it != m_sequencers.end(); it++) { 1652798Sktlim@umich.edu (*it).second->printConfig(out); 1662901Ssaidi@eecs.umich.edu } 1673222Sktlim@umich.edu 1682798Sktlim@umich.edu m_network_ptr->printConfig(out); 1692798Sktlim@umich.edu m_profiler_ptr->printConfig(out); 1702798Sktlim@umich.edu 1712798Sktlim@umich.edu out << "\n================ End RubySystem Configuration Print ================\n\n"; 1722798Sktlim@umich.edu} 1732798Sktlim@umich.edu 1742798Sktlim@umich.eduvoid RubySystem::printStats(ostream& out) 1753222Sktlim@umich.edu{ 1762867Sktlim@umich.edu 1772867Sktlim@umich.edu const time_t T = time(NULL); 1782867Sktlim@umich.edu tm *localTime = localtime(&T); 1792867Sktlim@umich.edu char buf[100]; 1802867Sktlim@umich.edu strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); 1812623SN/A 1822623SN/A out << "Real time: " << buf << endl; 1832623SN/A 1842623SN/A m_profiler_ptr->printStats(out); 1852623SN/A m_network_ptr->printStats(out); 1862623SN/A for (map<string, Sequencer*>::const_iterator it = m_sequencers.begin(); 1872623SN/A it != m_sequencers.end(); it++) { 1882623SN/A (*it).second->printStats(out); 1892680Sktlim@umich.edu } 1902623SN/A for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 1912680Sktlim@umich.edu it != m_caches.end(); it++) { 1922680Sktlim@umich.edu (*it).second->printStats(out); 1932680Sktlim@umich.edu } 1942623SN/A for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 1952623SN/A it != m_controllers.end(); it++) { 1962623SN/A (*it).second->printStats(out); 1972623SN/A } 1983201Shsul@eecs.umich.edu} 1993201Shsul@eecs.umich.edu 2003201Shsul@eecs.umich.eduvoid RubySystem::clearStats() const 2013201Shsul@eecs.umich.edu{ 2023227Sktlim@umich.edu m_profiler_ptr->clearStats(); 2033222Sktlim@umich.edu m_network_ptr->clearStats(); 2043222Sktlim@umich.edu for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); 2053227Sktlim@umich.edu it != m_caches.end(); it++) { 2063222Sktlim@umich.edu (*it).second->clearStats(); 2073222Sktlim@umich.edu } 2083222Sktlim@umich.edu for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); 2093222Sktlim@umich.edu it != m_controllers.end(); it++) { 2103222Sktlim@umich.edu (*it).second->clearStats(); 2113222Sktlim@umich.edu } 2123222Sktlim@umich.edu} 2133227Sktlim@umich.edu 2143222Sktlim@umich.eduvoid RubySystem::recordCacheContents(CacheRecorder& tr) const 2153222Sktlim@umich.edu{ 2163222Sktlim@umich.edu 2173222Sktlim@umich.edu} 2183222Sktlim@umich.edu 2192623SN/A#ifdef CHECK_COHERENCE 2202623SN/A// This code will check for cases if the given cache block is exclusive in 2212623SN/A// one node and shared in another-- a coherence violation 2222623SN/A// 2232623SN/A// To use, the SLICC specification must call sequencer.checkCoherence(address) 2242623SN/A// when the controller changes to a state with new permissions. Do this 2252623SN/A// in setState. The SLICC spec must also define methods "isBlockShared" 2262683Sktlim@umich.edu// and "isBlockExclusive" that are specific to that protocol 2272623SN/A// 2282623SN/Avoid RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) { 2292623SN/A /* 2302623SN/A NodeID exclusive = -1; 2312623SN/A bool sharedDetected = false; 2322623SN/A NodeID lastShared = -1; 2332867Sktlim@umich.edu 2342867Sktlim@umich.edu for (int i = 0; i < m_chip_vector.size(); i++) { 2352867Sktlim@umich.edu 2362623SN/A if (m_chip_vector[i]->isBlockExclusive(addr)) { 2372623SN/A if (exclusive != -1) { 2382623SN/A // coherence violation 2392623SN/A WARN_EXPR(exclusive); 2402623SN/A WARN_EXPR(m_chip_vector[i]->getID()); 2412623SN/A WARN_EXPR(addr); 2422623SN/A WARN_EXPR(g_eventQueue_ptr->getTime()); 2432683Sktlim@umich.edu ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); 2442623SN/A } 2452644Sstever@eecs.umich.edu else if (sharedDetected) { 2462623SN/A WARN_EXPR(lastShared); 2472644Sstever@eecs.umich.edu WARN_EXPR(m_chip_vector[i]->getID()); 2482644Sstever@eecs.umich.edu WARN_EXPR(addr); 2492623SN/A WARN_EXPR(g_eventQueue_ptr->getTime()); 2502623SN/A ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 2512623SN/A } 2522623SN/A else { 2532623SN/A exclusive = m_chip_vector[i]->getID(); 2542623SN/A } 2552623SN/A } 2562623SN/A else if (m_chip_vector[i]->isBlockShared(addr)) { 2572623SN/A sharedDetected = true; 2582623SN/A lastShared = m_chip_vector[i]->getID(); 2593169Sstever@eecs.umich.edu 2603169Sstever@eecs.umich.edu if (exclusive != -1) { 2613170Sstever@eecs.umich.edu WARN_EXPR(lastShared); 2622623SN/A WARN_EXPR(exclusive); 2632623SN/A WARN_EXPR(addr); 2643169Sstever@eecs.umich.edu WARN_EXPR(g_eventQueue_ptr->getTime()); 2652623SN/A ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); 2662623SN/A } 2672623SN/A } 2683169Sstever@eecs.umich.edu } 2692623SN/A */ 2702623SN/A} 2712623SN/A#endif 2723169Sstever@eecs.umich.edu 2733169Sstever@eecs.umich.eduRubySystem * 2743169Sstever@eecs.umich.eduRubySystemParams::create() 2752623SN/A{ 2763169Sstever@eecs.umich.edu return new RubySystem(this); 2772623SN/A} 2783169Sstever@eecs.umich.edu 2792623SN/A/** 2802623SN/A * virtual process function that is invoked when the callback 2813169Sstever@eecs.umich.edu * queue is executed. 2822623SN/A */ 2832623SN/Avoid RubyExitCallback::process() 2842623SN/A{ 2852623SN/A std::ostream *os = simout.create(stats_filename); 2862623SN/A RubySystem::printConfig(*os); 2873172Sstever@eecs.umich.edu *os << endl; 2882623SN/A RubySystem::printStats(*os); 2892623SN/A} 2902623SN/A