summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r--src/mem/ruby/system/AbstractMemOrCache.hh66
-rw-r--r--src/mem/ruby/system/AbstractReplacementPolicy.hh76
-rw-r--r--src/mem/ruby/system/CacheMemory.cc648
-rw-r--r--src/mem/ruby/system/CacheMemory.hh209
-rw-r--r--src/mem/ruby/system/DMASequencer.cc233
-rw-r--r--src/mem/ruby/system/DMASequencer.hh62
-rw-r--r--src/mem/ruby/system/DirectoryMemory.cc293
-rw-r--r--src/mem/ruby/system/DirectoryMemory.hh139
-rw-r--r--src/mem/ruby/system/LRUPolicy.hh79
-rw-r--r--src/mem/ruby/system/MachineID.hh70
-rw-r--r--src/mem/ruby/system/MemoryControl.cc840
-rw-r--r--src/mem/ruby/system/MemoryControl.hh258
-rw-r--r--src/mem/ruby/system/MemoryNode.cc13
-rw-r--r--src/mem/ruby/system/MemoryNode.hh99
-rw-r--r--src/mem/ruby/system/MemoryVector.hh164
-rw-r--r--src/mem/ruby/system/NodeID.hh25
-rw-r--r--src/mem/ruby/system/PerfectCacheMemory.hh216
-rw-r--r--src/mem/ruby/system/PersistentTable.cc264
-rw-r--r--src/mem/ruby/system/PersistentTable.hh101
-rw-r--r--src/mem/ruby/system/PseudoLRUPolicy.hh157
-rw-r--r--src/mem/ruby/system/RubyPort.cc140
-rw-r--r--src/mem/ruby/system/RubyPort.hh49
-rw-r--r--src/mem/ruby/system/Sequencer.cc880
-rw-r--r--src/mem/ruby/system/Sequencer.hh163
-rw-r--r--src/mem/ruby/system/SparseMemory.cc158
-rw-r--r--src/mem/ruby/system/SparseMemory.hh42
-rw-r--r--src/mem/ruby/system/System.cc184
-rw-r--r--src/mem/ruby/system/System.hh201
-rw-r--r--src/mem/ruby/system/TBETable.hh173
-rw-r--r--src/mem/ruby/system/TimerTable.cc137
-rw-r--r--src/mem/ruby/system/TimerTable.hh94
31 files changed, 3046 insertions, 3187 deletions
diff --git a/src/mem/ruby/system/AbstractMemOrCache.hh b/src/mem/ruby/system/AbstractMemOrCache.hh
index 4a8b667e8..28b446ef8 100644
--- a/src/mem/ruby/system/AbstractMemOrCache.hh
+++ b/src/mem/ruby/system/AbstractMemOrCache.hh
@@ -26,42 +26,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * AbstractMemOrCache.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef ABSTRACT_MEM_OR_CACHE_H
-#define ABSTRACT_MEM_OR_CACHE_H
-
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/Address.hh"
-
-class AbstractMemOrCache {
-public:
-
- virtual ~AbstractMemOrCache() {};
- virtual void setConsumer(Consumer* consumer_ptr) = 0;
- virtual Consumer* getConsumer() = 0;
-
- virtual void enqueue (const MsgPtr& message, int latency ) = 0;
- virtual void enqueueMemRef (MemoryNode& memRef) = 0;
- virtual void dequeue () = 0;
- virtual const Message* peek () = 0;
- virtual bool isReady () = 0;
- virtual MemoryNode peekNode () = 0;
- virtual bool areNSlotsAvailable (int n) = 0;
- virtual void printConfig (ostream& out) = 0;
- virtual void print (ostream& out) const = 0;
- virtual void setDebug (int debugFlag) = 0;
-
-private:
-
+#ifndef __MEM_RUBY_SYSTEM_ABSTRACTMEMORCACHE_HH__
+#define __MEM_RUBY_SYSTEM_ABSTRACTMEMORCACHE_HH__
+
+#include <iosfwd>
+
+#include "mem/ruby/slicc_interface/Message.hh"
+
+class Consumer;
+class MemoryNode;
+class Message;
+
+class AbstractMemOrCache
+{
+ public:
+ virtual ~AbstractMemOrCache() {};
+ virtual void setConsumer(Consumer* consumer_ptr) = 0;
+ virtual Consumer* getConsumer() = 0;
+
+ virtual void enqueue (const MsgPtr& message, int latency) = 0;
+ virtual void enqueueMemRef (MemoryNode& memRef) = 0;
+ virtual void dequeue () = 0;
+ virtual const Message* peek () = 0;
+ virtual bool isReady () = 0;
+ virtual MemoryNode peekNode () = 0;
+ virtual bool areNSlotsAvailable (int n) = 0;
+ virtual void printConfig (std::ostream& out) = 0;
+ virtual void print (std::ostream& out) const = 0;
+ virtual void setDebug (int debugFlag) = 0;
};
-
-#endif
-
+#endif // __MEM_RUBY_SYSTEM_ABSTRACTMEMORCACHE_HH__
diff --git a/src/mem/ruby/system/AbstractReplacementPolicy.hh b/src/mem/ruby/system/AbstractReplacementPolicy.hh
index f06b8b8ee..3ddf4ab60 100644
--- a/src/mem/ruby/system/AbstractReplacementPolicy.hh
+++ b/src/mem/ruby/system/AbstractReplacementPolicy.hh
@@ -26,64 +26,64 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ABSTRACTREPLACEMENTPOLICY_H
-#define ABSTRACTREPLACEMENTPOLICY_H
+#ifndef __MEM_RUBY_SYSTEM_ABSTRACTREPLACEMENTPOLICY_HH__
+#define __MEM_RUBY_SYSTEM_ABSTRACTREPLACEMENTPOLICY_HH__
#include "mem/ruby/common/Global.hh"
-class AbstractReplacementPolicy {
-
-public:
-
- AbstractReplacementPolicy(Index num_sets, Index assoc);
- virtual ~AbstractReplacementPolicy();
+class AbstractReplacementPolicy
+{
+ public:
+ AbstractReplacementPolicy(Index num_sets, Index assoc);
+ virtual ~AbstractReplacementPolicy();
- /* touch a block. a.k.a. update timestamp */
- virtual void touch(Index set, Index way, Time time) = 0;
+ /* touch a block. a.k.a. update timestamp */
+ virtual void touch(Index set, Index way, Time time) = 0;
- /* returns the way to replace */
- virtual Index getVictim(Index set) const = 0;
+ /* returns the way to replace */
+ virtual Index getVictim(Index set) const = 0;
- /* get the time of the last access */
- Time getLastAccess(Index set, Index way);
+ /* get the time of the last access */
+ Time getLastAccess(Index set, Index way);
- protected:
- unsigned int m_num_sets; /** total number of sets */
- unsigned int m_assoc; /** set associativity */
- Time **m_last_ref_ptr; /** timestamp of last reference */
+ protected:
+ unsigned m_num_sets; /** total number of sets */
+ unsigned m_assoc; /** set associativity */
+ Time **m_last_ref_ptr; /** timestamp of last reference */
};
inline
-AbstractReplacementPolicy::AbstractReplacementPolicy(Index num_sets, Index assoc)
+AbstractReplacementPolicy::AbstractReplacementPolicy(Index num_sets,
+ Index assoc)
{
- m_num_sets = num_sets;
- m_assoc = assoc;
- m_last_ref_ptr = new Time*[m_num_sets];
- for(unsigned int i = 0; i < m_num_sets; i++){
- m_last_ref_ptr[i] = new Time[m_assoc];
- for(unsigned int j = 0; j < m_assoc; j++){
- m_last_ref_ptr[i][j] = 0;
+ m_num_sets = num_sets;
+ m_assoc = assoc;
+ m_last_ref_ptr = new Time*[m_num_sets];
+ for(unsigned i = 0; i < m_num_sets; i++){
+ m_last_ref_ptr[i] = new Time[m_assoc];
+ for(unsigned j = 0; j < m_assoc; j++){
+ m_last_ref_ptr[i][j] = 0;
+ }
}
- }
}
inline
AbstractReplacementPolicy::~AbstractReplacementPolicy()
{
- if(m_last_ref_ptr != NULL){
- for(unsigned int i = 0; i < m_num_sets; i++){
- if(m_last_ref_ptr[i] != NULL){
- delete[] m_last_ref_ptr[i];
- }
+ if (m_last_ref_ptr != NULL){
+ for (unsigned i = 0; i < m_num_sets; i++){
+ if (m_last_ref_ptr[i] != NULL){
+ delete[] m_last_ref_ptr[i];
+ }
+ }
+ delete[] m_last_ref_ptr;
}
- delete[] m_last_ref_ptr;
- }
}
-inline
-Time AbstractReplacementPolicy::getLastAccess(Index set, Index way)
+inline Time
+AbstractReplacementPolicy::getLastAccess(Index set, Index way)
{
- return m_last_ref_ptr[set][way];
+ return m_last_ref_ptr[set][way];
}
-#endif // ABSTRACTREPLACEMENTPOLICY_H
+#endif // __MEM_RUBY_SYSTEM_ABSTRACTREPLACEMENTPOLICY_HH__
diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc
index 35625245a..10ea8a6fc 100644
--- a/src/mem/ruby/system/CacheMemory.cc
+++ b/src/mem/ruby/system/CacheMemory.cc
@@ -28,19 +28,14 @@
#include "mem/ruby/system/CacheMemory.hh"
-// ******************* Definitions *******************
-
-// Output operator definition
-ostream& operator<<(ostream& out, const CacheMemory& obj)
+ostream&
+operator<<(ostream& out, const CacheMemory& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-
-// ****************************************************************
-
CacheMemory *
RubyCacheParams::create()
{
@@ -57,410 +52,451 @@ CacheMemory::CacheMemory(const Params *p)
m_profiler_ptr = new CacheProfiler(name());
}
-
-void CacheMemory::init()
+void
+CacheMemory::init()
{
- m_cache_num_sets = (m_cache_size / m_cache_assoc) / RubySystem::getBlockSizeBytes();
+ m_cache_num_sets = (m_cache_size / m_cache_assoc) /
+ RubySystem::getBlockSizeBytes();
assert(m_cache_num_sets > 1);
m_cache_num_set_bits = log_int(m_cache_num_sets);
assert(m_cache_num_set_bits > 0);
-
- if(m_policy == "PSEUDO_LRU")
- m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
+
+ if (m_policy == "PSEUDO_LRU")
+ m_replacementPolicy_ptr =
+ new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
else if (m_policy == "LRU")
- m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc);
+ m_replacementPolicy_ptr =
+ new LRUPolicy(m_cache_num_sets, m_cache_assoc);
else
- assert(false);
-
- m_cache.setSize(m_cache_num_sets);
- m_locked.setSize(m_cache_num_sets);
- for (int i = 0; i < m_cache_num_sets; i++) {
- m_cache[i].setSize(m_cache_assoc);
- m_locked[i].setSize(m_cache_assoc);
- for (int j = 0; j < m_cache_assoc; j++) {
- m_cache[i][j] = NULL;
- m_locked[i][j] = -1;
+ assert(false);
+
+ m_cache.setSize(m_cache_num_sets);
+ m_locked.setSize(m_cache_num_sets);
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ m_cache[i].setSize(m_cache_assoc);
+ m_locked[i].setSize(m_cache_assoc);
+ for (int j = 0; j < m_cache_assoc; j++) {
+ m_cache[i][j] = NULL;
+ m_locked[i][j] = -1;
+ }
}
- }
}
CacheMemory::~CacheMemory()
{
- if(m_replacementPolicy_ptr != NULL)
- delete m_replacementPolicy_ptr;
- delete m_profiler_ptr;
- for (int i = 0; i < m_cache_num_sets; i++) {
- for (int j = 0; j < m_cache_assoc; j++) {
- delete m_cache[i][j];
+ if (m_replacementPolicy_ptr != NULL)
+ delete m_replacementPolicy_ptr;
+ delete m_profiler_ptr;
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for (int j = 0; j < m_cache_assoc; j++) {
+ delete m_cache[i][j];
+ }
}
- }
}
-void CacheMemory::printConfig(ostream& out)
+void
+CacheMemory::printConfig(ostream& out)
{
- out << "Cache config: " << m_cache_name << endl;
- out << " cache_associativity: " << m_cache_assoc << endl;
- out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl;
- const int cache_num_sets = 1 << m_cache_num_set_bits;
- out << " num_cache_sets: " << cache_num_sets << endl;
- out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl;
- out << " cache_set_size_Kbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl;
- out << " cache_set_size_Mbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl;
- out << " cache_size_bytes: "
- << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl;
- out << " cache_size_Kbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl;
- out << " cache_size_Mbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl;
+ int block_size = RubySystem::getBlockSizeBytes();
+
+ out << "Cache config: " << m_cache_name << endl;
+ out << " cache_associativity: " << m_cache_assoc << endl;
+ out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl;
+ const int cache_num_sets = 1 << m_cache_num_set_bits;
+ out << " num_cache_sets: " << cache_num_sets << endl;
+ out << " cache_set_size_bytes: " << cache_num_sets * block_size << endl;
+ out << " cache_set_size_Kbytes: "
+ << double(cache_num_sets * block_size) / (1<<10) << endl;
+ out << " cache_set_size_Mbytes: "
+ << double(cache_num_sets * block_size) / (1<<20) << endl;
+ out << " cache_size_bytes: "
+ << cache_num_sets * block_size * m_cache_assoc << endl;
+ out << " cache_size_Kbytes: "
+ << double(cache_num_sets * block_size * m_cache_assoc) / (1<<10)
+ << endl;
+ out << " cache_size_Mbytes: "
+ << double(cache_num_sets * block_size * m_cache_assoc) / (1<<20)
+ << endl;
}
-// PRIVATE METHODS
-
// convert a Address to its location in the cache
-Index CacheMemory::addressToCacheSet(const Address& address) const
+Index
+CacheMemory::addressToCacheSet(const Address& address) const
{
- assert(address == line_address(address));
- return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1);
+ assert(address == line_address(address));
+ return address.bitSelect(RubySystem::getBlockSizeBits(),
+ RubySystem::getBlockSizeBits() + m_cache_num_set_bits - 1);
}
// Given a cache index: returns the index of the tag in a set.
// returns -1 if the tag is not found.
-int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const
+int
+CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const
{
- assert(tag == line_address(tag));
- // search the set for the tags
- m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
- if (it != m_tag_index.end())
- if (m_cache[cacheSet][it->second]->m_Permission != AccessPermission_NotPresent)
- return it->second;
- return -1; // Not found
+ assert(tag == line_address(tag));
+ // search the set for the tags
+ m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
+ if (it != m_tag_index.end())
+ if (m_cache[cacheSet][it->second]->m_Permission !=
+ AccessPermission_NotPresent)
+ return it->second;
+ return -1; // Not found
}
// Given a cache index: returns the index of the tag in a set.
// returns -1 if the tag is not found.
-int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const
-{
- assert(tag == line_address(tag));
- // search the set for the tags
- m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
- if (it != m_tag_index.end())
- return it->second;
- return -1; // Not found
-}
-
-// PUBLIC METHODS
-bool CacheMemory::tryCacheAccess(const Address& address,
- CacheRequestType type,
- DataBlock*& data_ptr)
-{
- assert(address == line_address(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- if(loc != -1){ // Do we even have a tag match?
- AbstractCacheEntry* entry = m_cache[cacheSet][loc];
- m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime());
- data_ptr = &(entry->getDataBlk());
-
- if(entry->m_Permission == AccessPermission_Read_Write) {
- return true;
- }
- if ((entry->m_Permission == AccessPermission_Read_Only) &&
- (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) {
- return true;
+int
+CacheMemory::findTagInSetIgnorePermissions(Index cacheSet,
+ const Address& tag) const
+{
+ assert(tag == line_address(tag));
+ // search the set for the tags
+ m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
+ if (it != m_tag_index.end())
+ return it->second;
+ return -1; // Not found
+}
+
+bool
+CacheMemory::tryCacheAccess(const Address& address, CacheRequestType type,
+ DataBlock*& data_ptr)
+{
+ assert(address == line_address(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ if (loc != -1) {
+ // Do we even have a tag match?
+ AbstractCacheEntry* entry = m_cache[cacheSet][loc];
+ m_replacementPolicy_ptr->
+ touch(cacheSet, loc, g_eventQueue_ptr->getTime());
+ data_ptr = &(entry->getDataBlk());
+
+ if (entry->m_Permission == AccessPermission_Read_Write) {
+ return true;
+ }
+ if ((entry->m_Permission == AccessPermission_Read_Only) &&
+ (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) {
+ return true;
+ }
+ // The line must not be accessible
}
- // The line must not be accessible
- }
- data_ptr = NULL;
- return false;
+ data_ptr = NULL;
+ return false;
}
-bool CacheMemory::testCacheAccess(const Address& address,
- CacheRequestType type,
- DataBlock*& data_ptr)
+bool
+CacheMemory::testCacheAccess(const Address& address, CacheRequestType type,
+ DataBlock*& data_ptr)
{
- assert(address == line_address(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- if(loc != -1){ // Do we even have a tag match?
- AbstractCacheEntry* entry = m_cache[cacheSet][loc];
- m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime());
- data_ptr = &(entry->getDataBlk());
+ assert(address == line_address(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+
+ if (loc != -1) {
+ // Do we even have a tag match?
+ AbstractCacheEntry* entry = m_cache[cacheSet][loc];
+ m_replacementPolicy_ptr->
+ touch(cacheSet, loc, g_eventQueue_ptr->getTime());
+ data_ptr = &(entry->getDataBlk());
+
+ return m_cache[cacheSet][loc]->m_Permission !=
+ AccessPermission_NotPresent;
+ }
- return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent);
- }
- data_ptr = NULL;
- return false;
+ data_ptr = NULL;
+ return false;
}
// tests to see if an address is present in the cache
-bool CacheMemory::isTagPresent(const Address& address) const
+bool
+CacheMemory::isTagPresent(const Address& address) const
{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int location = findTagInSet(cacheSet, address);
-
- if (location == -1) {
- // We didn't find the tag
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+
+ if (loc == -1) {
+ // We didn't find the tag
+ DEBUG_EXPR(CACHE_COMP, LowPrio, address);
+ DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match");
+ return false;
+ }
DEBUG_EXPR(CACHE_COMP, LowPrio, address);
- DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match");
- return false;
- }
- DEBUG_EXPR(CACHE_COMP, LowPrio, address);
- DEBUG_MSG(CACHE_COMP, LowPrio, "found");
- return true;
+ DEBUG_MSG(CACHE_COMP, LowPrio, "found");
+ return true;
}
// Returns true if there is:
// a) a tag match on this address or there is
// b) an unused line in the same cache "way"
-bool CacheMemory::cacheAvail(const Address& address) const
+bool
+CacheMemory::cacheAvail(const Address& address) const
{
- assert(address == line_address(address));
-
- Index cacheSet = addressToCacheSet(address);
-
- for (int i=0; i < m_cache_assoc; i++) {
- AbstractCacheEntry* entry = m_cache[cacheSet][i];
- if (entry != NULL) {
- if (entry->m_Address == address || // Already in the cache
- entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry
- return true;
- }
- } else {
- return true;
+ assert(address == line_address(address));
+
+ Index cacheSet = addressToCacheSet(address);
+
+ for (int i = 0; i < m_cache_assoc; i++) {
+ AbstractCacheEntry* entry = m_cache[cacheSet][i];
+ if (entry != NULL) {
+ if (entry->m_Address == address ||
+ entry->m_Permission == AccessPermission_NotPresent) {
+ // Already in the cache or we found an empty entry
+ return true;
+ }
+ } else {
+ return true;
+ }
}
- }
- return false;
+ return false;
}
-void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry)
+void
+CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry)
{
- assert(address == line_address(address));
- assert(!isTagPresent(address));
- assert(cacheAvail(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
-
- // Find the first open slot
- Index cacheSet = addressToCacheSet(address);
- for (int i=0; i < m_cache_assoc; i++) {
- if (m_cache[cacheSet][i] == NULL ||
- m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) {
- m_cache[cacheSet][i] = entry; // Init entry
- m_cache[cacheSet][i]->m_Address = address;
- m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid;
- DPRINTF(RubyCache, "Allocate clearing lock for addr: %llx\n", address);
- m_locked[cacheSet][i] = -1;
- m_tag_index[address] = i;
-
- m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime());
-
- return;
+ assert(address == line_address(address));
+ assert(!isTagPresent(address));
+ assert(cacheAvail(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+
+ // Find the first open slot
+ Index cacheSet = addressToCacheSet(address);
+ Vector<AbstractCacheEntry*> &set = m_cache[cacheSet];
+ for (int i = 0; i < m_cache_assoc; i++) {
+ if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) {
+ set[i] = entry; // Init entry
+ set[i]->m_Address = address;
+ set[i]->m_Permission = AccessPermission_Invalid;
+ DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n",
+ address);
+ m_locked[cacheSet][i] = -1;
+ m_tag_index[address] = i;
+
+ m_replacementPolicy_ptr->
+ touch(cacheSet, i, g_eventQueue_ptr->getTime());
+
+ return;
+ }
}
- }
- ERROR_MSG("Allocate didn't find an available entry");
+ ERROR_MSG("Allocate didn't find an available entry");
}
-void CacheMemory::deallocate(const Address& address)
+void
+CacheMemory::deallocate(const Address& address)
{
- assert(address == line_address(address));
- assert(isTagPresent(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- Index cacheSet = addressToCacheSet(address);
- int location = findTagInSet(cacheSet, address);
- if (location != -1){
- delete m_cache[cacheSet][location];
- m_cache[cacheSet][location] = NULL;
- DPRINTF(RubyCache, "Deallocate clearing lock for addr: %llx\n", address);
- m_locked[cacheSet][location] = -1;
- m_tag_index.erase(address);
- }
+ assert(address == line_address(address));
+ assert(isTagPresent(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ if (loc != -1) {
+ delete m_cache[cacheSet][loc];
+ m_cache[cacheSet][loc] = NULL;
+ DPRINTF(RubyCache, "Deallocate clearing lock for addr: %x\n",
+ address);
+ m_locked[cacheSet][loc] = -1;
+ m_tag_index.erase(address);
+ }
}
// Returns with the physical address of the conflicting cache line
-Address CacheMemory::cacheProbe(const Address& address) const
+Address
+CacheMemory::cacheProbe(const Address& address) const
{
- assert(address == line_address(address));
- assert(!cacheAvail(address));
+ assert(address == line_address(address));
+ assert(!cacheAvail(address));
- Index cacheSet = addressToCacheSet(address);
- return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address;
+ Index cacheSet = addressToCacheSet(address);
+ return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->
+ m_Address;
}
// looks an address up in the cache
-AbstractCacheEntry& CacheMemory::lookup(const Address& address)
+AbstractCacheEntry&
+CacheMemory::lookup(const Address& address)
{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- return *m_cache[cacheSet][loc];
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ return *m_cache[cacheSet][loc];
}
// looks an address up in the cache
-const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const
+const AbstractCacheEntry&
+CacheMemory::lookup(const Address& address) const
{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- return *m_cache[cacheSet][loc];
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ return *m_cache[cacheSet][loc];
}
-AccessPermission CacheMemory::getPermission(const Address& address) const
+AccessPermission
+CacheMemory::getPermission(const Address& address) const
{
- assert(address == line_address(address));
- return lookup(address).m_Permission;
+ assert(address == line_address(address));
+ return lookup(address).m_Permission;
}
-void CacheMemory::changePermission(const Address& address, AccessPermission new_perm)
+void
+CacheMemory::changePermission(const Address& address,
+ AccessPermission new_perm)
{
- assert(address == line_address(address));
- lookup(address).m_Permission = new_perm;
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- if (new_perm != AccessPermission_Read_Write) {
- DPRINTF(RubyCache, "Permission clearing lock for addr: %llx\n", address);
- m_locked[cacheSet][loc] = -1;
- }
- assert(getPermission(address) == new_perm);
+ assert(address == line_address(address));
+ lookup(address).m_Permission = new_perm;
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ if (new_perm != AccessPermission_Read_Write) {
+ DPRINTF(RubyCache, "Permission clearing lock for addr: %x\n", address);
+ m_locked[cacheSet][loc] = -1;
+ }
+ assert(getPermission(address) == new_perm);
}
// Sets the most recently used bit for a cache block
-void CacheMemory::setMRU(const Address& address)
+void
+CacheMemory::setMRU(const Address& address)
{
- Index cacheSet;
+ Index cacheSet;
- cacheSet = addressToCacheSet(address);
- m_replacementPolicy_ptr->touch(cacheSet,
- findTagInSet(cacheSet, address),
- g_eventQueue_ptr->getTime());
+ cacheSet = addressToCacheSet(address);
+ m_replacementPolicy_ptr->
+ touch(cacheSet, findTagInSet(cacheSet, address),
+ g_eventQueue_ptr->getTime());
}
-void CacheMemory::profileMiss(const CacheMsg & msg)
+void
+CacheMemory::profileMiss(const CacheMsg& msg)
{
- m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(),
- msg.getSize(), msg.getPrefetch());
+ m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(),
+ msg.getSize(), msg.getPrefetch());
}
-void CacheMemory::recordCacheContents(CacheRecorder& tr) const
+void
+CacheMemory::recordCacheContents(CacheRecorder& tr) const
{
- for (int i = 0; i < m_cache_num_sets; i++) {
- for (int j = 0; j < m_cache_assoc; j++) {
- AccessPermission perm = m_cache[i][j]->m_Permission;
- CacheRequestType request_type = CacheRequestType_NULL;
- if (perm == AccessPermission_Read_Only) {
- if (m_is_instruction_only_cache) {
- request_type = CacheRequestType_IFETCH;
- } else {
- request_type = CacheRequestType_LD;
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for (int j = 0; j < m_cache_assoc; j++) {
+ AccessPermission perm = m_cache[i][j]->m_Permission;
+ CacheRequestType request_type = CacheRequestType_NULL;
+ if (perm == AccessPermission_Read_Only) {
+ if (m_is_instruction_only_cache) {
+ request_type = CacheRequestType_IFETCH;
+ } else {
+ request_type = CacheRequestType_LD;
+ }
+ } else if (perm == AccessPermission_Read_Write) {
+ request_type = CacheRequestType_ST;
+ }
+
+ if (request_type != CacheRequestType_NULL) {
+#if 0
+ tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address,
+ Address(0), request_type,
+ m_replacementPolicy_ptr->getLastAccess(i, j));
+#endif
+ }
}
- } else if (perm == AccessPermission_Read_Write) {
- request_type = CacheRequestType_ST;
- }
-
- if (request_type != CacheRequestType_NULL) {
- // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address,
- // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j));
- }
}
- }
-}
-
-void CacheMemory::print(ostream& out) const
-{
- out << "Cache dump: " << m_cache_name << endl;
- for (int i = 0; i < m_cache_num_sets; i++) {
- for (int j = 0; j < m_cache_assoc; j++) {
- if (m_cache[i][j] != NULL) {
- out << " Index: " << i
- << " way: " << j
- << " entry: " << *m_cache[i][j] << endl;
- } else {
- out << " Index: " << i
- << " way: " << j
- << " entry: NULL" << endl;
- }
+}
+
+void
+CacheMemory::print(ostream& out) const
+{
+ out << "Cache dump: " << m_cache_name << endl;
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for (int j = 0; j < m_cache_assoc; j++) {
+ if (m_cache[i][j] != NULL) {
+ out << " Index: " << i
+ << " way: " << j
+ << " entry: " << *m_cache[i][j] << endl;
+ } else {
+ out << " Index: " << i
+ << " way: " << j
+ << " entry: NULL" << endl;
+ }
+ }
}
- }
}
-void CacheMemory::printData(ostream& out) const
+void
+CacheMemory::printData(ostream& out) const
{
- out << "printData() not supported" << endl;
+ out << "printData() not supported" << endl;
}
-void CacheMemory::clearStats() const
+void
+CacheMemory::clearStats() const
{
- m_profiler_ptr->clearStats();
+ m_profiler_ptr->clearStats();
}
-void CacheMemory::printStats(ostream& out) const
+void
+CacheMemory::printStats(ostream& out) const
{
- m_profiler_ptr->printStats(out);
+ m_profiler_ptr->printStats(out);
}
-void CacheMemory::getMemoryValue(const Address& addr, char* value,
- unsigned int size_in_bytes ){
- AbstractCacheEntry& entry = lookup(line_address(addr));
- unsigned int startByte = addr.getAddress() - line_address(addr).getAddress();
- for(unsigned int i=0; i<size_in_bytes; ++i){
- value[i] = entry.getDataBlk().getByte(i + startByte);
- }
+void
+CacheMemory::getMemoryValue(const Address& addr, char* value,
+ unsigned size_in_bytes)
+{
+ AbstractCacheEntry& entry = lookup(line_address(addr));
+ unsigned startByte = addr.getAddress() - line_address(addr).getAddress();
+ for (unsigned i = 0; i < size_in_bytes; ++i) {
+ value[i] = entry.getDataBlk().getByte(i + startByte);
+ }
}
-void CacheMemory::setMemoryValue(const Address& addr, char* value,
- unsigned int size_in_bytes ){
- AbstractCacheEntry& entry = lookup(line_address(addr));
- unsigned int startByte = addr.getAddress() - line_address(addr).getAddress();
- assert(size_in_bytes > 0);
- for(unsigned int i=0; i<size_in_bytes; ++i){
- entry.getDataBlk().setByte(i + startByte, value[i]);
- }
+void
+CacheMemory::setMemoryValue(const Address& addr, char* value,
+ unsigned size_in_bytes)
+{
+ AbstractCacheEntry& entry = lookup(line_address(addr));
+ unsigned startByte = addr.getAddress() - line_address(addr).getAddress();
+ assert(size_in_bytes > 0);
+ for (unsigned i = 0; i < size_in_bytes; ++i) {
+ entry.getDataBlk().setByte(i + startByte, value[i]);
+ }
- // entry = lookup(line_address(addr));
+ // entry = lookup(line_address(addr));
}
-void
-CacheMemory::setLocked(const Address& address, int context)
-{
- DPRINTF(RubyCache,
- "Setting Lock for addr: %llx to %d\n",
- address,
- context);
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- m_locked[cacheSet][loc] = context;
+void
+CacheMemory::setLocked(const Address& address, int context)
+{
+ DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", address, context);
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ m_locked[cacheSet][loc] = context;
}
-void
-CacheMemory::clearLocked(const Address& address)
+void
+CacheMemory::clearLocked(const Address& address)
{
- DPRINTF(RubyCache, "Clear Lock for addr: %llx\n", address);
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- m_locked[cacheSet][loc] = -1;
+ DPRINTF(RubyCache, "Clear Lock for addr: %x\n", address);
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ m_locked[cacheSet][loc] = -1;
}
bool
CacheMemory::isLocked(const Address& address, int context)
{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- DPRINTF(RubyCache,
- "Testing Lock for addr: %llx cur %d con %d\n",
- address,
- m_locked[cacheSet][loc],
- context);
- return m_locked[cacheSet][loc] == context;
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n",
+ address, m_locked[cacheSet][loc], context);
+ return m_locked[cacheSet][loc] == context;
}
diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh
index 74eb5d68d..bdf2bb25c 100644
--- a/src/mem/ruby/system/CacheMemory.hh
+++ b/src/mem/ruby/system/CacheMemory.hh
@@ -26,151 +26,144 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * CacheMemory.hh
- *
- * Description:
- *
- * $Id: CacheMemory.hh,v 3.7 2004/06/18 20:15:15 beckmann Exp $
- *
- */
+#ifndef __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__
+#define __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__
-#ifndef CACHEMEMORY_H
-#define CACHEMEMORY_H
-
-#include "sim/sim_object.hh"
-#include "params/RubyCache.hh"
+#include <vector>
-#include "mem/ruby/common/Global.hh"
+#include "base/hashmap.hh"
+#include "mem/gems_common/Vector.hh"
#include "mem/protocol/AccessPermission.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/recorder/CacheRecorder.hh"
+#include "mem/protocol/CacheMsg.hh"
#include "mem/protocol/CacheRequestType.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/ruby/common/DataBlock.hh"
#include "mem/protocol/MachineType.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/DataBlock.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/profiler/CacheProfiler.hh"
+#include "mem/ruby/recorder/CacheRecorder.hh"
+#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
-#include "mem/ruby/system/PseudoLRUPolicy.hh"
#include "mem/ruby/system/LRUPolicy.hh"
-#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
+#include "mem/ruby/system/PseudoLRUPolicy.hh"
#include "mem/ruby/system/System.hh"
-#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "mem/ruby/profiler/CacheProfiler.hh"
-#include "mem/protocol/CacheMsg.hh"
-#include "base/hashmap.hh"
-#include <vector>
-
-class CacheMemory : public SimObject {
-public:
+#include "params/RubyCache.hh"
+#include "sim/sim_object.hh"
+class CacheMemory : public SimObject
+{
+ public:
typedef RubyCacheParams Params;
- // Constructors
- CacheMemory(const Params *p);
- // CacheMemory(const string & name);
- void init();
-
- // Destructor
- ~CacheMemory();
+ CacheMemory(const Params *p);
+ ~CacheMemory();
- // Public Methods
- void printConfig(ostream& out);
+ void init();
- // perform a cache access and see if we hit or not. Return true on a hit.
- bool tryCacheAccess(const Address& address, CacheRequestType type, DataBlock*& data_ptr);
+ // Public Methods
+ void printConfig(ostream& out);
- // similar to above, but doesn't require full access check
- bool testCacheAccess(const Address& address, CacheRequestType type, DataBlock*& data_ptr);
+ // perform a cache access and see if we hit or not. Return true on a hit.
+ bool tryCacheAccess(const Address& address, CacheRequestType type,
+ DataBlock*& data_ptr);
- // tests to see if an address is present in the cache
- bool isTagPresent(const Address& address) const;
+ // similar to above, but doesn't require full access check
+ bool testCacheAccess(const Address& address, CacheRequestType type,
+ DataBlock*& data_ptr);
- // Returns true if there is:
- // a) a tag match on this address or there is
- // b) an unused line in the same cache "way"
- bool cacheAvail(const Address& address) const;
+ // tests to see if an address is present in the cache
+ bool isTagPresent(const Address& address) const;
- // find an unused entry and sets the tag appropriate for the address
- void allocate(const Address& address, AbstractCacheEntry* new_entry);
+ // Returns true if there is:
+ // a) a tag match on this address or there is
+ // b) an unused line in the same cache "way"
+ bool cacheAvail(const Address& address) const;
- // Explicitly free up this address
- void deallocate(const Address& address);
+ // find an unused entry and sets the tag appropriate for the address
+ void allocate(const Address& address, AbstractCacheEntry* new_entry);
- // Returns with the physical address of the conflicting cache line
- Address cacheProbe(const Address& address) const;
+ // Explicitly free up this address
+ void deallocate(const Address& address);
- // looks an address up in the cache
- AbstractCacheEntry& lookup(const Address& address);
- const AbstractCacheEntry& lookup(const Address& address) const;
+ // Returns with the physical address of the conflicting cache line
+ Address cacheProbe(const Address& address) const;
- // Get/Set permission of cache block
- AccessPermission getPermission(const Address& address) const;
- void changePermission(const Address& address, AccessPermission new_perm);
+ // looks an address up in the cache
+ AbstractCacheEntry& lookup(const Address& address);
+ const AbstractCacheEntry& lookup(const Address& address) const;
- int getLatency() const { return m_latency; }
+ // Get/Set permission of cache block
+ AccessPermission getPermission(const Address& address) const;
+ void changePermission(const Address& address, AccessPermission new_perm);
- // Hook for checkpointing the contents of the cache
- void recordCacheContents(CacheRecorder& tr) const;
- void setAsInstructionCache(bool is_icache) { m_is_instruction_only_cache = is_icache; }
+ int getLatency() const { return m_latency; }
- // Set this address to most recently used
- void setMRU(const Address& address);
+ // Hook for checkpointing the contents of the cache
+ void recordCacheContents(CacheRecorder& tr) const;
+ void
+ setAsInstructionCache(bool is_icache)
+ {
+ m_is_instruction_only_cache = is_icache;
+ }
- void profileMiss(const CacheMsg & msg);
+ // Set this address to most recently used
+ void setMRU(const Address& address);
- void getMemoryValue(const Address& addr, char* value,
- unsigned int size_in_bytes );
- void setMemoryValue(const Address& addr, char* value,
- unsigned int size_in_bytes );
+ void profileMiss(const CacheMsg & msg);
- void setLocked (const Address& addr, int context);
- void clearLocked (const Address& addr);
- bool isLocked (const Address& addr, int context);
- // Print cache contents
- void print(ostream& out) const;
- void printData(ostream& out) const;
+ void getMemoryValue(const Address& addr, char* value,
+ unsigned int size_in_bytes);
+ void setMemoryValue(const Address& addr, char* value,
+ unsigned int size_in_bytes);
- void clearStats() const;
- void printStats(ostream& out) const;
+ void setLocked (const Address& addr, int context);
+ void clearLocked (const Address& addr);
+ bool isLocked (const Address& addr, int context);
+ // Print cache contents
+ void print(ostream& out) const;
+ void printData(ostream& out) const;
-private:
- // Private Methods
+ void clearStats() const;
+ void printStats(ostream& out) const;
- // convert a Address to its location in the cache
- Index addressToCacheSet(const Address& address) const;
+ private:
+ // convert a Address to its location in the cache
+ Index addressToCacheSet(const Address& address) const;
- // Given a cache tag: returns the index of the tag in a set.
- // returns -1 if the tag is not found.
- int findTagInSet(Index line, const Address& tag) const;
- int findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const;
+ // Given a cache tag: returns the index of the tag in a set.
+ // returns -1 if the tag is not found.
+ int findTagInSet(Index line, const Address& tag) const;
+ int findTagInSetIgnorePermissions(Index cacheSet,
+ const Address& tag) const;
- // Private copy constructor and assignment operator
- CacheMemory(const CacheMemory& obj);
- CacheMemory& operator=(const CacheMemory& obj);
+ // Private copy constructor and assignment operator
+ CacheMemory(const CacheMemory& obj);
+ CacheMemory& operator=(const CacheMemory& obj);
-private:
- const string m_cache_name;
- int m_latency;
+ private:
+ const string m_cache_name;
+ int m_latency;
- // Data Members (m_prefix)
- bool m_is_instruction_only_cache;
- bool m_is_data_only_cache;
+ // Data Members (m_prefix)
+ bool m_is_instruction_only_cache;
+ bool m_is_data_only_cache;
- // The first index is the # of cache lines.
- // The second index is the the amount associativity.
- m5::hash_map<Address, int> m_tag_index;
- Vector<Vector<AbstractCacheEntry*> > m_cache;
- Vector<Vector<int> > m_locked;
+ // The first index is the # of cache lines.
+ // The second index is the the amount associativity.
+ m5::hash_map<Address, int> m_tag_index;
+ Vector<Vector<AbstractCacheEntry*> > m_cache;
+ Vector<Vector<int> > m_locked;
- AbstractReplacementPolicy *m_replacementPolicy_ptr;
+ AbstractReplacementPolicy *m_replacementPolicy_ptr;
- CacheProfiler* m_profiler_ptr;
+ CacheProfiler* m_profiler_ptr;
- int m_cache_size;
- string m_policy;
- int m_cache_num_sets;
- int m_cache_num_set_bits;
- int m_cache_assoc;
+ int m_cache_size;
+ string m_policy;
+ int m_cache_num_sets;
+ int m_cache_num_set_bits;
+ int m_cache_assoc;
};
-#endif //CACHEMEMORY_H
+#endif // __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__
diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc
index 063b66862..315dab62a 100644
--- a/src/mem/ruby/system/DMASequencer.cc
+++ b/src/mem/ruby/system/DMASequencer.cc
@@ -26,149 +26,148 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "mem/ruby/system/DMASequencer.hh"
-#include "mem/ruby/buffers/MessageBuffer.hh"
-#include "mem/ruby/slicc_interface/AbstractController.hh"
-
-/* SLICC generated types */
#include "mem/protocol/SequencerMsg.hh"
#include "mem/protocol/SequencerRequestType.hh"
+#include "mem/ruby/buffers/MessageBuffer.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/ruby/system/DMASequencer.hh"
#include "mem/ruby/system/System.hh"
-//
-// Fix me: This code needs comments!
-//
-
DMASequencer::DMASequencer(const Params *p)
- : RubyPort(p)
+ : RubyPort(p)
{
}
-void DMASequencer::init()
+void
+DMASequencer::init()
{
- RubyPort::init();
- m_is_busy = false;
- m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
+ RubyPort::init();
+ m_is_busy = false;
+ m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
}
-RequestStatus DMASequencer::makeRequest(const RubyRequest & request)
+RequestStatus
+DMASequencer::makeRequest(const RubyRequest &request)
{
- uint64_t paddr = request.paddr;
- uint8_t* data = request.data;
- int len = request.len;
- bool write = false;
- switch(request.type) {
- case RubyRequestType_LD:
- write = false;
- break;
- case RubyRequestType_ST:
- write = true;
- break;
- case RubyRequestType_NULL:
- case RubyRequestType_IFETCH:
- case RubyRequestType_Locked_Read:
- case RubyRequestType_Locked_Write:
- case RubyRequestType_RMW_Read:
- case RubyRequestType_RMW_Write:
- case RubyRequestType_NUM:
- panic("DMASequencer::makeRequest does not support the RubyRequestType");
- return RequestStatus_NULL;
- }
-
- assert(!m_is_busy); // only support one outstanding DMA request
- m_is_busy = true;
-
- active_request.start_paddr = paddr;
- active_request.write = write;
- active_request.data = data;
- active_request.len = len;
- active_request.bytes_completed = 0;
- active_request.bytes_issued = 0;
- active_request.pkt = request.pkt;
-
- SequencerMsg msg;
- msg.getPhysicalAddress() = Address(paddr);
- msg.getLineAddress() = line_address(msg.getPhysicalAddress());
- msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
- int offset = paddr & m_data_block_mask;
-
- msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
- len :
- RubySystem::getBlockSizeBytes() - offset;
-
- if (write) {
- msg.getDataBlk().setData(data, offset, msg.getLen());
- }
-
- assert(m_mandatory_q_ptr != NULL);
- m_mandatory_q_ptr->enqueue(msg);
- active_request.bytes_issued += msg.getLen();
-
- return RequestStatus_Issued;
+ uint64_t paddr = request.paddr;
+ uint8_t* data = request.data;
+ int len = request.len;
+ bool write = false;
+ switch(request.type) {
+ case RubyRequestType_LD:
+ write = false;
+ break;
+ case RubyRequestType_ST:
+ write = true;
+ break;
+ case RubyRequestType_NULL:
+ case RubyRequestType_IFETCH:
+ case RubyRequestType_Locked_Read:
+ case RubyRequestType_Locked_Write:
+ case RubyRequestType_RMW_Read:
+ case RubyRequestType_RMW_Write:
+ case RubyRequestType_NUM:
+ panic("DMASequencer::makeRequest does not support RubyRequestType");
+ return RequestStatus_NULL;
+ }
+
+ assert(!m_is_busy); // only support one outstanding DMA request
+ m_is_busy = true;
+
+ active_request.start_paddr = paddr;
+ active_request.write = write;
+ active_request.data = data;
+ active_request.len = len;
+ active_request.bytes_completed = 0;
+ active_request.bytes_issued = 0;
+ active_request.pkt = request.pkt;
+
+ SequencerMsg msg;
+ msg.getPhysicalAddress() = Address(paddr);
+ msg.getLineAddress() = line_address(msg.getPhysicalAddress());
+ msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
+ int offset = paddr & m_data_block_mask;
+
+ msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
+ len : RubySystem::getBlockSizeBytes() - offset;
+
+ if (write) {
+ msg.getDataBlk().setData(data, offset, msg.getLen());
+ }
+
+ assert(m_mandatory_q_ptr != NULL);
+ m_mandatory_q_ptr->enqueue(msg);
+ active_request.bytes_issued += msg.getLen();
+
+ return RequestStatus_Issued;
}
-void DMASequencer::issueNext()
+void
+DMASequencer::issueNext()
{
- assert(m_is_busy == true);
- active_request.bytes_completed = active_request.bytes_issued;
- if (active_request.len == active_request.bytes_completed) {
- ruby_hit_callback(active_request.pkt);
- m_is_busy = false;
- return;
- }
-
- SequencerMsg msg;
- msg.getPhysicalAddress() = Address(active_request.start_paddr +
- active_request.bytes_completed);
-
- assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
- msg.getLineAddress() = line_address(msg.getPhysicalAddress());
-
- msg.getType() = (active_request.write ? SequencerRequestType_ST :
- SequencerRequestType_LD);
-
- msg.getLen() = (active_request.len -
- active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
- active_request.len - active_request.bytes_completed :
- RubySystem::getBlockSizeBytes());
-
- if (active_request.write) {
- msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed],
- 0, msg.getLen());
- msg.getType() = SequencerRequestType_ST;
- } else {
- msg.getType() = SequencerRequestType_LD;
- }
-
- assert(m_mandatory_q_ptr != NULL);
- m_mandatory_q_ptr->enqueue(msg);
- active_request.bytes_issued += msg.getLen();
+ assert(m_is_busy == true);
+ active_request.bytes_completed = active_request.bytes_issued;
+ if (active_request.len == active_request.bytes_completed) {
+ ruby_hit_callback(active_request.pkt);
+ m_is_busy = false;
+ return;
+ }
+
+ SequencerMsg msg;
+ msg.getPhysicalAddress() = Address(active_request.start_paddr +
+ active_request.bytes_completed);
+
+ assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
+ msg.getLineAddress() = line_address(msg.getPhysicalAddress());
+
+ msg.getType() = (active_request.write ? SequencerRequestType_ST :
+ SequencerRequestType_LD);
+
+ msg.getLen() =
+ (active_request.len -
+ active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
+ active_request.len - active_request.bytes_completed :
+ RubySystem::getBlockSizeBytes());
+
+ if (active_request.write) {
+ msg.getDataBlk().
+ setData(&active_request.data[active_request.bytes_completed],
+ 0, msg.getLen());
+ msg.getType() = SequencerRequestType_ST;
+ } else {
+ msg.getType() = SequencerRequestType_LD;
+ }
+
+ assert(m_mandatory_q_ptr != NULL);
+ m_mandatory_q_ptr->enqueue(msg);
+ active_request.bytes_issued += msg.getLen();
}
-void DMASequencer::dataCallback(const DataBlock & dblk)
+void
+DMASequencer::dataCallback(const DataBlock & dblk)
{
- assert(m_is_busy == true);
- int len = active_request.bytes_issued - active_request.bytes_completed;
- int offset = 0;
- if (active_request.bytes_completed == 0)
- offset = active_request.start_paddr & m_data_block_mask;
- assert( active_request.write == false );
- memcpy(&active_request.data[active_request.bytes_completed],
- dblk.getData(offset, len), len);
- issueNext();
+ assert(m_is_busy == true);
+ int len = active_request.bytes_issued - active_request.bytes_completed;
+ int offset = 0;
+ if (active_request.bytes_completed == 0)
+ offset = active_request.start_paddr & m_data_block_mask;
+ assert(active_request.write == false);
+ memcpy(&active_request.data[active_request.bytes_completed],
+ dblk.getData(offset, len), len);
+ issueNext();
}
-void DMASequencer::ackCallback()
+void
+DMASequencer::ackCallback()
{
- issueNext();
+ issueNext();
}
-void DMASequencer::printConfig(ostream & out)
+void
+DMASequencer::printConfig(ostream & out)
{
-
}
-
DMASequencer *
DMASequencerParams::create()
{
diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh
index 24129526a..61d7ef1c6 100644
--- a/src/mem/ruby/system/DMASequencer.hh
+++ b/src/mem/ruby/system/DMASequencer.hh
@@ -26,48 +26,50 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DMASEQUENCER_H
-#define DMASEQUENCER_H
+#ifndef __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__
+#define __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__
#include <ostream>
+
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/system/RubyPort.hh"
-
#include "params/DMASequencer.hh"
-struct DMARequest {
- uint64_t start_paddr;
- int len;
- bool write;
- int bytes_completed;
- int bytes_issued;
- uint8* data;
- PacketPtr pkt;
+struct DMARequest
+{
+ uint64_t start_paddr;
+ int len;
+ bool write;
+ int bytes_completed;
+ int bytes_issued;
+ uint8* data;
+ PacketPtr pkt;
};
-class DMASequencer :public RubyPort {
-public:
+class DMASequencer : public RubyPort
+{
+ public:
typedef DMASequencerParams Params;
- DMASequencer(const Params *);
- void init();
- /* external interface */
- RequestStatus makeRequest(const RubyRequest & request);
- bool busy() { return m_is_busy;}
+ DMASequencer(const Params *);
+ void init();
+ /* external interface */
+ RequestStatus makeRequest(const RubyRequest & request);
+ bool busy() { return m_is_busy;}
- /* SLICC callback */
- void dataCallback(const DataBlock & dblk);
- void ackCallback();
+ /* SLICC callback */
+ void dataCallback(const DataBlock & dblk);
+ void ackCallback();
- void printConfig(std::ostream & out);
+ void printConfig(std::ostream & out);
-private:
- void issueNext();
+ private:
+ void issueNext();
-private:
- bool m_is_busy;
- uint64_t m_data_block_mask;
- DMARequest active_request;
- int num_active_requests;
+ private:
+ bool m_is_busy;
+ uint64_t m_data_block_mask;
+ DMARequest active_request;
+ int num_active_requests;
};
-#endif // DMACONTROLLER_H
+#endif // __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__
diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc
index d8037aec1..93f537090 100644
--- a/src/mem/ruby/system/DirectoryMemory.cc
+++ b/src/mem/ruby/system/DirectoryMemory.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,19 +26,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * DirectoryMemory.cc
- *
- * Description: See DirectoryMemory.hh
- *
- * $Id$
- *
- */
-
-#include "mem/ruby/system/System.hh"
-#include "mem/ruby/system/DirectoryMemory.hh"
-#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
#include "mem/gems_common/util.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
+#include "mem/ruby/system/DirectoryMemory.hh"
+#include "mem/ruby/system/System.hh"
int DirectoryMemory::m_num_directories = 0;
int DirectoryMemory::m_num_directories_bits = 0;
@@ -58,89 +48,95 @@ DirectoryMemory::DirectoryMemory(const Params *p)
m_numa_high_bit = p->numa_high_bit;
}
-void DirectoryMemory::init()
+void
+DirectoryMemory::init()
{
- m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
-
- if (m_use_map) {
- int entry_bits = log_int(m_num_entries);
- assert(entry_bits >= m_map_levels);
- m_sparseMemory = new SparseMemory(entry_bits, m_map_levels);
- } else {
- m_entries = new Directory_Entry*[m_num_entries];
- for (int i=0; i < m_num_entries; i++)
- m_entries[i] = NULL;
- m_ram = g_system_ptr->getMemoryVector();
- }
-
- m_num_directories++;
- m_num_directories_bits = log_int(m_num_directories);
- m_total_size_bytes += m_size_bytes;
-
- if (m_numa_high_bit == 0) {
- m_numa_high_bit = RubySystem::getMemorySizeBits();
- }
- assert(m_numa_high_bit != 0);
+ m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
+
+ if (m_use_map) {
+ int entry_bits = log_int(m_num_entries);
+ assert(entry_bits >= m_map_levels);
+ m_sparseMemory = new SparseMemory(entry_bits, m_map_levels);
+ } else {
+ m_entries = new Directory_Entry*[m_num_entries];
+ for (int i = 0; i < m_num_entries; i++)
+ m_entries[i] = NULL;
+ m_ram = g_system_ptr->getMemoryVector();
+ }
+
+ m_num_directories++;
+ m_num_directories_bits = log_int(m_num_directories);
+ m_total_size_bytes += m_size_bytes;
+
+ if (m_numa_high_bit == 0) {
+ m_numa_high_bit = RubySystem::getMemorySizeBits();
+ }
+ assert(m_numa_high_bit != 0);
}
DirectoryMemory::~DirectoryMemory()
{
- // free up all the directory entries
- if (m_entries != NULL) {
- for (uint64 i = 0; i < m_num_entries; i++) {
- if (m_entries[i] != NULL) {
- delete m_entries[i];
- }
- }
- delete [] m_entries;
- } else if (m_use_map) {
- delete m_sparseMemory;
- }
+ // free up all the directory entries
+ if (m_entries != NULL) {
+ for (uint64 i = 0; i < m_num_entries; i++) {
+ if (m_entries[i] != NULL) {
+ delete m_entries[i];
+ }
+ }
+ delete [] m_entries;
+ } else if (m_use_map) {
+ delete m_sparseMemory;
+ }
}
-void DirectoryMemory::printConfig(ostream& out) const
+void
+DirectoryMemory::printConfig(ostream& out) const
{
- out << "DirectoryMemory module config: " << m_name << endl;
- out << " version: " << m_version << endl;
- out << " memory_bits: " << m_size_bits << endl;
- out << " memory_size_bytes: " << m_size_bytes << endl;
- out << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl;
- out << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl;
- out << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl;
+ out << "DirectoryMemory module config: " << m_name << endl
+ << " version: " << m_version << endl
+ << " memory_bits: " << m_size_bits << endl
+ << " memory_size_bytes: " << m_size_bytes << endl
+ << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl
+ << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl
+ << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl;
}
// Static method
-void DirectoryMemory::printGlobalConfig(ostream & out)
+void
+DirectoryMemory::printGlobalConfig(ostream & out)
{
- out << "DirectoryMemory Global Config: " << endl;
- out << " number of directory memories: " << m_num_directories << endl;
- if (m_num_directories > 1) {
- out << " number of selection bits: " << m_num_directories_bits << endl;
- out << " selection bits: " << m_numa_high_bit
- << "-" << m_numa_high_bit-m_num_directories_bits
- << endl;
- }
- out << " total memory size bytes: " << m_total_size_bytes << endl;
- out << " total memory bits: " << log_int(m_total_size_bytes) << endl;
-
+ out << "DirectoryMemory Global Config: " << endl;
+ out << " number of directory memories: " << m_num_directories << endl;
+ if (m_num_directories > 1) {
+ out << " number of selection bits: " << m_num_directories_bits << endl
+ << " selection bits: " << m_numa_high_bit
+ << "-" << m_numa_high_bit-m_num_directories_bits
+ << endl;
+ }
+ out << " total memory size bytes: " << m_total_size_bytes << endl;
+ out << " total memory bits: " << log_int(m_total_size_bytes) << endl;
}
-uint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
+uint64
+DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
{
- if (m_num_directories_bits == 0) return 0;
- uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits,
- m_numa_high_bit);
- return ret;
+ if (m_num_directories_bits == 0)
+ return 0;
+
+ uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits,
+ m_numa_high_bit);
+ return ret;
}
-// Public method
-bool DirectoryMemory::isPresent(PhysAddress address)
+bool
+DirectoryMemory::isPresent(PhysAddress address)
{
- bool ret = (mapAddressToDirectoryVersion(address) == m_version);
- return ret;
+ bool ret = (mapAddressToDirectoryVersion(address) == m_version);
+ return ret;
}
-uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
+uint64
+DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
{
uint64 ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits,
m_numa_high_bit)
@@ -148,98 +144,99 @@ uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
return ret;
}
-Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
+Directory_Entry&
+DirectoryMemory::lookup(PhysAddress address)
{
- assert(isPresent(address));
- Directory_Entry* entry;
- uint64 idx;
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
-
- if (m_use_map) {
- if (m_sparseMemory->exist(address)) {
- entry = m_sparseMemory->lookup(address);
- assert(entry != NULL);
- } else {
- //
- // Note: SparseMemory internally creates a new Directory Entry
- //
- m_sparseMemory->add(address);
- entry = m_sparseMemory->lookup(address);
- }
- } else {
- idx = mapAddressToLocalIdx(address);
- assert(idx < m_num_entries);
- entry = m_entries[idx];
+ assert(isPresent(address));
+ Directory_Entry* entry;
+ uint64 idx;
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- if (entry == NULL) {
- entry = new Directory_Entry();
- entry->getDataBlk().assign(m_ram->getBlockPtr(address));
- m_entries[idx] = entry;
+ if (m_use_map) {
+ if (m_sparseMemory->exist(address)) {
+ entry = m_sparseMemory->lookup(address);
+ assert(entry != NULL);
+ } else {
+ // Note: SparseMemory internally creates a new Directory Entry
+ m_sparseMemory->add(address);
+ entry = m_sparseMemory->lookup(address);
+ }
+ } else {
+ idx = mapAddressToLocalIdx(address);
+ assert(idx < m_num_entries);
+ entry = m_entries[idx];
+
+ if (entry == NULL) {
+ entry = new Directory_Entry();
+ entry->getDataBlk().assign(m_ram->getBlockPtr(address));
+ m_entries[idx] = entry;
+ }
}
- }
- return (*entry);
-}
-/*
-Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
-{
- assert(isPresent(address));
- Index index = address.memoryModuleIndex();
-
- if (index < 0 || index > m_size) {
- WARN_EXPR(address.getAddress());
- WARN_EXPR(index);
- WARN_EXPR(m_size);
- ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
- }
- Directory_Entry* entry = m_entries[index];
-
- // allocate the directory entry on demand.
- if (entry == NULL) {
- entry = new Directory_Entry;
- entry->getDataBlk().assign(m_ram->getBlockPtr(address));
-
- // store entry to the table
- m_entries[index] = entry;
- }
-
- return (*entry);
+ return *entry;
}
-*/
-void DirectoryMemory::invalidateBlock(PhysAddress address)
+#if 0
+Directory_Entry&
+DirectoryMemory::lookup(PhysAddress address)
{
-
- if (m_use_map) {
- assert(m_sparseMemory->exist(address));
- m_sparseMemory->remove(address);
- }
- /*
- else {
assert(isPresent(address));
-
Index index = address.memoryModuleIndex();
-
+
if (index < 0 || index > m_size) {
- ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
+ WARN_EXPR(address.getAddress());
+ WARN_EXPR(index);
+ WARN_EXPR(m_size);
+ ERROR_MSG("Directory Memory Assertion: accessing memory out of range");
}
+ Directory_Entry* entry = m_entries[index];
- if(m_entries[index] != NULL){
- delete m_entries[index];
- m_entries[index] = NULL;
- }
- }
- */
+ // allocate the directory entry on demand.
+ if (entry == NULL) {
+ entry = new Directory_Entry;
+ entry->getDataBlk().assign(m_ram->getBlockPtr(address));
+ // store entry to the table
+ m_entries[index] = entry;
+ }
+ return *entry;
}
+#endif
-void DirectoryMemory::print(ostream& out) const
+void
+DirectoryMemory::invalidateBlock(PhysAddress address)
{
+ if (m_use_map) {
+ assert(m_sparseMemory->exist(address));
+ m_sparseMemory->remove(address);
+ }
+#if 0
+ else {
+ assert(isPresent(address));
+
+ Index index = address.memoryModuleIndex();
+
+ if (index < 0 || index > m_size) {
+ ERROR_MSG("Directory Memory Assertion: "
+ "accessing memory out of range.");
+ }
+
+ if (m_entries[index] != NULL){
+ delete m_entries[index];
+ m_entries[index] = NULL;
+ }
+ }
+#endif
+}
+void
+DirectoryMemory::print(ostream& out) const
+{
}
-void DirectoryMemory::printStats(ostream& out) const
+void
+DirectoryMemory::printStats(ostream& out) const
{
if (m_use_map) {
m_sparseMemory->printStats(out);
diff --git a/src/mem/ruby/system/DirectoryMemory.hh b/src/mem/ruby/system/DirectoryMemory.hh
index 8b23ced02..4e7bfc4f6 100644
--- a/src/mem/ruby/system/DirectoryMemory.hh
+++ b/src/mem/ruby/system/DirectoryMemory.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,94 +26,74 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * DirectoryMemory.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef DIRECTORYMEMORY_H
-#define DIRECTORYMEMORY_H
+#ifndef __MEM_RUBY_SYSTEM_DIRECTORYMEMORY_HH__
+#define __MEM_RUBY_SYSTEM_DIRECTORYMEMORY_HH__
-#include "mem/ruby/common/Global.hh"
+#include "mem/protocol/Directory_Entry.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/MemoryVector.hh"
-#include "mem/protocol/Directory_Entry.hh"
-#include "sim/sim_object.hh"
-#include "params/RubyDirectoryMemory.hh"
#include "mem/ruby/system/SparseMemory.hh"
+#include "params/RubyDirectoryMemory.hh"
+#include "sim/sim_object.hh"
-class DirectoryMemory : public SimObject {
-public:
- // Constructors
+class DirectoryMemory : public SimObject
+{
+ public:
typedef RubyDirectoryMemoryParams Params;
DirectoryMemory(const Params *p);
- void init();
- // DirectoryMemory(int version);
-
- // Destructor
- ~DirectoryMemory();
-
- uint64 mapAddressToLocalIdx(PhysAddress address);
- static uint64 mapAddressToDirectoryVersion(PhysAddress address);
-
- bool isSparseImplementation() { return m_use_map; }
- uint64 getSize() { return m_size_bytes; }
-
- // Public Methods
- void printConfig(ostream& out) const;
- static void printGlobalConfig(ostream & out);
- bool isPresent(PhysAddress address);
- Directory_Entry& lookup(PhysAddress address);
-
- void invalidateBlock(PhysAddress address);
-
- void print(ostream& out) const;
- void printStats(ostream& out) const;
-
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- DirectoryMemory(const DirectoryMemory& obj);
- DirectoryMemory& operator=(const DirectoryMemory& obj);
-
-private:
- const string m_name;
- // Data Members (m_ prefix)
- Directory_Entry **m_entries;
- // int m_size; // # of memory module blocks this directory is responsible for
- uint64 m_size_bytes;
- uint64 m_size_bits;
- uint64 m_num_entries;
- int m_version;
-
- static int m_num_directories;
- static int m_num_directories_bits;
- static uint64_t m_total_size_bytes;
- static int m_numa_high_bit;
-
- MemoryVector* m_ram;
- SparseMemory* m_sparseMemory;
- bool m_use_map;
- int m_map_levels;
+ ~DirectoryMemory();
+
+ void init();
+
+ uint64 mapAddressToLocalIdx(PhysAddress address);
+ static uint64 mapAddressToDirectoryVersion(PhysAddress address);
+
+ bool isSparseImplementation() { return m_use_map; }
+ uint64 getSize() { return m_size_bytes; }
+
+ void printConfig(ostream& out) const;
+ static void printGlobalConfig(ostream & out);
+ bool isPresent(PhysAddress address);
+ Directory_Entry& lookup(PhysAddress address);
+
+ void invalidateBlock(PhysAddress address);
+
+ void print(ostream& out) const;
+ void printStats(ostream& out) const;
+
+ private:
+ // Private copy constructor and assignment operator
+ DirectoryMemory(const DirectoryMemory& obj);
+ DirectoryMemory& operator=(const DirectoryMemory& obj);
+
+ private:
+ const string m_name;
+ Directory_Entry **m_entries;
+ // int m_size; // # of memory module blocks this directory is
+ // responsible for
+ uint64 m_size_bytes;
+ uint64 m_size_bits;
+ uint64 m_num_entries;
+ int m_version;
+
+ static int m_num_directories;
+ static int m_num_directories_bits;
+ static uint64_t m_total_size_bytes;
+ static int m_numa_high_bit;
+
+ MemoryVector* m_ram;
+ SparseMemory* m_sparseMemory;
+ bool m_use_map;
+ int m_map_levels;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const DirectoryMemory& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const DirectoryMemory& obj)
+inline ostream&
+operator<<(ostream& out, const DirectoryMemory& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //DIRECTORYMEMORY_H
+#endif // __MEM_RUBY_SYSTEM_DIRECTORYMEMORY_HH__
diff --git a/src/mem/ruby/system/LRUPolicy.hh b/src/mem/ruby/system/LRUPolicy.hh
index 55b1eec6e..b1b9d7478 100644
--- a/src/mem/ruby/system/LRUPolicy.hh
+++ b/src/mem/ruby/system/LRUPolicy.hh
@@ -26,26 +26,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LRUPOLICY_H
-#define LRUPOLICY_H
+#ifndef __MEM_RUBY_SYSTEM_LRUPOLICY_HH__
+#define __MEM_RUBY_SYSTEM_LRUPOLICY_HH__
#include "mem/ruby/system/AbstractReplacementPolicy.hh"
/* Simple true LRU replacement policy */
-class LRUPolicy : public AbstractReplacementPolicy {
- public:
-
- LRUPolicy(Index num_sets, Index assoc);
- ~LRUPolicy();
+class LRUPolicy : public AbstractReplacementPolicy
+{
+ public:
+ LRUPolicy(Index num_sets, Index assoc);
+ ~LRUPolicy();
- void touch(Index set, Index way, Time time);
- Index getVictim(Index set) const;
+ void touch(Index set, Index way, Time time);
+ Index getVictim(Index set) const;
};
inline
LRUPolicy::LRUPolicy(Index num_sets, Index assoc)
- : AbstractReplacementPolicy(num_sets, assoc)
+ : AbstractReplacementPolicy(num_sets, assoc)
{
}
@@ -54,39 +54,42 @@ LRUPolicy::~LRUPolicy()
{
}
-inline
-void LRUPolicy::touch(Index set, Index index, Time time){
- assert(index >= 0 && index < m_assoc);
- assert(set >= 0 && set < m_num_sets);
+inline void
+LRUPolicy::touch(Index set, Index index, Time time)
+{
+ assert(index >= 0 && index < m_assoc);
+ assert(set >= 0 && set < m_num_sets);
- m_last_ref_ptr[set][index] = time;
+ m_last_ref_ptr[set][index] = time;
}
-inline
-Index LRUPolicy::getVictim(Index set) const {
- // assert(m_assoc != 0);
- Time time, smallest_time;
- Index smallest_index;
-
- smallest_index = 0;
- smallest_time = m_last_ref_ptr[set][0];
-
- for (unsigned int i=0; i < m_assoc; i++) {
- time = m_last_ref_ptr[set][i];
- //assert(m_cache[cacheSet][i].m_Permission != AccessPermission_NotPresent);
-
- if (time < smallest_time){
- smallest_index = i;
- smallest_time = time;
+inline Index
+LRUPolicy::getVictim(Index set) const
+{
+ // assert(m_assoc != 0);
+ Time time, smallest_time;
+ Index smallest_index;
+
+ smallest_index = 0;
+ smallest_time = m_last_ref_ptr[set][0];
+
+ for (unsigned i = 0; i < m_assoc; i++) {
+ time = m_last_ref_ptr[set][i];
+ // assert(m_cache[cacheSet][i].m_Permission !=
+ // AccessPermission_NotPresent);
+
+ if (time < smallest_time) {
+ smallest_index = i;
+ smallest_time = time;
+ }
}
- }
- // DEBUG_EXPR(CACHE_COMP, MedPrio, cacheSet);
- // DEBUG_EXPR(CACHE_COMP, MedPrio, smallest_index);
- // DEBUG_EXPR(CACHE_COMP, MedPrio, m_cache[cacheSet][smallest_index]);
- // DEBUG_EXPR(CACHE_COMP, MedPrio, *this);
+ // DEBUG_EXPR(CACHE_COMP, MedPrio, cacheSet);
+ // DEBUG_EXPR(CACHE_COMP, MedPrio, smallest_index);
+ // DEBUG_EXPR(CACHE_COMP, MedPrio, m_cache[cacheSet][smallest_index]);
+ // DEBUG_EXPR(CACHE_COMP, MedPrio, *this);
- return smallest_index;
+ return smallest_index;
}
-#endif // PSEUDOLRUBITS_H
+#endif // __MEM_RUBY_SYSTEM_LRUPOLICY_HH__
diff --git a/src/mem/ruby/system/MachineID.hh b/src/mem/ruby/system/MachineID.hh
index 9da71f349..716196248 100644
--- a/src/mem/ruby/system/MachineID.hh
+++ b/src/mem/ruby/system/MachineID.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,66 +26,55 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NodeID.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef MACHINEID_H
-#define MACHINEID_H
+#ifndef __MEM_RUBY_SYSTEM_MACHINEID_HH__
+#define __MEM_RUBY_SYSTEM_MACHINEID_HH__
#include <iostream>
#include <string>
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/util.hh"
#include "mem/protocol/MachineType.hh"
+#include "mem/ruby/common/Global.hh"
-struct MachineID {
- MachineType type;
- int num; // range: 0 ... number of this machine's components in the system - 1
+struct MachineID
+{
+ MachineType type;
+ int num; // range: 0 ... number of this machine's components in system - 1
};
-extern inline
-std::string MachineIDToString (MachineID machine) {
- return MachineType_to_string(machine.type)+"_"+int_to_string(machine.num);
+inline std::string
+MachineIDToString(MachineID machine)
+{
+ return MachineType_to_string(machine.type)+"_"+int_to_string(machine.num);
}
-extern inline
-bool operator==(const MachineID & obj1, const MachineID & obj2)
+inline bool
+operator==(const MachineID & obj1, const MachineID & obj2)
{
- return (obj1.type == obj2.type && obj1.num == obj2.num);
+ return (obj1.type == obj2.type && obj1.num == obj2.num);
}
-extern inline
-bool operator!=(const MachineID & obj1, const MachineID & obj2)
+inline bool
+operator!=(const MachineID & obj1, const MachineID & obj2)
{
- return (obj1.type != obj2.type || obj1.num != obj2.num);
+ return (obj1.type != obj2.type || obj1.num != obj2.num);
}
// Output operator declaration
std::ostream& operator<<(std::ostream& out, const MachineID& obj);
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const MachineID& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const MachineID& obj)
{
- if ((obj.type < MachineType_NUM) && (obj.type >= MachineType_FIRST)) {
- out << MachineType_to_string(obj.type);
- } else {
- out << "NULL";
- }
- out << "-";
- out << obj.num;
- out << std::flush;
- return out;
+ if ((obj.type < MachineType_NUM) && (obj.type >= MachineType_FIRST)) {
+ out << MachineType_to_string(obj.type);
+ } else {
+ out << "NULL";
+ }
+ out << "-";
+ out << obj.num;
+ out << std::flush;
+ return out;
}
-
-#endif //MACHINEID_H
+#endif // __MEM_RUBY_SYSTEM_MACHINEID_HH__
diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc
index 0f12efc36..963cc3947 100644
--- a/src/mem/ruby/system/MemoryControl.cc
+++ b/src/mem/ruby/system/MemoryControl.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -28,8 +27,6 @@
*/
/*
- * MemoryControl.cc
- *
* Description: This module simulates a basic DDR-style memory controller
* (and can easily be extended to do FB-DIMM as well).
*
@@ -105,25 +102,21 @@
* then no more than four activates may happen within any 16 cycle window.
* Refreshes are included in the activates.
*
- *
- * $Id: $
- *
*/
-#include "mem/ruby/common/Global.hh"
+#include <list>
+
+#include "base/cprintf.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/network/Network.hh"
#include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
#include "mem/ruby/slicc_interface/NetworkMessage.hh"
-#include "mem/ruby/network/Network.hh"
-
-#include "mem/ruby/common/Consumer.hh"
-
+#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
#include "mem/ruby/system/MemoryControl.hh"
-
-#include <list>
+#include "mem/ruby/system/System.hh"
class Consumer;
@@ -140,11 +133,12 @@ class Consumer;
// Output operator definition
-ostream& operator<<(ostream& out, const MemoryControl& obj)
+ostream&
+operator<<(ostream& out, const MemoryControl& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
@@ -178,471 +172,509 @@ MemoryControl::MemoryControl(const Params *p)
m_dimms_per_channel);
}
-void MemoryControl::init()
+void
+MemoryControl::init()
{
- m_msg_counter = 0;
-
- m_debug = 0;
-
- assert(m_tFaw <= 62); // must fit in a uint64 shift register
-
- m_total_banks = m_banks_per_rank * m_ranks_per_dimm * m_dimms_per_channel;
- m_total_ranks = m_ranks_per_dimm * m_dimms_per_channel;
- m_refresh_period_system = m_refresh_period / m_total_banks;
-
- m_bankQueues = new list<MemoryNode> [m_total_banks];
- assert(m_bankQueues);
-
- m_bankBusyCounter = new int [m_total_banks];
- assert(m_bankBusyCounter);
-
- m_oldRequest = new int [m_total_banks];
- assert(m_oldRequest);
-
- for (int i=0; i<m_total_banks; i++) {
- m_bankBusyCounter[i] = 0;
- m_oldRequest[i] = 0;
- }
-
- m_busBusyCounter_Basic = 0;
- m_busBusyCounter_Write = 0;
- m_busBusyCounter_ReadNewRank = 0;
- m_busBusy_WhichRank = 0;
-
- m_roundRobin = 0;
- m_refresh_count = 1;
- m_need_refresh = 0;
- m_refresh_bank = 0;
- m_awakened = 0;
- m_idleCount = 0;
- m_ageCounter = 0;
-
- // Each tfaw shift register keeps a moving bit pattern
- // which shows when recent activates have occurred.
- // m_tfaw_count keeps track of how many 1 bits are set
- // in each shift register. When m_tfaw_count is >= 4,
- // new activates are not allowed.
- m_tfaw_shift = new uint64 [m_total_ranks];
- m_tfaw_count = new int [m_total_ranks];
- for (int i=0; i<m_total_ranks; i++) {
- m_tfaw_shift[i] = 0;
- m_tfaw_count[i] = 0;
- }
-}
+ m_msg_counter = 0;
+ m_debug = 0;
-// DESTRUCTOR
+ assert(m_tFaw <= 62); // must fit in a uint64 shift register
-MemoryControl::~MemoryControl () {
- delete [] m_bankQueues;
- delete [] m_bankBusyCounter;
- delete [] m_oldRequest;
- delete m_profiler_ptr;
-}
+ m_total_banks = m_banks_per_rank * m_ranks_per_dimm * m_dimms_per_channel;
+ m_total_ranks = m_ranks_per_dimm * m_dimms_per_channel;
+ m_refresh_period_system = m_refresh_period / m_total_banks;
+ m_bankQueues = new list<MemoryNode> [m_total_banks];
+ assert(m_bankQueues);
-// PUBLIC METHODS
+ m_bankBusyCounter = new int [m_total_banks];
+ assert(m_bankBusyCounter);
-// enqueue new request from directory
-
-void MemoryControl::enqueue (const MsgPtr& message, int latency) {
- Time current_time = g_eventQueue_ptr->getTime();
- Time arrival_time = current_time + latency;
- const MemoryMsg* memMess = dynamic_cast<const MemoryMsg*>(message.ref());
- physical_address_t addr = memMess->getAddress().getAddress();
- MemoryRequestType type = memMess->getType();
- bool is_mem_read = (type == MemoryRequestType_MEMORY_READ);
- MemoryNode thisReq(arrival_time, message, addr, is_mem_read, !is_mem_read);
- enqueueMemRef(thisReq);
-}
-
-// Alternate entry point used when we already have a MemoryNode structure built.
-
-void MemoryControl::enqueueMemRef (MemoryNode& memRef) {
- m_msg_counter++;
- memRef.m_msg_counter = m_msg_counter;
- Time arrival_time = memRef.m_time;
- uint64 at = arrival_time;
- bool is_mem_read = memRef.m_is_mem_read;
- physical_address_t addr = memRef.m_addr;
- int bank = getBank(addr);
- if (m_debug) {
- printf("New memory request%7d: 0x%08llx %c arrived at %10lld ", m_msg_counter, addr, is_mem_read? 'R':'W', at);
- printf("bank =%3x\n", bank);
- }
-
- m_profiler_ptr->profileMemReq(bank);
- m_input_queue.push_back(memRef);
- if (!m_awakened) {
- g_eventQueue_ptr->scheduleEvent(this, 1);
- m_awakened = 1;
- }
-}
+ m_oldRequest = new int [m_total_banks];
+ assert(m_oldRequest);
+ for (int i = 0; i < m_total_banks; i++) {
+ m_bankBusyCounter[i] = 0;
+ m_oldRequest[i] = 0;
+ }
+ m_busBusyCounter_Basic = 0;
+ m_busBusyCounter_Write = 0;
+ m_busBusyCounter_ReadNewRank = 0;
+ m_busBusy_WhichRank = 0;
-// dequeue, peek, and isReady are used to transfer completed requests
-// back to the directory
+ m_roundRobin = 0;
+ m_refresh_count = 1;
+ m_need_refresh = 0;
+ m_refresh_bank = 0;
+ m_awakened = 0;
+ m_idleCount = 0;
+ m_ageCounter = 0;
-void MemoryControl::dequeue () {
- assert(isReady());
- m_response_queue.pop_front();
+ // Each tfaw shift register keeps a moving bit pattern
+ // which shows when recent activates have occurred.
+ // m_tfaw_count keeps track of how many 1 bits are set
+ // in each shift register. When m_tfaw_count is >= 4,
+ // new activates are not allowed.
+ m_tfaw_shift = new uint64[m_total_ranks];
+ m_tfaw_count = new int[m_total_ranks];
+ for (int i = 0; i < m_total_ranks; i++) {
+ m_tfaw_shift[i] = 0;
+ m_tfaw_count[i] = 0;
+ }
}
-
-const Message* MemoryControl::peek () {
- MemoryNode node = peekNode();
- Message* msg_ptr = node.m_msgptr.ref();
- assert(msg_ptr != NULL);
- return msg_ptr;
+MemoryControl::~MemoryControl()
+{
+ delete [] m_bankQueues;
+ delete [] m_bankBusyCounter;
+ delete [] m_oldRequest;
+ delete m_profiler_ptr;
}
-
-MemoryNode MemoryControl::peekNode () {
- assert(isReady());
- MemoryNode req = m_response_queue.front();
- uint64 returnTime = req.m_time;
- if (m_debug) {
- printf("Old memory request%7d: 0x%08llx %c peeked at %10lld\n",
- req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W', returnTime);
- }
- return req;
+// enqueue new request from directory
+void
+MemoryControl::enqueue(const MsgPtr& message, int latency)
+{
+ Time current_time = g_eventQueue_ptr->getTime();
+ Time arrival_time = current_time + latency;
+ const MemoryMsg* memMess = dynamic_cast<const MemoryMsg*>(message.ref());
+ physical_address_t addr = memMess->getAddress().getAddress();
+ MemoryRequestType type = memMess->getType();
+ bool is_mem_read = (type == MemoryRequestType_MEMORY_READ);
+ MemoryNode thisReq(arrival_time, message, addr, is_mem_read, !is_mem_read);
+ enqueueMemRef(thisReq);
}
+// Alternate entry point used when we already have a MemoryNode
+// structure built.
+void
+MemoryControl::enqueueMemRef(MemoryNode& memRef)
+{
+ m_msg_counter++;
+ memRef.m_msg_counter = m_msg_counter;
+ Time arrival_time = memRef.m_time;
+ uint64 at = arrival_time;
+ bool is_mem_read = memRef.m_is_mem_read;
+ physical_address_t addr = memRef.m_addr;
+ int bank = getBank(addr);
+ if (m_debug) {
+ cprintf("New memory request%7d: %#08x %c arrived at %10d bank = %3x\n",
+ m_msg_counter, addr, is_mem_read? 'R':'W', at, bank);
+ }
-bool MemoryControl::isReady () {
- return ((!m_response_queue.empty()) &&
- (m_response_queue.front().m_time <= g_eventQueue_ptr->getTime()));
+ m_profiler_ptr->profileMemReq(bank);
+ m_input_queue.push_back(memRef);
+ if (!m_awakened) {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ m_awakened = 1;
+ }
}
-void MemoryControl::setConsumer (Consumer* consumer_ptr) {
- m_consumer_ptr = consumer_ptr;
+// dequeue, peek, and isReady are used to transfer completed requests
+// back to the directory
+void
+MemoryControl::dequeue()
+{
+ assert(isReady());
+ m_response_queue.pop_front();
}
-void MemoryControl::print (ostream& out) const {
+const Message*
+MemoryControl::peek()
+{
+ MemoryNode node = peekNode();
+ Message* msg_ptr = node.m_msgptr.ref();
+ assert(msg_ptr != NULL);
+ return msg_ptr;
}
-
-void MemoryControl::printConfig (ostream& out) {
- out << "Memory Control " << name() << ":" << endl;
- out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl;
- out << " Basic read latency: " << m_mem_ctl_latency << endl;
- if (m_mem_fixed_delay) {
- out << " Fixed Latency mode: Added cycles = " << m_mem_fixed_delay << endl;
- } else {
- out << " Bank busy time: " << m_bank_busy_time << " memory cycles" << endl;
- out << " Memory channel busy time: " << m_basic_bus_busy_time << endl;
- out << " Dead cycles between reads to different ranks: " << m_rank_rank_delay << endl;
- out << " Dead cycle between a read and a write: " << m_read_write_delay << endl;
- out << " tFaw (four-activate) window: " << m_tFaw << endl;
- }
- out << " Banks per rank: " << m_banks_per_rank << endl;
- out << " Ranks per DIMM: " << m_ranks_per_dimm << endl;
- out << " DIMMs per channel: " << m_dimms_per_channel << endl;
- out << " LSB of bank field in address: " << m_bank_bit_0 << endl;
- out << " LSB of rank field in address: " << m_rank_bit_0 << endl;
- out << " LSB of DIMM field in address: " << m_dimm_bit_0 << endl;
- out << " Max size of each bank queue: " << m_bank_queue_size << endl;
- out << " Refresh period (within one bank): " << m_refresh_period << endl;
- out << " Arbitration randomness: " << m_mem_random_arbitrate << endl;
+MemoryNode
+MemoryControl::peekNode()
+{
+ assert(isReady());
+ MemoryNode req = m_response_queue.front();
+ uint64 returnTime = req.m_time;
+ if (m_debug) {
+ cprintf("Old memory request%7d: %#08x %c peeked at %10d\n",
+ req.m_msg_counter, req.m_addr, req.m_is_mem_read ? 'R':'W',
+ returnTime);
+ }
+ return req;
}
+bool
+MemoryControl::isReady()
+{
+ return ((!m_response_queue.empty()) &&
+ (m_response_queue.front().m_time <= g_eventQueue_ptr->getTime()));
+}
-void MemoryControl::setDebug (int debugFlag) {
- m_debug = debugFlag;
+void
+MemoryControl::setConsumer(Consumer* consumer_ptr)
+{
+ m_consumer_ptr = consumer_ptr;
}
-void MemoryControl::clearStats() const
+void
+MemoryControl::print(ostream& out) const
{
- m_profiler_ptr->clearStats();
}
-void MemoryControl::printStats(ostream& out) const
+void
+MemoryControl::printConfig(ostream& out)
{
- m_profiler_ptr->printStats(out);
+ out << "Memory Control " << name() << ":" << endl;
+ out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier
+ << endl;
+ out << " Basic read latency: " << m_mem_ctl_latency << endl;
+ if (m_mem_fixed_delay) {
+ out << " Fixed Latency mode: Added cycles = " << m_mem_fixed_delay
+ << endl;
+ } else {
+ out << " Bank busy time: " << m_bank_busy_time << " memory cycles"
+ << endl;
+ out << " Memory channel busy time: " << m_basic_bus_busy_time << endl;
+ out << " Dead cycles between reads to different ranks: "
+ << m_rank_rank_delay << endl;
+ out << " Dead cycle between a read and a write: "
+ << m_read_write_delay << endl;
+ out << " tFaw (four-activate) window: " << m_tFaw << endl;
+ }
+ out << " Banks per rank: " << m_banks_per_rank << endl;
+ out << " Ranks per DIMM: " << m_ranks_per_dimm << endl;
+ out << " DIMMs per channel: " << m_dimms_per_channel << endl;
+ out << " LSB of bank field in address: " << m_bank_bit_0 << endl;
+ out << " LSB of rank field in address: " << m_rank_bit_0 << endl;
+ out << " LSB of DIMM field in address: " << m_dimm_bit_0 << endl;
+ out << " Max size of each bank queue: " << m_bank_queue_size << endl;
+ out << " Refresh period (within one bank): " << m_refresh_period << endl;
+ out << " Arbitration randomness: " << m_mem_random_arbitrate << endl;
}
+void
+MemoryControl::setDebug(int debugFlag)
+{
+ m_debug = debugFlag;
+}
-// ****************************************************************
+void
+MemoryControl::clearStats() const
+{
+ m_profiler_ptr->clearStats();
+}
-// PRIVATE METHODS
+void
+MemoryControl::printStats(ostream& out) const
+{
+ m_profiler_ptr->printStats(out);
+}
// Queue up a completed request to send back to directory
+void
+MemoryControl::enqueueToDirectory(MemoryNode req, int latency)
+{
+ Time arrival_time = g_eventQueue_ptr->getTime()
+ + (latency * m_mem_bus_cycle_multiplier);
+ req.m_time = arrival_time;
+ m_response_queue.push_back(req);
-void MemoryControl::enqueueToDirectory (MemoryNode req, int latency) {
- Time arrival_time = g_eventQueue_ptr->getTime()
- + (latency * m_mem_bus_cycle_multiplier);
- req.m_time = arrival_time;
- m_response_queue.push_back(req);
-
- // schedule the wake up
- g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time);
+ // schedule the wake up
+ g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time);
}
-
-
// getBank returns an integer that is unique for each
// bank across this memory controller.
-
-int MemoryControl::getBank (physical_address_t addr) {
- int dimm = (addr >> m_dimm_bit_0) & (m_dimms_per_channel - 1);
- int rank = (addr >> m_rank_bit_0) & (m_ranks_per_dimm - 1);
- int bank = (addr >> m_bank_bit_0) & (m_banks_per_rank - 1);
- return (dimm * m_ranks_per_dimm * m_banks_per_rank)
- + (rank * m_banks_per_rank)
- + bank;
+int
+MemoryControl::getBank(physical_address_t addr)
+{
+ int dimm = (addr >> m_dimm_bit_0) & (m_dimms_per_channel - 1);
+ int rank = (addr >> m_rank_bit_0) & (m_ranks_per_dimm - 1);
+ int bank = (addr >> m_bank_bit_0) & (m_banks_per_rank - 1);
+ return (dimm * m_ranks_per_dimm * m_banks_per_rank)
+ + (rank * m_banks_per_rank)
+ + bank;
}
// getRank returns an integer that is unique for each rank
// and independent of individual bank.
-
-int MemoryControl::getRank (int bank) {
- int rank = (bank / m_banks_per_rank);
- assert (rank < (m_ranks_per_dimm * m_dimms_per_channel));
- return rank;
+int
+MemoryControl::getRank(int bank)
+{
+ int rank = (bank / m_banks_per_rank);
+ assert (rank < (m_ranks_per_dimm * m_dimms_per_channel));
+ return rank;
}
-
// queueReady determines if the head item in a bank queue
// can be issued this cycle
+bool
+MemoryControl::queueReady(int bank)
+{
+ if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) {
+ m_profiler_ptr->profileMemBankBusy();
+#if 0
+ if (m_debug)
+ printf(" bank %x busy %d\n", bank, m_bankBusyCounter[bank]);
+#endif
+ return false;
+ }
-bool MemoryControl::queueReady (int bank) {
- if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) {
- m_profiler_ptr->profileMemBankBusy();
- //if (m_debug) printf(" bank %x busy %d\n", bank, m_bankBusyCounter[bank]);
- return false;
- }
- if (m_mem_random_arbitrate >= 2) {
- if ((random() % 100) < m_mem_random_arbitrate) {
- m_profiler_ptr->profileMemRandBusy();
- return false;
+ if (m_mem_random_arbitrate >= 2) {
+ if ((random() % 100) < m_mem_random_arbitrate) {
+ m_profiler_ptr->profileMemRandBusy();
+ return false;
+ }
}
- }
- if (m_mem_fixed_delay) return true;
- if ((m_ageCounter > (2 * m_bank_busy_time)) && !m_oldRequest[bank]) {
- m_profiler_ptr->profileMemNotOld();
- return false;
- }
- if (m_busBusyCounter_Basic == m_basic_bus_busy_time) {
- // Another bank must have issued this same cycle.
- // For profiling, we count this as an arb wait rather than
- // a bus wait. This is a little inaccurate since it MIGHT
- // have also been blocked waiting for a read-write or a
- // read-read instead, but it's pretty close.
- m_profiler_ptr->profileMemArbWait(1);
- return false;
- }
- if (m_busBusyCounter_Basic > 0) {
- m_profiler_ptr->profileMemBusBusy();
- return false;
- }
- int rank = getRank(bank);
- if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) {
- m_profiler_ptr->profileMemTfawBusy();
- return false;
- }
- bool write = !m_bankQueues[bank].front().m_is_mem_read;
- if (write && (m_busBusyCounter_Write > 0)) {
- m_profiler_ptr->profileMemReadWriteBusy();
- return false;
- }
- if (!write && (rank != m_busBusy_WhichRank)
- && (m_busBusyCounter_ReadNewRank > 0)) {
- m_profiler_ptr->profileMemDataBusBusy();
- return false;
- }
- return true;
-}
+ if (m_mem_fixed_delay)
+ return true;
-// issueRefresh checks to see if this bank has a refresh scheduled
-// and, if so, does the refresh and returns true
+ if ((m_ageCounter > (2 * m_bank_busy_time)) && !m_oldRequest[bank]) {
+ m_profiler_ptr->profileMemNotOld();
+ return false;
+ }
-bool MemoryControl::issueRefresh (int bank) {
- if (!m_need_refresh || (m_refresh_bank != bank)) return false;
- if (m_bankBusyCounter[bank] > 0) return false;
- // Note that m_busBusyCounter will prevent multiple issues during
- // the same cycle, as well as on different but close cycles:
- if (m_busBusyCounter_Basic > 0) return false;
- int rank = getRank(bank);
- if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) return false;
-
- // Issue it:
-
- //if (m_debug) {
- //uint64 current_time = g_eventQueue_ptr->getTime();
- //printf(" Refresh bank %3x at %lld\n", bank, current_time);
- //}
- m_profiler_ptr->profileMemRefresh();
- m_need_refresh--;
- m_refresh_bank++;
- if (m_refresh_bank >= m_total_banks) m_refresh_bank = 0;
- m_bankBusyCounter[bank] = m_bank_busy_time;
- m_busBusyCounter_Basic = m_basic_bus_busy_time;
- m_busBusyCounter_Write = m_basic_bus_busy_time;
- m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time;
- markTfaw(rank);
- return true;
-}
+ if (m_busBusyCounter_Basic == m_basic_bus_busy_time) {
+ // Another bank must have issued this same cycle. For
+ // profiling, we count this as an arb wait rather than a bus
+ // wait. This is a little inaccurate since it MIGHT have also
+ // been blocked waiting for a read-write or a read-read
+ // instead, but it's pretty close.
+ m_profiler_ptr->profileMemArbWait(1);
+ return false;
+ }
+ if (m_busBusyCounter_Basic > 0) {
+ m_profiler_ptr->profileMemBusBusy();
+ return false;
+ }
-// Mark the activate in the tFaw shift register
-void MemoryControl::markTfaw (int rank) {
- if (m_tFaw) {
- m_tfaw_shift[rank] |= (1 << (m_tFaw-1));
- m_tfaw_count[rank]++;
- }
-}
+ int rank = getRank(bank);
+ if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) {
+ m_profiler_ptr->profileMemTfawBusy();
+ return false;
+ }
+ bool write = !m_bankQueues[bank].front().m_is_mem_read;
+ if (write && (m_busBusyCounter_Write > 0)) {
+ m_profiler_ptr->profileMemReadWriteBusy();
+ return false;
+ }
-// Issue a memory request: Activate the bank,
-// reserve the address and data buses, and queue
-// the request for return to the requesting
-// processor after a fixed latency.
+ if (!write && (rank != m_busBusy_WhichRank)
+ && (m_busBusyCounter_ReadNewRank > 0)) {
+ m_profiler_ptr->profileMemDataBusBusy();
+ return false;
+ }
-void MemoryControl::issueRequest (int bank) {
- int rank = getRank(bank);
- MemoryNode req = m_bankQueues[bank].front();
- m_bankQueues[bank].pop_front();
- if (m_debug) {
- uint64 current_time = g_eventQueue_ptr->getTime();
- printf(" Mem issue request%7d: 0x%08llx %c at %10lld bank =%3x\n",
- req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W', current_time, bank);
- }
- if (req.m_msgptr.ref() != NULL) { // don't enqueue L3 writebacks
- enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay);
- }
- m_oldRequest[bank] = 0;
- markTfaw(rank);
- m_bankBusyCounter[bank] = m_bank_busy_time;
- m_busBusy_WhichRank = rank;
- if (req.m_is_mem_read) {
- m_profiler_ptr->profileMemRead();
- m_busBusyCounter_Basic = m_basic_bus_busy_time;
- m_busBusyCounter_Write = m_basic_bus_busy_time + m_read_write_delay;
- m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time + m_rank_rank_delay;
- } else {
- m_profiler_ptr->profileMemWrite();
+ return true;
+}
+
+// issueRefresh checks to see if this bank has a refresh scheduled
+// and, if so, does the refresh and returns true
+bool
+MemoryControl::issueRefresh(int bank)
+{
+ if (!m_need_refresh || (m_refresh_bank != bank))
+ return false;
+ if (m_bankBusyCounter[bank] > 0)
+ return false;
+ // Note that m_busBusyCounter will prevent multiple issues during
+ // the same cycle, as well as on different but close cycles:
+ if (m_busBusyCounter_Basic > 0)
+ return false;
+ int rank = getRank(bank);
+ if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW)
+ return false;
+
+ // Issue it:
+#if 0
+ if (m_debug) {
+ uint64 current_time = g_eventQueue_ptr->getTime();
+ printf(" Refresh bank %3x at %lld\n", bank, current_time);
+ }
+#endif
+
+ m_profiler_ptr->profileMemRefresh();
+ m_need_refresh--;
+ m_refresh_bank++;
+ if (m_refresh_bank >= m_total_banks)
+ m_refresh_bank = 0;
+ m_bankBusyCounter[bank] = m_bank_busy_time;
m_busBusyCounter_Basic = m_basic_bus_busy_time;
m_busBusyCounter_Write = m_basic_bus_busy_time;
m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time;
- }
+ markTfaw(rank);
+ return true;
+}
+
+// Mark the activate in the tFaw shift register
+void
+MemoryControl::markTfaw(int rank)
+{
+ if (m_tFaw) {
+ m_tfaw_shift[rank] |= (1 << (m_tFaw-1));
+ m_tfaw_count[rank]++;
+ }
}
+// Issue a memory request: Activate the bank, reserve the address and
+// data buses, and queue the request for return to the requesting
+// processor after a fixed latency.
+void
+MemoryControl::issueRequest(int bank)
+{
+ int rank = getRank(bank);
+ MemoryNode req = m_bankQueues[bank].front();
+ m_bankQueues[bank].pop_front();
+ if (m_debug) {
+ uint64 current_time = g_eventQueue_ptr->getTime();
+ cprintf(" Mem issue request%7d: %#08x %c at %10d "
+ "bank=%3x\n",
+ req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W',
+ current_time, bank);
+ }
+ if (req.m_msgptr.ref() != NULL) { // don't enqueue L3 writebacks
+ enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay);
+ }
+ m_oldRequest[bank] = 0;
+ markTfaw(rank);
+ m_bankBusyCounter[bank] = m_bank_busy_time;
+ m_busBusy_WhichRank = rank;
+ if (req.m_is_mem_read) {
+ m_profiler_ptr->profileMemRead();
+ m_busBusyCounter_Basic = m_basic_bus_busy_time;
+ m_busBusyCounter_Write = m_basic_bus_busy_time + m_read_write_delay;
+ m_busBusyCounter_ReadNewRank =
+ m_basic_bus_busy_time + m_rank_rank_delay;
+ } else {
+ m_profiler_ptr->profileMemWrite();
+ m_busBusyCounter_Basic = m_basic_bus_busy_time;
+ m_busBusyCounter_Write = m_basic_bus_busy_time;
+ m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time;
+ }
+}
// executeCycle: This function is called once per memory clock cycle
// to simulate all the periodic hardware.
+void
+MemoryControl::executeCycle()
+{
+ // Keep track of time by counting down the busy counters:
+ for (int bank=0; bank < m_total_banks; bank++) {
+ if (m_bankBusyCounter[bank] > 0) m_bankBusyCounter[bank]--;
+ }
+ if (m_busBusyCounter_Write > 0)
+ m_busBusyCounter_Write--;
+ if (m_busBusyCounter_ReadNewRank > 0)
+ m_busBusyCounter_ReadNewRank--;
+ if (m_busBusyCounter_Basic > 0)
+ m_busBusyCounter_Basic--;
+
+ // Count down the tFAW shift registers:
+ for (int rank=0; rank < m_total_ranks; rank++) {
+ if (m_tfaw_shift[rank] & 1) m_tfaw_count[rank]--;
+ m_tfaw_shift[rank] >>= 1;
+ }
+
+ // After time period expires, latch an indication that we need a refresh.
+ // Disable refresh if in mem_fixed_delay mode.
+ if (!m_mem_fixed_delay) m_refresh_count--;
+ if (m_refresh_count == 0) {
+ m_refresh_count = m_refresh_period_system;
+
+ // Are we overrunning our ability to refresh?
+ assert(m_need_refresh < 10);
+ m_need_refresh++;
+ }
-void MemoryControl::executeCycle () {
- // Keep track of time by counting down the busy counters:
- for (int bank=0; bank < m_total_banks; bank++) {
- if (m_bankBusyCounter[bank] > 0) m_bankBusyCounter[bank]--;
- }
- if (m_busBusyCounter_Write > 0) m_busBusyCounter_Write--;
- if (m_busBusyCounter_ReadNewRank > 0) m_busBusyCounter_ReadNewRank--;
- if (m_busBusyCounter_Basic > 0) m_busBusyCounter_Basic--;
-
- // Count down the tFAW shift registers:
- for (int rank=0; rank < m_total_ranks; rank++) {
- if (m_tfaw_shift[rank] & 1) m_tfaw_count[rank]--;
- m_tfaw_shift[rank] >>= 1;
- }
-
- // After time period expires, latch an indication that we need a refresh.
- // Disable refresh if in mem_fixed_delay mode.
- if (!m_mem_fixed_delay) m_refresh_count--;
- if (m_refresh_count == 0) {
- m_refresh_count = m_refresh_period_system;
- assert (m_need_refresh < 10); // Are we overrunning our ability to refresh?
- m_need_refresh++;
- }
-
- // If this batch of requests is all done, make a new batch:
- m_ageCounter++;
- int anyOld = 0;
- for (int bank=0; bank < m_total_banks; bank++) {
- anyOld |= m_oldRequest[bank];
- }
- if (!anyOld) {
+ // If this batch of requests is all done, make a new batch:
+ m_ageCounter++;
+ int anyOld = 0;
for (int bank=0; bank < m_total_banks; bank++) {
- if (!m_bankQueues[bank].empty()) m_oldRequest[bank] = 1;
+ anyOld |= m_oldRequest[bank];
}
- m_ageCounter = 0;
- }
-
- // If randomness desired, re-randomize round-robin position each cycle
- if (m_mem_random_arbitrate) {
- m_roundRobin = random() % m_total_banks;
- }
-
-
- // For each channel, scan round-robin, and pick an old, ready
- // request and issue it. Treat a refresh request as if it
- // were at the head of its bank queue. After we issue something,
- // keep scanning the queues just to gather statistics about
- // how many are waiting. If in mem_fixed_delay mode, we can issue
- // more than one request per cycle.
-
- int queueHeads = 0;
- int banksIssued = 0;
- for (int i = 0; i < m_total_banks; i++) {
- m_roundRobin++;
- if (m_roundRobin >= m_total_banks) m_roundRobin = 0;
- issueRefresh(m_roundRobin);
- int qs = m_bankQueues[m_roundRobin].size();
- if (qs > 1) {
- m_profiler_ptr->profileMemBankQ(qs-1);
+ if (!anyOld) {
+ for (int bank=0; bank < m_total_banks; bank++) {
+ if (!m_bankQueues[bank].empty()) m_oldRequest[bank] = 1;
+ }
+ m_ageCounter = 0;
+ }
+
+ // If randomness desired, re-randomize round-robin position each cycle
+ if (m_mem_random_arbitrate) {
+ m_roundRobin = random() % m_total_banks;
}
- if (qs > 0) {
- m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is queued
- queueHeads++;
- if (queueReady(m_roundRobin)) {
- issueRequest(m_roundRobin);
- banksIssued++;
- if (m_mem_fixed_delay) {
- m_profiler_ptr->profileMemWaitCycles(m_mem_fixed_delay);
+
+ // For each channel, scan round-robin, and pick an old, ready
+ // request and issue it. Treat a refresh request as if it were at
+ // the head of its bank queue. After we issue something, keep
+ // scanning the queues just to gather statistics about how many
+ // are waiting. If in mem_fixed_delay mode, we can issue more
+ // than one request per cycle.
+ int queueHeads = 0;
+ int banksIssued = 0;
+ for (int i = 0; i < m_total_banks; i++) {
+ m_roundRobin++;
+ if (m_roundRobin >= m_total_banks) m_roundRobin = 0;
+ issueRefresh(m_roundRobin);
+ int qs = m_bankQueues[m_roundRobin].size();
+ if (qs > 1) {
+ m_profiler_ptr->profileMemBankQ(qs-1);
+ }
+ if (qs > 0) {
+ // we're not idle if anything is queued
+ m_idleCount = IDLECOUNT_MAX_VALUE;
+ queueHeads++;
+ if (queueReady(m_roundRobin)) {
+ issueRequest(m_roundRobin);
+ banksIssued++;
+ if (m_mem_fixed_delay) {
+ m_profiler_ptr->profileMemWaitCycles(m_mem_fixed_delay);
+ }
+ }
}
- }
}
- }
-
- // memWaitCycles is a redundant catch-all for the specific counters in queueReady
- m_profiler_ptr->profileMemWaitCycles(queueHeads - banksIssued);
-
- // Check input queue and move anything to bank queues if not full.
- // Since this is done here at the end of the cycle, there will always
- // be at least one cycle of latency in the bank queue.
- // We deliberately move at most one request per cycle (to simulate
- // typical hardware). Note that if one bank queue fills up, other
- // requests can get stuck behind it here.
-
- if (!m_input_queue.empty()) {
- m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is pending
- MemoryNode req = m_input_queue.front();
- int bank = getBank(req.m_addr);
- if (m_bankQueues[bank].size() < m_bank_queue_size) {
- m_input_queue.pop_front();
- m_bankQueues[bank].push_back(req);
+
+ // memWaitCycles is a redundant catch-all for the specific
+ // counters in queueReady
+ m_profiler_ptr->profileMemWaitCycles(queueHeads - banksIssued);
+
+ // Check input queue and move anything to bank queues if not full.
+ // Since this is done here at the end of the cycle, there will
+ // always be at least one cycle of latency in the bank queue. We
+ // deliberately move at most one request per cycle (to simulate
+ // typical hardware). Note that if one bank queue fills up, other
+ // requests can get stuck behind it here.
+ if (!m_input_queue.empty()) {
+ // we're not idle if anything is pending
+ m_idleCount = IDLECOUNT_MAX_VALUE;
+ MemoryNode req = m_input_queue.front();
+ int bank = getBank(req.m_addr);
+ if (m_bankQueues[bank].size() < m_bank_queue_size) {
+ m_input_queue.pop_front();
+ m_bankQueues[bank].push_back(req);
+ }
+ m_profiler_ptr->profileMemInputQ(m_input_queue.size());
}
- m_profiler_ptr->profileMemInputQ(m_input_queue.size());
- }
}
-
// wakeup: This function is called once per memory controller clock cycle.
-
-void MemoryControl::wakeup () {
-
- // execute everything
- executeCycle();
-
- m_idleCount--;
- if (m_idleCount <= 0) {
- m_awakened = 0;
- } else {
- // Reschedule ourselves so that we run every memory cycle:
- g_eventQueue_ptr->scheduleEvent(this, m_mem_bus_cycle_multiplier);
- }
+void
+MemoryControl::wakeup()
+{
+ // execute everything
+ executeCycle();
+
+ m_idleCount--;
+ if (m_idleCount <= 0) {
+ m_awakened = 0;
+ } else {
+ // Reschedule ourselves so that we run every memory cycle:
+ g_eventQueue_ptr->scheduleEvent(this, m_mem_bus_cycle_multiplier);
+ }
}
MemoryControl *
diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh
index b96055cb1..d42c1e6e0 100644
--- a/src/mem/ruby/system/MemoryControl.hh
+++ b/src/mem/ruby/system/MemoryControl.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,34 +26,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * MemoryControl.hh
- *
- * Description: See MemoryControl.cc
- *
- * $Id: $
- *
- */
+#ifndef __MEM_RUBY_SYSTEM_MEMORY_CONTROL_HH__
+#define __MEM_RUBY_SYSTEM_MEMORY_CONTROL_HH__
-#ifndef MEMORY_CONTROL_H
-#define MEMORY_CONTROL_H
+#include <list>
-#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/Address.hh"
#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/profiler/MemCntrlProfiler.hh"
+#include "mem/ruby/slicc_interface/Message.hh"
#include "mem/ruby/system/AbstractMemOrCache.hh"
-#include "sim/sim_object.hh"
+#include "mem/ruby/system/MemoryNode.hh"
+#include "mem/ruby/system/System.hh"
#include "params/RubyMemoryControl.hh"
-
-#include <list>
+#include "sim/sim_object.hh"
// This constant is part of the definition of tFAW; see
// the comments in header to MemoryControl.cc
@@ -64,124 +53,117 @@
class Consumer;
-class MemoryControl : public SimObject, public Consumer, public AbstractMemOrCache {
-public:
-
- // Constructors
+class MemoryControl :
+ public SimObject, public Consumer, public AbstractMemOrCache
+{
+ public:
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;
+ void init();
+
+ ~MemoryControl();
+
+ 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
-
+#endif // __MEM_RUBY_SYSTEM_MEMORY_CONTROL_HH__
diff --git a/src/mem/ruby/system/MemoryNode.cc b/src/mem/ruby/system/MemoryNode.cc
index 5b74f497a..07262fba0 100644
--- a/src/mem/ruby/system/MemoryNode.cc
+++ b/src/mem/ruby/system/MemoryNode.cc
@@ -30,11 +30,12 @@
using namespace std;
-void MemoryNode::print(ostream& out) const
+void
+MemoryNode::print(ostream& out) const
{
- out << "[";
- out << m_time << ", ";
- out << m_msg_counter << ", ";
- out << m_msgptr << "; ";
- out << "]";
+ out << "[";
+ out << m_time << ", ";
+ out << m_msg_counter << ", ";
+ out << m_msgptr << "; ";
+ out << "]";
}
diff --git a/src/mem/ruby/system/MemoryNode.hh b/src/mem/ruby/system/MemoryNode.hh
index 2c2b987ae..10648b715 100644
--- a/src/mem/ruby/system/MemoryNode.hh
+++ b/src/mem/ruby/system/MemoryNode.hh
@@ -35,68 +35,59 @@
* message is enqueued to be sent back to the directory.
*/
-#ifndef MEMORYNODE_H
-#define MEMORYNODE_H
+#ifndef __MEM_RUBY_SYSTEM_MEMORYNODE_HH__
+#define __MEM_RUBY_SYSTEM_MEMORYNODE_HH__
#include <iostream>
+#include "mem/protocol/MemoryRequestType.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/Message.hh"
-#include "mem/protocol/MemoryRequestType.hh"
-
-class MemoryNode {
-
-public:
- // Constructors
-
-// old one:
- MemoryNode(const Time& time, int counter, const MsgPtr& msgptr, const physical_address_t addr, const bool is_mem_read) {
- m_time = time;
- m_msg_counter = counter;
- m_msgptr = msgptr;
- m_addr = addr;
- m_is_mem_read = is_mem_read;
- m_is_dirty_wb = !is_mem_read;
- }
-
-// new one:
- MemoryNode(const Time& time, const MsgPtr& msgptr, const physical_address_t addr, const bool is_mem_read, const bool is_dirty_wb) {
- m_time = time;
- m_msg_counter = 0;
- m_msgptr = msgptr;
- m_addr = addr;
- m_is_mem_read = is_mem_read;
- m_is_dirty_wb = is_dirty_wb;
- }
- // Destructor
- ~MemoryNode() {};
-
- // Public Methods
- void print(std::ostream& out) const;
-
- // Data Members (m_ prefix) (all public -- this is really more a struct)
-
- Time m_time;
- int m_msg_counter;
- MsgPtr m_msgptr;
- physical_address_t m_addr;
- bool m_is_mem_read;
- bool m_is_dirty_wb;
+class MemoryNode
+{
+ public:
+ // old constructor
+ MemoryNode(const Time& time, int counter, const MsgPtr& msgptr,
+ const physical_address_t addr, const bool is_mem_read)
+ {
+ m_time = time;
+ m_msg_counter = counter;
+ m_msgptr = msgptr;
+ m_addr = addr;
+ m_is_mem_read = is_mem_read;
+ m_is_dirty_wb = !is_mem_read;
+ }
+
+ // new constructor
+ MemoryNode(const Time& time, const MsgPtr& msgptr,
+ const physical_address_t addr, const bool is_mem_read,
+ const bool is_dirty_wb)
+ {
+ m_time = time;
+ m_msg_counter = 0;
+ m_msgptr = msgptr;
+ m_addr = addr;
+ m_is_mem_read = is_mem_read;
+ m_is_dirty_wb = is_dirty_wb;
+ }
+
+ void print(std::ostream& out) const;
+
+ Time m_time;
+ int m_msg_counter;
+ MsgPtr m_msgptr;
+ physical_address_t m_addr;
+ bool m_is_mem_read;
+ bool m_is_dirty_wb;
};
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const MemoryNode& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const MemoryNode& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const MemoryNode& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //MEMORYNODE_H
+#endif // __MEM_RUBY_SYSTEM_MEMORYNODE_HH__
diff --git a/src/mem/ruby/system/MemoryVector.hh b/src/mem/ruby/system/MemoryVector.hh
index e450059fd..15cea168d 100644
--- a/src/mem/ruby/system/MemoryVector.hh
+++ b/src/mem/ruby/system/MemoryVector.hh
@@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MEMORYVECTOR_H
-#define MEMORYVECTOR_H
+#ifndef __MEM_RUBY_SYSTEM_MEMORYVECTOR_HH__
+#define __MEM_RUBY_SYSTEM_MEMORYVECTOR_HH__
#include "mem/ruby/common/Address.hh"
@@ -36,117 +36,121 @@ class DirectoryMemory;
/**
* MemoryVector holds memory data (DRAM only)
*/
-class MemoryVector {
- public:
- MemoryVector();
- MemoryVector(uint32 size);
- ~MemoryVector();
- friend class DirectoryMemory;
+class MemoryVector
+{
+ public:
+ MemoryVector();
+ MemoryVector(uint32 size);
+ ~MemoryVector();
+ friend class DirectoryMemory;
- void setSize(uint32 size); // destructive
+ void setSize(uint32 size); // destructive
- void write(const Address & paddr, uint8* data, int len);
- uint8* read(const Address & paddr, uint8* data, int len);
+ void write(const Address & paddr, uint8* data, int len);
+ uint8* read(const Address & paddr, uint8* data, int len);
-private:
- uint8* getBlockPtr(const PhysAddress & addr);
+ private:
+ uint8* getBlockPtr(const PhysAddress & addr);
- uint32 m_size;
- uint8** m_pages;
- uint32 m_num_pages;
- const uint32 m_page_offset_mask;
+ uint32 m_size;
+ uint8** m_pages;
+ uint32 m_num_pages;
+ const uint32 m_page_offset_mask;
};
inline
MemoryVector::MemoryVector()
- : m_page_offset_mask(4095)
+ : m_page_offset_mask(4095)
{
- m_size = 0;
- m_num_pages = 0;
- m_pages = NULL;
+ m_size = 0;
+ m_num_pages = 0;
+ m_pages = NULL;
}
inline
MemoryVector::MemoryVector(uint32 size)
- : m_page_offset_mask(4095)
+ : m_page_offset_mask(4095)
{
- setSize(size);
+ setSize(size);
}
inline
MemoryVector::~MemoryVector()
{
- for (int i=0; i<m_num_pages; i++) {
- if (m_pages[i] != 0) {
- delete [] m_pages[i];
+ for (int i = 0; i < m_num_pages; i++) {
+ if (m_pages[i] != 0) {
+ delete [] m_pages[i];
+ }
}
- }
- delete [] m_pages;
+ delete [] m_pages;
}
-inline
-void MemoryVector::setSize(uint32 size)
+inline void
+MemoryVector::setSize(uint32 size)
{
- if (m_pages != NULL){
- for (int i=0; i<m_num_pages; i++) {
- if (m_pages[i] != 0) {
- delete [] m_pages[i];
- }
+ if (m_pages != NULL){
+ for (int i = 0; i < m_num_pages; i++) {
+ if (m_pages[i] != 0) {
+ delete [] m_pages[i];
+ }
+ }
+ delete [] m_pages;
}
- delete [] m_pages;
- }
- m_size = size;
- assert(size%4096 == 0);
- m_num_pages = size >> 12;
- m_pages = new uint8*[m_num_pages];
- memset(m_pages, 0, m_num_pages * sizeof(uint8*));
+ m_size = size;
+ assert(size%4096 == 0);
+ m_num_pages = size >> 12;
+ m_pages = new uint8*[m_num_pages];
+ memset(m_pages, 0, m_num_pages * sizeof(uint8*));
}
-inline
-void MemoryVector::write(const Address & paddr, uint8* data, int len)
+inline void
+MemoryVector::write(const Address & paddr, uint8* data, int len)
{
- assert(paddr.getAddress() + len <= m_size);
- uint32 page_num = paddr.getAddress() >> 12;
- if (m_pages[page_num] == 0) {
- bool all_zeros = true;
- for (int i=0;i<len;i++) {
- if (data[i] != 0) {
- all_zeros = false;
- break;
- }
+ assert(paddr.getAddress() + len <= m_size);
+ uint32 page_num = paddr.getAddress() >> 12;
+ if (m_pages[page_num] == 0) {
+ bool all_zeros = true;
+ for (int i = 0; i < len;i++) {
+ if (data[i] != 0) {
+ all_zeros = false;
+ break;
+ }
+ }
+ if (all_zeros)
+ return;
+ m_pages[page_num] = new uint8[4096];
+ memset(m_pages[page_num], 0, 4096);
+ uint32 offset = paddr.getAddress() & m_page_offset_mask;
+ memcpy(&m_pages[page_num][offset], data, len);
+ } else {
+ memcpy(&m_pages[page_num][paddr.getAddress()&m_page_offset_mask],
+ data, len);
}
- if (all_zeros) return;
- m_pages[page_num] = new uint8[4096];
- memset(m_pages[page_num], 0, 4096);
- uint32 offset = paddr.getAddress() & m_page_offset_mask;
- memcpy(&m_pages[page_num][offset], data, len);
- } else {
- memcpy(&m_pages[page_num][paddr.getAddress()&m_page_offset_mask], data, len);
- }
}
-inline
-uint8* MemoryVector::read(const Address & paddr, uint8* data, int len)
+inline uint8*
+MemoryVector::read(const Address & paddr, uint8* data, int len)
{
- assert(paddr.getAddress() + len <= m_size);
- uint32 page_num = paddr.getAddress() >> 12;
- if (m_pages[page_num] == 0) {
- memset(data, 0, len);
- } else {
- memcpy(data, &m_pages[page_num][paddr.getAddress()&m_page_offset_mask], len);
- }
- return data;
+ assert(paddr.getAddress() + len <= m_size);
+ uint32 page_num = paddr.getAddress() >> 12;
+ if (m_pages[page_num] == 0) {
+ memset(data, 0, len);
+ } else {
+ memcpy(data, &m_pages[page_num][paddr.getAddress()&m_page_offset_mask],
+ len);
+ }
+ return data;
}
-inline
-uint8* MemoryVector::getBlockPtr(const PhysAddress & paddr)
+inline uint8*
+MemoryVector::getBlockPtr(const PhysAddress & paddr)
{
- uint32 page_num = paddr.getAddress() >> 12;
- if (m_pages[page_num] == 0) {
- m_pages[page_num] = new uint8[4096];
- memset(m_pages[page_num], 0, 4096);
- }
- return &m_pages[page_num][paddr.getAddress()&m_page_offset_mask];
+ uint32 page_num = paddr.getAddress() >> 12;
+ if (m_pages[page_num] == 0) {
+ m_pages[page_num] = new uint8[4096];
+ memset(m_pages[page_num], 0, 4096);
+ }
+ return &m_pages[page_num][paddr.getAddress()&m_page_offset_mask];
}
-#endif // MEMORYVECTOR_H
+#endif // __MEM_RUBY_SYSTEM_MEMORYVECTOR_HH__
diff --git a/src/mem/ruby/system/NodeID.hh b/src/mem/ruby/system/NodeID.hh
index 6191ad489..4ce8d8a8d 100644
--- a/src/mem/ruby/system/NodeID.hh
+++ b/src/mem/ruby/system/NodeID.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,26 +26,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NodeID.hh
- *
- * Description:
- *
- * $Id: NodeID.hh,v 3.3 2003/12/04 15:01:39 xu Exp $
- *
- */
-
-#ifndef NODEID_H
-#define NODEID_H
+#ifndef __MEM_RUBY_SYSTEM_NODEID_HH__
+#define __MEM_RUBY_SYSTEM_NODEID_HH__
#include <string>
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/util.hh"
+#include "mem/ruby/common/Global.hh"
typedef int NodeID;
-extern inline
-std::string NodeIDToString (NodeID node) { return int_to_string(node); }
+inline std::string
+NodeIDToString(NodeID node)
+{
+ return int_to_string(node);
+}
-#endif //NODEID_H
+#endif // __MEM_RUBY_SYSTEM_NODEID_HH__
diff --git a/src/mem/ruby/system/PerfectCacheMemory.hh b/src/mem/ruby/system/PerfectCacheMemory.hh
index 6561d028b..f1fb8b2e9 100644
--- a/src/mem/ruby/system/PerfectCacheMemory.hh
+++ b/src/mem/ruby/system/PerfectCacheMemory.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,215 +26,188 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * PerfectCacheMemory.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef PERFECTCACHEMEMORY_H
-#define PERFECTCACHEMEMORY_H
+#ifndef __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
+#define __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Map.hh"
#include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
template<class ENTRY>
-class PerfectCacheLineState {
-public:
- PerfectCacheLineState() { m_permission = AccessPermission_NUM; }
- AccessPermission m_permission;
- ENTRY m_entry;
+struct PerfectCacheLineState
+{
+ PerfectCacheLineState() { m_permission = AccessPermission_NUM; }
+ AccessPermission m_permission;
+ ENTRY m_entry;
};
template<class ENTRY>
-extern inline
-ostream& operator<<(ostream& out, const PerfectCacheLineState<ENTRY>& obj)
+inline ostream&
+operator<<(ostream& out, const PerfectCacheLineState<ENTRY>& obj)
{
- return out;
+ return out;
}
template<class ENTRY>
-class PerfectCacheMemory {
-public:
-
- // Constructors
- PerfectCacheMemory();
-
- // Destructor
- //~PerfectCacheMemory();
-
- // Public Methods
+class PerfectCacheMemory
+{
+ public:
+ PerfectCacheMemory();
- static void printConfig(ostream& out);
+ static void printConfig(ostream& out);
- // perform a cache access and see if we hit or not. Return true on
- // a hit.
- bool tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry);
+ // perform a cache access and see if we hit or not. Return true
+ // on a hit.
+ bool tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry);
- // tests to see if an address is present in the cache
- bool isTagPresent(const Address& address) const;
+ // tests to see if an address is present in the cache
+ bool isTagPresent(const Address& address) const;
- // Returns true if there is:
- // a) a tag match on this address or there is
- // b) an Invalid line in the same cache "way"
- bool cacheAvail(const Address& address) const;
+ // Returns true if there is:
+ // a) a tag match on this address or there is
+ // b) an Invalid line in the same cache "way"
+ bool cacheAvail(const Address& address) const;
- // find an Invalid entry and sets the tag appropriate for the address
- void allocate(const Address& address);
+ // find an Invalid entry and sets the tag appropriate for the address
+ void allocate(const Address& address);
- void deallocate(const Address& address);
+ void deallocate(const Address& address);
- // Returns with the physical address of the conflicting cache line
- Address cacheProbe(const Address& newAddress) const;
+ // Returns with the physical address of the conflicting cache line
+ Address cacheProbe(const Address& newAddress) const;
- // looks an address up in the cache
- ENTRY& lookup(const Address& address);
- const ENTRY& lookup(const Address& address) const;
+ // looks an address up in the cache
+ ENTRY& lookup(const Address& address);
+ const ENTRY& lookup(const Address& address) const;
- // Get/Set permission of cache block
- AccessPermission getPermission(const Address& address) const;
- void changePermission(const Address& address, AccessPermission new_perm);
+ // Get/Set permission of cache block
+ AccessPermission getPermission(const Address& address) const;
+ void changePermission(const Address& address, AccessPermission new_perm);
- // Print cache contents
- void print(ostream& out) const;
-private:
- // Private Methods
+ // Print cache contents
+ void print(ostream& out) const;
- // Private copy constructor and assignment operator
- PerfectCacheMemory(const PerfectCacheMemory& obj);
- PerfectCacheMemory& operator=(const PerfectCacheMemory& obj);
+ private:
+ // Private copy constructor and assignment operator
+ PerfectCacheMemory(const PerfectCacheMemory& obj);
+ PerfectCacheMemory& operator=(const PerfectCacheMemory& obj);
- // Data Members (m_prefix)
- Map<Address, PerfectCacheLineState<ENTRY> > m_map;
+ // Data Members (m_prefix)
+ Map<Address, PerfectCacheLineState<ENTRY> > m_map;
};
-// Output operator declaration
-//ostream& operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
template<class ENTRY>
-extern inline
-ostream& operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj)
+inline ostream&
+operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-
-// ****************************************************************
-
template<class ENTRY>
-extern inline
+inline
PerfectCacheMemory<ENTRY>::PerfectCacheMemory()
{
}
-// STATIC METHODS
-
template<class ENTRY>
-extern inline
-void PerfectCacheMemory<ENTRY>::printConfig(ostream& out)
+inline void
+PerfectCacheMemory<ENTRY>::printConfig(ostream& out)
{
}
-// PUBLIC METHODS
-
template<class ENTRY>
-extern inline
-bool PerfectCacheMemory<ENTRY>::tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry)
+inline bool
+PerfectCacheMemory<ENTRY>::tryCacheAccess(const CacheMsg& msg,
+ bool& block_stc, ENTRY*& entry)
{
- ERROR_MSG("not implemented");
+ ERROR_MSG("not implemented");
}
// tests to see if an address is present in the cache
template<class ENTRY>
-extern inline
-bool PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const
+inline bool
+PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const
{
- return m_map.exist(line_address(address));
+ return m_map.exist(line_address(address));
}
template<class ENTRY>
-extern inline
-bool PerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const
+inline bool
+PerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const
{
- return true;
+ return true;
}
// find an Invalid or already allocated entry and sets the tag
// appropriate for the address
template<class ENTRY>
-extern inline
-void PerfectCacheMemory<ENTRY>::allocate(const Address& address)
+inline void
+PerfectCacheMemory<ENTRY>::allocate(const Address& address)
{
- PerfectCacheLineState<ENTRY> line_state;
- line_state.m_permission = AccessPermission_Busy;
- line_state.m_entry = ENTRY();
- m_map.add(line_address(address), line_state);
+ PerfectCacheLineState<ENTRY> line_state;
+ line_state.m_permission = AccessPermission_Busy;
+ line_state.m_entry = ENTRY();
+ m_map.add(line_address(address), line_state);
}
// deallocate entry
template<class ENTRY>
-extern inline
-void PerfectCacheMemory<ENTRY>::deallocate(const Address& address)
+inline void
+PerfectCacheMemory<ENTRY>::deallocate(const Address& address)
{
- m_map.erase(line_address(address));
+ m_map.erase(line_address(address));
}
// Returns with the physical address of the conflicting cache line
template<class ENTRY>
-extern inline
-Address PerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const
+inline Address
+PerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const
{
- ERROR_MSG("cacheProbe called in perfect cache");
+ ERROR_MSG("cacheProbe called in perfect cache");
}
// looks an address up in the cache
template<class ENTRY>
-extern inline
-ENTRY& PerfectCacheMemory<ENTRY>::lookup(const Address& address)
+inline ENTRY&
+PerfectCacheMemory<ENTRY>::lookup(const Address& address)
{
- return m_map.lookup(line_address(address)).m_entry;
+ return m_map.lookup(line_address(address)).m_entry;
}
// looks an address up in the cache
template<class ENTRY>
-extern inline
-const ENTRY& PerfectCacheMemory<ENTRY>::lookup(const Address& address) const
+inline const ENTRY&
+PerfectCacheMemory<ENTRY>::lookup(const Address& address) const
{
- return m_map.lookup(line_address(address)).m_entry;
+ return m_map.lookup(line_address(address)).m_entry;
}
template<class ENTRY>
-extern inline
-AccessPermission PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const
+inline AccessPermission
+PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const
{
- return m_map.lookup(line_address(address)).m_permission;
+ return m_map.lookup(line_address(address)).m_permission;
}
template<class ENTRY>
-extern inline
-void PerfectCacheMemory<ENTRY>::changePermission(const Address& address, AccessPermission new_perm)
+inline void
+PerfectCacheMemory<ENTRY>::changePermission(const Address& address,
+ AccessPermission new_perm)
{
- Address line_address = address;
- line_address.makeLineAddress();
- PerfectCacheLineState<ENTRY>& line_state = m_map.lookup(line_address);
- AccessPermission old_perm = line_state.m_permission;
- line_state.m_permission = new_perm;
+ Address line_address = address;
+ line_address.makeLineAddress();
+ PerfectCacheLineState<ENTRY>& line_state = m_map.lookup(line_address);
+ AccessPermission old_perm = line_state.m_permission;
+ line_state.m_permission = new_perm;
}
template<class ENTRY>
-extern inline
-void PerfectCacheMemory<ENTRY>::print(ostream& out) const
+inline void
+PerfectCacheMemory<ENTRY>::print(ostream& out) const
{
}
-#endif //PERFECTCACHEMEMORY_H
+#endif // __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc
index 58b67ea60..1d971ae21 100644
--- a/src/mem/ruby/system/PersistentTable.cc
+++ b/src/mem/ruby/system/PersistentTable.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,178 +26,187 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "mem/ruby/system/PersistentTable.hh"
#include "mem/gems_common/util.hh"
+#include "mem/ruby/system/PersistentTable.hh"
// randomize so that handoffs are not locality-aware
-// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15};
-// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-
+#if 0
+int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6,
+ 10, 14, 3, 7, 11, 15};
+int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15};
+#endif
PersistentTable::PersistentTable()
{
- m_map_ptr = new Map<Address, PersistentTableEntry>;
+ m_map_ptr = new Map<Address, PersistentTableEntry>;
}
PersistentTable::~PersistentTable()
{
- delete m_map_ptr;
- m_map_ptr = NULL;
+ delete m_map_ptr;
+ m_map_ptr = NULL;
}
-void PersistentTable::persistentRequestLock(const Address& address,
- MachineID locker,
- AccessType type)
+void
+PersistentTable::persistentRequestLock(const Address& address,
+ MachineID locker,
+ AccessType type)
{
-
- // if (locker == m_chip_ptr->getID() )
- // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker
- // << " requesting lock for " << address << endl;
-
- // MachineID locker = (MachineID) persistent_randomize[llocker];
-
- assert(address == line_address(address));
- if (!m_map_ptr->exist(address)) {
- // Allocate if not present
- PersistentTableEntry entry;
- entry.m_starving.add(locker);
- if (type == AccessType_Write) {
- entry.m_request_to_write.add(locker);
+#if 0
+ if (locker == m_chip_ptr->getID())
+ cout << "Chip " << m_chip_ptr->getID() << ": " << llocker
+ << " requesting lock for " << address << endl;
+
+ MachineID locker = (MachineID) persistent_randomize[llocker];
+#endif
+
+ assert(address == line_address(address));
+ if (!m_map_ptr->exist(address)) {
+ // Allocate if not present
+ PersistentTableEntry entry;
+ entry.m_starving.add(locker);
+ if (type == AccessType_Write) {
+ entry.m_request_to_write.add(locker);
+ }
+ m_map_ptr->add(address, entry);
+ } else {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+
+ //
+ // Make sure we're not already in the locked set
+ //
+ assert(!(entry.m_starving.isElement(locker)));
+
+ entry.m_starving.add(locker);
+ if (type == AccessType_Write) {
+ entry.m_request_to_write.add(locker);
+ }
+ assert(entry.m_marked.isSubset(entry.m_starving));
}
- m_map_ptr->add(address, entry);
- } else {
+}
+
+void
+PersistentTable::persistentRequestUnlock(const Address& address,
+ MachineID unlocker)
+{
+#if 0
+ if (unlocker == m_chip_ptr->getID())
+ cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker
+ << " requesting unlock for " << address << endl;
+
+ MachineID unlocker = (MachineID) persistent_randomize[uunlocker];
+#endif
+
+ assert(address == line_address(address));
+ assert(m_map_ptr->exist(address));
PersistentTableEntry& entry = m_map_ptr->lookup(address);
//
- // Make sure we're not already in the locked set
+ // Make sure we're in the locked set
//
- assert(!(entry.m_starving.isElement(locker)));
-
- entry.m_starving.add(locker);
- if (type == AccessType_Write) {
- entry.m_request_to_write.add(locker);
- }
+ assert(entry.m_starving.isElement(unlocker));
+ assert(entry.m_marked.isSubset(entry.m_starving));
+ entry.m_starving.remove(unlocker);
+ entry.m_marked.remove(unlocker);
+ entry.m_request_to_write.remove(unlocker);
assert(entry.m_marked.isSubset(entry.m_starving));
- }
-}
-void PersistentTable::persistentRequestUnlock(const Address& address,
- MachineID unlocker)
-{
- // if (unlocker == m_chip_ptr->getID() )
- // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker
- // << " requesting unlock for " << address << endl;
-
- // MachineID unlocker = (MachineID) persistent_randomize[uunlocker];
-
- assert(address == line_address(address));
- assert(m_map_ptr->exist(address));
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
-
- //
- // Make sure we're in the locked set
- //
- assert(entry.m_starving.isElement(unlocker));
- assert(entry.m_marked.isSubset(entry.m_starving));
- entry.m_starving.remove(unlocker);
- entry.m_marked.remove(unlocker);
- entry.m_request_to_write.remove(unlocker);
- assert(entry.m_marked.isSubset(entry.m_starving));
-
- // Deallocate if empty
- if (entry.m_starving.isEmpty()) {
- assert(entry.m_marked.isEmpty());
- m_map_ptr->erase(address);
- }
+ // Deallocate if empty
+ if (entry.m_starving.isEmpty()) {
+ assert(entry.m_marked.isEmpty());
+ m_map_ptr->erase(address);
+ }
}
-bool PersistentTable::okToIssueStarving(const Address& address,
- MachineID machId) const
+bool
+PersistentTable::okToIssueStarving(const Address& address,
+ MachineID machId) const
{
- assert(address == line_address(address));
- if (!m_map_ptr->exist(address)) {
- //
- // No entry present
- //
- return true;
- } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) {
- //
- // We can't issue another lockdown until are previous unlock has occurred
- //
- return false;
- } else {
- return (m_map_ptr->lookup(address).m_marked.isEmpty());
- }
+ assert(address == line_address(address));
+ if (!m_map_ptr->exist(address)) {
+ // No entry present
+ return true;
+ } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) {
+ // We can't issue another lockdown until are previous unlock
+ // has occurred
+ return false;
+ } else {
+ return m_map_ptr->lookup(address).m_marked.isEmpty();
+ }
}
-MachineID PersistentTable::findSmallest(const Address& address) const
+MachineID
+PersistentTable::findSmallest(const Address& address) const
{
- assert(address == line_address(address));
- assert(m_map_ptr->exist(address));
- const PersistentTableEntry& entry = m_map_ptr->lookup(address);
- return entry.m_starving.smallestElement();
+ assert(address == line_address(address));
+ assert(m_map_ptr->exist(address));
+ const PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ return entry.m_starving.smallestElement();
}
-AccessType PersistentTable::typeOfSmallest(const Address& address) const
+AccessType
+PersistentTable::typeOfSmallest(const Address& address) const
{
- assert(address == line_address(address));
- assert(m_map_ptr->exist(address));
- const PersistentTableEntry& entry = m_map_ptr->lookup(address);
- if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) {
- return AccessType_Write;
- } else {
- return AccessType_Read;
- }
+ assert(address == line_address(address));
+ assert(m_map_ptr->exist(address));
+ const PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ if (entry.m_request_to_write.
+ isElement(entry.m_starving.smallestElement())) {
+ return AccessType_Write;
+ } else {
+ return AccessType_Read;
+ }
}
-void PersistentTable::markEntries(const Address& address)
+void
+PersistentTable::markEntries(const Address& address)
{
- assert(address == line_address(address));
- if (m_map_ptr->exist(address)) {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ assert(address == line_address(address));
+ if (m_map_ptr->exist(address)) {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
- //
- // None should be marked
- //
- assert(entry.m_marked.isEmpty());
+ // None should be marked
+ assert(entry.m_marked.isEmpty());
- //
- // Mark all the nodes currently in the table
- //
- entry.m_marked = entry.m_starving;
- }
+ // Mark all the nodes currently in the table
+ entry.m_marked = entry.m_starving;
+ }
}
-bool PersistentTable::isLocked(const Address& address) const
+bool
+PersistentTable::isLocked(const Address& address) const
{
- assert(address == line_address(address));
- // If an entry is present, it must be locked
- return (m_map_ptr->exist(address));
+ assert(address == line_address(address));
+
+ // If an entry is present, it must be locked
+ return m_map_ptr->exist(address);
}
-int PersistentTable::countStarvingForAddress(const Address& address) const
+int
+PersistentTable::countStarvingForAddress(const Address& address) const
{
- if (m_map_ptr->exist(address)) {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
- return (entry.m_starving.count());
- }
- else {
- return 0;
- }
+ if (m_map_ptr->exist(address)) {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ return (entry.m_starving.count());
+ } else {
+ return 0;
+ }
}
-int PersistentTable::countReadStarvingForAddress(const Address& address) const
+int
+PersistentTable::countReadStarvingForAddress(const Address& address) const
{
- if (m_map_ptr->exist(address)) {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
- return (entry.m_starving.count() - entry.m_request_to_write.count());
- }
- else {
- return 0;
- }
+ if (m_map_ptr->exist(address)) {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ return (entry.m_starving.count() - entry.m_request_to_write.count());
+ } else {
+ return 0;
+ }
}
-void PersistentTable::print(ostream& out) const
+void
+PersistentTable::print(ostream& out) const
{
}
diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh
index 8cbb48817..defcae2b8 100644
--- a/src/mem/ruby/system/PersistentTable.hh
+++ b/src/mem/ruby/system/PersistentTable.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,76 +26,74 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PersistentTable_H
-#define PersistentTable_H
+#ifndef __MEM_RUBY_SYSTEM_PERSISTENTTABLE_HH__
+#define __MEM_RUBY_SYSTEM_PERSISTENTTABLE_HH__
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/system/MachineID.hh"
#include "mem/protocol/AccessType.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/system/MachineID.hh"
-class PersistentTableEntry {
-public:
- void print(ostream& out) const {}
+class PersistentTableEntry
+{
+ public:
+ void print(ostream& out) const {}
- NetDest m_starving;
- NetDest m_marked;
- NetDest m_request_to_write;
+ NetDest m_starving;
+ NetDest m_marked;
+ NetDest m_request_to_write;
};
-class PersistentTable {
-public:
- // Constructors
- PersistentTable();
+class PersistentTable
+{
+ public:
+ // Constructors
+ PersistentTable();
- // Destructor
- ~PersistentTable();
+ // Destructor
+ ~PersistentTable();
- // Public Methods
- void persistentRequestLock(const Address& address, MachineID locker, AccessType type);
- void persistentRequestUnlock(const Address& address, MachineID unlocker);
- bool okToIssueStarving(const Address& address, MachineID machID) const;
- MachineID findSmallest(const Address& address) const;
- AccessType typeOfSmallest(const Address& address) const;
- void markEntries(const Address& address);
- bool isLocked(const Address& addr) const;
- int countStarvingForAddress(const Address& addr) const;
- int countReadStarvingForAddress(const Address& addr) const;
+ // Public Methods
+ void persistentRequestLock(const Address& address, MachineID locker,
+ AccessType type);
+ void persistentRequestUnlock(const Address& address, MachineID unlocker);
+ bool okToIssueStarving(const Address& address, MachineID machID) const;
+ MachineID findSmallest(const Address& address) const;
+ AccessType typeOfSmallest(const Address& address) const;
+ void markEntries(const Address& address);
+ bool isLocked(const Address& addr) const;
+ int countStarvingForAddress(const Address& addr) const;
+ int countReadStarvingForAddress(const Address& addr) const;
- static void printConfig(ostream& out) {}
+ static void printConfig(ostream& out) {}
- void print(ostream& out) const;
-private:
- // Private Methods
+ void print(ostream& out) const;
- // Private copy constructor and assignment operator
- PersistentTable(const PersistentTable& obj);
- PersistentTable& operator=(const PersistentTable& obj);
+ private:
+ // Private copy constructor and assignment operator
+ PersistentTable(const PersistentTable& obj);
+ PersistentTable& operator=(const PersistentTable& obj);
- // Data Members (m_prefix)
- Map<Address, PersistentTableEntry>* m_map_ptr;
+ // Data Members (m_prefix)
+ Map<Address, PersistentTableEntry>* m_map_ptr;
};
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const PersistentTable& obj)
+inline ostream&
+operator<<(ostream& out, const PersistentTable& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const PersistentTableEntry& obj)
+inline ostream&
+operator<<(ostream& out, const PersistentTableEntry& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //PersistentTable_H
+#endif // __MEM_RUBY_SYSTEM_PERSISTENTTABLE_HH__
diff --git a/src/mem/ruby/system/PseudoLRUPolicy.hh b/src/mem/ruby/system/PseudoLRUPolicy.hh
index 61bf72c3e..1e1e68188 100644
--- a/src/mem/ruby/system/PseudoLRUPolicy.hh
+++ b/src/mem/ruby/system/PseudoLRUPolicy.hh
@@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PSEUDOLRUPOLICY_H
-#define PSEUDOLRUPOLICY_H
+#ifndef __MEM_RUBY_SYSTEM_PSEUDOLRUPOLICY_HH__
+#define __MEM_RUBY_SYSTEM_PSEUDOLRUPOLICY_HH__
#include "mem/ruby/system/AbstractReplacementPolicy.hh"
@@ -44,94 +44,97 @@
* 2 is one below the associativy, and most fair when it is one above.
*/
-class PseudoLRUPolicy : public AbstractReplacementPolicy {
- public:
-
- PseudoLRUPolicy(Index num_sets, Index assoc);
- ~PseudoLRUPolicy();
-
- void touch(Index set, Index way, Time time);
- Index getVictim(Index set) const;
-
- private:
- unsigned int m_effective_assoc; /** nearest (to ceiling) power of 2 */
- unsigned int m_num_levels; /** number of levels in the tree */
- uint64* m_trees; /** bit representation of the trees, one for each set */
+class PseudoLRUPolicy : public AbstractReplacementPolicy
+{
+ public:
+ PseudoLRUPolicy(Index num_sets, Index assoc);
+ ~PseudoLRUPolicy();
+
+ void touch(Index set, Index way, Time time);
+ Index getVictim(Index set) const;
+
+ private:
+ unsigned int m_effective_assoc; /** nearest (to ceiling) power of 2 */
+ unsigned int m_num_levels; /** number of levels in the tree */
+ uint64* m_trees; /** bit representation of the
+ * trees, one for each set */
};
inline
PseudoLRUPolicy::PseudoLRUPolicy(Index num_sets, Index assoc)
- : AbstractReplacementPolicy(num_sets, assoc)
+ : AbstractReplacementPolicy(num_sets, assoc)
{
- int num_tree_nodes;
-
- // associativity cannot exceed capacity of tree representation
- assert(num_sets > 0 && assoc > 1 && assoc <= (Index) sizeof(uint64)*4);
-
- m_trees = NULL;
- m_num_levels = 0;
-
- m_effective_assoc = 1;
- while(m_effective_assoc < assoc){
- m_effective_assoc <<= 1; // effective associativity is ceiling power of 2
- }
- assoc = m_effective_assoc;
- while(true){
- assoc /= 2;
- if(!assoc) break;
- m_num_levels++;
- }
- assert(m_num_levels < sizeof(unsigned int)*4);
- num_tree_nodes = (1 << m_num_levels) - 1;
- m_trees = new uint64[m_num_sets];
- for(unsigned int i=0; i< m_num_sets; i++){
- m_trees[i] = 0;
- }
+ int num_tree_nodes;
+
+ // associativity cannot exceed capacity of tree representation
+ assert(num_sets > 0 && assoc > 1 && assoc <= (Index) sizeof(uint64)*4);
+
+ m_trees = NULL;
+ m_num_levels = 0;
+
+ m_effective_assoc = 1;
+ while (m_effective_assoc < assoc) {
+ // effective associativity is ceiling power of 2
+ m_effective_assoc <<= 1;
+ }
+ assoc = m_effective_assoc;
+ while (true) {
+ assoc /= 2;
+ if(!assoc) break;
+ m_num_levels++;
+ }
+ assert(m_num_levels < sizeof(unsigned int)*4);
+ num_tree_nodes = (1 << m_num_levels) - 1;
+ m_trees = new uint64[m_num_sets];
+ for (unsigned i = 0; i < m_num_sets; i++) {
+ m_trees[i] = 0;
+ }
}
inline
PseudoLRUPolicy::~PseudoLRUPolicy()
{
- if(m_trees != NULL)
- delete[] m_trees;
+ if (m_trees != NULL)
+ delete[] m_trees;
}
-inline
-void PseudoLRUPolicy::touch(Index set, Index index, Time time){
- assert(index >= 0 && index < m_assoc);
- assert(set >= 0 && set < m_num_sets);
-
- int tree_index = 0;
- int node_val;
- for(int i=m_num_levels -1; i>=0; i--){
- node_val = (index >> i)&1;
- if(node_val)
- m_trees[set] |= node_val << tree_index;
- else
- m_trees[set] &= ~(1 << tree_index);
- tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1;
- }
- m_last_ref_ptr[set][index] = time;
+inline void
+PseudoLRUPolicy::touch(Index set, Index index, Time time)
+{
+ assert(index >= 0 && index < m_assoc);
+ assert(set >= 0 && set < m_num_sets);
+
+ int tree_index = 0;
+ int node_val;
+ for (int i = m_num_levels - 1; i >= 0; i--) {
+ node_val = (index >> i)&1;
+ if (node_val)
+ m_trees[set] |= node_val << tree_index;
+ else
+ m_trees[set] &= ~(1 << tree_index);
+ tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1;
+ }
+ m_last_ref_ptr[set][index] = time;
}
-inline
-Index PseudoLRUPolicy::getVictim(Index set) const {
- // assert(m_assoc != 0);
-
- Index index = 0;
-
- int tree_index = 0;
- int node_val;
- for(unsigned int i=0;i<m_num_levels;i++){
- node_val = (m_trees[set]>>tree_index)&1;
- index += node_val?0:(m_effective_assoc >> (i+1));
- tree_index = node_val? (tree_index*2)+1 : (tree_index*2)+2;
- }
- assert(index >= 0 && index < m_effective_assoc);
-
- /* return either the found index or the max possible index */
- /* NOTE: this is not a fair replacement when assoc is not a power of 2 */
- return (index > (m_assoc-1)) ? m_assoc-1:index;
+inline Index
+PseudoLRUPolicy::getVictim(Index set) const
+{
+ // assert(m_assoc != 0);
+ Index index = 0;
+
+ int tree_index = 0;
+ int node_val;
+ for (unsigned i = 0; i < m_num_levels; i++){
+ node_val = (m_trees[set] >> tree_index) & 1;
+ index += node_val ? 0 : (m_effective_assoc >> (i + 1));
+ tree_index = node_val ? (tree_index * 2) + 1 : (tree_index * 2) + 2;
+ }
+ assert(index >= 0 && index < m_effective_assoc);
+
+ /* return either the found index or the max possible index */
+ /* NOTE: this is not a fair replacement when assoc is not a power of 2 */
+ return (index > (m_assoc - 1)) ? m_assoc - 1 : index;
}
-#endif // PSEUDOLRUPOLICY_H
+#endif // __MEM_RUBY_SYSTEM_PSEUDOLRUPOLICY_HH__
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 480c13ad8..87a98185c 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
@@ -27,10 +26,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "cpu/rubytest/RubyTester.hh"
#include "mem/physical.hh"
-#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "cpu/rubytest/RubyTester.hh"
+#include "mem/ruby/system/RubyPort.hh"
RubyPort::RubyPort(const Params *p)
: MemObject(p)
@@ -39,7 +38,7 @@ RubyPort::RubyPort(const Params *p)
assert(m_version != -1);
physmem = p->physmem;
-
+
m_controller = NULL;
m_mandatory_q_ptr = NULL;
@@ -48,7 +47,8 @@ RubyPort::RubyPort(const Params *p)
physMemPort = NULL;
}
-void RubyPort::init()
+void
+RubyPort::init()
{
assert(m_controller != NULL);
m_mandatory_q_ptr = m_controller->getMandatoryQueue();
@@ -59,38 +59,38 @@ RubyPort::getPort(const std::string &if_name, int idx)
{
if (if_name == "port") {
return new M5Port(csprintf("%s-port%d", name(), idx), this);
- } else if (if_name == "pio_port") {
- //
+ }
+
+ if (if_name == "pio_port") {
// ensure there is only one pio port
- //
assert(pio_port == NULL);
- pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx),
- this);
+ pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this);
return pio_port;
- } else if (if_name == "physMemPort") {
- //
+ }
+
+ if (if_name == "physMemPort") {
// RubyPort should only have one port to physical memory
- //
assert (physMemPort == NULL);
- physMemPort = new M5Port(csprintf("%s-physMemPort", name()),
- this);
-
+ physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this);
+
return physMemPort;
- } else if (if_name == "functional") {
- //
- // Calls for the functional port only want to access functional memory.
- // Therefore, directly pass these calls ports to physmem.
- //
+ }
+
+ if (if_name == "functional") {
+ // Calls for the functional port only want to access
+ // functional memory. Therefore, directly pass these calls
+ // ports to physmem.
assert(physmem != NULL);
return physmem->getPort(if_name, idx);
}
+
return NULL;
}
-RubyPort::PioPort::PioPort(const std::string &_name,
+RubyPort::PioPort::PioPort(const std::string &_name,
RubyPort *_port)
: SimpleTimingPort(_name, _port)
{
@@ -98,7 +98,7 @@ RubyPort::PioPort::PioPort(const std::string &_name,
ruby_port = _port;
}
-RubyPort::M5Port::M5Port(const std::string &_name,
+RubyPort::M5Port::M5Port(const std::string &_name,
RubyPort *_port)
: SimpleTimingPort(_name, _port)
{
@@ -113,7 +113,6 @@ RubyPort::PioPort::recvAtomic(PacketPtr pkt)
return 0;
}
-
Tick
RubyPort::M5Port::recvAtomic(PacketPtr pkt)
{
@@ -125,48 +124,39 @@ RubyPort::M5Port::recvAtomic(PacketPtr pkt)
bool
RubyPort::PioPort::recvTiming(PacketPtr pkt)
{
- //
- // In FS mode, ruby memory will receive pio responses from devices and
- // it must forward these responses back to the particular CPU.
- //
- DPRINTF(MemoryAccess,
- "Pio response for address %#x\n",
- pkt->getAddr());
+ // In FS mode, ruby memory will receive pio responses from devices
+ // and it must forward these responses back to the particular CPU.
+ DPRINTF(MemoryAccess, "Pio response for address %#x\n", pkt->getAddr());
assert(pkt->isResponse());
- //
// First we must retrieve the request port from the sender State
- //
- RubyPort::SenderState *senderState =
+ RubyPort::SenderState *senderState =
safe_cast<RubyPort::SenderState *>(pkt->senderState);
M5Port *port = senderState->port;
assert(port != NULL);
-
+
// pop the sender state from the packet
pkt->senderState = senderState->saved;
delete senderState;
-
+
port->sendTiming(pkt);
-
+
return true;
}
bool
RubyPort::M5Port::recvTiming(PacketPtr pkt)
{
- DPRINTF(MemoryAccess,
- "Timing access caught for address %#x\n",
- pkt->getAddr());
+ DPRINTF(MemoryAccess,
+ "Timing access caught for address %#x\n", pkt->getAddr());
//dsm: based on SimpleTimingPort::recvTiming(pkt);
- //
- // The received packets should only be M5 requests, which should never
- // get nacked. There used to be code to hanldle nacks here, but
- // I'm pretty sure it didn't work correctly with the drain code,
+ // The received packets should only be M5 requests, which should never
+ // get nacked. There used to be code to hanldle nacks here, but
+ // I'm pretty sure it didn't work correctly with the drain code,
// so that would need to be fixed if we ever added it back.
- //
assert(pkt->isRequest());
if (pkt->memInhibitAsserted()) {
@@ -177,34 +167,26 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
return true;
}
- //
// Save the port in the sender state object to be used later to
// route the response
- //
pkt->senderState = new SenderState(this, pkt->senderState);
- //
// Check for pio requests and directly send them to the dedicated
// pio port.
- //
if (!isPhysMemAddress(pkt->getAddr())) {
assert(ruby_port->pio_port != NULL);
- DPRINTF(MemoryAccess,
+ DPRINTF(MemoryAccess,
"Request for address 0x%#x is assumed to be a pio request\n",
pkt->getAddr());
return ruby_port->pio_port->sendTiming(pkt);
}
- //
// For DMA and CPU requests, translate them to ruby requests before
// sending them to our assigned ruby port.
- //
RubyRequestType type = RubyRequestType_NULL;
- //
// If valid, copy the pc to the ruby request
- //
Addr pc = 0;
if (pkt->req->hasPC()) {
pc = pkt->req->getPC();
@@ -224,47 +206,38 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
if (pkt->req->isInstFetch()) {
type = RubyRequestType_IFETCH;
} else {
- type = RubyRequestType_LD;
+ type = RubyRequestType_LD;
}
} else if (pkt->isWrite()) {
type = RubyRequestType_ST;
} else if (pkt->isReadWrite()) {
- //
- // Fix me. This conditional will never be executed because
- // isReadWrite() is just an OR of isRead() and isWrite().
- // Furthermore, just because the packet is a read/write request does
- // not necessary mean it is a read-modify-write atomic operation.
- //
+ // Fix me. This conditional will never be executed
+ // because isReadWrite() is just an OR of isRead() and
+ // isWrite(). Furthermore, just because the packet is a
+ // read/write request does not necessary mean it is a
+ // read-modify-write atomic operation.
type = RubyRequestType_RMW_Write;
} else {
panic("Unsupported ruby packet type\n");
}
}
- RubyRequest ruby_request(pkt->getAddr(),
- pkt->getPtr<uint8_t>(),
- pkt->getSize(),
- pc,
- type,
- RubyAccessMode_Supervisor,
- pkt);
+ RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
+ pkt->getSize(), pc, type,
+ RubyAccessMode_Supervisor, pkt);
// Submit the ruby request
RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);
- //
// If the request successfully issued or the SC request completed because
// exclusive permission was lost, then we should return true.
// Otherwise, we need to delete the senderStatus we just created and return
// false.
- //
if ((requestStatus == RequestStatus_Issued) ||
(requestStatus == RequestStatus_LlscFailed)) {
- //
// The communicate to M5 whether the SC command succeeded by seting the
// packet's extra data.
- //
if (pkt->isLLSC() && pkt->isWrite()) {
if (requestStatus == RequestStatus_LlscFailed) {
DPRINTF(MemoryAccess, "SC failed and request completed\n");
@@ -276,11 +249,10 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
return true;
}
- DPRINTF(MemoryAccess,
+ DPRINTF(MemoryAccess,
"Request for address #x did not issue because %s\n",
- pkt->getAddr(),
- RequestStatus_to_string(requestStatus));
-
+ pkt->getAddr(), RequestStatus_to_string(requestStatus));
+
SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
pkt->senderState = senderState->saved;
delete senderState;
@@ -290,14 +262,12 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
void
RubyPort::ruby_hit_callback(PacketPtr pkt)
{
- //
// Retrieve the request port from the sender State
- //
- RubyPort::SenderState *senderState =
+ RubyPort::SenderState *senderState =
safe_cast<RubyPort::SenderState *>(pkt->senderState);
M5Port *port = senderState->port;
assert(port != NULL);
-
+
// pop the sender state from the packet
pkt->senderState = senderState->saved;
delete senderState;
@@ -308,11 +278,9 @@ RubyPort::ruby_hit_callback(PacketPtr pkt)
void
RubyPort::M5Port::hitCallback(PacketPtr pkt)
{
-
bool needsResponse = pkt->needsResponse();
- DPRINTF(MemoryAccess, "Hit callback needs response %d\n",
- needsResponse);
+ DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse);
ruby_port->physMemPort->sendAtomic(pkt);
@@ -349,9 +317,9 @@ RubyPort::M5Port::isPhysMemAddress(Addr addr)
AddrRangeList physMemAddrList;
bool snoop = false;
ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
- for(AddrRangeIter iter = physMemAddrList.begin();
- iter != physMemAddrList.end();
- iter++) {
+ for (AddrRangeIter iter = physMemAddrList.begin();
+ iter != physMemAddrList.end();
+ iter++) {
if (addr >= iter->start && addr <= iter->end) {
DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n",
iter->start, iter->end);
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 3a862e068..4038c6007 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
@@ -27,18 +26,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RUBYPORT_H
-#define RUBYPORT_H
+#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__
+#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__
-#include "mem/ruby/libruby.hh"
+#include <cassert>
#include <string>
-#include <assert.h>
#include "mem/mem_object.hh"
-#include "mem/tport.hh"
#include "mem/physical.hh"
#include "mem/protocol/RequestStatus.hh"
-
+#include "mem/ruby/libruby.hh"
+#include "mem/tport.hh"
#include "params/RubyPort.hh"
using namespace std;
@@ -46,17 +44,16 @@ using namespace std;
class MessageBuffer;
class AbstractController;
-class RubyPort : public MemObject {
-public:
-
+class RubyPort : public MemObject
+{
+ public:
class M5Port : public SimpleTimingPort
{
-
+ private:
RubyPort *ruby_port;
public:
- M5Port(const std::string &_name,
- RubyPort *_port);
+ M5Port(const std::string &_name, RubyPort *_port);
bool sendTiming(PacketPtr pkt);
void hitCallback(PacketPtr pkt);
@@ -72,12 +69,11 @@ public:
class PioPort : public SimpleTimingPort
{
-
+ private:
RubyPort *ruby_port;
public:
- PioPort(const std::string &_name,
- RubyPort *_port);
+ PioPort(const std::string &_name, RubyPort *_port);
bool sendTiming(PacketPtr pkt);
protected:
@@ -92,8 +88,7 @@ public:
M5Port* port;
Packet::SenderState *saved;
- SenderState(M5Port* _port,
- Packet::SenderState *sender_state = NULL)
+ SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL)
: port(_port), saved(sender_state)
{}
};
@@ -114,17 +109,17 @@ public:
//
void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
-protected:
- const string m_name;
- void ruby_hit_callback(PacketPtr pkt);
- void hit(PacketPtr pkt);
+ protected:
+ const string m_name;
+ void ruby_hit_callback(PacketPtr pkt);
+ void hit(PacketPtr pkt);
- int m_version;
- AbstractController* m_controller;
- MessageBuffer* m_mandatory_q_ptr;
+ int m_version;
+ AbstractController* m_controller;
+ MessageBuffer* m_mandatory_q_ptr;
PioPort* pio_port;
-private:
+ private:
uint16_t m_port_id;
uint64_t m_request_cnt;
@@ -133,4 +128,4 @@ private:
PhysicalMemory* physmem;
};
-#endif
+#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
index d6dba08f9..a473ccf44 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,22 +26,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "mem/ruby/libruby.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/protocol/Protocol.hh"
-#include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/system/CacheMemory.hh"
+#include "cpu/rubytest/RubyTester.hh"
+#include "mem/gems_common/Map.hh"
#include "mem/protocol/CacheMsg.hh"
-#include "mem/ruby/recorder/Tracer.hh"
-#include "mem/ruby/common/SubBlock.hh"
#include "mem/protocol/Protocol.hh"
-#include "mem/gems_common/Map.hh"
+#include "mem/protocol/Protocol.hh"
#include "mem/ruby/buffers/MessageBuffer.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/SubBlock.hh"
+#include "mem/ruby/libruby.hh"
+#include "mem/ruby/profiler/Profiler.hh"
+#include "mem/ruby/recorder/Tracer.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "cpu/rubytest/RubyTester.hh"
-
+#include "mem/ruby/system/CacheMemory.hh"
+#include "mem/ruby/system/Sequencer.hh"
+#include "mem/ruby/system/System.hh"
#include "params/RubySequencer.hh"
Sequencer *
@@ -50,7 +48,7 @@ RubySequencerParams::create()
{
return new Sequencer(this);
}
-
+
Sequencer::Sequencer(const Params *p)
: RubyPort(p), deadlockCheckEvent(this)
{
@@ -58,7 +56,7 @@ Sequencer::Sequencer(const Params *p)
m_store_waiting_on_store_cycles = 0;
m_load_waiting_on_store_cycles = 0;
m_load_waiting_on_load_cycles = 0;
-
+
m_outstanding_count = 0;
m_max_outstanding_requests = 0;
@@ -78,478 +76,524 @@ Sequencer::Sequencer(const Params *p)
assert(m_dataCache_ptr != NULL);
}
-Sequencer::~Sequencer() {
-
+Sequencer::~Sequencer()
+{
}
-void Sequencer::wakeup() {
- // Check for deadlock of any of the requests
- Time current_time = g_eventQueue_ptr->getTime();
-
- // Check across all outstanding requests
- int total_outstanding = 0;
-
- Vector<Address> keys = m_readRequestTable.keys();
- for (int i=0; i<keys.size(); i++) {
- SequencerRequest* request = m_readRequestTable.lookup(keys[i]);
- if (current_time - request->issue_time >= m_deadlock_threshold) {
- WARN_MSG("Possible Deadlock detected");
- WARN_EXPR(request);
- WARN_EXPR(m_version);
- WARN_EXPR(request->ruby_request.paddr);
- WARN_EXPR(keys.size());
- WARN_EXPR(current_time);
- WARN_EXPR(request->issue_time);
- WARN_EXPR(current_time - request->issue_time);
- ERROR_MSG("Aborting");
+void
+Sequencer::wakeup()
+{
+ // Check for deadlock of any of the requests
+ Time current_time = g_eventQueue_ptr->getTime();
+
+ // Check across all outstanding requests
+ int total_outstanding = 0;
+
+ Vector<Address> keys = m_readRequestTable.keys();
+ for (int i = 0; i < keys.size(); i++) {
+ SequencerRequest* request = m_readRequestTable.lookup(keys[i]);
+ if (current_time - request->issue_time >= m_deadlock_threshold) {
+ WARN_MSG("Possible Deadlock detected");
+ WARN_EXPR(request);
+ WARN_EXPR(m_version);
+ WARN_EXPR(request->ruby_request.paddr);
+ WARN_EXPR(keys.size());
+ WARN_EXPR(current_time);
+ WARN_EXPR(request->issue_time);
+ WARN_EXPR(current_time - request->issue_time);
+ ERROR_MSG("Aborting");
+ }
}
- }
-
- keys = m_writeRequestTable.keys();
- for (int i=0; i<keys.size(); i++) {
- SequencerRequest* request = m_writeRequestTable.lookup(keys[i]);
- if (current_time - request->issue_time >= m_deadlock_threshold) {
- WARN_MSG("Possible Deadlock detected");
- WARN_EXPR(request);
- WARN_EXPR(m_version);
- WARN_EXPR(current_time);
- WARN_EXPR(request->issue_time);
- WARN_EXPR(current_time - request->issue_time);
- WARN_EXPR(keys.size());
- ERROR_MSG("Aborting");
+
+ keys = m_writeRequestTable.keys();
+ for (int i = 0; i < keys.size(); i++) {
+ SequencerRequest* request = m_writeRequestTable.lookup(keys[i]);
+ if (current_time - request->issue_time >= m_deadlock_threshold) {
+ WARN_MSG("Possible Deadlock detected");
+ WARN_EXPR(request);
+ WARN_EXPR(m_version);
+ WARN_EXPR(current_time);
+ WARN_EXPR(request->issue_time);
+ WARN_EXPR(current_time - request->issue_time);
+ WARN_EXPR(keys.size());
+ ERROR_MSG("Aborting");
+ }
}
- }
- total_outstanding += m_writeRequestTable.size() + m_readRequestTable.size();
- assert(m_outstanding_count == total_outstanding);
+ total_outstanding += m_writeRequestTable.size();
+ total_outstanding += m_readRequestTable.size();
- if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking
- schedule(deadlockCheckEvent,
- (m_deadlock_threshold * g_eventQueue_ptr->getClock()) + curTick);
- }
+ assert(m_outstanding_count == total_outstanding);
+
+ if (m_outstanding_count > 0) {
+ // If there are still outstanding requests, keep checking
+ schedule(deadlockCheckEvent,
+ m_deadlock_threshold * g_eventQueue_ptr->getClock() +
+ curTick);
+ }
}
-void Sequencer::printStats(ostream & out) const {
- out << "Sequencer: " << m_name << endl;
- out << " store_waiting_on_load_cycles: " << m_store_waiting_on_load_cycles << endl;
- out << " store_waiting_on_store_cycles: " << m_store_waiting_on_store_cycles << endl;
- out << " load_waiting_on_load_cycles: " << m_load_waiting_on_load_cycles << endl;
- out << " load_waiting_on_store_cycles: " << m_load_waiting_on_store_cycles << endl;
+void
+Sequencer::printStats(ostream & out) const
+{
+ out << "Sequencer: " << m_name << endl
+ << " store_waiting_on_load_cycles: "
+ << m_store_waiting_on_load_cycles << endl
+ << " store_waiting_on_store_cycles: "
+ << m_store_waiting_on_store_cycles << endl
+ << " load_waiting_on_load_cycles: "
+ << m_load_waiting_on_load_cycles << endl
+ << " load_waiting_on_store_cycles: "
+ << m_load_waiting_on_store_cycles << endl;
}
-void Sequencer::printProgress(ostream& out) const{
- /*
- int total_demand = 0;
- out << "Sequencer Stats Version " << m_version << endl;
- out << "Current time = " << g_eventQueue_ptr->getTime() << endl;
- out << "---------------" << endl;
- out << "outstanding requests" << endl;
-
- Vector<Address> rkeys = m_readRequestTable.keys();
- int read_size = rkeys.size();
- out << "proc " << m_version << " Read Requests = " << read_size << endl;
- // print the request table
- for(int i=0; i < read_size; ++i){
- SequencerRequest * request = m_readRequestTable.lookup(rkeys[i]);
- out << "\tRequest[ " << i << " ] = " << request->type << " Address " << rkeys[i] << " Posted " << request->issue_time << " PF " << PrefetchBit_No << endl;
- total_demand++;
- }
-
- Vector<Address> wkeys = m_writeRequestTable.keys();
- int write_size = wkeys.size();
- out << "proc " << m_version << " Write Requests = " << write_size << endl;
- // print the request table
- for(int i=0; i < write_size; ++i){
- CacheMsg & request = m_writeRequestTable.lookup(wkeys[i]);
- out << "\tRequest[ " << i << " ] = " << request.getType() << " Address " << wkeys[i] << " Posted " << request.getTime() << " PF " << request.getPrefetch() << endl;
- if( request.getPrefetch() == PrefetchBit_No ){
+void
+Sequencer::printProgress(ostream& out) const
+{
+#if 0
+ int total_demand = 0;
+ out << "Sequencer Stats Version " << m_version << endl;
+ out << "Current time = " << g_eventQueue_ptr->getTime() << endl;
+ out << "---------------" << endl;
+ out << "outstanding requests" << endl;
+
+ Vector<Address> rkeys = m_readRequestTable.keys();
+ int read_size = rkeys.size();
+ out << "proc " << m_version << " Read Requests = " << read_size << endl;
+
+ // print the request table
+ for (int i = 0; i < read_size; ++i) {
+ SequencerRequest *request = m_readRequestTable.lookup(rkeys[i]);
+ out << "\tRequest[ " << i << " ] = " << request->type
+ << " Address " << rkeys[i]
+ << " Posted " << request->issue_time
+ << " PF " << PrefetchBit_No << endl;
total_demand++;
- }
- }
+ }
- out << endl;
+ Vector<Address> wkeys = m_writeRequestTable.keys();
+ int write_size = wkeys.size();
+ out << "proc " << m_version << " Write Requests = " << write_size << endl;
+
+ // print the request table
+ for (int i = 0; i < write_size; ++i){
+ CacheMsg &request = m_writeRequestTable.lookup(wkeys[i]);
+ out << "\tRequest[ " << i << " ] = " << request.getType()
+ << " Address " << wkeys[i]
+ << " Posted " << request.getTime()
+ << " PF " << request.getPrefetch() << endl;
+ if (request.getPrefetch() == PrefetchBit_No) {
+ total_demand++;
+ }
+ }
- out << "Total Number Outstanding: " << m_outstanding_count << endl;
- out << "Total Number Demand : " << total_demand << endl;
- out << "Total Number Prefetches : " << m_outstanding_count - total_demand << endl;
- out << endl;
- out << endl;
- */
+ out << endl;
+
+ out << "Total Number Outstanding: " << m_outstanding_count << endl
+ << "Total Number Demand : " << total_demand << endl
+ << "Total Number Prefetches : " << m_outstanding_count - total_demand
+ << endl << endl << endl;
+#endif
}
-void Sequencer::printConfig(ostream& out) const {
- out << "Seqeuncer config: " << m_name << endl;
- out << " controller: " << m_controller->getName() << endl;
- out << " version: " << m_version << endl;
- out << " max_outstanding_requests: " << m_max_outstanding_requests << endl;
- out << " deadlock_threshold: " << m_deadlock_threshold << endl;
+void
+Sequencer::printConfig(ostream& out) const
+{
+ out << "Seqeuncer config: " << m_name << endl
+ << " controller: " << m_controller->getName() << endl
+ << " version: " << m_version << endl
+ << " max_outstanding_requests: " << m_max_outstanding_requests << endl
+ << " deadlock_threshold: " << m_deadlock_threshold << endl;
}
// Insert the request on the correct request table. Return true if
// the entry was already present.
-bool Sequencer::insertRequest(SequencerRequest* request) {
- int total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size();
-
- assert(m_outstanding_count == total_outstanding);
-
- // See if we should schedule a deadlock check
- if (deadlockCheckEvent.scheduled() == false) {
- schedule(deadlockCheckEvent, m_deadlock_threshold + curTick);
- }
-
- Address line_addr(request->ruby_request.paddr);
- line_addr.makeLineAddress();
- if ((request->ruby_request.type == RubyRequestType_ST) ||
- (request->ruby_request.type == RubyRequestType_RMW_Read) ||
- (request->ruby_request.type == RubyRequestType_RMW_Write) ||
- (request->ruby_request.type == RubyRequestType_Locked_Read) ||
- (request->ruby_request.type == RubyRequestType_Locked_Write)) {
- if (m_writeRequestTable.exist(line_addr)) {
- m_writeRequestTable.lookup(line_addr) = request;
- // return true;
- assert(0); // drh5: isn't this an error? do you lose the initial request?
+bool
+Sequencer::insertRequest(SequencerRequest* request)
+{
+ int total_outstanding =
+ m_writeRequestTable.size() + m_readRequestTable.size();
+
+ assert(m_outstanding_count == total_outstanding);
+
+ // See if we should schedule a deadlock check
+ if (deadlockCheckEvent.scheduled() == false) {
+ schedule(deadlockCheckEvent, m_deadlock_threshold + curTick);
}
- m_writeRequestTable.allocate(line_addr);
- m_writeRequestTable.lookup(line_addr) = request;
- m_outstanding_count++;
- } else {
- if (m_readRequestTable.exist(line_addr)) {
- m_readRequestTable.lookup(line_addr) = request;
- // return true;
- assert(0); // drh5: isn't this an error? do you lose the initial request?
+
+ Address line_addr(request->ruby_request.paddr);
+ line_addr.makeLineAddress();
+ if ((request->ruby_request.type == RubyRequestType_ST) ||
+ (request->ruby_request.type == RubyRequestType_RMW_Read) ||
+ (request->ruby_request.type == RubyRequestType_RMW_Write) ||
+ (request->ruby_request.type == RubyRequestType_Locked_Read) ||
+ (request->ruby_request.type == RubyRequestType_Locked_Write)) {
+ if (m_writeRequestTable.exist(line_addr)) {
+ m_writeRequestTable.lookup(line_addr) = request;
+ // return true;
+
+ // drh5: isn't this an error? do you lose the initial request?
+ assert(0);
+ }
+ m_writeRequestTable.allocate(line_addr);
+ m_writeRequestTable.lookup(line_addr) = request;
+ m_outstanding_count++;
+ } else {
+ if (m_readRequestTable.exist(line_addr)) {
+ m_readRequestTable.lookup(line_addr) = request;
+ // return true;
+
+ // drh5: isn't this an error? do you lose the initial request?
+ assert(0);
+ }
+ m_readRequestTable.allocate(line_addr);
+ m_readRequestTable.lookup(line_addr) = request;
+ m_outstanding_count++;
}
- m_readRequestTable.allocate(line_addr);
- m_readRequestTable.lookup(line_addr) = request;
- m_outstanding_count++;
- }
- g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count);
+ g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count);
- total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size();
- assert(m_outstanding_count == total_outstanding);
+ total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size();
+ assert(m_outstanding_count == total_outstanding);
- return false;
+ return false;
}
-void Sequencer::removeRequest(SequencerRequest* srequest) {
-
- assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size());
-
- const RubyRequest & ruby_request = srequest->ruby_request;
- Address line_addr(ruby_request.paddr);
- line_addr.makeLineAddress();
- if ((ruby_request.type == RubyRequestType_ST) ||
- (ruby_request.type == RubyRequestType_RMW_Read) ||
- (ruby_request.type == RubyRequestType_RMW_Write) ||
- (ruby_request.type == RubyRequestType_Locked_Read) ||
- (ruby_request.type == RubyRequestType_Locked_Write)) {
- m_writeRequestTable.deallocate(line_addr);
- } else {
- m_readRequestTable.deallocate(line_addr);
- }
- m_outstanding_count--;
-
- assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size());
-}
+void
+Sequencer::removeRequest(SequencerRequest* srequest)
+{
+ assert(m_outstanding_count ==
+ m_writeRequestTable.size() + m_readRequestTable.size());
+
+ const RubyRequest & ruby_request = srequest->ruby_request;
+ Address line_addr(ruby_request.paddr);
+ line_addr.makeLineAddress();
+ if ((ruby_request.type == RubyRequestType_ST) ||
+ (ruby_request.type == RubyRequestType_RMW_Read) ||
+ (ruby_request.type == RubyRequestType_RMW_Write) ||
+ (ruby_request.type == RubyRequestType_Locked_Read) ||
+ (ruby_request.type == RubyRequestType_Locked_Write)) {
+ m_writeRequestTable.deallocate(line_addr);
+ } else {
+ m_readRequestTable.deallocate(line_addr);
+ }
+ m_outstanding_count--;
-void Sequencer::writeCallback(const Address& address, DataBlock& data) {
+ assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size());
+}
- assert(address == line_address(address));
- assert(m_writeRequestTable.exist(line_address(address)));
+void
+Sequencer::writeCallback(const Address& address, DataBlock& data)
+{
+ assert(address == line_address(address));
+ assert(m_writeRequestTable.exist(line_address(address)));
- SequencerRequest* request = m_writeRequestTable.lookup(address);
+ SequencerRequest* request = m_writeRequestTable.lookup(address);
- removeRequest(request);
+ removeRequest(request);
- assert((request->ruby_request.type == RubyRequestType_ST) ||
- (request->ruby_request.type == RubyRequestType_RMW_Read) ||
- (request->ruby_request.type == RubyRequestType_RMW_Write) ||
- (request->ruby_request.type == RubyRequestType_Locked_Read) ||
- (request->ruby_request.type == RubyRequestType_Locked_Write));
+ assert((request->ruby_request.type == RubyRequestType_ST) ||
+ (request->ruby_request.type == RubyRequestType_RMW_Read) ||
+ (request->ruby_request.type == RubyRequestType_RMW_Write) ||
+ (request->ruby_request.type == RubyRequestType_Locked_Read) ||
+ (request->ruby_request.type == RubyRequestType_Locked_Write));
- if (request->ruby_request.type == RubyRequestType_Locked_Read) {
- m_dataCache_ptr->setLocked(address, m_version);
- }
- else if (request->ruby_request.type == RubyRequestType_RMW_Read) {
- m_controller->blockOnQueue(address, m_mandatory_q_ptr);
- }
- else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
- m_controller->unblock(address);
- }
+ if (request->ruby_request.type == RubyRequestType_Locked_Read) {
+ m_dataCache_ptr->setLocked(address, m_version);
+ } else if (request->ruby_request.type == RubyRequestType_RMW_Read) {
+ m_controller->blockOnQueue(address, m_mandatory_q_ptr);
+ } else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
+ m_controller->unblock(address);
+ }
- hitCallback(request, data);
+ hitCallback(request, data);
}
-void Sequencer::readCallback(const Address& address, DataBlock& data) {
-
- assert(address == line_address(address));
- assert(m_readRequestTable.exist(line_address(address)));
+void
+Sequencer::readCallback(const Address& address, DataBlock& data)
+{
+ assert(address == line_address(address));
+ assert(m_readRequestTable.exist(line_address(address)));
- SequencerRequest* request = m_readRequestTable.lookup(address);
- removeRequest(request);
+ SequencerRequest* request = m_readRequestTable.lookup(address);
+ removeRequest(request);
- assert((request->ruby_request.type == RubyRequestType_LD) ||
- (request->ruby_request.type == RubyRequestType_RMW_Read) ||
- (request->ruby_request.type == RubyRequestType_IFETCH));
+ assert((request->ruby_request.type == RubyRequestType_LD) ||
+ (request->ruby_request.type == RubyRequestType_RMW_Read) ||
+ (request->ruby_request.type == RubyRequestType_IFETCH));
- hitCallback(request, data);
+ hitCallback(request, data);
}
-void Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data) {
- const RubyRequest & ruby_request = srequest->ruby_request;
- Address request_address(ruby_request.paddr);
- Address request_line_address(ruby_request.paddr);
- request_line_address.makeLineAddress();
- RubyRequestType type = ruby_request.type;
- Time issued_time = srequest->issue_time;
-
- // Set this cache entry to the most recently used
- if (type == RubyRequestType_IFETCH) {
- if (m_instCache_ptr->isTagPresent(request_line_address) )
- m_instCache_ptr->setMRU(request_line_address);
- } else {
- if (m_dataCache_ptr->isTagPresent(request_line_address) )
- m_dataCache_ptr->setMRU(request_line_address);
- }
-
- assert(g_eventQueue_ptr->getTime() >= issued_time);
- Time miss_latency = g_eventQueue_ptr->getTime() - issued_time;
-
- // Profile the miss latency for all non-zero demand misses
- if (miss_latency != 0) {
- g_system_ptr->getProfiler()->missLatency(miss_latency, type);
+void
+Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data)
+{
+ const RubyRequest & ruby_request = srequest->ruby_request;
+ Address request_address(ruby_request.paddr);
+ Address request_line_address(ruby_request.paddr);
+ request_line_address.makeLineAddress();
+ RubyRequestType type = ruby_request.type;
+ Time issued_time = srequest->issue_time;
+
+ // Set this cache entry to the most recently used
+ if (type == RubyRequestType_IFETCH) {
+ if (m_instCache_ptr->isTagPresent(request_line_address))
+ m_instCache_ptr->setMRU(request_line_address);
+ } else {
+ if (m_dataCache_ptr->isTagPresent(request_line_address))
+ m_dataCache_ptr->setMRU(request_line_address);
+ }
+
+ assert(g_eventQueue_ptr->getTime() >= issued_time);
+ Time miss_latency = g_eventQueue_ptr->getTime() - issued_time;
- if (Debug::getProtocolTrace()) {
- g_system_ptr->getProfiler()->profileTransition("Seq", m_version, Address(ruby_request.paddr),
- "", "Done", "", int_to_string(miss_latency)+" cycles");
+ // Profile the miss latency for all non-zero demand misses
+ if (miss_latency != 0) {
+ g_system_ptr->getProfiler()->missLatency(miss_latency, type);
+
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->
+ profileTransition("Seq", m_version,
+ Address(ruby_request.paddr), "", "Done", "",
+ csprintf("%d cycles", miss_latency));
+ }
}
- }
- /*
- if (request.getPrefetch() == PrefetchBit_Yes) {
- return; // Ignore the prefetch
- }
- */
-
- // update the data
- if (ruby_request.data != NULL) {
- if ((type == RubyRequestType_LD) ||
- (type == RubyRequestType_IFETCH) ||
- (type == RubyRequestType_RMW_Read) ||
- (type == RubyRequestType_Locked_Read)) {
-
- memcpy(ruby_request.data,
- data.getData(request_address.getOffset(), ruby_request.len),
- ruby_request.len);
-
- } else {
+#if 0
+ if (request.getPrefetch() == PrefetchBit_Yes) {
+ return; // Ignore the prefetch
+ }
+#endif
- data.setData(ruby_request.data,
- request_address.getOffset(),
- ruby_request.len);
+ // update the data
+ if (ruby_request.data != NULL) {
+ if ((type == RubyRequestType_LD) ||
+ (type == RubyRequestType_IFETCH) ||
+ (type == RubyRequestType_RMW_Read) ||
+ (type == RubyRequestType_Locked_Read)) {
+
+ memcpy(ruby_request.data,
+ data.getData(request_address.getOffset(), ruby_request.len),
+ ruby_request.len);
+ } else {
+ data.setData(ruby_request.data, request_address.getOffset(),
+ ruby_request.len);
+ }
+ } else {
+ DPRINTF(MemoryAccess,
+ "WARNING. Data not transfered from Ruby to M5 for type %s\n",
+ RubyRequestType_to_string(type));
+ }
+ // If using the RubyTester, update the RubyTester sender state's
+ // subBlock with the recieved data. The tester will later access
+ // this state.
+ // Note: RubyPort will access it's sender state before the
+ // RubyTester.
+ if (m_usingRubyTester) {
+ RubyPort::SenderState *requestSenderState =
+ safe_cast<RubyPort::SenderState*>(ruby_request.pkt->senderState);
+ RubyTester::SenderState* testerSenderState =
+ safe_cast<RubyTester::SenderState*>(requestSenderState->saved);
+ testerSenderState->subBlock->mergeFrom(data);
}
- } else {
- DPRINTF(MemoryAccess,
- "WARNING. Data not transfered from Ruby to M5 for type %s\n",
- RubyRequestType_to_string(type));
- }
-
- //
- // If using the RubyTester, update the RubyTester sender state's subBlock
- // with the recieved data. The tester will later access this state.
- // Note: RubyPort will access it's sender state before the RubyTester.
- //
- if (m_usingRubyTester) {
- RubyTester::SenderState* testerSenderState;
- testerSenderState = safe_cast<RubyTester::SenderState*>( \
- safe_cast<RubyPort::SenderState*>(ruby_request.pkt->senderState)->saved);
- testerSenderState->subBlock->mergeFrom(data);
- }
-
- ruby_hit_callback(ruby_request.pkt);
- delete srequest;
+
+ ruby_hit_callback(ruby_request.pkt);
+ delete srequest;
}
// Returns true if the sequencer already has a load or store outstanding
-RequestStatus Sequencer::getRequestStatus(const RubyRequest& request) {
- bool is_outstanding_store = m_writeRequestTable.exist(line_address(Address(request.paddr)));
- bool is_outstanding_load = m_readRequestTable.exist(line_address(Address(request.paddr)));
- if ( is_outstanding_store ) {
- if ((request.type == RubyRequestType_LD) ||
- (request.type == RubyRequestType_IFETCH) ||
- (request.type == RubyRequestType_RMW_Read)) {
- m_store_waiting_on_load_cycles++;
- } else {
- m_store_waiting_on_store_cycles++;
+RequestStatus
+Sequencer::getRequestStatus(const RubyRequest& request)
+{
+ bool is_outstanding_store =
+ m_writeRequestTable.exist(line_address(Address(request.paddr)));
+ bool is_outstanding_load =
+ m_readRequestTable.exist(line_address(Address(request.paddr)));
+ if (is_outstanding_store) {
+ if ((request.type == RubyRequestType_LD) ||
+ (request.type == RubyRequestType_IFETCH) ||
+ (request.type == RubyRequestType_RMW_Read)) {
+ m_store_waiting_on_load_cycles++;
+ } else {
+ m_store_waiting_on_store_cycles++;
+ }
+ return RequestStatus_Aliased;
+ } else if (is_outstanding_load) {
+ if ((request.type == RubyRequestType_ST) ||
+ (request.type == RubyRequestType_RMW_Write)) {
+ m_load_waiting_on_store_cycles++;
+ } else {
+ m_load_waiting_on_load_cycles++;
+ }
+ return RequestStatus_Aliased;
}
- return RequestStatus_Aliased;
- } else if ( is_outstanding_load ) {
- if ((request.type == RubyRequestType_ST) ||
- (request.type == RubyRequestType_RMW_Write) ) {
- m_load_waiting_on_store_cycles++;
- } else {
- m_load_waiting_on_load_cycles++;
+
+ if (m_outstanding_count >= m_max_outstanding_requests) {
+ return RequestStatus_BufferFull;
}
- return RequestStatus_Aliased;
- }
-
- if (m_outstanding_count >= m_max_outstanding_requests) {
- return RequestStatus_BufferFull;
- }
-
- return RequestStatus_Ready;
-}
-bool Sequencer::empty() const {
- return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0);
+ return RequestStatus_Ready;
}
+bool
+Sequencer::empty() const
+{
+ return m_writeRequestTable.size() == 0 && m_readRequestTable.size() == 0;
+}
-RequestStatus Sequencer::makeRequest(const RubyRequest & request)
+RequestStatus
+Sequencer::makeRequest(const RubyRequest &request)
{
- assert(Address(request.paddr).getOffset() + request.len <=
- RubySystem::getBlockSizeBytes());
- RequestStatus status = getRequestStatus(request);
- if (status == RequestStatus_Ready) {
- SequencerRequest *srequest = new SequencerRequest(request,
- g_eventQueue_ptr->getTime());
+ assert(Address(request.paddr).getOffset() + request.len <=
+ RubySystem::getBlockSizeBytes());
+ RequestStatus status = getRequestStatus(request);
+ if (status != RequestStatus_Ready)
+ return status;
+
+ SequencerRequest *srequest =
+ new SequencerRequest(request, g_eventQueue_ptr->getTime());
bool found = insertRequest(srequest);
- if (!found) {
- if (request.type == RubyRequestType_Locked_Write) {
- //
- // NOTE: it is OK to check the locked flag here as the mandatory queue
- // will be checked first ensuring that nothing comes between checking
- // the flag and servicing the store.
- //
- if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)),
- m_version)) {
- removeRequest(srequest);
- if (Debug::getProtocolTrace()) {
-
- g_system_ptr->getProfiler()->profileTransition("Seq",
- m_version,
- Address(request.paddr),
- "",
- "SC Fail",
- "",
- RubyRequestType_to_string(request.type));
+ if (found) {
+ panic("Sequencer::makeRequest should never be called if the "
+ "request is already outstanding\n");
+ return RequestStatus_NULL;
+ }
+ if (request.type == RubyRequestType_Locked_Write) {
+ // NOTE: it is OK to check the locked flag here as the
+ // mandatory queue will be checked first ensuring that nothing
+ // comes between checking the flag and servicing the store.
+
+ Address line_addr = line_address(Address(request.paddr));
+ if (!m_dataCache_ptr->isLocked(line_addr, m_version)) {
+ removeRequest(srequest);
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->
+ profileTransition("Seq", m_version,
+ Address(request.paddr),
+ "", "SC Fail", "",
+ RubyRequestType_to_string(request.type));
}
return RequestStatus_LlscFailed;
- }
- else {
- m_dataCache_ptr->clearLocked(line_address(Address(request.paddr)));
+ } else {
+ m_dataCache_ptr->clearLocked(line_addr);
}
- }
- issueRequest(request);
+ }
+ issueRequest(request);
- // TODO: issue hardware prefetches here
- return RequestStatus_Issued;
+ // TODO: issue hardware prefetches here
+ return RequestStatus_Issued;
+}
+
+void
+Sequencer::issueRequest(const RubyRequest& request)
+{
+ // TODO: get rid of CacheMsg, CacheRequestType, and
+ // AccessModeTYpe, & have SLICC use RubyRequest and subtypes
+ // natively
+ CacheRequestType ctype;
+ switch(request.type) {
+ case RubyRequestType_IFETCH:
+ ctype = CacheRequestType_IFETCH;
+ break;
+ case RubyRequestType_LD:
+ ctype = CacheRequestType_LD;
+ break;
+ case RubyRequestType_ST:
+ ctype = CacheRequestType_ST;
+ break;
+ case RubyRequestType_Locked_Read:
+ case RubyRequestType_Locked_Write:
+ ctype = CacheRequestType_ATOMIC;
+ break;
+ case RubyRequestType_RMW_Read:
+ ctype = CacheRequestType_ATOMIC;
+ break;
+ case RubyRequestType_RMW_Write:
+ ctype = CacheRequestType_ATOMIC;
+ break;
+ default:
+ assert(0);
}
- else {
- panic("Sequencer::makeRequest should never be called if the request"\
- "is already outstanding\n");
- return RequestStatus_NULL;
+
+ AccessModeType amtype;
+ switch(request.access_mode){
+ case RubyAccessMode_User:
+ amtype = AccessModeType_UserMode;
+ break;
+ case RubyAccessMode_Supervisor:
+ amtype = AccessModeType_SupervisorMode;
+ break;
+ case RubyAccessMode_Device:
+ amtype = AccessModeType_UserMode;
+ break;
+ default:
+ assert(0);
}
- } else {
- return status;
- }
-}
-void Sequencer::issueRequest(const RubyRequest& request) {
-
- // TODO: get rid of CacheMsg, CacheRequestType, and AccessModeTYpe, & have SLICC use RubyRequest and subtypes natively
- CacheRequestType ctype;
- switch(request.type) {
- case RubyRequestType_IFETCH:
- ctype = CacheRequestType_IFETCH;
- break;
- case RubyRequestType_LD:
- ctype = CacheRequestType_LD;
- break;
- case RubyRequestType_ST:
- ctype = CacheRequestType_ST;
- break;
- case RubyRequestType_Locked_Read:
- case RubyRequestType_Locked_Write:
- ctype = CacheRequestType_ATOMIC;
- break;
- case RubyRequestType_RMW_Read:
- ctype = CacheRequestType_ATOMIC;
- break;
- case RubyRequestType_RMW_Write:
- ctype = CacheRequestType_ATOMIC;
- break;
- default:
- assert(0);
- }
- AccessModeType amtype;
- switch(request.access_mode){
- case RubyAccessMode_User:
- amtype = AccessModeType_UserMode;
- break;
- case RubyAccessMode_Supervisor:
- amtype = AccessModeType_SupervisorMode;
- break;
- case RubyAccessMode_Device:
- amtype = AccessModeType_UserMode;
- break;
- default:
- assert(0);
- }
- Address line_addr(request.paddr);
- line_addr.makeLineAddress();
- CacheMsg msg(line_addr, Address(request.paddr), ctype, Address(request.pc), amtype, request.len, PrefetchBit_No, request.proc_id);
-
- if (Debug::getProtocolTrace()) {
- g_system_ptr->getProfiler()->profileTransition("Seq", m_version, Address(request.paddr),
- "", "Begin", "", RubyRequestType_to_string(request.type));
- }
-
- if (g_system_ptr->getTracer()->traceEnabled()) {
- g_system_ptr->getTracer()->traceRequest(this, line_addr, Address(request.pc),
- request.type, g_eventQueue_ptr->getTime());
- }
-
- Time latency = 0; // initialzed to an null value
-
- if (request.type == RubyRequestType_IFETCH)
- latency = m_instCache_ptr->getLatency();
- else
- latency = m_dataCache_ptr->getLatency();
-
- // Send the message to the cache controller
- assert(latency > 0);
-
- assert(m_mandatory_q_ptr != NULL);
- m_mandatory_q_ptr->enqueue(msg, latency);
-}
-/*
-bool Sequencer::tryCacheAccess(const Address& addr, CacheRequestType type,
- AccessModeType access_mode,
- int size, DataBlock*& data_ptr) {
- if (type == CacheRequestType_IFETCH) {
- return m_instCache_ptr->tryCacheAccess(line_address(addr), type, data_ptr);
- } else {
- return m_dataCache_ptr->tryCacheAccess(line_address(addr), type, data_ptr);
- }
+ Address line_addr(request.paddr);
+ line_addr.makeLineAddress();
+ CacheMsg msg(line_addr, Address(request.paddr), ctype,
+ Address(request.pc), amtype, request.len, PrefetchBit_No,
+ request.proc_id);
+
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->
+ profileTransition("Seq", m_version, Address(request.paddr),
+ "", "Begin", "",
+ RubyRequestType_to_string(request.type));
+ }
+
+ if (g_system_ptr->getTracer()->traceEnabled()) {
+ g_system_ptr->getTracer()->
+ traceRequest(this, line_addr, Address(request.pc),
+ request.type, g_eventQueue_ptr->getTime());
+ }
+
+ Time latency = 0; // initialzed to an null value
+
+ if (request.type == RubyRequestType_IFETCH)
+ latency = m_instCache_ptr->getLatency();
+ else
+ latency = m_dataCache_ptr->getLatency();
+
+ // Send the message to the cache controller
+ assert(latency > 0);
+
+ assert(m_mandatory_q_ptr != NULL);
+ m_mandatory_q_ptr->enqueue(msg, latency);
}
-*/
-void Sequencer::print(ostream& out) const {
- out << "[Sequencer: " << m_version
- << ", outstanding requests: " << m_outstanding_count;
+#if 0
+bool
+Sequencer::tryCacheAccess(const Address& addr, CacheRequestType type,
+ AccessModeType access_mode,
+ int size, DataBlock*& data_ptr)
+{
+ CacheMemory *cache =
+ (type == CacheRequestType_IFETCH) ? m_instCache_ptr : m_dataCache_ptr;
- out << ", read request table: " << m_readRequestTable
- << ", write request table: " << m_writeRequestTable;
- out << "]";
+ return cache->tryCacheAccess(line_address(addr), type, data_ptr);
+}
+#endif
+
+void
+Sequencer::print(ostream& out) const
+{
+ out << "[Sequencer: " << m_version
+ << ", outstanding requests: " << m_outstanding_count
+ << ", read request table: " << m_readRequestTable
+ << ", write request table: " << m_writeRequestTable
+ << "]";
}
-// this can be called from setState whenever coherence permissions are upgraded
-// when invoked, coherence violations will be checked for the given block
-void Sequencer::checkCoherence(const Address& addr) {
+// this can be called from setState whenever coherence permissions are
+// upgraded when invoked, coherence violations will be checked for the
+// given block
+void
+Sequencer::checkCoherence(const Address& addr)
+{
#ifdef CHECK_COHERENCE
- g_system_ptr->checkGlobalCoherenceInvariant(addr);
+ g_system_ptr->checkGlobalCoherenceInvariant(addr);
#endif
}
-
diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh
index 333ca5f24..69fd3b771 100644
--- a/src/mem/ruby/system/Sequencer.hh
+++ b/src/mem/ruby/system/Sequencer.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,25 +26,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id: Sequencer.hh 1.70 2006/09/27 14:56:41-05:00 bobba@s1-01.cs.wisc.edu $
- *
- * Description:
- *
- */
-
-#ifndef SEQUENCER_H
-#define SEQUENCER_H
+#ifndef __MEM_RUBY_SYSTEM_SEQUENCER_HH__
+#define __MEM_RUBY_SYSTEM_SEQUENCER_HH__
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/Consumer.hh"
-#include "mem/protocol/CacheRequestType.hh"
+#include "mem/gems_common/Map.hh"
#include "mem/protocol/AccessModeType.hh"
+#include "mem/protocol/CacheRequestType.hh"
#include "mem/protocol/GenericMachineType.hh"
#include "mem/protocol/PrefetchBit.hh"
-#include "mem/ruby/system/RubyPort.hh"
-#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/system/RubyPort.hh"
class DataBlock;
class CacheMsg;
@@ -54,109 +46,100 @@ class CacheMemory;
class RubySequencerParams;
-struct SequencerRequest {
- RubyRequest ruby_request;
- Time issue_time;
+struct SequencerRequest
+{
+ RubyRequest ruby_request;
+ Time issue_time;
- SequencerRequest(const RubyRequest & _ruby_request,
- Time _issue_time)
- : ruby_request(_ruby_request),
- issue_time(_issue_time)
- {}
+ SequencerRequest(const RubyRequest & _ruby_request, Time _issue_time)
+ : ruby_request(_ruby_request), issue_time(_issue_time)
+ {}
};
std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj);
-class Sequencer : public RubyPort, public Consumer {
-public:
+class Sequencer : public RubyPort, public Consumer
+{
+ public:
typedef RubySequencerParams Params;
- // Constructors
- Sequencer(const Params *);
-
- // Destructor
- ~Sequencer();
+ Sequencer(const Params *);
+ ~Sequencer();
- // Public Methods
- void wakeup(); // Used only for deadlock detection
+ // Public Methods
+ void wakeup(); // Used only for deadlock detection
- void printConfig(ostream& out) const;
+ void printConfig(ostream& out) const;
- void printProgress(ostream& out) const;
+ void printProgress(ostream& out) const;
- void writeCallback(const Address& address, DataBlock& data);
- void readCallback(const Address& address, DataBlock& data);
+ void writeCallback(const Address& address, DataBlock& data);
+ void readCallback(const Address& address, DataBlock& data);
- RequestStatus makeRequest(const RubyRequest & request);
- RequestStatus getRequestStatus(const RubyRequest& request);
- bool empty() const;
+ RequestStatus makeRequest(const RubyRequest & request);
+ RequestStatus getRequestStatus(const RubyRequest& request);
+ bool empty() const;
- void print(ostream& out) const;
- void printStats(ostream & out) const;
- void checkCoherence(const Address& address);
+ void print(ostream& out) const;
+ void printStats(ostream & out) const;
+ void checkCoherence(const Address& address);
- // bool getRubyMemoryValue(const Address& addr, char* value, unsigned int size_in_bytes);
- // bool setRubyMemoryValue(const Address& addr, char *value, unsigned int size_in_bytes);
+ void removeRequest(SequencerRequest* request);
- void removeRequest(SequencerRequest* request);
-private:
- // Private Methods
- bool tryCacheAccess(const Address& addr, CacheRequestType type, const Address& pc, AccessModeType access_mode, int size, DataBlock*& data_ptr);
- void issueRequest(const RubyRequest& request);
+ private:
+ bool tryCacheAccess(const Address& addr, CacheRequestType type,
+ const Address& pc, AccessModeType access_mode,
+ int size, DataBlock*& data_ptr);
+ void issueRequest(const RubyRequest& request);
- void hitCallback(SequencerRequest* request, DataBlock& data);
- bool insertRequest(SequencerRequest* request);
+ void hitCallback(SequencerRequest* request, DataBlock& data);
+ bool insertRequest(SequencerRequest* request);
- // Private copy constructor and assignment operator
- Sequencer(const Sequencer& obj);
- Sequencer& operator=(const Sequencer& obj);
+ // Private copy constructor and assignment operator
+ Sequencer(const Sequencer& obj);
+ Sequencer& operator=(const Sequencer& obj);
-private:
- int m_max_outstanding_requests;
- int m_deadlock_threshold;
+ private:
+ int m_max_outstanding_requests;
+ int m_deadlock_threshold;
- CacheMemory* m_dataCache_ptr;
- CacheMemory* m_instCache_ptr;
+ CacheMemory* m_dataCache_ptr;
+ CacheMemory* m_instCache_ptr;
- Map<Address, SequencerRequest*> m_writeRequestTable;
- Map<Address, SequencerRequest*> m_readRequestTable;
- // Global outstanding request count, across all request tables
- int m_outstanding_count;
- bool m_deadlock_check_scheduled;
+ Map<Address, SequencerRequest*> m_writeRequestTable;
+ Map<Address, SequencerRequest*> m_readRequestTable;
+ // Global outstanding request count, across all request tables
+ int m_outstanding_count;
+ bool m_deadlock_check_scheduled;
- int m_store_waiting_on_load_cycles;
- int m_store_waiting_on_store_cycles;
- int m_load_waiting_on_store_cycles;
- int m_load_waiting_on_load_cycles;
+ int m_store_waiting_on_load_cycles;
+ int m_store_waiting_on_store_cycles;
+ int m_load_waiting_on_store_cycles;
+ int m_load_waiting_on_load_cycles;
- bool m_usingRubyTester;
+ bool m_usingRubyTester;
- class SequencerWakeupEvent : public Event
- {
- Sequencer *m_sequencer_ptr;
+ class SequencerWakeupEvent : public Event
+ {
+ private:
+ Sequencer *m_sequencer_ptr;
- public:
- SequencerWakeupEvent(Sequencer *_seq) : m_sequencer_ptr(_seq) {}
- void process() { m_sequencer_ptr->wakeup(); }
- const char *description() const { return "Sequencer deadlock check"; }
- };
+ public:
+ SequencerWakeupEvent(Sequencer *_seq) : m_sequencer_ptr(_seq) {}
+ void process() { m_sequencer_ptr->wakeup(); }
+ const char *description() const { return "Sequencer deadlock check"; }
+ };
- SequencerWakeupEvent deadlockCheckEvent;
+ SequencerWakeupEvent deadlockCheckEvent;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const Sequencer& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Sequencer& obj)
+inline ostream&
+operator<<(ostream& out, const Sequencer& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //SEQUENCER_H
+#endif // __MEM_RUBY_SYSTEM_SEQUENCER_HH__
diff --git a/src/mem/ruby/system/SparseMemory.cc b/src/mem/ruby/system/SparseMemory.cc
index c351f9e60..6271d24c3 100644
--- a/src/mem/ruby/system/SparseMemory.cc
+++ b/src/mem/ruby/system/SparseMemory.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
@@ -29,10 +28,6 @@
#include "mem/ruby/system/SparseMemory.hh"
-
-// ****************************************************************
-
-
SparseMemory::SparseMemory(int number_of_bits, int number_of_levels)
{
int even_level_bits;
@@ -81,22 +76,16 @@ SparseMemory::recursivelyRemoveTables(SparseMapType* curTable, int curLevel)
SparseMapType::iterator iter;
for (iter = curTable->begin(); iter != curTable->end(); iter++) {
- SparseMemEntry_t* entryStruct = &((*iter).second);
+ SparseMemEntry* entryStruct = &((*iter).second);
if (curLevel != (m_number_of_levels - 1)) {
- //
- // If the not at the last level, analyze those lower level tables first,
- // then delete those next tables
- //
- SparseMapType* nextTable;
- nextTable = (SparseMapType*)(entryStruct->entry);
+ // If the not at the last level, analyze those lower level
+ // tables first, then delete those next tables
+ SparseMapType* nextTable = (SparseMapType*)(entryStruct->entry);
recursivelyRemoveTables(nextTable, (curLevel + 1));
delete nextTable;
-
} else {
- //
// If at the last level, delete the directory entry
- //
Directory_Entry* dirEntry;
dirEntry = (Directory_Entry*)(entryStruct->entry);
delete dirEntry;
@@ -104,15 +93,10 @@ SparseMemory::recursivelyRemoveTables(SparseMapType* curTable, int curLevel)
entryStruct->entry = NULL;
}
- //
// Once all entries have been deleted, erase the entries
- //
curTable->erase(curTable->begin(), curTable->end());
}
-
-// PUBLIC METHODS
-
// tests to see if an address is present in the memory
bool
SparseMemory::exist(const Address& address) const
@@ -120,22 +104,19 @@ SparseMemory::exist(const Address& address) const
SparseMapType* curTable = m_map_head;
Address curAddress;
- //
- // Initiallize the high bit to be the total number of bits plus the block
- // offset. However the highest bit index is one less than this value.
- //
+ // Initiallize the high bit to be the total number of bits plus
+ // the block offset. However the highest bit index is one less
+ // than this value.
int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits();
int lowBit;
assert(address == line_address(address));
DEBUG_EXPR(CACHE_COMP, HighPrio, address);
for (int level = 0; level < m_number_of_levels; level++) {
- //
// Create the appropriate sub address for this level
- // Note: that set Address is inclusive of the specified range, thus the
- // high bit is one less than the total number of bits used to create the
- // address.
- //
+ // Note: that set Address is inclusive of the specified range,
+ // thus the high bit is one less than the total number of bits
+ // used to create the address.
lowBit = highBit - m_number_of_bits_per_level[level];
curAddress.setAddress(address.bitSelect(lowBit, highBit - 1));
@@ -144,15 +125,11 @@ SparseMemory::exist(const Address& address) const
DEBUG_EXPR(CACHE_COMP, HighPrio, highBit - 1);
DEBUG_EXPR(CACHE_COMP, HighPrio, curAddress);
- //
// Adjust the highBit value for the next level
- //
highBit -= m_number_of_bits_per_level[level];
- //
- // If the address is found, move on to the next level. Otherwise,
- // return not found
- //
+ // If the address is found, move on to the next level.
+ // Otherwise, return not found
if (curTable->count(curAddress) != 0) {
curTable = (SparseMapType*)(((*curTable)[curAddress]).entry);
} else {
@@ -176,43 +153,34 @@ SparseMemory::add(const Address& address)
Address curAddress;
SparseMapType* curTable = m_map_head;
- SparseMemEntry_t* entryStruct = NULL;
+ SparseMemEntry* entryStruct = NULL;
- //
- // Initiallize the high bit to be the total number of bits plus the block
- // offset. However the highest bit index is one less than this value.
- //
+ // Initiallize the high bit to be the total number of bits plus
+ // the block offset. However the highest bit index is one less
+ // than this value.
int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits();
int lowBit;
void* newEntry = NULL;
for (int level = 0; level < m_number_of_levels; level++) {
- //
// create the appropriate address for this level
- // Note: that set Address is inclusive of the specified range, thus the
- // high bit is one less than the total number of bits used to create the
- // address.
- //
+ // Note: that set Address is inclusive of the specified range,
+ // thus the high bit is one less than the total number of bits
+ // used to create the address.
lowBit = highBit - m_number_of_bits_per_level[level];
curAddress.setAddress(address.bitSelect(lowBit, highBit - 1));
- //
// Adjust the highBit value for the next level
- //
highBit -= m_number_of_bits_per_level[level];
- //
// if the address exists in the cur table, move on. Otherwise
// create a new table.
- //
if (curTable->count(curAddress) != 0) {
curTable = (SparseMapType*)(((*curTable)[curAddress]).entry);
- } else {
-
+ } else {
m_adds_per_level[level]++;
- //
+
// if the last level, add a directory entry. Otherwise add a map.
- //
if (level == (m_number_of_levels - 1)) {
Directory_Entry* tempDirEntry = new Directory_Entry();
tempDirEntry->getDataBlk().clear();
@@ -222,17 +190,13 @@ SparseMemory::add(const Address& address)
newEntry = (void*)(tempMap);
}
- //
- // Create the pointer container SparseMemEntry_t and add it to the
- // table.
- //
- entryStruct = new SparseMemEntry_t;
+ // Create the pointer container SparseMemEntry and add it
+ // to the table.
+ entryStruct = new SparseMemEntry;
entryStruct->entry = newEntry;
(*curTable)[curAddress] = *entryStruct;
- //
// Move to the next level of the heirarchy
- //
curTable = (SparseMapType*)newEntry;
}
}
@@ -244,20 +208,17 @@ SparseMemory::add(const Address& address)
// recursively search table hierarchy for the lowest level table.
// remove the lowest entry and any empty tables above it.
int
-SparseMemory::recursivelyRemoveLevels(
- const Address& address,
- curNextInfo& curInfo)
+SparseMemory::recursivelyRemoveLevels(const Address& address,
+ CurNextInfo& curInfo)
{
Address curAddress;
- curNextInfo nextInfo;
- SparseMemEntry_t* entryStruct;
+ CurNextInfo nextInfo;
+ SparseMemEntry* entryStruct;
- //
// create the appropriate address for this level
- // Note: that set Address is inclusive of the specified range, thus the
- // high bit is one less than the total number of bits used to create the
- // address.
- //
+ // Note: that set Address is inclusive of the specified range,
+ // thus the high bit is one less than the total number of bits
+ // used to create the address.
curAddress.setAddress(address.bitSelect(curInfo.lowBit,
curInfo.highBit - 1));
@@ -272,9 +233,7 @@ SparseMemory::recursivelyRemoveLevels(
entryStruct = &((*(curInfo.curTable))[curAddress]);
if (curInfo.level < (m_number_of_levels - 1)) {
- //
// set up next level's info
- //
nextInfo.curTable = (SparseMapType*)(entryStruct->entry);
nextInfo.level = curInfo.level + 1;
@@ -284,15 +243,11 @@ SparseMemory::recursivelyRemoveLevels(
nextInfo.lowBit = curInfo.lowBit -
m_number_of_bits_per_level[curInfo.level + 1];
- //
// recursively search the table hierarchy
- //
int tableSize = recursivelyRemoveLevels(address, nextInfo);
- //
- // If this table below is now empty, we must delete it and erase it from
- // our table.
- //
+ // If this table below is now empty, we must delete it and
+ // erase it from our table.
if (tableSize == 0) {
m_removes_per_level[curInfo.level]++;
delete nextInfo.curTable;
@@ -300,10 +255,9 @@ SparseMemory::recursivelyRemoveLevels(
curInfo.curTable->erase(curAddress);
}
} else {
- //
- // if this is the last level, we have reached the Directory Entry and thus
- // we should delete it including the SparseMemEntry container struct.
- //
+ // if this is the last level, we have reached the Directory
+ // Entry and thus we should delete it including the
+ // SparseMemEntry container struct.
Directory_Entry* dirEntry;
dirEntry = (Directory_Entry*)(entryStruct->entry);
entryStruct->entry = NULL;
@@ -323,26 +277,21 @@ SparseMemory::remove(const Address& address)
m_total_removes++;
- curNextInfo nextInfo;
+ CurNextInfo nextInfo;
- //
// Initialize table pointer and level value
- //
nextInfo.curTable = m_map_head;
nextInfo.level = 0;
- //
- // Initiallize the high bit to be the total number of bits plus the block
- // offset. However the highest bit index is one less than this value.
- //
+ // Initiallize the high bit to be the total number of bits plus
+ // the block offset. However the highest bit index is one less
+ // than this value.
nextInfo.highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits();
nextInfo.lowBit = nextInfo.highBit - m_number_of_bits_per_level[0];;
- //
- // recursively search the table hierarchy for empty tables starting from the
- // level 0. Note we do not check the return value because the head table is
- // never deleted;
- //
+ // recursively search the table hierarchy for empty tables
+ // starting from the level 0. Note we do not check the return
+ // value because the head table is never deleted;
recursivelyRemoveLevels(address, nextInfo);
assert(!exist(address));
@@ -362,20 +311,17 @@ SparseMemory::lookup(const Address& address)
SparseMapType* curTable = m_map_head;
Directory_Entry* entry = NULL;
- //
- // Initiallize the high bit to be the total number of bits plus the block
- // offset. However the highest bit index is one less than this value.
- //
+ // Initiallize the high bit to be the total number of bits plus
+ // the block offset. However the highest bit index is one less
+ // than this value.
int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits();
int lowBit;
for (int level = 0; level < m_number_of_levels; level++) {
- //
// create the appropriate address for this level
- // Note: that set Address is inclusive of the specified range, thus the
- // high bit is one less than the total number of bits used to create the
- // address.
- //
+ // Note: that set Address is inclusive of the specified range,
+ // thus the high bit is one less than the total number of bits
+ // used to create the address.
lowBit = highBit - m_number_of_bits_per_level[level];
curAddress.setAddress(address.bitSelect(lowBit, highBit - 1));
@@ -384,21 +330,15 @@ SparseMemory::lookup(const Address& address)
DEBUG_EXPR(CACHE_COMP, HighPrio, highBit - 1);
DEBUG_EXPR(CACHE_COMP, HighPrio, curAddress);
- //
// Adjust the highBit value for the next level
- //
highBit -= m_number_of_bits_per_level[level];
- //
// The entry should be in the table and valid
- //
curTable = (SparseMapType*)(((*curTable)[curAddress]).entry);
assert(curTable != NULL);
}
- //
// The last entry actually points to the Directory entry not a table
- //
entry = (Directory_Entry*)curTable;
return entry;
diff --git a/src/mem/ruby/system/SparseMemory.hh b/src/mem/ruby/system/SparseMemory.hh
index 4a7ac98c2..6e3c8f926 100644
--- a/src/mem/ruby/system/SparseMemory.hh
+++ b/src/mem/ruby/system/SparseMemory.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
@@ -27,39 +26,35 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef __MEM_RUBY_SYSTEM_SPARSEMEMORY_HH__
+#define __MEM_RUBY_SYSTEM_SPARSEMEMORY_HH__
-#ifndef SPARSEMEMORY_H
-#define SPARSEMEMORY_H
-
-#include "mem/ruby/common/Global.hh"
#include "base/hashmap.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/protocol/Directory_Entry.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
-typedef struct SparseMemEntry {
+struct SparseMemEntry
+{
void* entry;
-} SparseMemEntry_t;
+};
-typedef m5::hash_map<Address, SparseMemEntry_t> SparseMapType;
+typedef m5::hash_map<Address, SparseMemEntry> SparseMapType;
-typedef struct curNextInfo {
+struct CurNextInfo
+{
SparseMapType* curTable;
int level;
int highBit;
int lowBit;
};
-class SparseMemory {
+class SparseMemory
+{
public:
-
- // Constructors
SparseMemory(int number_of_bits, int number_of_levels);
-
- // Destructor
~SparseMemory();
- // Public Methods
-
void printConfig(ostream& out) { }
bool exist(const Address& address) const;
@@ -83,7 +78,7 @@ class SparseMemory {
void recursivelyRemoveTables(SparseMapType* currentTable, int level);
// recursive search for address and remove associated entries
- int recursivelyRemoveLevels(const Address& address, curNextInfo& curInfo);
+ int recursivelyRemoveLevels(const Address& address, CurNextInfo& curInfo);
// Data Members (m_prefix)
SparseMapType* m_map_head;
@@ -98,17 +93,12 @@ class SparseMemory {
uint64_t* m_removes_per_level;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const SparseMemEntry& obj);
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const SparseMemEntry& obj)
+inline ostream&
+operator<<(ostream& out, const SparseMemEntry& obj)
{
out << "SparseMemEntry";
out << flush;
return out;
}
-
-#endif //SPARSEMEMORY_H
+#endif // __MEM_RUBY_SYSTEM_SPARSEMEMORY_HH__
diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc
index 69dbf69c4..ef4b66290 100644
--- a/src/mem/ruby/system/System.cc
+++ b/src/mem/ruby/system/System.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,25 +26,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * RubySystem.cc
- *
- * Description: See System.hh
- *
- * $Id$
- *
- */
-
-
-#include "mem/ruby/system/System.hh"
+#include "base/output.hh"
+#include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/network/Network.hh"
+#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/recorder/Tracer.hh"
-#include "mem/ruby/buffers/MessageBuffer.hh"
-#include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "base/output.hh"
+#include "mem/ruby/system/MemoryVector.hh"
+#include "mem/ruby/system/System.hh"
int RubySystem::m_random_seed;
bool RubySystem::m_randomization;
@@ -103,68 +92,68 @@ RubySystem::RubySystem(const Params *p)
registerExitCallback(rubyExitCB);
}
-
-void RubySystem::init()
+void
+RubySystem::init()
{
- m_profiler_ptr->clearStats();
+ m_profiler_ptr->clearStats();
}
-
RubySystem::~RubySystem()
{
- delete m_network_ptr;
- delete m_profiler_ptr;
- delete m_tracer_ptr;
- if (m_mem_vec_ptr != NULL) {
- delete m_mem_vec_ptr;
- }
+ delete m_network_ptr;
+ delete m_profiler_ptr;
+ delete m_tracer_ptr;
+ if (m_mem_vec_ptr)
+ delete m_mem_vec_ptr;
}
-void RubySystem::printSystemConfig(ostream & out)
+void
+RubySystem::printSystemConfig(ostream & out)
{
- out << "RubySystem config:" << endl;
- out << " random_seed: " << m_random_seed << endl;
- out << " randomization: " << m_randomization << endl;
- out << " cycle_period: " << m_clock << endl;
- out << " block_size_bytes: " << m_block_size_bytes << endl;
- out << " block_size_bits: " << m_block_size_bits << endl;
- out << " memory_size_bytes: " << m_memory_size_bytes << endl;
- out << " memory_size_bits: " << m_memory_size_bits << endl;
-
+ out << "RubySystem config:" << endl
+ << " random_seed: " << m_random_seed << endl
+ << " randomization: " << m_randomization << endl
+ << " cycle_period: " << m_clock << endl
+ << " block_size_bytes: " << m_block_size_bytes << endl
+ << " block_size_bits: " << m_block_size_bits << endl
+ << " memory_size_bytes: " << m_memory_size_bytes << endl
+ << " memory_size_bits: " << m_memory_size_bits << endl;
}
-void RubySystem::printConfig(ostream& out)
+void
+RubySystem::printConfig(ostream& out)
{
- out << "\n================ Begin RubySystem Configuration Print ================\n\n";
- printSystemConfig(out);
- m_network_ptr->printConfig(out);
- m_profiler_ptr->printConfig(out);
- out << "\n================ End RubySystem Configuration Print ================\n\n";
+ out << "\n================ Begin RubySystem Configuration Print ================\n\n";
+ printSystemConfig(out);
+ m_network_ptr->printConfig(out);
+ m_profiler_ptr->printConfig(out);
+ out << "\n================ End RubySystem Configuration Print ================\n\n";
}
-void RubySystem::printStats(ostream& out)
+void
+RubySystem::printStats(ostream& out)
{
+ const time_t T = time(NULL);
+ tm *localTime = localtime(&T);
+ char buf[100];
+ strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
- const time_t T = time(NULL);
- tm *localTime = localtime(&T);
- char buf[100];
- strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
-
- out << "Real time: " << buf << endl;
+ out << "Real time: " << buf << endl;
- m_profiler_ptr->printStats(out);
- m_network_ptr->printStats(out);
+ m_profiler_ptr->printStats(out);
+ m_network_ptr->printStats(out);
}
-void RubySystem::clearStats() const
+void
+RubySystem::clearStats() const
{
- m_profiler_ptr->clearStats();
- m_network_ptr->clearStats();
+ m_profiler_ptr->clearStats();
+ m_network_ptr->clearStats();
}
-void RubySystem::recordCacheContents(CacheRecorder& tr) const
+void
+RubySystem::recordCacheContents(CacheRecorder& tr) const
{
-
}
#ifdef CHECK_COHERENCE
@@ -176,48 +165,46 @@ void RubySystem::recordCacheContents(CacheRecorder& tr) const
// in setState. The SLICC spec must also define methods "isBlockShared"
// and "isBlockExclusive" that are specific to that protocol
//
-void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) {
- /*
- NodeID exclusive = -1;
- bool sharedDetected = false;
- NodeID lastShared = -1;
-
- for (int i = 0; i < m_chip_vector.size(); i++) {
-
- if (m_chip_vector[i]->isBlockExclusive(addr)) {
- if (exclusive != -1) {
- // coherence violation
- WARN_EXPR(exclusive);
- WARN_EXPR(m_chip_vector[i]->getID());
- WARN_EXPR(addr);
- WARN_EXPR(g_eventQueue_ptr->getTime());
- ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
- }
- else if (sharedDetected) {
- WARN_EXPR(lastShared);
- WARN_EXPR(m_chip_vector[i]->getID());
- WARN_EXPR(addr);
- WARN_EXPR(g_eventQueue_ptr->getTime());
- ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
- }
- else {
- exclusive = m_chip_vector[i]->getID();
- }
- }
- else if (m_chip_vector[i]->isBlockShared(addr)) {
- sharedDetected = true;
- lastShared = m_chip_vector[i]->getID();
-
- if (exclusive != -1) {
- WARN_EXPR(lastShared);
- WARN_EXPR(exclusive);
- WARN_EXPR(addr);
- WARN_EXPR(g_eventQueue_ptr->getTime());
- ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
- }
+void
+RubySystem::checkGlobalCoherenceInvariant(const Address& addr)
+{
+#if 0
+ NodeID exclusive = -1;
+ bool sharedDetected = false;
+ NodeID lastShared = -1;
+
+ for (int i = 0; i < m_chip_vector.size(); i++) {
+ if (m_chip_vector[i]->isBlockExclusive(addr)) {
+ if (exclusive != -1) {
+ // coherence violation
+ WARN_EXPR(exclusive);
+ WARN_EXPR(m_chip_vector[i]->getID());
+ WARN_EXPR(addr);
+ WARN_EXPR(g_eventQueue_ptr->getTime());
+ ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
+ } else if (sharedDetected) {
+ WARN_EXPR(lastShared);
+ WARN_EXPR(m_chip_vector[i]->getID());
+ WARN_EXPR(addr);
+ WARN_EXPR(g_eventQueue_ptr->getTime());
+ ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
+ } else {
+ exclusive = m_chip_vector[i]->getID();
+ }
+ } else if (m_chip_vector[i]->isBlockShared(addr)) {
+ sharedDetected = true;
+ lastShared = m_chip_vector[i]->getID();
+
+ if (exclusive != -1) {
+ WARN_EXPR(lastShared);
+ WARN_EXPR(exclusive);
+ WARN_EXPR(addr);
+ WARN_EXPR(g_eventQueue_ptr->getTime());
+ ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
+ }
+ }
}
- }
- */
+#endif
}
#endif
@@ -231,7 +218,8 @@ RubySystemParams::create()
* virtual process function that is invoked when the callback
* queue is executed.
*/
-void RubyExitCallback::process()
+void
+RubyExitCallback::process()
{
std::ostream *os = simout.create(stats_filename);
RubySystem::printConfig(*os);
diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh
index 7868da4b6..ccec2d61c 100644
--- a/src/mem/ruby/system/System.hh
+++ b/src/mem/ruby/system/System.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -28,32 +27,27 @@
*/
/*
- * System.hh
- *
- * Description: Contains all of the various parts of the system we are
- * simulating. Performs allocation, deallocation, and setup of all
- * the major components of the system
- *
- * $Id$
- *
+ * Contains all of the various parts of the system we are simulating.
+ * Performs allocation, deallocation, and setup of all the major
+ * components of the system
*/
-#ifndef SYSTEM_H
-#define SYSTEM_H
+#ifndef __MEM_RUBY_SYSTEM_SYSTEM_HH__
+#define __MEM_RUBY_SYSTEM_SYSTEM_HH__
-#include "mem/ruby/system/RubyPort.hh"
-#include "mem/ruby/common/Global.hh"
+#include "base/callback.hh"
#include "mem/gems_common/Vector.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
-#include "sim/sim_object.hh"
+#include "mem/ruby/system/RubyPort.hh"
#include "params/RubySystem.hh"
-#include "base/callback.hh"
+#include "sim/sim_object.hh"
-class Profiler;
-class Network;
class CacheRecorder;
-class Tracer;
class MemoryVector;
+class Network;
+class Profiler;
+class Tracer;
/*
* This defines the number of longs (32-bits on 32 bit machines,
@@ -68,83 +62,103 @@ class MemoryVector;
*/
const int NUMBER_WORDS_PER_SET = 1;
-class RubySystem : public SimObject {
-public:
+class RubySystem : public SimObject
+{
+ public:
typedef RubySystemParams Params;
RubySystem(const Params *p);
- // Destructor
- ~RubySystem();
-
- // config accessors
- static int getRandomSeed() { return m_random_seed; }
- static int getRandomization() { return m_randomization; }
- static int getBlockSizeBytes() { return m_block_size_bytes; }
- static int getBlockSizeBits() { return m_block_size_bits; }
- static uint64 getMemorySizeBytes() { return m_memory_size_bytes; }
- static int getMemorySizeBits() { return m_memory_size_bits; }
-
- // Public Methods
- static Network* getNetwork() { assert(m_network_ptr != NULL); return m_network_ptr; }
- static RubyEventQueue* getEventQueue() { return g_eventQueue_ptr; }
- Profiler* getProfiler() {assert(m_profiler_ptr != NULL); return m_profiler_ptr; }
- static Tracer* getTracer() { assert(m_tracer_ptr != NULL); return m_tracer_ptr; }
- static MemoryVector* getMemoryVector() { assert(m_mem_vec_ptr != NULL); return m_mem_vec_ptr;}
-
- void recordCacheContents(CacheRecorder& tr) const;
- static void printConfig(ostream& out);
- static void printStats(ostream& out);
- void clearStats() const;
-
- uint64 getInstructionCount(int thread) { return 1; }
- static uint64 getCycleCount(int thread) { return g_eventQueue_ptr->getTime(); }
-
- void print(ostream& out) const;
- /*
-#ifdef CHECK_COHERENCE
- void checkGlobalCoherenceInvariant(const Address& addr);
-#endif
- */
-
-private:
- // Private copy constructor and assignment operator
- RubySystem(const RubySystem& obj);
- RubySystem& operator=(const RubySystem& obj);
-
- void init();
-
- static void printSystemConfig(ostream& out);
-
-private:
- // configuration parameters
- static int m_random_seed;
- static bool m_randomization;
- static Tick m_clock;
- static int m_block_size_bytes;
- static int m_block_size_bits;
- static uint64 m_memory_size_bytes;
- static int m_memory_size_bits;
-
- // Data Members (m_ prefix)
- static Network* m_network_ptr;
-
-public:
- static Profiler* m_profiler_ptr;
- static Tracer* m_tracer_ptr;
- static MemoryVector* m_mem_vec_ptr;
-};
+ ~RubySystem();
+
+ // config accessors
+ static int getRandomSeed() { return m_random_seed; }
+ static int getRandomization() { return m_randomization; }
+ static int getBlockSizeBytes() { return m_block_size_bytes; }
+ static int getBlockSizeBits() { return m_block_size_bits; }
+ static uint64 getMemorySizeBytes() { return m_memory_size_bytes; }
+ static int getMemorySizeBits() { return m_memory_size_bits; }
+
+ // Public Methods
+ static Network*
+ getNetwork()
+ {
+ assert(m_network_ptr != NULL);
+ return m_network_ptr;
+ }
-// Output operator declaration
-ostream& operator<<(ostream& out, const RubySystem& obj);
+ static RubyEventQueue*
+ getEventQueue()
+ {
+ return g_eventQueue_ptr;
+ }
-// ******************* Definitions *******************
+ Profiler*
+ getProfiler()
+ {
+ assert(m_profiler_ptr != NULL);
+ return m_profiler_ptr;
+ }
+
+ static Tracer*
+ getTracer()
+ {
+ assert(m_tracer_ptr != NULL);
+ return m_tracer_ptr;
+ }
+
+ static MemoryVector*
+ getMemoryVector()
+ {
+ assert(m_mem_vec_ptr != NULL);
+ return m_mem_vec_ptr;
+ }
+
+ void recordCacheContents(CacheRecorder& tr) const;
+ static void printConfig(ostream& out);
+ static void printStats(ostream& out);
+ void clearStats() const;
+
+ uint64 getInstructionCount(int thread) { return 1; }
+ static uint64
+ getCycleCount(int thread)
+ {
+ return g_eventQueue_ptr->getTime();
+ }
-// Output operator definition
-inline
-ostream& operator<<(ostream& out, const RubySystem& obj)
+ void print(ostream& out) const;
+
+ private:
+ // Private copy constructor and assignment operator
+ RubySystem(const RubySystem& obj);
+ RubySystem& operator=(const RubySystem& obj);
+
+ void init();
+
+ static void printSystemConfig(ostream& out);
+
+ private:
+ // configuration parameters
+ static int m_random_seed;
+ static bool m_randomization;
+ static Tick m_clock;
+ static int m_block_size_bytes;
+ static int m_block_size_bits;
+ static uint64 m_memory_size_bytes;
+ static int m_memory_size_bits;
+
+ static Network* m_network_ptr;
+
+ public:
+ static Profiler* m_profiler_ptr;
+ static Tracer* m_tracer_ptr;
+ static MemoryVector* m_mem_vec_ptr;
+};
+
+inline ostream&
+operator<<(ostream& out, const RubySystem& obj)
{
-// obj.print(out);
- out << flush;
- return out;
+ //obj.print(out);
+ out << flush;
+ return out;
}
class RubyExitCallback : public Callback
@@ -153,22 +167,17 @@ class RubyExitCallback : public Callback
string stats_filename;
public:
- /**
- * virtualize the destructor to make sure that the correct one
- * gets called.
- */
-
virtual ~RubyExitCallback() {}
RubyExitCallback(const string& _stats_filename)
{
- stats_filename = _stats_filename;
+ stats_filename = _stats_filename;
}
virtual void process();
};
-#endif //SYSTEM_H
+#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__
diff --git a/src/mem/ruby/system/TBETable.hh b/src/mem/ruby/system/TBETable.hh
index 2b00f7a06..d21946abd 100644
--- a/src/mem/ruby/system/TBETable.hh
+++ b/src/mem/ruby/system/TBETable.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,141 +26,115 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * TBETable.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef TBETABLE_H
-#define TBETABLE_H
+#ifndef __MEM_RUBY_SYSTEM_TBETABLE_HH__
+#define __MEM_RUBY_SYSTEM_TBETABLE_HH__
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/System.hh"
template<class ENTRY>
-class TBETable {
-public:
-
- // Constructors
- TBETable(int number_of_TBEs);
-
-
- // Destructor
- //~TBETable();
-
- // Public Methods
-
- void printConfig(ostream& out) { out << "TBEs_per_TBETable: " << m_number_of_TBEs << endl; }
-
- bool isPresent(const Address& address) const;
- void allocate(const Address& address);
- void deallocate(const Address& address);
- bool areNSlotsAvailable(int n) const { return (m_number_of_TBEs - m_map.size()) >= n; }
-
- ENTRY& lookup(const Address& address);
- const ENTRY& lookup(const Address& address) const;
-
- // Print cache contents
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- TBETable(const TBETable& obj);
- TBETable& operator=(const TBETable& obj);
-
- // Data Members (m_prefix)
- Map<Address, ENTRY> m_map;
-
-private:
- int m_number_of_TBEs;
-};
-
-// Output operator declaration
-//ostream& operator<<(ostream& out, const TBETable<ENTRY>& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-template<class ENTRY>
-extern inline
-ostream& operator<<(ostream& out, const TBETable<ENTRY>& obj)
+class TBETable
{
- obj.print(out);
- out << flush;
- return out;
-}
-
-
-// ****************************************************************
-
+ public:
+ TBETable(int number_of_TBEs)
+ : m_number_of_TBEs(number_of_TBEs)
+ {
+ }
+
+ void
+ printConfig(ostream& out)
+ {
+ out << "TBEs_per_TBETable: " << m_number_of_TBEs << endl;
+ }
+
+ bool isPresent(const Address& address) const;
+ void allocate(const Address& address);
+ void deallocate(const Address& address);
+ bool
+ areNSlotsAvailable(int n) const
+ {
+ return (m_number_of_TBEs - m_map.size()) >= n;
+ }
+
+ ENTRY& lookup(const Address& address);
+ const ENTRY& lookup(const Address& address) const;
+
+ // Print cache contents
+ void print(ostream& out) const;
+
+ private:
+ // Private copy constructor and assignment operator
+ TBETable(const TBETable& obj);
+ TBETable& operator=(const TBETable& obj);
+
+ // Data Members (m_prefix)
+ Map<Address, ENTRY> m_map;
+
+ private:
+ int m_number_of_TBEs;
+};
template<class ENTRY>
-extern inline
-TBETable<ENTRY>::TBETable(int number_of_TBEs)
+inline ostream&
+operator<<(ostream& out, const TBETable<ENTRY>& obj)
{
- m_number_of_TBEs = number_of_TBEs;
+ obj.print(out);
+ out << flush;
+ return out;
}
-// PUBLIC METHODS
-
-// tests to see if an address is present in the cache
template<class ENTRY>
-extern inline
-bool TBETable<ENTRY>::isPresent(const Address& address) const
+inline bool
+TBETable<ENTRY>::isPresent(const Address& address) const
{
- assert(address == line_address(address));
- assert(m_map.size() <= m_number_of_TBEs);
- return m_map.exist(address);
+ assert(address == line_address(address));
+ assert(m_map.size() <= m_number_of_TBEs);
+ return m_map.exist(address);
}
template<class ENTRY>
-extern inline
-void TBETable<ENTRY>::allocate(const Address& address)
+inline void
+TBETable<ENTRY>::allocate(const Address& address)
{
- assert(isPresent(address) == false);
- assert(m_map.size() < m_number_of_TBEs);
- m_map.add(address, ENTRY());
+ assert(isPresent(address) == false);
+ assert(m_map.size() < m_number_of_TBEs);
+ m_map.add(address, ENTRY());
}
template<class ENTRY>
-extern inline
-void TBETable<ENTRY>::deallocate(const Address& address)
+inline void
+TBETable<ENTRY>::deallocate(const Address& address)
{
- assert(isPresent(address) == true);
- assert(m_map.size() > 0);
- m_map.erase(address);
+ assert(isPresent(address) == true);
+ assert(m_map.size() > 0);
+ m_map.erase(address);
}
// looks an address up in the cache
template<class ENTRY>
-extern inline
-ENTRY& TBETable<ENTRY>::lookup(const Address& address)
+inline ENTRY&
+TBETable<ENTRY>::lookup(const Address& address)
{
- assert(isPresent(address) == true);
- return m_map.lookup(address);
+ assert(isPresent(address) == true);
+ return m_map.lookup(address);
}
// looks an address up in the cache
template<class ENTRY>
-extern inline
-const ENTRY& TBETable<ENTRY>::lookup(const Address& address) const
+inline const ENTRY&
+TBETable<ENTRY>::lookup(const Address& address) const
{
- assert(isPresent(address) == true);
- return m_map.lookup(address);
+ assert(isPresent(address) == true);
+ return m_map.lookup(address);
}
template<class ENTRY>
-extern inline
-void TBETable<ENTRY>::print(ostream& out) const
+inline void
+TBETable<ENTRY>::print(ostream& out) const
{
}
-#endif //TBETABLE_H
+#endif // __MEM_RUBY_SYSTEM_TBETABLE_HH__
diff --git a/src/mem/ruby/system/TimerTable.cc b/src/mem/ruby/system/TimerTable.cc
index 5d496da04..eba04e3e3 100644
--- a/src/mem/ruby/system/TimerTable.cc
+++ b/src/mem/ruby/system/TimerTable.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,101 +26,101 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/TimerTable.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
+#include "mem/ruby/system/TimerTable.hh"
TimerTable::TimerTable()
{
- m_consumer_ptr = NULL;
- m_next_valid = false;
- m_next_address = Address(0);
- m_next_time = 0;
+ m_consumer_ptr = NULL;
+ m_next_valid = false;
+ m_next_address = Address(0);
+ m_next_time = 0;
}
-
-bool TimerTable::isReady() const
+bool
+TimerTable::isReady() const
{
- if (m_map.size() == 0) {
- return false;
- }
+ if (m_map.size() == 0) {
+ return false;
+ }
- if (!m_next_valid) {
- updateNext();
- }
- assert(m_next_valid);
- return (g_eventQueue_ptr->getTime() >= m_next_time);
+ if (!m_next_valid) {
+ updateNext();
+ }
+ assert(m_next_valid);
+ return (g_eventQueue_ptr->getTime() >= m_next_time);
}
-const Address& TimerTable::readyAddress() const
+const Address&
+TimerTable::readyAddress() const
{
- assert(isReady());
+ assert(isReady());
- if (!m_next_valid) {
- updateNext();
- }
- assert(m_next_valid);
- return m_next_address;
+ if (!m_next_valid) {
+ updateNext();
+ }
+ assert(m_next_valid);
+ return m_next_address;
}
-void TimerTable::set(const Address& address, Time relative_latency)
+void
+TimerTable::set(const Address& address, Time relative_latency)
{
- assert(address == line_address(address));
- assert(relative_latency > 0);
- assert(m_map.exist(address) == false);
- Time ready_time = g_eventQueue_ptr->getTime() + relative_latency;
- m_map.add(address, ready_time);
- assert(m_consumer_ptr != NULL);
- g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, ready_time);
- m_next_valid = false;
-
- // Don't always recalculate the next ready address
- if (ready_time <= m_next_time) {
+ assert(address == line_address(address));
+ assert(relative_latency > 0);
+ assert(m_map.exist(address) == false);
+ Time ready_time = g_eventQueue_ptr->getTime() + relative_latency;
+ m_map.add(address, ready_time);
+ assert(m_consumer_ptr != NULL);
+ g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, ready_time);
m_next_valid = false;
- }
+
+ // Don't always recalculate the next ready address
+ if (ready_time <= m_next_time) {
+ m_next_valid = false;
+ }
}
-void TimerTable::unset(const Address& address)
+void
+TimerTable::unset(const Address& address)
{
- assert(address == line_address(address));
- assert(m_map.exist(address) == true);
- m_map.remove(address);
+ assert(address == line_address(address));
+ assert(m_map.exist(address) == true);
+ m_map.remove(address);
- // Don't always recalculate the next ready address
- if (address == m_next_address) {
- m_next_valid = false;
- }
+ // Don't always recalculate the next ready address
+ if (address == m_next_address) {
+ m_next_valid = false;
+ }
}
-void TimerTable::print(ostream& out) const
+void
+TimerTable::print(ostream& out) const
{
}
-
-void TimerTable::updateNext() const
+void
+TimerTable::updateNext() const
{
- if (m_map.size() == 0) {
- assert(m_next_valid == false);
- return;
- }
-
- Vector<Address> addresses = m_map.keys();
- m_next_address = addresses[0];
- m_next_time = m_map.lookup(m_next_address);
+ if (m_map.size() == 0) {
+ assert(m_next_valid == false);
+ return;
+ }
- // Search for the minimum time
- int size = addresses.size();
- for (int i=1; i<size; i++) {
- Address maybe_next_address = addresses[i];
- Time maybe_next_time = m_map.lookup(maybe_next_address);
- if (maybe_next_time < m_next_time) {
- m_next_time = maybe_next_time;
- m_next_address= maybe_next_address;
+ Vector<Address> addresses = m_map.keys();
+ m_next_address = addresses[0];
+ m_next_time = m_map.lookup(m_next_address);
+
+ // Search for the minimum time
+ int size = addresses.size();
+ for (int i=1; i<size; i++) {
+ Address maybe_next_address = addresses[i];
+ Time maybe_next_time = m_map.lookup(maybe_next_address);
+ if (maybe_next_time < m_next_time) {
+ m_next_time = maybe_next_time;
+ m_next_address= maybe_next_address;
+ }
}
- }
- m_next_valid = true;
+ m_next_valid = true;
}
diff --git a/src/mem/ruby/system/TimerTable.hh b/src/mem/ruby/system/TimerTable.hh
index eda84069d..96b4b0b15 100644
--- a/src/mem/ruby/system/TimerTable.hh
+++ b/src/mem/ruby/system/TimerTable.hh
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -27,70 +26,69 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * TimerTable.hh
- *
- * Description:
- *
- * $Id$
- *
- */
+#ifndef __MEM_RUBY_SYSTEM_TIMERTABLE_HH__
+#define __MEM_RUBY_SYSTEM_TIMERTABLE_HH__
-#ifndef TIMERTABLE_H
-#define TIMERTABLE_H
+#include <cassert>
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
+
class Consumer;
-class TimerTable {
-public:
+class TimerTable
+{
+ public:
+ TimerTable();
- // Constructors
- TimerTable();
+ static void printConfig(ostream& out) {}
- // Destructor
- //~TimerTable();
+ void
+ setConsumer(Consumer* consumer_ptr)
+ {
+ assert(m_consumer_ptr == NULL);
+ m_consumer_ptr = consumer_ptr;
+ }
- // Class Methods
- static void printConfig(ostream& out) {}
+ void
+ setDescription(const string& name)
+ {
+ m_name = name;
+ }
- // Public Methods
- void setConsumer(Consumer* consumer_ptr) { ASSERT(m_consumer_ptr==NULL); m_consumer_ptr = consumer_ptr; }
- void setDescription(const string& name) { m_name = name; }
+ bool isReady() const;
+ const Address& readyAddress() const;
+ bool isSet(const Address& address) const { return m_map.exist(address); }
+ void set(const Address& address, Time relative_latency);
+ void unset(const Address& address);
+ void print(ostream& out) const;
- bool isReady() const;
- const Address& readyAddress() const;
- bool isSet(const Address& address) const { return m_map.exist(address); }
- void set(const Address& address, Time relative_latency);
- void unset(const Address& address);
- void print(ostream& out) const;
-private:
- // Private Methods
- void updateNext() const;
+ private:
+ void updateNext() const;
- // Private copy constructor and assignment operator
- TimerTable(const TimerTable& obj);
- TimerTable& operator=(const TimerTable& obj);
+ // Private copy constructor and assignment operator
+ TimerTable(const TimerTable& obj);
+ TimerTable& operator=(const TimerTable& obj);
- // Data Members (m_prefix)
- Map<Address, Time> m_map;
- mutable bool m_next_valid;
- mutable Time m_next_time; // Only valid if m_next_valid is true
- mutable Address m_next_address; // Only valid if m_next_valid is true
- Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
- string m_name;
+ // Data Members (m_prefix)
+ Map<Address, Time> m_map;
+ mutable bool m_next_valid;
+ mutable Time m_next_time; // Only valid if m_next_valid is true
+ mutable Address m_next_address; // Only valid if m_next_valid is true
+ Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
+ string m_name;
};
// ******************* Definitions *******************
// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TimerTable& obj)
+inline ostream&
+operator<<(ostream& out, const TimerTable& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //TIMERTABLE_H
+
+#endif // __MEM_RUBY_SYSTEM_TIMERTABLE_HH__