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