gem5/src/mem/ruby/system/MemoryControl.hh
Brad Beckmann f88faa6c11 ruby: cleaned up ruby profilers
Cleaned up the ruby profilers by moving the memory controller profiling code
out of the main profiler object and into a separate object similar to the
current CacheProfiler.  Both the CacheProfiler and MemCntrlProfiler are
specific to a particular Ruby object, CacheMemory and MemoryControl
respectively.  Therefore, these profilers should not be SimObjects and
created by the python configuration system, but instead private objects.  This
simplifies the creation of these profilers.
2010-01-29 20:29:22 -08:00

187 lines
5.8 KiB
C++

/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* MemoryControl.hh
*
* Description: See MemoryControl.cc
*
* $Id: $
*
*/
#ifndef MEMORY_CONTROL_H
#define MEMORY_CONTROL_H
#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/profiler/MemCntrlProfiler.hh"
#include "mem/ruby/system/System.hh"
#include "mem/ruby/slicc_interface/Message.hh"
#include "mem/gems_common/util.hh"
#include "mem/ruby/system/MemoryNode.hh"
// Note that "MemoryMsg" is in the "generated" directory:
#include "mem/protocol/MemoryMsg.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/AbstractMemOrCache.hh"
#include "sim/sim_object.hh"
#include "params/RubyMemoryControl.hh"
#include <list>
// This constant is part of the definition of tFAW; see
// the comments in header to MemoryControl.cc
#define ACTIVATE_PER_TFAW 4
//////////////////////////////////////////////////////////////////////////////
class Consumer;
class MemoryControl : public SimObject, public Consumer, public AbstractMemOrCache {
public:
// Constructors
typedef RubyMemoryControlParams Params;
MemoryControl(const Params *p);
void init();
// Destructor
~MemoryControl ();
// Public Methods
void wakeup() ;
void setConsumer (Consumer* consumer_ptr);
Consumer* getConsumer () { return m_consumer_ptr; };
void setDescription (const string& name) { m_description = name; };
string getDescription () { return m_description; };
// Called from the directory:
void enqueue (const MsgPtr& message, int latency );
void enqueueMemRef (MemoryNode& memRef);
void dequeue ();
const Message* peek ();
MemoryNode peekNode ();
bool isReady();
bool areNSlotsAvailable (int n) { return true; }; // infinite queue length
//// Called from L3 cache:
//void writeBack(physical_address_t addr);
void printConfig (ostream& out);
void print (ostream& out) const;
void setDebug (int debugFlag);
void clearStats() const;
void printStats(ostream& out) const;
//added by SS
int getBanksPerRank() { return m_banks_per_rank; };
int getRanksPerDimm() { return m_ranks_per_dimm; };
int getDimmsPerChannel() { return m_dimms_per_channel; }
private:
void enqueueToDirectory (MemoryNode req, int latency);
int getBank (physical_address_t addr);
int getRank (int bank);
bool queueReady (int bank);
void issueRequest (int bank);
bool issueRefresh (int bank);
void markTfaw (int rank);
void executeCycle ();
// Private copy constructor and assignment operator
MemoryControl (const MemoryControl& obj);
MemoryControl& operator=(const MemoryControl& obj);
// data members
Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
string m_description;
int m_msg_counter;
int m_awakened;
int m_mem_bus_cycle_multiplier;
int m_banks_per_rank;
int m_ranks_per_dimm;
int m_dimms_per_channel;
int m_bank_bit_0;
int m_rank_bit_0;
int m_dimm_bit_0;
unsigned int m_bank_queue_size;
int m_bank_busy_time;
int m_rank_rank_delay;
int m_read_write_delay;
int m_basic_bus_busy_time;
int m_mem_ctl_latency;
int m_refresh_period;
int m_mem_random_arbitrate;
int m_tFaw;
int m_mem_fixed_delay;
int m_total_banks;
int m_total_ranks;
int m_refresh_period_system;
// queues where memory requests live
list<MemoryNode> m_response_queue;
list<MemoryNode> m_input_queue;
list<MemoryNode>* m_bankQueues;
// Each entry indicates number of address-bus cycles until bank
// is reschedulable:
int* m_bankBusyCounter;
int* m_oldRequest;
uint64* m_tfaw_shift;
int* m_tfaw_count;
// Each of these indicates number of address-bus cycles until
// we can issue a new request of the corresponding type:
int m_busBusyCounter_Write;
int m_busBusyCounter_ReadNewRank;
int m_busBusyCounter_Basic;
int m_busBusy_WhichRank; // which rank last granted
int m_roundRobin; // which bank queue was last granted
int m_refresh_count; // cycles until next refresh
int m_need_refresh; // set whenever m_refresh_count goes to zero
int m_refresh_bank; // which bank to refresh next
int m_ageCounter; // age of old requests; to detect starvation
int m_idleCount; // watchdog timer for shutting down
int m_debug; // turn on printf's
MemCntrlProfiler* m_profiler_ptr;
};
#endif // MEMORY_CONTROL_H