-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
#include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/system/System.hh"
MessageBuffer::MessageBuffer(const string &name)
{
- m_msg_counter = 0;
- m_consumer_ptr = NULL;
- m_ordering_set = false;
- m_strict_fifo = true;
- m_size = 0;
- m_max_size = -1;
- m_last_arrival_time = 0;
- m_randomization = true;
- m_size_last_time_size_checked = 0;
- m_time_last_time_size_checked = 0;
- m_time_last_time_enqueue = 0;
- m_time_last_time_pop = 0;
- m_size_at_cycle_start = 0;
- m_msgs_this_cycle = 0;
- m_not_avail_count = 0;
- m_priority_rank = 0;
- m_name = name;
+ m_msg_counter = 0;
+ m_consumer_ptr = NULL;
+ m_ordering_set = false;
+ m_strict_fifo = true;
+ m_size = 0;
+ m_max_size = -1;
+ m_last_arrival_time = 0;
+ m_randomization = true;
+ m_size_last_time_size_checked = 0;
+ m_time_last_time_size_checked = 0;
+ m_time_last_time_enqueue = 0;
+ m_time_last_time_pop = 0;
+ m_size_at_cycle_start = 0;
+ m_msgs_this_cycle = 0;
+ m_not_avail_count = 0;
+ m_priority_rank = 0;
+ m_name = name;
}
-int MessageBuffer::getSize()
+int
+MessageBuffer::getSize()
{
- if(m_time_last_time_size_checked == g_eventQueue_ptr->getTime()){
- return m_size_last_time_size_checked;
- } else {
- m_time_last_time_size_checked = g_eventQueue_ptr->getTime();
- m_size_last_time_size_checked = m_size;
- return m_size;
- }
+ if (m_time_last_time_size_checked == g_eventQueue_ptr->getTime()) {
+ return m_size_last_time_size_checked;
+ } else {
+ m_time_last_time_size_checked = g_eventQueue_ptr->getTime();
+ m_size_last_time_size_checked = m_size;
+ return m_size;
+ }
}
-bool MessageBuffer::areNSlotsAvailable(int n)
+bool
+MessageBuffer::areNSlotsAvailable(int n)
{
- // fast path when message buffers have infinite size
- if(m_max_size == -1) {
- return true;
- }
-
- // determine my correct size for the current cycle
- // pop operations shouldn't effect the network's visible size until next cycle,
- // but enqueue operations effect the visible size immediately
- int current_size = max(m_size_at_cycle_start, m_size);
- if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) { // no pops this cycle - m_size is correct
- current_size = m_size;
- } else {
- if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) { // no enqueues this cycle - m_size_at_cycle_start is correct
- current_size = m_size_at_cycle_start;
- } else { // both pops and enqueues occured this cycle - add new enqueued msgs to m_size_at_cycle_start
- current_size = m_size_at_cycle_start+m_msgs_this_cycle;
+ // fast path when message buffers have infinite size
+ if (m_max_size == -1) {
+ return true;
+ }
+
+ // determine my correct size for the current cycle
+ // pop operations shouldn't effect the network's visible size
+ // until next cycle, but enqueue operations effect the visible
+ // size immediately
+ int current_size = max(m_size_at_cycle_start, m_size);
+ if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) {
+ // no pops this cycle - m_size is correct
+ current_size = m_size;
+ } else {
+ if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) {
+ // no enqueues this cycle - m_size_at_cycle_start is correct
+ current_size = m_size_at_cycle_start;
+ } else {
+ // both pops and enqueues occured this cycle - add new
+ // enqueued msgs to m_size_at_cycle_start
+ current_size = m_size_at_cycle_start+m_msgs_this_cycle;
+ }
+ }
+
+ // now compare the new size with our max size
+ if (current_size + n <= m_max_size) {
+ return true;
+ } else {
+ DEBUG_MSG(QUEUE_COMP, MedPrio, n);
+ DEBUG_MSG(QUEUE_COMP, MedPrio, current_size);
+ DEBUG_MSG(QUEUE_COMP, MedPrio, m_size);
+ DEBUG_MSG(QUEUE_COMP, MedPrio, m_max_size);
+ m_not_avail_count++;
+ return false;
}
- }
-
- // now compare the new size with our max size
- if(current_size+n <= m_max_size){
- return true;
- } else {
- DEBUG_MSG(QUEUE_COMP,MedPrio,n);
- DEBUG_MSG(QUEUE_COMP,MedPrio,current_size);
- DEBUG_MSG(QUEUE_COMP,MedPrio,m_size);
- DEBUG_MSG(QUEUE_COMP,MedPrio,m_max_size);
- m_not_avail_count++;
- return false;
- }
}
-const MsgPtr MessageBuffer::getMsgPtrCopy() const
+const MsgPtr
+MessageBuffer::getMsgPtrCopy() const
{
- assert(isReady());
+ assert(isReady());
- MsgPtr temp_msg;
- temp_msg = *(m_prio_heap.peekMin().m_msgptr.ref());
- assert(temp_msg.ref() != NULL);
- return temp_msg;
+ MsgPtr temp_msg;
+ temp_msg = *(m_prio_heap.peekMin().m_msgptr.ref());
+ assert(temp_msg.ref() != NULL);
+ return temp_msg;
}
-const Message* MessageBuffer::peekAtHeadOfQueue() const
+const Message*
+MessageBuffer::peekAtHeadOfQueue() const
{
- const Message* msg_ptr;
- DEBUG_NEWLINE(QUEUE_COMP,MedPrio);
+ const Message* msg_ptr;
+ DEBUG_NEWLINE(QUEUE_COMP, MedPrio);
- DEBUG_MSG(QUEUE_COMP,MedPrio,"Peeking at head of queue " + m_name + " time: "
- + int_to_string(g_eventQueue_ptr->getTime()) + ".");
- assert(isReady());
+ DEBUG_MSG(QUEUE_COMP, MedPrio,
+ "Peeking at head of queue " + m_name + " time: "
+ + int_to_string(g_eventQueue_ptr->getTime()) + ".");
+ assert(isReady());
- msg_ptr = m_prio_heap.peekMin().m_msgptr.ref();
- assert(msg_ptr != NULL);
+ msg_ptr = m_prio_heap.peekMin().m_msgptr.ref();
+ assert(msg_ptr != NULL);
- DEBUG_EXPR(QUEUE_COMP,MedPrio,*msg_ptr);
- DEBUG_NEWLINE(QUEUE_COMP,MedPrio);
- return msg_ptr;
+ DEBUG_EXPR(QUEUE_COMP, MedPrio, *msg_ptr);
+ DEBUG_NEWLINE(QUEUE_COMP, MedPrio);
+ return msg_ptr;
}
// FIXME - move me somewhere else
-int random_time()
+int
+random_time()
{
- int time = 1;
- time += random() & 0x3; // [0...3]
- if ((random() & 0x7) == 0) { // 1 in 8 chance
- time += 100 + (random() % 0xf); // 100 + [1...15]
- }
- return time;
+ int time = 1;
+ time += random() & 0x3; // [0...3]
+ if ((random() & 0x7) == 0) { // 1 in 8 chance
+ time += 100 + (random() % 0xf); // 100 + [1...15]
+ }
+ return time;
}
-void MessageBuffer::enqueue(const MsgPtr& message, Time delta)
+void
+MessageBuffer::enqueue(const MsgPtr& message, Time delta)
{
- DEBUG_NEWLINE(QUEUE_COMP,HighPrio);
- DEBUG_MSG(QUEUE_COMP,HighPrio,"enqueue " + m_name + " time: "
- + int_to_string(g_eventQueue_ptr->getTime()) + ".");
- DEBUG_EXPR(QUEUE_COMP,MedPrio,message);
- DEBUG_NEWLINE(QUEUE_COMP,HighPrio);
-
- m_msg_counter++;
- m_size++;
-
- // record current time incase we have a pop that also adjusts my size
- if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) {
- m_msgs_this_cycle = 0; // first msg this cycle
- m_time_last_time_enqueue = g_eventQueue_ptr->getTime();
- }
- m_msgs_this_cycle++;
-
- // ASSERT(m_max_size == -1 || m_size <= m_max_size + 1);
- // the plus one is a kluge because of a SLICC issue
-
- if (!m_ordering_set) {
- // WARN_EXPR(*this);
- WARN_EXPR(m_name);
- ERROR_MSG("Ordering property of this queue has not been set");
- }
-
- // Calculate the arrival time of the message, that is, the first
- // cycle the message can be dequeued.
-// printf ("delta %i \n", delta);
- assert(delta>0);
- Time current_time = g_eventQueue_ptr->getTime();
- Time arrival_time = 0;
- if (!RubySystem::getRandomization() || (m_randomization == false)) {
- // No randomization
- arrival_time = current_time + delta;
-
- } else {
- // Randomization - ignore delta
- if (m_strict_fifo) {
- if (m_last_arrival_time < current_time) {
- m_last_arrival_time = current_time;
- }
- arrival_time = m_last_arrival_time + random_time();
- } else {
- arrival_time = current_time + random_time();
+ DEBUG_NEWLINE(QUEUE_COMP, HighPrio);
+ DEBUG_MSG(QUEUE_COMP, HighPrio, "enqueue " + m_name + " time: "
+ + int_to_string(g_eventQueue_ptr->getTime()) + ".");
+ DEBUG_EXPR(QUEUE_COMP, MedPrio, message);
+ DEBUG_NEWLINE(QUEUE_COMP, HighPrio);
+
+ m_msg_counter++;
+ m_size++;
+
+ // record current time incase we have a pop that also adjusts my size
+ if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) {
+ m_msgs_this_cycle = 0; // first msg this cycle
+ m_time_last_time_enqueue = g_eventQueue_ptr->getTime();
}
- }
+ m_msgs_this_cycle++;
+
+ // ASSERT(m_max_size == -1 || m_size <= m_max_size + 1);
+ // the plus one is a kluge because of a SLICC issue
- // Check the arrival time
- assert(arrival_time > current_time);
- if (m_strict_fifo) {
- if (arrival_time >= m_last_arrival_time) {
+ if (!m_ordering_set) {
+ // WARN_EXPR(*this);
+ WARN_EXPR(m_name);
+ ERROR_MSG("Ordering property of this queue has not been set");
+ }
+ // Calculate the arrival time of the message, that is, the first
+ // cycle the message can be dequeued.
+ //printf ("delta %i \n", delta);
+ assert(delta>0);
+ Time current_time = g_eventQueue_ptr->getTime();
+ Time arrival_time = 0;
+ if (!RubySystem::getRandomization() || (m_randomization == false)) {
+ // No randomization
+ arrival_time = current_time + delta;
+ } else {
+ // Randomization - ignore delta
+ if (m_strict_fifo) {
+ if (m_last_arrival_time < current_time) {
+ m_last_arrival_time = current_time;
+ }
+ arrival_time = m_last_arrival_time + random_time();
+ } else {
+ arrival_time = current_time + random_time();
+ }
+ }
+
+ // Check the arrival time
+ assert(arrival_time > current_time);
+ if (m_strict_fifo) {
+ if (arrival_time < m_last_arrival_time) {
+ WARN_EXPR(*this);
+ WARN_EXPR(m_name);
+ WARN_EXPR(current_time);
+ WARN_EXPR(delta);
+ WARN_EXPR(arrival_time);
+ WARN_EXPR(m_last_arrival_time);
+ ERROR_MSG("FIFO ordering violated");
+ }
+ }
+ m_last_arrival_time = arrival_time;
+
+ // compute the delay cycles and set enqueue time
+ Message* msg_ptr = message.mod_ref();
+ assert(msg_ptr != NULL);
+
+ assert(g_eventQueue_ptr->getTime() >= msg_ptr->getLastEnqueueTime() &&
+ "ensure we aren't dequeued early");
+
+ msg_ptr->setDelayedCycles(g_eventQueue_ptr->getTime() -
+ msg_ptr->getLastEnqueueTime() +
+ msg_ptr->getDelayedCycles());
+ msg_ptr->setLastEnqueueTime(arrival_time);
+
+ // Insert the message into the priority heap
+ MessageBufferNode thisNode(arrival_time, m_msg_counter, message);
+ m_prio_heap.insert(thisNode);
+
+ DEBUG_NEWLINE(QUEUE_COMP, HighPrio);
+ DEBUG_MSG(QUEUE_COMP, HighPrio, "enqueue " + m_name
+ + " with arrival_time " + int_to_string(arrival_time)
+ + " cur_time: " + int_to_string(g_eventQueue_ptr->getTime())
+ + ".");
+ DEBUG_EXPR(QUEUE_COMP, MedPrio, message);
+ DEBUG_NEWLINE(QUEUE_COMP, HighPrio);
+
+ // Schedule the wakeup
+ if (m_consumer_ptr != NULL) {
+ g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time);
} else {
- WARN_EXPR(*this);
- WARN_EXPR(m_name);
- WARN_EXPR(current_time);
- WARN_EXPR(delta);
- WARN_EXPR(arrival_time);
- WARN_EXPR(m_last_arrival_time);
- ERROR_MSG("FIFO ordering violated");
+ WARN_EXPR(*this);
+ WARN_EXPR(m_name);
+ ERROR_MSG("No consumer");
}
- }
- m_last_arrival_time = arrival_time;
-
- // compute the delay cycles and set enqueue time
- Message* msg_ptr = NULL;
- msg_ptr = message.mod_ref();
- assert(msg_ptr != NULL);
- assert(g_eventQueue_ptr->getTime() >= msg_ptr->getLastEnqueueTime()); // ensure we aren't dequeued early
- msg_ptr->setDelayedCycles((g_eventQueue_ptr->getTime() - msg_ptr->getLastEnqueueTime())+msg_ptr->getDelayedCycles());
- msg_ptr->setLastEnqueueTime(arrival_time);
-
- // Insert the message into the priority heap
- MessageBufferNode thisNode(arrival_time, m_msg_counter, message);
- m_prio_heap.insert(thisNode);
-
- DEBUG_NEWLINE(QUEUE_COMP,HighPrio);
- DEBUG_MSG(QUEUE_COMP,HighPrio,"enqueue " + m_name
- + " with arrival_time " + int_to_string(arrival_time)
- + " cur_time: " + int_to_string(g_eventQueue_ptr->getTime()) + ".");
- DEBUG_EXPR(QUEUE_COMP,MedPrio,message);
- DEBUG_NEWLINE(QUEUE_COMP,HighPrio);
-
- // Schedule the wakeup
- if (m_consumer_ptr != NULL) {
- g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time);
- } else {
- WARN_EXPR(*this);
- WARN_EXPR(m_name);
- ERROR_MSG("No consumer");
- }
}
-int MessageBuffer::dequeue_getDelayCycles(MsgPtr& message)
+int
+MessageBuffer::dequeue_getDelayCycles(MsgPtr& message)
{
- int delay_cycles = -1; // null value
+ int delay_cycles = -1; // null value
- dequeue(message);
+ dequeue(message);
- // get the delay cycles
- delay_cycles = setAndReturnDelayCycles(message);
+ // get the delay cycles
+ delay_cycles = setAndReturnDelayCycles(message);
- assert(delay_cycles >= 0);
- return delay_cycles;
+ assert(delay_cycles >= 0);
+ return delay_cycles;
}
-void MessageBuffer::dequeue(MsgPtr& message)
+void
+MessageBuffer::dequeue(MsgPtr& message)
{
- DEBUG_MSG(QUEUE_COMP,MedPrio,"dequeue from " + m_name);
- message = m_prio_heap.peekMin().m_msgptr;
+ DEBUG_MSG(QUEUE_COMP, MedPrio, "dequeue from " + m_name);
+ message = m_prio_heap.peekMin().m_msgptr;
- pop();
- DEBUG_EXPR(QUEUE_COMP,MedPrio,message);
+ pop();
+ DEBUG_EXPR(QUEUE_COMP, MedPrio, message);
}
-int MessageBuffer::dequeue_getDelayCycles()
+int
+MessageBuffer::dequeue_getDelayCycles()
{
- int delay_cycles = -1; // null value
+ int delay_cycles = -1; // null value
- // get MsgPtr of the message about to be dequeued
- MsgPtr message = m_prio_heap.peekMin().m_msgptr;
+ // get MsgPtr of the message about to be dequeued
+ MsgPtr message = m_prio_heap.peekMin().m_msgptr;
- // get the delay cycles
- delay_cycles = setAndReturnDelayCycles(message);
+ // get the delay cycles
+ delay_cycles = setAndReturnDelayCycles(message);
- dequeue();
+ dequeue();
- assert(delay_cycles >= 0);
- return delay_cycles;
+ assert(delay_cycles >= 0);
+ return delay_cycles;
}
-void MessageBuffer::pop()
+void
+MessageBuffer::pop()
{
- DEBUG_MSG(QUEUE_COMP,MedPrio,"pop from " + m_name);
- assert(isReady());
- m_prio_heap.extractMin();
- // record previous size and time so the current buffer size isn't adjusted until next cycle
- if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) {
- m_size_at_cycle_start = m_size;
- m_time_last_time_pop = g_eventQueue_ptr->getTime();
- }
- m_size--;
+ DEBUG_MSG(QUEUE_COMP, MedPrio, "pop from " + m_name);
+ assert(isReady());
+ m_prio_heap.extractMin();
+ // record previous size and time so the current buffer size isn't
+ // adjusted until next cycle
+ if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) {
+ m_size_at_cycle_start = m_size;
+ m_time_last_time_pop = g_eventQueue_ptr->getTime();
+ }
+ m_size--;
}
-void MessageBuffer::clear()
+void
+MessageBuffer::clear()
{
- while(m_prio_heap.size() > 0){
- m_prio_heap.extractMin();
- }
+ while(m_prio_heap.size() > 0){
+ m_prio_heap.extractMin();
+ }
- ASSERT(m_prio_heap.size() == 0);
+ ASSERT(m_prio_heap.size() == 0);
- m_msg_counter = 0;
- m_size = 0;
- m_time_last_time_enqueue = 0;
- m_time_last_time_pop = 0;
- m_size_at_cycle_start = 0;
- m_msgs_this_cycle = 0;
+ m_msg_counter = 0;
+ m_size = 0;
+ m_time_last_time_enqueue = 0;
+ m_time_last_time_pop = 0;
+ m_size_at_cycle_start = 0;
+ m_msgs_this_cycle = 0;
}
-void MessageBuffer::recycle()
+void
+MessageBuffer::recycle()
{
- DEBUG_MSG(QUEUE_COMP,MedPrio,"recycling " + m_name);
- assert(isReady());
- MessageBufferNode node = m_prio_heap.extractMin();
- node.m_time = g_eventQueue_ptr->getTime() + m_recycle_latency;
- m_prio_heap.insert(node);
- g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, g_eventQueue_ptr->getTime() + m_recycle_latency);
+ DEBUG_MSG(QUEUE_COMP, MedPrio, "recycling " + m_name);
+ assert(isReady());
+ MessageBufferNode node = m_prio_heap.extractMin();
+ node.m_time = g_eventQueue_ptr->getTime() + m_recycle_latency;
+ m_prio_heap.insert(node);
+ g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr,
+ g_eventQueue_ptr->getTime() + m_recycle_latency);
}
-int MessageBuffer::setAndReturnDelayCycles(MsgPtr& message)
+int
+MessageBuffer::setAndReturnDelayCycles(MsgPtr& message)
{
- int delay_cycles = -1; // null value
+ int delay_cycles = -1; // null value
- // get the delay cycles of the message at the top of the queue
- Message* msg_ptr = message.ref();
+ // get the delay cycles of the message at the top of the queue
+ Message* msg_ptr = message.ref();
- // this function should only be called on dequeue
- // ensure the msg hasn't been enqueued
- assert(msg_ptr->getLastEnqueueTime() <= g_eventQueue_ptr->getTime());
- msg_ptr->setDelayedCycles((g_eventQueue_ptr->getTime() - msg_ptr->getLastEnqueueTime())+msg_ptr->getDelayedCycles());
- delay_cycles = msg_ptr->getDelayedCycles();
+ // this function should only be called on dequeue
+ // ensure the msg hasn't been enqueued
+ assert(msg_ptr->getLastEnqueueTime() <= g_eventQueue_ptr->getTime());
+ msg_ptr->setDelayedCycles(g_eventQueue_ptr->getTime() -
+ msg_ptr->getLastEnqueueTime() +
+ msg_ptr->getDelayedCycles());
+ delay_cycles = msg_ptr->getDelayedCycles();
- assert(delay_cycles >= 0);
- return delay_cycles;
+ assert(delay_cycles >= 0);
+ return delay_cycles;
}
-void MessageBuffer::print(ostream& out) const
+void
+MessageBuffer::print(ostream& out) const
{
- out << "[MessageBuffer: ";
- if (m_consumer_ptr != NULL) {
- out << " consumer-yes ";
- }
- out << m_prio_heap << "] " << m_name << endl;
+ out << "[MessageBuffer: ";
+ if (m_consumer_ptr != NULL) {
+ out << " consumer-yes ";
+ }
+ out << m_prio_heap << "] " << m_name << endl;
}
-void MessageBuffer::printStats(ostream& out)
+void
+MessageBuffer::printStats(ostream& out)
{
- out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter << " full:" << m_not_avail_count << endl;
+ out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter
+ << " full:" << m_not_avail_count << endl;
}
-
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * $Id$
- *
- * Description: Unordered buffer of messages that can be inserted such
+ * Unordered buffer of messages that can be inserted such
* that they can be dequeued after a given delta time has expired.
- *
*/
-#ifndef MESSAGEBUFFER_H
-#define MESSAGEBUFFER_H
+#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__
+#define __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__
#include <iostream>
#include <string>
-#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/PrioHeap.hh"
+#include "mem/gems_common/util.hh"
#include "mem/ruby/buffers/MessageBufferNode.hh"
#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/slicc_interface/Message.hh"
-#include "mem/gems_common/PrioHeap.hh"
-#include "mem/gems_common/util.hh"
-class MessageBuffer {
-public:
- // Constructors
- MessageBuffer(const std::string &name = "");
-
- // ~MessageBuffer()
-
- // Public Methods
-
- static void printConfig(std::ostream& out) {}
- void setRecycleLatency(int recycle_latency) { m_recycle_latency = recycle_latency; }
-
- // TRUE if head of queue timestamp <= SystemTime
- bool isReady() const {
- return ((m_prio_heap.size() > 0) &&
- (m_prio_heap.peekMin().m_time <= g_eventQueue_ptr->getTime()));
- }
-
- void delayHead() {
- MessageBufferNode node = m_prio_heap.extractMin();
- enqueue(node.m_msgptr, 1);
- }
-
- bool areNSlotsAvailable(int n);
- int getPriority() { return m_priority_rank; }
- void setPriority(int rank) { m_priority_rank = rank; }
- void setConsumer(Consumer* consumer_ptr) { ASSERT(m_consumer_ptr==NULL); m_consumer_ptr = consumer_ptr; }
- void setDescription(const std::string& name) { m_name = name; }
- std::string getDescription() { return m_name;}
-
- Consumer* getConsumer() { return m_consumer_ptr; }
-
- const Message* peekAtHeadOfQueue() const;
- const Message* peek() const { return peekAtHeadOfQueue(); }
- const MsgPtr getMsgPtrCopy() const;
- const MsgPtr& peekMsgPtr() const { assert(isReady()); return m_prio_heap.peekMin().m_msgptr; }
- const MsgPtr& peekMsgPtrEvenIfNotReady() const {return m_prio_heap.peekMin().m_msgptr; }
-
- void enqueue(const MsgPtr& message) { enqueue(message, 1); }
- void enqueue(const MsgPtr& message, Time delta);
- // void enqueueAbsolute(const MsgPtr& message, Time absolute_time);
- int dequeue_getDelayCycles(MsgPtr& message); // returns delay cycles of the message
- void dequeue(MsgPtr& message);
- int dequeue_getDelayCycles(); // returns delay cycles of the message
- void dequeue() { pop(); }
- void pop();
- void recycle();
- bool isEmpty() const { return m_prio_heap.size() == 0; }
-
- void setOrdering(bool order) { m_strict_fifo = order; m_ordering_set = true; }
- void setSize(int size) {m_max_size = size;}
- int getSize();
- void setRandomization(bool random_flag) { m_randomization = random_flag; }
-
- void clear();
-
- void print(std::ostream& out) const;
- void printStats(std::ostream& out);
- void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; }
-
-private:
- //added by SS
- int m_recycle_latency;
-
- // Private Methods
- int setAndReturnDelayCycles(MsgPtr& message);
-
- // Private copy constructor and assignment operator
- MessageBuffer(const MessageBuffer& obj);
- MessageBuffer& operator=(const MessageBuffer& obj);
-
- // Data Members (m_ prefix)
- Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL
- PrioHeap<MessageBufferNode> m_prio_heap;
- std::string m_name;
-
- int m_max_size;
- int m_size;
-
- Time m_time_last_time_size_checked;
- int m_size_last_time_size_checked;
-
- // variables used so enqueues appear to happen imediately, while pop happen the next cycle
- Time m_time_last_time_enqueue;
- Time m_time_last_time_pop;
- int m_size_at_cycle_start;
- int m_msgs_this_cycle;
-
- int m_not_avail_count; // count the # of times I didn't have N slots available
- int m_msg_counter;
- int m_priority_rank;
- bool m_strict_fifo;
- bool m_ordering_set;
- bool m_randomization;
- Time m_last_arrival_time;
+class MessageBuffer
+{
+ public:
+ MessageBuffer(const std::string &name = "");
+
+ static void printConfig(std::ostream& out) {}
+ void
+ setRecycleLatency(int recycle_latency)
+ {
+ m_recycle_latency = recycle_latency;
+ }
+
+ // TRUE if head of queue timestamp <= SystemTime
+ bool
+ isReady() const
+ {
+ return ((m_prio_heap.size() > 0) &&
+ (m_prio_heap.peekMin().m_time <= g_eventQueue_ptr->getTime()));
+ }
+
+ void
+ delayHead()
+ {
+ MessageBufferNode node = m_prio_heap.extractMin();
+ enqueue(node.m_msgptr, 1);
+ }
+
+ bool areNSlotsAvailable(int n);
+ int getPriority() { return m_priority_rank; }
+ void setPriority(int rank) { m_priority_rank = rank; }
+ void setConsumer(Consumer* consumer_ptr)
+ {
+ ASSERT(m_consumer_ptr == NULL);
+ m_consumer_ptr = consumer_ptr;
+ }
+
+ void setDescription(const std::string& name) { m_name = name; }
+ std::string getDescription() { return m_name;}
+
+ Consumer* getConsumer() { return m_consumer_ptr; }
+
+ const Message* peekAtHeadOfQueue() const;
+ const Message* peek() const { return peekAtHeadOfQueue(); }
+ const MsgPtr getMsgPtrCopy() const;
+
+ const MsgPtr&
+ peekMsgPtr() const
+ {
+ assert(isReady());
+ return m_prio_heap.peekMin().m_msgptr;
+ }
+
+ const MsgPtr&
+ peekMsgPtrEvenIfNotReady() const
+ {
+ return m_prio_heap.peekMin().m_msgptr;
+ }
+
+ void enqueue(const MsgPtr& message) { enqueue(message, 1); }
+ void enqueue(const MsgPtr& message, Time delta);
+ // void enqueueAbsolute(const MsgPtr& message, Time absolute_time);
+ int dequeue_getDelayCycles(MsgPtr& message); // returns delay
+ // cycles of the
+ // message
+ void dequeue(MsgPtr& message);
+ int dequeue_getDelayCycles(); // returns delay cycles of the message
+ void dequeue() { pop(); }
+ void pop();
+ void recycle();
+ bool isEmpty() const { return m_prio_heap.size() == 0; }
+
+ void
+ setOrdering(bool order)
+ {
+ m_strict_fifo = order;
+ m_ordering_set = true;
+ }
+ void setSize(int size) { m_max_size = size; }
+ int getSize();
+ void setRandomization(bool random_flag) { m_randomization = random_flag; }
+
+ void clear();
+
+ void print(std::ostream& out) const;
+ void printStats(std::ostream& out);
+ void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; }
+
+ private:
+ //added by SS
+ int m_recycle_latency;
+
+ // Private Methods
+ int setAndReturnDelayCycles(MsgPtr& message);
+
+ // Private copy constructor and assignment operator
+ MessageBuffer(const MessageBuffer& obj);
+ MessageBuffer& operator=(const MessageBuffer& obj);
+
+ // Data Members (m_ prefix)
+ Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL
+ PrioHeap<MessageBufferNode> m_prio_heap;
+ std::string m_name;
+
+ int m_max_size;
+ int m_size;
+
+ Time m_time_last_time_size_checked;
+ int m_size_last_time_size_checked;
+
+ // variables used so enqueues appear to happen imediately, while
+ // pop happen the next cycle
+ Time m_time_last_time_enqueue;
+ Time m_time_last_time_pop;
+ int m_size_at_cycle_start;
+ int m_msgs_this_cycle;
+
+ int m_not_avail_count; // count the # of times I didn't have N
+ // slots available
+ int m_msg_counter;
+ int m_priority_rank;
+ bool m_strict_fifo;
+ bool m_ordering_set;
+ bool m_randomization;
+ Time m_last_arrival_time;
};
-// Output operator declaration
-//template <class TYPE>
-std::ostream& operator<<(std::ostream& out, const MessageBuffer& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const MessageBuffer& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const MessageBuffer& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //MESSAGEBUFFER_H
+#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
void
MessageBufferNode::print(std::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 << "]";
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MESSAGEBUFFERNODE_H
-#define MESSAGEBUFFERNODE_H
+#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFERNODE_HH__
+#define __MEM_RUBY_BUFFERS_MESSAGEBUFFERNODE_HH__
#include <iostream>
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/Message.hh"
-class MessageBufferNode {
-public:
- // Constructors
- MessageBufferNode() { m_time = 0; m_msg_counter = 0; }
- MessageBufferNode(const Time& time, int counter, const MsgPtr& msgptr)
- { m_time = time; m_msgptr = msgptr; m_msg_counter = counter; }
- // Destructor
- //~MessageBufferNode();
+class MessageBufferNode
+{
+ public:
+ MessageBufferNode()
+ {
+ m_time = 0;
+ m_msg_counter = 0;
+ }
- // Public Methods
- void print(std::ostream& out) const;
-private:
- // Private Methods
+ MessageBufferNode(const Time& time, int counter, const MsgPtr& msgptr)
+ {
+ m_time = time;
+ m_msgptr = msgptr;
+ m_msg_counter = counter;
+ }
- // Default copy constructor and assignment operator
- // MessageBufferNode(const MessageBufferNode& obj);
- // MessageBufferNode& operator=(const MessageBufferNode& obj);
+ void print(std::ostream& out) const;
- // Data Members (m_ prefix)
-public:
- Time m_time;
- int m_msg_counter; // FIXME, should this be a 64-bit value?
- MsgPtr m_msgptr;
+ public:
+ Time m_time;
+ int m_msg_counter; // FIXME, should this be a 64-bit value?
+ MsgPtr m_msgptr;
};
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const MessageBufferNode& obj);
-
-// ******************* Definitions *******************
-
-inline extern bool node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2);
-
-inline extern
-bool node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2)
+inline bool
+node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2)
{
- if (n1.m_time == n2.m_time) {
- assert(n1.m_msg_counter != n2.m_msg_counter);
- return (n1.m_msg_counter <= n2.m_msg_counter);
- } else {
- return (n1.m_time <= n2.m_time);
- }
+ if (n1.m_time == n2.m_time) {
+ assert(n1.m_msg_counter != n2.m_msg_counter);
+ return (n1.m_msg_counter <= n2.m_msg_counter);
+ } else {
+ return (n1.m_time <= n2.m_time);
+ }
}
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const MessageBufferNode& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const MessageBufferNode& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //MESSAGEBUFFERNODE_H
+#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFERNODE_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
#include "mem/ruby/common/Address.hh"
-void Address::output(ostream& out) const
+void
+Address::output(ostream& out) const
{
- // Note: this outputs addresses in the form "ffff", not "0xffff".
- // This code should always be able to write out addresses in a
- // format that can be read in by the below input() method. Please
- // don't change this without talking to Milo first.
- out << hex << m_address << dec;
+ // Note: this outputs addresses in the form "ffff", not "0xffff".
+ // This code should always be able to write out addresses in a
+ // format that can be read in by the below input() method. Please
+ // don't change this without talking to Milo first.
+ out << hex << m_address << dec;
}
-void Address::input(istream& in)
+void
+Address::input(istream& in)
{
- // Note: this only works with addresses in the form "ffff", not
- // "0xffff". This code should always be able to read in addresses
- // written out by the above output() method. Please don't change
- // this without talking to Milo first.
- in >> hex >> m_address >> dec;
+ // Note: this only works with addresses in the form "ffff", not
+ // "0xffff". This code should always be able to read in addresses
+ // written out by the above output() method. Please don't change
+ // this without talking to Milo first.
+ in >> hex >> m_address >> dec;
}
Address::Address(const Address& obj)
{
- m_address = obj.m_address;
+ m_address = obj.m_address;
}
-Address& Address::operator=(const Address& obj)
+Address&
+Address::operator=(const Address& obj)
{
- if (this == &obj) {
- // assert(false);
- } else {
- m_address = obj.m_address;
- }
- return *this;
+ if (this == &obj) {
+ // assert(false);
+ } else {
+ m_address = obj.m_address;
+ }
+ return *this;
}
-
/*
* Copyright (c) 1999 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
-#ifndef ADDRESS_H
-#define ADDRESS_H
+#ifndef __MEM_RUBY_COMMON_ADDRESS_HH__
+#define __MEM_RUBY_COMMON_ADDRESS_HH__
#include <iomanip>
#include "base/hashmap.hh"
#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/ruby/system/NodeID.hh"
#include "mem/ruby/system/MachineID.hh"
+#include "mem/ruby/system/NodeID.hh"
+#include "mem/ruby/system/System.hh"
const int ADDRESS_WIDTH = 64; // address width in bytes
typedef Address PhysAddress;
typedef Address VirtAddress;
-class Address {
-public:
- // Constructors
- Address() { m_address = 0; }
- explicit Address(physical_address_t address) { m_address = address; }
-
- Address(const Address& obj);
- Address& operator=(const Address& obj);
-
- // Destructor
- // ~Address();
-
- // Public Methods
-
- void setAddress(physical_address_t address) { m_address = address; }
- physical_address_t getAddress() const {return m_address;}
- // selects bits inclusive
- physical_address_t bitSelect(int small, int big) const;
- physical_address_t bitRemove(int small, int big) const;
- physical_address_t maskLowOrderBits(int number) const;
- physical_address_t maskHighOrderBits(int number) const;
- physical_address_t shiftLowOrderBits(int number) const;
- physical_address_t getLineAddress() const
- { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); }
- physical_address_t getOffset() const
- { return bitSelect(0, RubySystem::getBlockSizeBits()-1); }
-
- void makeLineAddress() { m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); }
- // returns the next stride address based on line address
- void makeNextStrideAddress( int stride) {
- m_address = maskLowOrderBits(RubySystem::getBlockSizeBits())
- + RubySystem::getBlockSizeBytes()*stride;
- }
- int getBankSetNum() const;
- int getBankSetDist() const;
+class Address
+{
+ public:
+ Address()
+ : m_address(0)
+ { }
+
+ explicit
+ Address(physical_address_t address)
+ : m_address(address)
+ { }
+
+ Address(const Address& obj);
+ Address& operator=(const Address& obj);
+
+ void setAddress(physical_address_t address) { m_address = address; }
+ physical_address_t getAddress() const {return m_address;}
+ // selects bits inclusive
+ physical_address_t bitSelect(int small, int big) const;
+ physical_address_t bitRemove(int small, int big) const;
+ physical_address_t maskLowOrderBits(int number) const;
+ physical_address_t maskHighOrderBits(int number) const;
+ physical_address_t shiftLowOrderBits(int number) const;
+
+ physical_address_t
+ getLineAddress() const
+ {
+ return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH);
+ }
- Index memoryModuleIndex() const;
+ physical_address_t
+ getOffset() const
+ {
+ return bitSelect(0, RubySystem::getBlockSizeBits() - 1);
+ }
- void print(ostream& out) const;
- void output(ostream& out) const;
- void input(istream& in);
+ void
+ makeLineAddress()
+ {
+ m_address = maskLowOrderBits(RubySystem::getBlockSizeBits());
+ }
- void setOffset( int offset ){
- // first, zero out the offset bits
- makeLineAddress();
- m_address |= (physical_address_t) offset;
- }
+ // returns the next stride address based on line address
+ void
+ makeNextStrideAddress(int stride)
+ {
+ m_address = maskLowOrderBits(RubySystem::getBlockSizeBits())
+ + RubySystem::getBlockSizeBytes()*stride;
+ }
-private:
- // Private Methods
+ int getBankSetNum() const;
+ int getBankSetDist() const;
- // Private copy constructor and assignment operator
- // Address(const Address& obj);
- // Address& operator=(const Address& obj);
+ Index memoryModuleIndex() const;
- // Data Members (m_ prefix)
- physical_address_t m_address;
-};
+ void print(ostream& out) const;
+ void output(ostream& out) const;
+ void input(istream& in);
-inline
-Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; }
+ void
+ setOffset(int offset)
+ {
+ // first, zero out the offset bits
+ makeLineAddress();
+ m_address |= (physical_address_t) offset;
+ }
-// Output operator declaration
-ostream& operator<<(ostream& out, const Address& obj);
-// comparison operator declaration
-bool operator==(const Address& obj1, const Address& obj2);
-bool operator!=(const Address& obj1, const Address& obj2);
-bool operator<(const Address& obj1, const Address& obj2);
-/* Address& operator=(const physical_address_t address); */
+ private:
+ physical_address_t m_address;
+};
-inline
-bool operator<(const Address& obj1, const Address& obj2)
+inline Address
+line_address(const Address& addr)
{
- return obj1.getAddress() < obj2.getAddress();
+ Address temp(addr);
+ temp.makeLineAddress();
+ return temp;
}
-// ******************* Definitions *******************
+inline bool
+operator<(const Address& obj1, const Address& obj2)
+{
+ return obj1.getAddress() < obj2.getAddress();
+}
-// Output operator definition
-inline
-ostream& operator<<(ostream& out, const Address& obj)
+inline ostream&
+operator<<(ostream& out, const Address& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-inline
-bool operator==(const Address& obj1, const Address& obj2)
+inline bool
+operator==(const Address& obj1, const Address& obj2)
{
- return (obj1.getAddress() == obj2.getAddress());
+ return (obj1.getAddress() == obj2.getAddress());
}
-inline
-bool operator!=(const Address& obj1, const Address& obj2)
+inline bool
+operator!=(const Address& obj1, const Address& obj2)
{
- return (obj1.getAddress() != obj2.getAddress());
+ return (obj1.getAddress() != obj2.getAddress());
}
-inline
-physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive
+// rips bits inclusive
+inline physical_address_t
+Address::bitSelect(int small, int big) const
{
- physical_address_t mask;
- assert((unsigned)big >= (unsigned)small);
+ physical_address_t mask;
+ assert((unsigned)big >= (unsigned)small);
- if (big >= ADDRESS_WIDTH - 1) {
- return (m_address >> small);
- } else {
- mask = ~((physical_address_t)~0 << (big + 1));
- // FIXME - this is slow to manipulate a 64-bit number using 32-bits
- physical_address_t partial = (m_address & mask);
- return (partial >> small);
- }
+ if (big >= ADDRESS_WIDTH - 1) {
+ return (m_address >> small);
+ } else {
+ mask = ~((physical_address_t)~0 << (big + 1));
+ // FIXME - this is slow to manipulate a 64-bit number using 32-bits
+ physical_address_t partial = (m_address & mask);
+ return (partial >> small);
+ }
}
// removes bits inclusive
-inline
-physical_address_t Address::bitRemove(int small, int big) const
+inline physical_address_t
+Address::bitRemove(int small, int big) const
{
physical_address_t mask;
assert((unsigned)big >= (unsigned)small);
mask = (physical_address_t)~0 << (big + 1);
physical_address_t higher_bits = m_address & mask;
- //
// Shift the valid high bits over the removed section
- //
higher_bits = higher_bits >> (big - small);
return (higher_bits | lower_bits);
}
}
-inline
-physical_address_t Address::maskLowOrderBits(int number) const
+inline physical_address_t
+Address::maskLowOrderBits(int number) const
{
physical_address_t mask;
if (number >= ADDRESS_WIDTH - 1) {
- mask = ~0;
+ mask = ~0;
} else {
- mask = (physical_address_t)~0 << number;
+ mask = (physical_address_t)~0 << number;
}
return (m_address & mask);
}
-inline
-physical_address_t Address::maskHighOrderBits(int number) const
+inline physical_address_t
+Address::maskHighOrderBits(int number) const
{
- physical_address_t mask;
+ physical_address_t mask;
- if (number >= ADDRESS_WIDTH - 1) {
- mask = ~0;
- } else {
- mask = (physical_address_t)~0 >> number;
- }
- return (m_address & mask);
+ if (number >= ADDRESS_WIDTH - 1) {
+ mask = ~0;
+ } else {
+ mask = (physical_address_t)~0 >> number;
+ }
+ return (m_address & mask);
}
-inline
-physical_address_t Address::shiftLowOrderBits(int number) const
+inline physical_address_t
+Address::shiftLowOrderBits(int number) const
{
- return (m_address >> number);
+ return (m_address >> number);
}
-inline
-integer_t Address::memoryModuleIndex() const
+inline integer_t
+Address::memoryModuleIndex() const
{
- integer_t index = bitSelect(RubySystem::getBlockSizeBits()+RubySystem::getMemorySizeBits(), ADDRESS_WIDTH);
- assert (index >= 0);
- return index;
-
- // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS);
- // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1);
-
- //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS));
-
- /*
- Round-robin mapping of addresses, at page size granularity
+ integer_t index =
+ bitSelect(RubySystem::getBlockSizeBits() +
+ RubySystem::getMemorySizeBits(), ADDRESS_WIDTH);
+ assert (index >= 0);
+ return index;
+
+ // Index indexHighPortion =
+ // address.bitSelect(MEMORY_SIZE_BITS - 1,
+ // PAGE_SIZE_BITS + NUMBER_OF_MEMORY_MODULE_BITS);
+ // Index indexLowPortion =
+ // address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS - 1);
+ //
+ // Index index = indexLowPortion |
+ // (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS));
+
+ /*
+ Round-robin mapping of addresses, at page size granularity
ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS
| | | |
indexHighPortion indexLowPortion
<------->
NUMBER_OF_MEMORY_MODULE_BITS
- */
+ */
}
-inline
-void Address::print(ostream& out) const
+inline void
+Address::print(ostream& out) const
{
using namespace std;
- out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush;
+ out << "[" << hex << "0x" << m_address << "," << " line 0x"
+ << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]"
+ << flush;
}
class Address;
namespace __hash_namespace {
- template <> struct hash<Address>
- {
- size_t operator()(const Address &s) const { return (size_t) s.getAddress(); }
- };
-}
-namespace std {
- template <> struct equal_to<Address>
- {
- bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; }
- };
-}
+template <> struct hash<Address>
+{
+ size_t
+ operator()(const Address &s) const
+ {
+ return (size_t)s.getAddress();
+ }
+};
+/* namespace __hash_namespace */ }
-#endif //ADDRESS_H
+namespace std {
+template <> struct equal_to<Address>
+{
+ bool
+ operator()(const Address& s1, const Address& s2) const
+ {
+ return s1 == s2;
+ }
+};
+/* namespace std */ }
+#endif // __MEM_RUBY_COMMON_ADDRESS_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * $Id$
- *
- * Description: This is the virtual base class of all classes that can
- * be the targets of wakeup events. There is only two methods,
- * wakeup() and print() and no data members.
- *
+ * This is the virtual base class of all classes that can be the
+ * targets of wakeup events. There is only two methods, wakeup() and
+ * print() and no data members.
*/
-#ifndef CONSUMER_H
-#define CONSUMER_H
+#ifndef __MEM_RUBY_COMMON_CONSUMER_HH__
+#define __MEM_RUBY_COMMON_CONSUMER_HH__
#include <iostream>
#include <set>
class MessageBuffer;
-class Consumer {
-public:
- // Constructors
- Consumer() { m_last_scheduled_wakeup = 0; m_last_wakeup = 0; }
-
- // Destructor
- virtual ~Consumer() { }
-
- // Public Methods - pure virtual methods
- void triggerWakeup(RubyEventQueue * eventQueue)
- {
- Time time = eventQueue->getTime();
- if (m_last_wakeup != time) {
- wakeup(); m_last_wakeup = time;
- }
- }
- virtual void wakeup() = 0;
- virtual void print(std::ostream& out) const = 0;
- const Time& getLastScheduledWakeup() const
- {
- return m_last_scheduled_wakeup;
- }
- void setLastScheduledWakeup(const Time& time)
- {
- m_last_scheduled_wakeup = time;
- }
- bool alreadyScheduled(Time time)
- {
- return (m_scheduled_wakeups.find(time) != m_scheduled_wakeups.end());
- }
- void insertScheduledWakeupTime(Time time)
- {
- m_scheduled_wakeups.insert(time);
- }
- void removeScheduledWakeupTime(Time time)
- {
- assert(alreadyScheduled(time));
- m_scheduled_wakeups.erase(time);
- }
-
-private:
- // Private Methods
-
- // Data Members (m_ prefix)
- Time m_last_scheduled_wakeup;
- std::set<Time> m_scheduled_wakeups;
- Time m_last_wakeup;
-};
+class Consumer
+{
+ public:
+ Consumer()
+ : m_last_scheduled_wakeup(0), m_last_wakeup(0)
+ {
+ }
+
+ virtual
+ ~Consumer()
+ { }
+
+ void
+ triggerWakeup(RubyEventQueue *eventQueue)
+ {
+ Time time = eventQueue->getTime();
+ if (m_last_wakeup != time) {
+ wakeup();
+ m_last_wakeup = time;
+ }
+ }
-// Output operator declaration
-inline extern
-std::ostream& operator<<(std::ostream& out, const Consumer& obj);
+ virtual void wakeup() = 0;
+ virtual void print(std::ostream& out) const = 0;
-// ******************* Definitions *******************
+ const Time&
+ getLastScheduledWakeup() const
+ {
+ return m_last_scheduled_wakeup;
+ }
+
+ void
+ setLastScheduledWakeup(const Time& time)
+ {
+ m_last_scheduled_wakeup = time;
+ }
+
+ bool
+ alreadyScheduled(Time time)
+ {
+ return m_scheduled_wakeups.find(time) != m_scheduled_wakeups.end();
+ }
+
+ void
+ insertScheduledWakeupTime(Time time)
+ {
+ m_scheduled_wakeups.insert(time);
+ }
+
+ void
+ removeScheduledWakeupTime(Time time)
+ {
+ assert(alreadyScheduled(time));
+ m_scheduled_wakeups.erase(time);
+ }
+
+ private:
+ Time m_last_scheduled_wakeup;
+ std::set<Time> m_scheduled_wakeups;
+ Time m_last_wakeup;
+};
-// Output operator definition
-inline extern
-std::ostream& operator<<(std::ostream& out, const Consumer& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const Consumer& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //CONSUMER_H
+#endif // __MEM_RUBY_COMMON_CONSUMER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
DataBlock &
DataBlock::operator=(const DataBlock & obj)
{
- if (this == &obj) {
- // assert(false);
- } else {
- if (!m_alloc)
- m_data = new uint8[RubySystem::getBlockSizeBytes()];
- memcpy(m_data, obj.m_data, RubySystem::getBlockSizeBytes());
- m_alloc = true;
- }
- return *this;
+ if (this == &obj) {
+ // assert(false);
+ } else {
+ if (!m_alloc)
+ m_data = new uint8[RubySystem::getBlockSizeBytes()];
+ memcpy(m_data, obj.m_data, RubySystem::getBlockSizeBytes());
+ m_alloc = true;
+ }
+
+ return *this;
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DATABLOCK_H
-#define DATABLOCK_H
+#ifndef __MEM_RUBY_COMMON_DATABLOCK_HH__
+#define __MEM_RUBY_COMMON_DATABLOCK_HH__
#include <iomanip>
#include <iostream>
+#include "mem/gems_common/Vector.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/System.hh"
-#include "mem/gems_common/Vector.hh"
-class DataBlock {
- public:
- // Constructors
- DataBlock() {alloc();}
- DataBlock(const DataBlock & cp) {
- m_data = new uint8[RubySystem::getBlockSizeBytes()];
- memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes());
- m_alloc = true;
- }
+class DataBlock
+{
+ public:
+ DataBlock()
+ {
+ alloc();
+ }
- // Destructor
- ~DataBlock() {
- if(m_alloc) {
- delete [] m_data;
+ DataBlock(const DataBlock &cp)
+ {
+ m_data = new uint8[RubySystem::getBlockSizeBytes()];
+ memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes());
+ m_alloc = true;
}
- }
-
- DataBlock& operator=(const DataBlock& obj);
-
- // Public Methods
- void assign(uint8* data);
-
- void clear();
- uint8 getByte(int whichByte) const;
- const uint8* getData(int offset, int len) const;
- void setByte(int whichByte, uint8 data);
- void setData(uint8* data, int offset, int len);
- void copyPartial(const DataBlock & dblk, int offset, int len);
- bool equal(const DataBlock& obj) const;
- void print(std::ostream& out) const;
-
-private:
- void alloc();
- // Data Members (m_ prefix)
- uint8* m_data;
- bool m_alloc;
-};
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const DataBlock& obj);
+ ~DataBlock()
+ {
+ if (m_alloc)
+ delete [] m_data;
+ }
+
+ DataBlock& operator=(const DataBlock& obj);
+
+ void assign(uint8* data);
-bool operator==(const DataBlock& obj1, const DataBlock& obj2);
+ void clear();
+ uint8 getByte(int whichByte) const;
+ const uint8* getData(int offset, int len) const;
+ void setByte(int whichByte, uint8 data);
+ void setData(uint8* data, int offset, int len);
+ void copyPartial(const DataBlock & dblk, int offset, int len);
+ bool equal(const DataBlock& obj) const;
+ void print(std::ostream& out) const;
-// inline functions for speed
+ private:
+ void alloc();
+ uint8* m_data;
+ bool m_alloc;
+};
-inline
-void DataBlock::assign(uint8* data)
+inline void
+DataBlock::assign(uint8* data)
{
- if (m_alloc) {
- delete [] m_data;
- }
- m_data = data;
- m_alloc = false;
+ if (m_alloc) {
+ delete [] m_data;
+ }
+ m_data = data;
+ m_alloc = false;
}
-inline
-void DataBlock::alloc()
+inline void
+DataBlock::alloc()
{
- m_data = new uint8[RubySystem::getBlockSizeBytes()];
- m_alloc = true;
- clear();
+ m_data = new uint8[RubySystem::getBlockSizeBytes()];
+ m_alloc = true;
+ clear();
}
-inline
-void DataBlock::clear()
+inline void
+DataBlock::clear()
{
- memset(m_data, 0, RubySystem::getBlockSizeBytes());
+ memset(m_data, 0, RubySystem::getBlockSizeBytes());
}
-inline
-bool DataBlock::equal(const DataBlock& obj) const
+inline bool
+DataBlock::equal(const DataBlock& obj) const
{
- return !memcmp(m_data, obj.m_data, RubySystem::getBlockSizeBytes());
+ return !memcmp(m_data, obj.m_data, RubySystem::getBlockSizeBytes());
}
-inline
-void DataBlock::print(std::ostream& out) const
+inline void
+DataBlock::print(std::ostream& out) const
{
- using namespace std;
-
- int size = RubySystem::getBlockSizeBytes();
- out << "[ ";
- for (int i = 0; i < size; i++) {
- out << setw(2) << setfill('0') << hex << "0x" << (int)m_data[i] << " ";
- out << setfill(' ');
- }
- out << dec << "]" << flush;
+ using namespace std;
+
+ int size = RubySystem::getBlockSizeBytes();
+ out << "[ ";
+ for (int i = 0; i < size; i++) {
+ out << setw(2) << setfill('0') << hex << "0x" << (int)m_data[i] << " ";
+ out << setfill(' ');
+ }
+ out << dec << "]" << flush;
}
-inline
-uint8 DataBlock::getByte(int whichByte) const
+inline uint8
+DataBlock::getByte(int whichByte) const
{
- return m_data[whichByte];
+ return m_data[whichByte];
}
-inline
-const uint8* DataBlock::getData(int offset, int len) const
+inline const uint8*
+DataBlock::getData(int offset, int len) const
{
- assert(offset + len <= RubySystem::getBlockSizeBytes());
- return &m_data[offset];
+ assert(offset + len <= RubySystem::getBlockSizeBytes());
+ return &m_data[offset];
}
-inline
-void DataBlock::setByte(int whichByte, uint8 data)
+inline void
+DataBlock::setByte(int whichByte, uint8 data)
{
m_data[whichByte] = data;
}
-inline
-void DataBlock::setData(uint8* data, int offset, int len)
+inline void
+DataBlock::setData(uint8* data, int offset, int len)
{
- assert(offset + len <= RubySystem::getBlockSizeBytes());
- memcpy(&m_data[offset], data, len);
+ assert(offset + len <= RubySystem::getBlockSizeBytes());
+ memcpy(&m_data[offset], data, len);
}
-inline
-void DataBlock::copyPartial(const DataBlock & dblk, int offset, int len)
+inline void
+DataBlock::copyPartial(const DataBlock & dblk, int offset, int len)
{
- setData(&dblk.m_data[offset], offset, len);
+ setData(&dblk.m_data[offset], offset, len);
}
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const DataBlock& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const DataBlock& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-extern inline
-bool operator==(const DataBlock& obj1,const DataBlock& obj2)
+inline bool
+operator==(const DataBlock& obj1,const DataBlock& obj2)
{
- return (obj1.equal(obj2));
+ return obj1.equal(obj2);
}
-#endif //DATABLOCK_H
+#endif // __MEM_RUBY_COMMON_DATABLOCK_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- */
-
#include <fstream>
#include <stdarg.h>
-#include "mem/ruby/common/Global.hh"
+#include "base/misc.hh"
+#include "mem/gems_common/util.hh"
#include "mem/ruby/common/Debug.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
-#include "mem/gems_common/util.hh"
-#include "base/misc.hh"
using namespace std;
extern "C" void changeDebugVerbosity(VerbosityLevel vb);
extern "C" void changeDebugFilter(int filter);
-void changeDebugVerbosity(VerbosityLevel vb)
+void
+changeDebugVerbosity(VerbosityLevel vb)
{
- g_debug_ptr->setVerbosity(vb);
+ g_debug_ptr->setVerbosity(vb);
}
-void changeDebugFilter(int filter)
+void
+changeDebugFilter(int filter)
{
- g_debug_ptr->setFilter(filter);
+ g_debug_ptr->setFilter(filter);
}
Debug::Debug(const Params *p)
: SimObject(p)
{
- clearFilter();
- debug_cout_ptr = &cout;
-
- setFilterString(p->filter_string.c_str());
- setVerbosityString(p->verbosity_string.c_str());
- setDebugOutputFile(p->output_filename.c_str());
- m_starting_cycle = p->start_time;
- m_protocol_trace = p->protocol_trace;
- g_debug_ptr = this;
-}
-
+ clearFilter();
+ debug_cout_ptr = &cout;
-Debug::~Debug()
-{
+ setFilterString(p->filter_string.c_str());
+ setVerbosityString(p->verbosity_string.c_str());
+ setDebugOutputFile(p->output_filename.c_str());
+ m_starting_cycle = p->start_time;
+ m_protocol_trace = p->protocol_trace;
+ g_debug_ptr = this;
}
-void Debug::printVerbosity(ostream& out) const
+Debug::~Debug()
{
- switch (getVerbosity()) {
- case No_Verb:
- out << "verbosity = No_Verb" << endl;
- break;
- case Low_Verb:
- out << "verbosity = Low_Verb" << endl;
- break;
- case Med_Verb:
- out << "verbosity = Med_Verb" << endl;
- break;
- case High_Verb:
- out << "verbosity = High_Verb" << endl;
- break;
- default:
- out << "verbosity = unknown" << endl;
- }
}
-bool Debug::validDebug(int module, PriorityLevel priority)
+void
+Debug::printVerbosity(ostream& out) const
{
- int local_module = (1 << module);
- if(m_filter & local_module) {
- if (g_eventQueue_ptr == NULL ||
- g_eventQueue_ptr->getTime() >= m_starting_cycle) {
- switch(m_verbosityLevel) {
+ switch (getVerbosity()) {
case No_Verb:
- return false;
+ out << "verbosity = No_Verb" << endl;
break;
case Low_Verb:
- if(priority == HighPrio) {
- return true;
- }else{
- return false;
- }
+ out << "verbosity = Low_Verb" << endl;
break;
case Med_Verb:
- if(priority == HighPrio || priority == MedPrio ) {
- return true;
- }else{
- return false;
- }
+ out << "verbosity = Med_Verb" << endl;
break;
case High_Verb:
- return true;
+ out << "verbosity = High_Verb" << endl;
break;
- }
+ default:
+ out << "verbosity = unknown" << endl;
}
- }
- return false;
}
-void Debug::setDebugTime(Time t)
+bool
+Debug::validDebug(int module, PriorityLevel priority)
{
- m_starting_cycle = t;
+ int local_module = (1 << module);
+ if (m_filter & local_module) {
+ if (g_eventQueue_ptr == NULL ||
+ g_eventQueue_ptr->getTime() >= m_starting_cycle) {
+ switch (m_verbosityLevel) {
+ case No_Verb:
+ return false;
+ case Low_Verb:
+ return (priority == HighPrio);
+ case Med_Verb:
+ return (priority == HighPrio || priority == MedPrio);
+ case High_Verb:
+ return true;
+ }
+ }
+ }
+ return false;
}
-void Debug::setVerbosity(VerbosityLevel vb)
+void
+Debug::setDebugTime(Time t)
{
- m_verbosityLevel = vb;
+ m_starting_cycle = t;
}
-void Debug::setFilter(int filter)
+void
+Debug::setVerbosity(VerbosityLevel vb)
{
- m_filter = filter;
+ m_verbosityLevel = vb;
}
-bool Debug::checkVerbosityString(const char *verb_str)
+void
+Debug::setFilter(int filter)
{
- if (verb_str == NULL) {
- cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
- return true; // error
- } else if ( (string(verb_str) == "none") ||
- (string(verb_str) == "low") ||
- (string(verb_str) == "med") ||
- (string(verb_str) == "high") ) {
- return false;
- }
- cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
- return true; // error
+ m_filter = filter;
}
-bool Debug::setVerbosityString(const char *verb_str)
+bool
+Debug::setVerbosityString(const char *verb_str)
{
- bool check_fails = checkVerbosityString(verb_str);
- if (check_fails) {
- return true; // error
- }
- if (string(verb_str) == "none") {
- setVerbosity(No_Verb);
- } else if (string(verb_str) == "low") {
- setVerbosity(Low_Verb);
- } else if (string(verb_str) == "med") {
- setVerbosity(Med_Verb);
- } else if (string(verb_str) == "high") {
- setVerbosity(High_Verb);
- } else {
- cerr << "Error: unrecognized verbosity (use none, low, med, high): " << verb_str << endl;
- return true; // error
- }
- return false; // no error
+ string verb = verb_str ? verb_str : "";
+ if (verb == "none") {
+ setVerbosity(No_Verb);
+ } else if (verb == "low") {
+ setVerbosity(Low_Verb);
+ } else if (verb == "med") {
+ setVerbosity(Med_Verb);
+ } else if (verb == "high") {
+ setVerbosity(High_Verb);
+ } else {
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): "
+ << verb << endl;
+ return true; // error
+ }
+ return false; // no error
}
-bool Debug::checkFilter(char ch)
+bool
+Debug::checkFilter(char ch)
{
- for (int i=0; i<NUMBER_OF_COMPS; i++) {
- // Look at all components to find a character match
- if (debugComponents[i].ch == ch) {
- // We found a match - return no error
- return false; // no error
+ for (int i = 0; i < NUMBER_OF_COMPS; i++) {
+ // Look at all components to find a character match
+ if (debugComponents[i].ch == ch) {
+ // We found a match - return no error
+ return false; // no error
+ }
}
- }
- return true; // error
+ return true; // error
}
-bool Debug::checkFilterString(const char *filter_str)
+bool
+Debug::checkFilterString(const char *filter_str)
{
- if (filter_str == NULL) {
- cerr << "Error: unrecognized component filter: NULL" << endl;
- return true; // error
- }
+ if (filter_str == NULL) {
+ cerr << "Error: unrecognized component filter: NULL" << endl;
+ return true; // error
+ }
- // check for default filter ("none") before reporting RUBY_DEBUG error
- if ( (string(filter_str) == "none") ) {
- return false; // no error
- }
+ // check for default filter ("none") before reporting RUBY_DEBUG error
+ if (string(filter_str) == "none") {
+ return false; // no error
+ }
- if (RUBY_DEBUG == false) {
- cerr << "Error: User specified set of debug components, but the RUBY_DEBUG compile-time flag is false." << endl;
- cerr << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
- return true; // error
- }
+ if (RUBY_DEBUG == false) {
+ cerr << "Error: User specified set of debug components, but the "
+ << "RUBY_DEBUG compile-time flag is false." << endl
+ << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
+ return true; // error
+ }
- if ( (string(filter_str) == "all") ) {
- return false; // no error
- }
+ if (string(filter_str) == "all") {
+ return false; // no error
+ }
- // scan string checking each character
- for (unsigned int i = 0; i < strlen(filter_str); i++) {
- bool unrecognized = checkFilter( filter_str[i] );
- if (unrecognized == true) {
- return true; // error
+ // scan string checking each character
+ for (unsigned int i = 0; i < strlen(filter_str); i++) {
+ bool unrecognized = checkFilter(filter_str[i]);
+ if (unrecognized == true) {
+ return true; // error
+ }
}
- }
- return false; // no error
+ return false; // no error
}
-bool Debug::setFilterString(const char *filter_str)
+bool
+Debug::setFilterString(const char *filter_str)
{
- if (checkFilterString(filter_str)) {
- return true; // error
- }
-
- if (string(filter_str) == "all" ) {
- allFilter();
- } else if (string(filter_str) == "none") {
- clearFilter();
- } else {
- // scan string adding to bit mask for each component which is present
- for (unsigned int i = 0; i < strlen(filter_str); i++) {
- bool error = addFilter( filter_str[i] );
- if (error) {
+ if (checkFilterString(filter_str)) {
return true; // error
- }
}
- }
- return false; // no error
+
+ if (string(filter_str) == "all" ) {
+ allFilter();
+ } else if (string(filter_str) == "none") {
+ clearFilter();
+ } else {
+ // scan string adding to bit mask for each component which is present
+ for (unsigned int i = 0; i < strlen(filter_str); i++) {
+ bool error = addFilter( filter_str[i] );
+ if (error) {
+ return true; // error
+ }
+ }
+ }
+ return false; // no error
}
-bool Debug::addFilter(char ch)
+bool
+Debug::addFilter(char ch)
{
- for (int i=0; i<NUMBER_OF_COMPS; i++) {
- // Look at all components to find a character match
- if (debugComponents[i].ch == ch) {
- // We found a match - update the filter bit mask
- cout << " Debug: Adding to filter: '" << ch << "' (" << debugComponents[i].desc << ")" << endl;
- m_filter |= (1 << i);
- return false; // no error
+ for (int i = 0; i < NUMBER_OF_COMPS; i++) {
+ // Look at all components to find a character match
+ if (debugComponents[i].ch == ch) {
+ // We found a match - update the filter bit mask
+ cout << " Debug: Adding to filter: '" << ch << "' ("
+ << debugComponents[i].desc << ")" << endl;
+ m_filter |= (1 << i);
+ return false; // no error
+ }
}
- }
- // We didn't find the character
- cerr << "Error: unrecognized component filter: " << ch << endl;
- usageInstructions();
- return true; // error
+ // We didn't find the character
+ cerr << "Error: unrecognized component filter: " << ch << endl;
+ usageInstructions();
+ return true; // error
}
-void Debug::clearFilter()
+void
+Debug::clearFilter()
{
- m_filter = 0;
+ m_filter = 0;
}
void Debug::allFilter()
{
- m_filter = ~0;
+ m_filter = ~0;
}
-void Debug::usageInstructions(void)
+void
+Debug::usageInstructions(void)
{
- cerr << "Debug components: " << endl;
- for (int i=0; i<NUMBER_OF_COMPS; i++) {
- cerr << " " << debugComponents[i].ch << ": " << debugComponents[i].desc << endl;
- }
+ cerr << "Debug components: " << endl;
+ for (int i = 0; i < NUMBER_OF_COMPS; i++) {
+ cerr << " " << debugComponents[i].ch << ": "
+ << debugComponents[i].desc << endl;
+ }
}
-void Debug::print(ostream& out) const
+void
+Debug::print(ostream& out) const
{
- out << "[Debug]" << endl;
+ out << "[Debug]" << endl;
}
-void Debug::setDebugOutputFile (const char * filename)
+void
+Debug::setDebugOutputFile (const char *filename)
{
- if ( (filename == NULL) ||
- (!strcmp(filename, "none")) ) {
- debug_cout_ptr = &cout;
- return;
- }
-
- if (m_fout.is_open() ) {
- m_fout.close ();
- }
- m_fout.open (filename, ios::out);
- if (! m_fout.is_open() ) {
- cerr << "setDebugOutputFile: can't open file " << filename << endl;
- }
- else {
- debug_cout_ptr = &m_fout;
- }
-}
+ if (filename == NULL || !strcmp(filename, "none")) {
+ debug_cout_ptr = &cout;
+ return;
+ }
-void Debug::closeDebugOutputFile ()
-{
- if (m_fout.is_open() ) {
- m_fout.close ();
- debug_cout_ptr = &cout;
- }
+ if (m_fout.is_open()) {
+ m_fout.close();
+ }
+ m_fout.open(filename, ios::out);
+ if (!m_fout.is_open()) {
+ cerr << "setDebugOutputFile: can't open file " << filename << endl;
+ } else {
+ debug_cout_ptr = &m_fout;
+ }
}
-void Debug::debugMsg( const char *fmt, ... )
+void
+Debug::closeDebugOutputFile ()
{
- va_list args;
-
- // you could check validDebug() here before printing the message
- va_start(args, fmt);
- vfprintf(stdout, fmt, args);
- va_end(args);
+ if (m_fout.is_open()) {
+ m_fout.close ();
+ debug_cout_ptr = &cout;
+ }
}
-/*
-void DEBUG_OUT( const char* fmt, ...) {
- if (RUBY_DEBUG) {
- cout << "Debug: in fn "
- << __PRETTY_FUNCTION__
- << " in " << __FILE__ << ":"
- << __LINE__ << ": ";
+void
+Debug::debugMsg( const char *fmt, ...)
+{
va_list args;
- va_start(args, fmt);
- vfprintf(stdout, fmt, args);
- va_end(args);
- }
-}
-void ERROR_OUT( const char* fmt, ... ) {
- if (ERROR_MESSAGE_FLAG) {
- cout << "error: in fn "
- << __PRETTY_FUNCTION__ << " in "
- << __FILE__ << ":"
- << __LINE__ << ": ";
- va_list args;
+ // you could check validDebug() here before printing the message
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
- }
- assert(0);
}
-*/
-
Debug *
RubyDebugParams::create()
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
-#ifndef __MEM_RUBY_DEBUG_HH__
-#define __MEM_RUBY_DEBUG_HH__
+#ifndef __MEM_RUBY_COMMON_DEBUG_HH__
+#define __MEM_RUBY_COMMON_DEBUG_HH__
#include <unistd.h>
enum PriorityLevel {HighPrio, MedPrio, LowPrio};
enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb};
-class Debug : public SimObject {
-public:
- // Constructors
+class Debug : public SimObject
+{
+ public:
typedef RubyDebugParams Params;
- Debug(const Params *p);
-
- // Destructor
- ~Debug();
-
- // Public Methods
- static bool getProtocolTrace() { return m_protocol_trace; }
- bool validDebug(int module, PriorityLevel priority);
- void printVerbosity(std::ostream& out) const;
- void setVerbosity(VerbosityLevel vb);
- static bool checkVerbosityString(const char *verb_str);
- bool setVerbosityString(const char *);
- VerbosityLevel getVerbosity() const { return m_verbosityLevel; }
- void setFilter(int);
- static bool checkFilter( char);
- static bool checkFilterString(const char *);
- bool setFilterString(const char *);
- void setDebugTime(Time);
- Time getDebugTime() const { return m_starting_cycle; }
- bool addFilter(char);
- void clearFilter();
- void allFilter();
- void print(std::ostream& out) const;
- /* old school debugging "vararg": sends messages to screen and log */
- void debugMsg( const char *fmt, ... );
-
- void setDebugOutputFile (const char * filename);
- void closeDebugOutputFile ();
- static void usageInstructions(void);
-
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- Debug(const Debug& obj);
- Debug& operator=(const Debug& obj);
-
- // Data Members (m_ prefix)
- static bool m_protocol_trace;
- VerbosityLevel m_verbosityLevel;
- int m_filter;
- Time m_starting_cycle;
-
- std::fstream m_fout;
+ Debug(const Params *p);
+ ~Debug();
+
+ static bool getProtocolTrace() { return m_protocol_trace; }
+ bool validDebug(int module, PriorityLevel priority);
+ void printVerbosity(std::ostream& out) const;
+ void setVerbosity(VerbosityLevel vb);
+ bool setVerbosityString(const char *);
+ VerbosityLevel getVerbosity() const { return m_verbosityLevel; }
+ void setFilter(int);
+ static bool checkFilter( char);
+ static bool checkFilterString(const char *);
+ bool setFilterString(const char *);
+ void setDebugTime(Time);
+ Time getDebugTime() const { return m_starting_cycle; }
+ bool addFilter(char);
+ void clearFilter();
+ void allFilter();
+ void print(std::ostream& out) const;
+ /* old school debugging "vararg": sends messages to screen and log */
+ void debugMsg(const char *fmt, ...);
+
+ void setDebugOutputFile (const char * filename);
+ void closeDebugOutputFile ();
+ static void usageInstructions(void);
+
+ private:
+ // Private copy constructor and assignment operator
+ Debug(const Debug& obj);
+ Debug& operator=(const Debug& obj);
+
+ static bool m_protocol_trace;
+ VerbosityLevel m_verbosityLevel;
+ int m_filter;
+ Time m_starting_cycle;
+
+ std::fstream m_fout;
};
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const Debug& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const Debug& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const Debug& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
const bool ERROR_MESSAGE_FLAG = true;
#undef assert
#define assert(EXPR) ASSERT(EXPR)
#undef ASSERT
-#define ASSERT(EXPR)\
-{\
- using namespace std;\
- if (ASSERT_FLAG) {\
- if (!(EXPR)) {\
- cerr << "failed assertion '"\
- << #EXPR << "' at fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << endl << flush;\
- (* debug_cout_ptr) << "failed assertion '"\
- << #EXPR << "' at fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << endl << flush;\
- if(isatty(STDIN_FILENO)) {\
- cerr << "At this point you might want to attach a debug to ";\
- cerr << "the running and get to the" << endl;\
- cerr << "crash site; otherwise press enter to continue" << endl;\
- cerr << "PID: " << getpid();\
- cerr << endl << flush; \
- char c; \
- cin.get(c); \
- }\
- abort();\
- }\
- }\
-}
-
-#define BREAK(X)\
-{\
- using namespace std;\
- cerr << "breakpoint '"\
- << #X << "' reached at fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << endl << flush;\
- if(isatty(STDIN_FILENO)) {\
- cerr << "press enter to continue" << endl;\
- cerr << "PID: " << getpid();\
- cerr << endl << flush; \
- char c; \
- cin.get(c); \
- }\
-}
-
-#define ERROR_MSG(MESSAGE)\
-{\
- using namespace std;\
- if (ERROR_MESSAGE_FLAG) {\
- cerr << "Fatal Error: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": "\
- << (MESSAGE) << endl << flush;\
- (* debug_cout_ptr) << "Fatal Error: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": "\
- << (MESSAGE) << endl << flush;\
- abort();\
- }\
-}
-
-#define WARN_MSG(MESSAGE)\
-{\
- using namespace std;\
- if (WARNING_MESSAGE_FLAG) {\
- cerr << "Warning: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": "\
- << (MESSAGE) << endl << flush;\
- (* debug_cout_ptr) << "Warning: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": "\
- << (MESSAGE) << endl << flush;\
- }\
-}
-
-#define WARN_EXPR(EXPR)\
-{\
- using namespace std;\
- if (WARNING_MESSAGE_FLAG) {\
- cerr << "Warning: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": "\
- << #EXPR << " is "\
- << (EXPR) << endl << flush;\
- (* debug_cout_ptr) << "Warning: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": "\
- << #EXPR << " is "\
- << (EXPR) << endl << flush;\
- }\
-}
-
-#define DEBUG_MSG(module, priority, MESSAGE)\
-{\
- using namespace std;\
- if (RUBY_DEBUG) {\
- if (g_debug_ptr->validDebug(module, priority)) {\
- (* debug_cout_ptr) << "Debug: in fn "\
- << __PRETTY_FUNCTION__\
- << " in " << __FILE__ << ":"\
- << __LINE__ << ": "\
- << (MESSAGE) << endl << flush;\
- }\
- }\
-}
-
-#define DEBUG_EXPR(module, priority, EXPR)\
-{\
- using namespace std;\
- if (RUBY_DEBUG) {\
- if (g_debug_ptr->validDebug(module, priority)) {\
- (* debug_cout_ptr) << "Debug: in fn "\
- << __PRETTY_FUNCTION__\
- << " in " << __FILE__ << ":"\
- << __LINE__ << ": "\
- << #EXPR << " is "\
- << (EXPR) << endl << flush;\
- }\
- }\
-}
-
-#define DEBUG_NEWLINE(module, priority)\
-{\
- using namespace std;\
- if (RUBY_DEBUG) {\
- if (g_debug_ptr->validDebug(module, priority)) {\
- (* debug_cout_ptr) << endl << flush;\
- }\
- }\
-}
-
-#define DEBUG_SLICC(priority, LINE, MESSAGE)\
-{\
- using namespace std;\
- if (RUBY_DEBUG) {\
- if (g_debug_ptr->validDebug(SLICC_COMP, priority)) {\
- (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush;\
- }\
- }\
-}
-
-#define DEBUG_OUT( rest... ) \
-{\
- using namespace std;\
- if (RUBY_DEBUG) {\
- cout << "Debug: in fn "\
- << __PRETTY_FUNCTION__\
- << " in " << __FILE__ << ":"\
- << __LINE__ << ": "; \
- g_debug_ptr->debugMsg(rest); \
- }\
-}
-
-#define ERROR_OUT( rest... ) \
-{\
- using namespace std;\
- if (ERROR_MESSAGE_FLAG) {\
- cout << "error: in fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << ": ";\
- g_debug_ptr->debugMsg(rest); \
- }\
-}
-
-#endif //DEBUG_H
+#define ASSERT(EXPR) do { \
+ using namespace std; \
+ if (ASSERT_FLAG) { \
+ if (!(EXPR)) { \
+ cerr << "failed assertion '" \
+ << #EXPR << "' at fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << endl << flush; \
+ (*debug_cout_ptr) << "failed assertion '" \
+ << #EXPR << "' at fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << endl << flush; \
+ if (isatty(STDIN_FILENO)) { \
+ cerr << "At this point you might want to attach a debug to " \
+ << "the running and get to the" << endl \
+ << "crash site; otherwise press enter to continue" \
+ << endl \
+ << "PID: " << getpid() \
+ << endl << flush; \
+ char c; \
+ cin.get(c); \
+ } \
+ abort(); \
+ } \
+ } \
+} while (0)
+
+#define BREAK(X) do { \
+ using namespace std; \
+ cerr << "breakpoint '" \
+ << #X << "' reached at fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << endl << flush; \
+ if(isatty(STDIN_FILENO)) { \
+ cerr << "press enter to continue" << endl; \
+ cerr << "PID: " << getpid(); \
+ cerr << endl << flush; \
+ char c; \
+ cin.get(c); \
+ } \
+} while (0)
+
+#define ERROR_MSG(MESSAGE) do { \
+ using namespace std; \
+ if (ERROR_MESSAGE_FLAG) { \
+ cerr << "Fatal Error: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << (MESSAGE) << endl << flush; \
+ (* debug_cout_ptr) << "Fatal Error: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << (MESSAGE) << endl << flush; \
+ abort(); \
+ } \
+} while(0)
+
+#define WARN_MSG(MESSAGE) do { \
+ using namespace std; \
+ if (WARNING_MESSAGE_FLAG) { \
+ cerr << "Warning: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << (MESSAGE) << endl << flush; \
+ (* debug_cout_ptr) << "Warning: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << (MESSAGE) << endl << flush; \
+ } \
+} while (0)
+
+#define WARN_EXPR(EXPR) do { \
+ using namespace std; \
+ if (WARNING_MESSAGE_FLAG) { \
+ cerr << "Warning: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << #EXPR << " is " \
+ << (EXPR) << endl << flush; \
+ (* debug_cout_ptr) << "Warning: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << #EXPR << " is " \
+ << (EXPR) << endl << flush; \
+ } \
+} while (0)
+
+#define DEBUG_MSG(module, priority, MESSAGE) do { \
+ using namespace std; \
+ if (RUBY_DEBUG) { \
+ if (g_debug_ptr->validDebug(module, priority)) { \
+ (* debug_cout_ptr) << "Debug: in fn " \
+ << __PRETTY_FUNCTION__ \
+ << " in " << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << (MESSAGE) << endl << flush; \
+ } \
+ } \
+} while (0)
+
+#define DEBUG_EXPR(module, priority, EXPR) do { \
+ using namespace std; \
+ if (RUBY_DEBUG) { \
+ if (g_debug_ptr->validDebug(module, priority)) { \
+ (* debug_cout_ptr) << "Debug: in fn " \
+ << __PRETTY_FUNCTION__ \
+ << " in " << __FILE__ << ":" \
+ << __LINE__ << ": " \
+ << #EXPR << " is " \
+ << (EXPR) << endl << flush; \
+ } \
+ } \
+} while (0)
+
+#define DEBUG_NEWLINE(module, priority) do { \
+ using namespace std; \
+ if (RUBY_DEBUG) { \
+ if (g_debug_ptr->validDebug(module, priority)) { \
+ (* debug_cout_ptr) << endl << flush; \
+ } \
+ } \
+} while (0)
+
+#define DEBUG_SLICC(priority, LINE, MESSAGE) do { \
+ using namespace std; \
+ if (RUBY_DEBUG) { \
+ if (g_debug_ptr->validDebug(SLICC_COMP, priority)) { \
+ (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush; \
+ } \
+ } \
+} while (0)
+
+#define DEBUG_OUT(rest... ) do { \
+ using namespace std; \
+ if (RUBY_DEBUG) { \
+ cout << "Debug: in fn " \
+ << __PRETTY_FUNCTION__ \
+ << " in " << __FILE__ << ":" \
+ << __LINE__ << ": "; \
+ g_debug_ptr->debugMsg(rest); \
+ } \
+} while (0)
+
+#define ERROR_OUT( rest... ) do { \
+ using namespace std; \
+ if (ERROR_MESSAGE_FLAG) { \
+ cout << "error: in fn " \
+ << __PRETTY_FUNCTION__ << " in " \
+ << __FILE__ << ":" \
+ << __LINE__ << ": "; \
+ g_debug_ptr->debugMsg(rest); \
+ } \
+} while (0)
+
+#endif // __MEM_RUBY_COMMON_DEBUG_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <cassert>
+
#include "mem/ruby/common/Driver.hh"
Driver::Driver()
Driver::~Driver()
{
}
+
+integer_t
+Driver::getInstructionCount(int procID) const
+{
+ return 1;
+}
+
+integer_t
+Driver::getCycleCount(int procID) const
+{
+ return 1;
+}
+
+void
+Driver::addThreadDependency(int procID, int requestor_thread,
+ int conflict_thread) const
+{
+ assert(0);
+}
+
+void
+Driver::printDebug()
+{}
+
+integer_t
+Driver::readPhysicalMemory(int procID, physical_address_t address, int len)
+{
+ assert(0);
+ return 0;
+}
+
+void
+Driver::writePhysicalMemory(int procID, physical_address_t address,
+ integer_t value, int len)
+{
+ assert(0);
+}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- * Description:
- *
- */
-
-#ifndef DRIVER_H
-#define DRIVER_H
+#ifndef __MEM_RUBY_COMMON_DRIVER_HH__
+#define __MEM_RUBY_COMMON_DRIVER_HH__
-#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/NodeID.hh"
-#include "mem/ruby/common/Address.hh"
-
-
-class Driver {
-public:
- // Constructors
- Driver();
-
- // Destructor
- virtual ~Driver() = 0;
-
- // Public Methods
- virtual void get_network_config() {}
- virtual void dmaHitCallback() {};
- virtual void hitCallback(int64_t id) = 0; // Called by sequencer
- virtual void go() = 0;
- virtual integer_t getInstructionCount(int procID) const { return 1; }
- virtual integer_t getCycleCount(int procID) const { return 1; }
- virtual void addThreadDependency(int procID, int requestor_thread, int conflict_thread) const { assert(0);}
- virtual void printDebug(){} //called by Sequencer
-
- virtual void printStats(ostream& out) const = 0;
- virtual void clearStats() = 0;
-
- virtual void printConfig(ostream& out) const = 0;
-
-
- virtual integer_t readPhysicalMemory(int procID, physical_address_t address,
- int len ){ ASSERT(0); return 0; }
-
- virtual void writePhysicalMemory( int procID, physical_address_t address,
- integer_t value, int len ){ ASSERT(0); }
-
-protected:
- // accessible by subclasses
-
-private:
- // inaccessible by subclasses
+class Driver
+{
+ public:
+ Driver();
+ virtual ~Driver() = 0;
+
+ // Public Methods
+ virtual void get_network_config() {}
+ virtual void dmaHitCallback() {};
+ virtual void hitCallback(int64_t id) = 0; // Called by sequencer
+ virtual void go() = 0;
+ virtual integer_t getInstructionCount(int procID) const;
+ virtual integer_t getCycleCount(int procID) const;
+ virtual void addThreadDependency(int procID, int requestor_thread,
+ int conflict_thread) const;
+ virtual void printDebug(); //called by Sequencer
+
+ virtual void printStats(ostream& out) const = 0;
+ virtual void clearStats() = 0;
+
+ virtual void printConfig(ostream& out) const = 0;
+
+ virtual integer_t readPhysicalMemory(int procID, physical_address_t addr,
+ int len);
+ virtual void writePhysicalMemory(int procID, physical_address_t addr,
+ integer_t value, int len);
};
-#endif //DRIVER_H
+#endif //__MEM_RUBY_COMMON_DRIVER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- * */
-
-#ifndef GLOBAL_H
-#define GLOBAL_H
-
-/*
-#ifdef SINGLE_LEVEL_CACHE
-const bool TWO_LEVEL_CACHE = false;
-#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // currently all protocols require L1s == nodes
-#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // "
-#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // "
-#define L2_CACHE_VARIABLE m_L1Cache_cacheMemory_vec
-#else
-const bool TWO_LEVEL_CACHE = true;
-#ifdef IS_CMP
-#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version]
-#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version]
-#define L2_CACHE_MEMBER_VARIABLE m_L2Cache_L2cacheMemory_vec[m_version]
-#define L2_CACHE_VARIABLE m_L2Cache_L2cacheMemory_vec
-#else // not IS_CMP
-#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version] // currently all protocols require L1s == nodes
-#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version] // "
-// #define L2_CACHE_MEMBER_VARIABLE m_L1Cache_L2cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes
-#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes
-#define L2_CACHE_VARIABLE m_L1Cache_L2cacheMemory_vec
-#endif // IS_CMP
-#endif //SINGLE_LEVEL_CACHE
-
-#define DIRECTORY_MEMBER_VARIABLE m_Directory_directory_vec[m_version]
-#define TBE_TABLE_MEMBER_VARIABLE m_L1Cache_TBEs_vec[m_version]
-
-*/
-
+#ifndef __MEM_RUBY_COMMON_GLOBAL_HH__
+#define __MEM_RUBY_COMMON_GLOBAL_HH__
// external includes for all classes
#include "mem/ruby/common/TypeDefines.hh"
class Debug;
extern Debug* g_debug_ptr;
-// FIXME: this is required by the contructor of Directory_Entry.hh. It can't go
-// into slicc_util.hh because it opens a can of ugly worms
+// FIXME: this is required by the contructor of Directory_Entry.hh.
+// It can't go into slicc_util.hh because it opens a can of ugly worms
extern inline int max_tokens()
{
return 1024;
}
-
-#endif //GLOBAL_H
+#endif // __MEM_RUBY_COMMON_GLOBAL_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- */
-
#include <cmath>
#include <iomanip>
+#include "base/intmath.hh"
#include "mem/ruby/common/Histogram.hh"
using namespace std;
Histogram::Histogram(int binsize, int bins)
{
- m_binsize = binsize;
- m_bins = bins;
- clear();
+ m_binsize = binsize;
+ m_bins = bins;
+ clear();
}
Histogram::~Histogram()
{
}
-void Histogram::clear(int binsize, int bins)
+void
+Histogram::clear(int binsize, int bins)
{
- m_binsize = binsize;
- clear(bins);
+ m_binsize = binsize;
+ clear(bins);
}
-void Histogram::clear(int bins)
+void
+Histogram::clear(int bins)
{
- m_bins = bins;
- m_largest_bin = 0;
- m_max = 0;
- m_data.setSize(m_bins);
- for (int i = 0; i < m_bins; i++) {
- m_data[i] = 0;
- }
- m_count = 0;
- m_max = 0;
-
- m_sumSamples = 0;
- m_sumSquaredSamples = 0;
+ m_bins = bins;
+ m_largest_bin = 0;
+ m_max = 0;
+ m_data.setSize(m_bins);
+ for (int i = 0; i < m_bins; i++) {
+ m_data[i] = 0;
+ }
+ m_count = 0;
+ m_max = 0;
+
+ m_sumSamples = 0;
+ m_sumSquaredSamples = 0;
}
-void Histogram::add(int64 value)
+void
+Histogram::add(int64 value)
{
- assert(value >= 0);
- m_max = max(m_max, value);
- m_count++;
-
- m_sumSamples += value;
- m_sumSquaredSamples += (value*value);
-
- int index;
- if (m_binsize == -1) {
- // This is a log base 2 histogram
- if (value == 0) {
- index = 0;
+ assert(value >= 0);
+ m_max = max(m_max, value);
+ m_count++;
+
+ m_sumSamples += value;
+ m_sumSquaredSamples += (value*value);
+
+ int index;
+ if (m_binsize == -1) {
+ // This is a log base 2 histogram
+ if (value == 0) {
+ index = 0;
+ } else {
+ index = floorLog2(value) + 1;
+ if (index >= m_data.size()) {
+ index = m_data.size() - 1;
+ }
+ }
} else {
- index = int(log(double(value))/log(2.0))+1;
- if (index >= m_data.size()) {
- index = m_data.size()-1;
- }
- }
- } else {
- // This is a linear histogram
- while (m_max >= (m_bins * m_binsize)) {
- for (int i = 0; i < m_bins/2; i++) {
- m_data[i] = m_data[i*2] + m_data[i*2 + 1];
- }
- for (int i = m_bins/2; i < m_bins; i++) {
- m_data[i] = 0;
- }
- m_binsize *= 2;
+ // This is a linear histogram
+ while (m_max >= (m_bins * m_binsize)) {
+ for (int i = 0; i < m_bins/2; i++) {
+ m_data[i] = m_data[i*2] + m_data[i*2 + 1];
+ }
+ for (int i = m_bins/2; i < m_bins; i++) {
+ m_data[i] = 0;
+ }
+ m_binsize *= 2;
+ }
+ index = value/m_binsize;
}
- index = value/m_binsize;
- }
- assert(index >= 0);
- m_data[index]++;
- m_largest_bin = max(m_largest_bin, index);
+ assert(index >= 0);
+ m_data[index]++;
+ m_largest_bin = max(m_largest_bin, index);
}
-void Histogram::add(const Histogram& hist)
+void
+Histogram::add(const Histogram& hist)
{
- assert(hist.getBins() == m_bins);
- assert(hist.getBinSize() == -1); // assume log histogram
- assert(m_binsize == -1);
-
- for (int j = 0; j < hist.getData(0); j++) {
- add(0);
- }
+ assert(hist.getBins() == m_bins);
+ assert(hist.getBinSize() == -1); // assume log histogram
+ assert(m_binsize == -1);
- for (int i = 1; i < m_bins; i++) {
- for (int j = 0; j < hist.getData(i); j++) {
- add(1<<(i-1)); // account for the + 1 index
+ for (int j = 0; j < hist.getData(0); j++) {
+ add(0);
}
- }
+ for (int i = 1; i < m_bins; i++) {
+ for (int j = 0; j < hist.getData(i); j++) {
+ add(1<<(i-1)); // account for the + 1 index
+ }
+ }
}
// Computation of standard deviation of samples a1, a2, ... aN
// variance = [SUM {ai^2} - (SUM {ai})^2/N]/(N-1)
// std deviation equals square root of variance
-double Histogram::getStandardDeviation() const
+double
+Histogram::getStandardDeviation() const
{
- double variance;
- if(m_count > 1){
- variance = (double)(m_sumSquaredSamples - m_sumSamples*m_sumSamples/m_count)/(m_count - 1);
- } else {
- return 0;
- }
- return sqrt(variance);
+ if (m_count <= 1)
+ return 0.0;
+
+ double variance =
+ (double)(m_sumSquaredSamples - m_sumSamples * m_sumSamples / m_count)
+ / (m_count - 1);
+ return sqrt(variance);
}
-void Histogram::print(ostream& out) const
+void
+Histogram::print(ostream& out) const
{
- printWithMultiplier(out, 1.0);
+ printWithMultiplier(out, 1.0);
}
-void Histogram::printPercent(ostream& out) const
+void
+Histogram::printPercent(ostream& out) const
{
- if (m_count == 0) {
- printWithMultiplier(out, 0.0);
- } else {
- printWithMultiplier(out, 100.0/double(m_count));
- }
+ if (m_count == 0) {
+ printWithMultiplier(out, 0.0);
+ } else {
+ printWithMultiplier(out, 100.0 / double(m_count));
+ }
}
-void Histogram::printWithMultiplier(ostream& out, double multiplier) const
+void
+Histogram::printWithMultiplier(ostream& out, double multiplier) const
{
- if (m_binsize == -1) {
- out << "[binsize: log2 ";
- } else {
- out << "[binsize: " << m_binsize << " ";
- }
- out << "max: " << m_max << " ";
- out << "count: " << m_count << " ";
- // out << "total: " << m_sumSamples << " ";
- if (m_count == 0) {
- out << "average: NaN |";
- out << "standard deviation: NaN |";
- } else {
- out << "average: " << setw(5) << ((double) m_sumSamples)/m_count << " | ";
- out << "standard deviation: " << getStandardDeviation() << " |";
- }
- for (int i = 0; i < m_bins && i <= m_largest_bin; i++) {
- if (multiplier == 1.0) {
- out << " " << m_data[i];
+ if (m_binsize == -1) {
+ out << "[binsize: log2 ";
+ } else {
+ out << "[binsize: " << m_binsize << " ";
+ }
+ out << "max: " << m_max << " ";
+ out << "count: " << m_count << " ";
+ // out << "total: " << m_sumSamples << " ";
+ if (m_count == 0) {
+ out << "average: NaN |";
+ out << "standard deviation: NaN |";
} else {
- out << " " << double(m_data[i]) * multiplier;
+ out << "average: " << setw(5) << ((double) m_sumSamples)/m_count
+ << " | ";
+ out << "standard deviation: " << getStandardDeviation() << " |";
+ }
+ for (int i = 0; i < m_bins && i <= m_largest_bin; i++) {
+ if (multiplier == 1.0) {
+ out << " " << m_data[i];
+ } else {
+ out << " " << double(m_data[i]) * multiplier;
+ }
}
- }
- out << " ]";
+ out << " ]";
}
-bool node_less_then_eq(const Histogram* n1, const Histogram* n2)
+bool
+node_less_then_eq(const Histogram* n1, const Histogram* n2)
{
- return (n1->size() > n2->size());
+ return (n1->size() > n2->size());
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- * Description: The histogram class implements a simple histogram
- *
- */
-
-#ifndef HISTOGRAM_H
-#define HISTOGRAM_H
+#ifndef __MEM_RUBY_COMMON_HISTOGRAM_HH__
+#define __MEM_RUBY_COMMON_HISTOGRAM_HH__
#include <iostream>
#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Vector.hh"
-class Histogram {
-public:
- // Constructors
- Histogram(int binsize = 1, int bins = 50);
-
- // Destructor
- ~Histogram();
-
- // Public Methods
-
- void add(int64 value);
- void add(const Histogram& hist);
- void clear() { clear(m_bins); }
- void clear(int bins);
- void clear(int binsize, int bins);
- int64 size() const { return m_count; }
- int getBins() const { return m_bins; }
- int getBinSize() const { return m_binsize; }
- int64 getTotal() const { return m_sumSamples; }
- int64 getData(int index) const { return m_data[index]; }
+class Histogram
+{
+ public:
+ Histogram(int binsize = 1, int bins = 50);
+ ~Histogram();
+
+ void add(int64 value);
+ void add(const Histogram& hist);
+ void clear() { clear(m_bins); }
+ void clear(int bins);
+ void clear(int binsize, int bins);
+ int64 size() const { return m_count; }
+ int getBins() const { return m_bins; }
+ int getBinSize() const { return m_binsize; }
+ int64 getTotal() const { return m_sumSamples; }
+ int64 getData(int index) const { return m_data[index]; }
+
+ void printWithMultiplier(std::ostream& out, double multiplier) const;
+ void printPercent(std::ostream& out) const;
+ void print(std::ostream& out) const;
- void printWithMultiplier(std::ostream& out, double multiplier) const;
- void printPercent(std::ostream& out) const;
- void print(std::ostream& out) const;
private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- // Histogram(const Histogram& obj);
- // Histogram& operator=(const Histogram& obj);
+ Vector<int64> m_data;
+ int64 m_max; // the maximum value seen so far
+ int64 m_count; // the number of elements added
+ int m_binsize; // the size of each bucket
+ int m_bins; // the number of buckets
+ int m_largest_bin; // the largest bin used
- // Data Members (m_ prefix)
- Vector<int64> m_data;
- int64 m_max; // the maximum value seen so far
- int64 m_count; // the number of elements added
- int m_binsize; // the size of each bucket
- int m_bins; // the number of buckets
- int m_largest_bin; // the largest bin used
+ int64 m_sumSamples; // the sum of all samples
+ int64 m_sumSquaredSamples; // the sum of the square of all samples
- int64 m_sumSamples; // the sum of all samples
- int64 m_sumSquaredSamples; // the sum of the square of all samples
-
- double getStandardDeviation() const;
+ double getStandardDeviation() const;
};
bool node_less_then_eq(const Histogram* n1, const Histogram* n2);
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const Histogram& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const Histogram& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const Histogram& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //HISTOGRAM_H
+#endif // __MEM_RUBY_COMMON_HISTOGRAM_HH__
+++ /dev/null
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#include "mem/ruby/slicc_interface/Message.hh"
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NetDest.C
- *
- * Description: See NetDest.hh
- *
- * $Id$
- *
- */
-
#include "mem/ruby/common/NetDest.hh"
#include "mem/protocol/Protocol.hh"
setSize();
}
-void NetDest::add(MachineID newElement)
+void
+NetDest::add(MachineID newElement)
{
- m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
+ m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
}
-void NetDest::addNetDest(const NetDest& netDest)
+void
+NetDest::addNetDest(const NetDest& netDest)
{
- assert(m_bits.size() == netDest.getSize());
- for (int i = 0; i < m_bits.size(); i++) {
- m_bits[i].addSet(netDest.m_bits[i]);
- }
+ assert(m_bits.size() == netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].addSet(netDest.m_bits[i]);
+ }
}
-void NetDest::addRandom()
+void
+NetDest::addRandom()
{
- int i = random()%m_bits.size();
- m_bits[i].addRandom();
+ int i = random()%m_bits.size();
+ m_bits[i].addRandom();
}
-void NetDest::setNetDest(MachineType machine, const Set& set)
+void
+NetDest::setNetDest(MachineType machine, const Set& set)
{
- // assure that there is only one set of destinations for this machine
- assert(MachineType_base_level((MachineType)(machine+1)) - MachineType_base_level(machine) == 1);
- m_bits[MachineType_base_level(machine)] = set;
+ // assure that there is only one set of destinations for this machine
+ assert(MachineType_base_level((MachineType)(machine + 1)) -
+ MachineType_base_level(machine) == 1);
+ m_bits[MachineType_base_level(machine)] = set;
}
-void NetDest::remove(MachineID oldElement)
+void
+NetDest::remove(MachineID oldElement)
{
- m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
+ m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
}
-void NetDest::removeNetDest(const NetDest& netDest)
+void
+NetDest::removeNetDest(const NetDest& netDest)
{
- assert(m_bits.size() == netDest.getSize());
- for (int i = 0; i < m_bits.size(); i++) {
- m_bits[i].removeSet(netDest.m_bits[i]);
-
- }
+ assert(m_bits.size() == netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].removeSet(netDest.m_bits[i]);
+ }
}
-void NetDest::clear()
+void
+NetDest::clear()
{
- for (int i = 0; i < m_bits.size(); i++) {
- m_bits[i].clear();
- }
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].clear();
+ }
}
-void NetDest::broadcast()
+void
+NetDest::broadcast()
{
- for (MachineType machine = MachineType_FIRST; machine < MachineType_NUM; ++machine) {
- broadcast(machine);
- }
+ for (MachineType machine = MachineType_FIRST;
+ machine < MachineType_NUM; ++machine) {
+ broadcast(machine);
+ }
}
-void NetDest::broadcast(MachineType machineType) {
-
- for (int i = 0; i < MachineType_base_count(machineType); i++) {
- MachineID mach = {machineType, i};
- add(mach);
- }
+void
+NetDest::broadcast(MachineType machineType)
+{
+ for (int i = 0; i < MachineType_base_count(machineType); i++) {
+ MachineID mach = {machineType, i};
+ add(mach);
+ }
}
//For Princeton Network
-Vector<NodeID> NetDest::getAllDest() {
- Vector<NodeID> dest;
- dest.clear();
- for (int i=0; i<m_bits.size(); i++) {
- for (int j=0; j<m_bits[i].getSize(); j++) {
- if (m_bits[i].isElement(j)) {
- dest.insertAtBottom((NodeID) (MachineType_base_number((MachineType) i) + j));
- }
- }
+Vector<NodeID>
+NetDest::getAllDest()
+{
+ Vector<NodeID> dest;
+ dest.clear();
+ for (int i = 0; i < m_bits.size(); i++) {
+ for (int j = 0; j < m_bits[i].getSize(); j++) {
+ if (m_bits[i].isElement(j)) {
+ int id = MachineType_base_number((MachineType)i) + j;
+ dest.insertAtBottom((NodeID)id);
+ }
}
- return dest;
+ }
+ return dest;
}
-int NetDest::count() const
+int
+NetDest::count() const
{
- int counter = 0;
- for (int i=0; i<m_bits.size(); i++) {
- counter += m_bits[i].count();
- }
- return counter;
+ int counter = 0;
+ for (int i = 0; i < m_bits.size(); i++) {
+ counter += m_bits[i].count();
+ }
+ return counter;
}
-NodeID NetDest::elementAt(MachineID index) {
- return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
+NodeID
+NetDest::elementAt(MachineID index)
+{
+ return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
}
-MachineID NetDest::smallestElement() const
+MachineID
+NetDest::smallestElement() const
{
- assert(count() > 0);
- for (int i=0; i<m_bits.size(); i++) {
- for (int j=0; j<m_bits[i].getSize(); j++) {
- if (m_bits[i].isElement(j)) {
- MachineID mach = {MachineType_from_base_level(i), j};
- return mach;
- }
+ assert(count() > 0);
+ for (int i = 0; i < m_bits.size(); i++) {
+ for (int j = 0; j < m_bits[i].getSize(); j++) {
+ if (m_bits[i].isElement(j)) {
+ MachineID mach = {MachineType_from_base_level(i), j};
+ return mach;
+ }
+ }
}
- }
- ERROR_MSG("No smallest element of an empty set.");
+ ERROR_MSG("No smallest element of an empty set.");
}
-MachineID NetDest::smallestElement(MachineType machine) const
+MachineID
+NetDest::smallestElement(MachineType machine) const
{
- for (int j = 0; j < m_bits[MachineType_base_level(machine)].getSize(); j++) {
- if (m_bits[MachineType_base_level(machine)].isElement(j)) {
- MachineID mach = {machine, j};
- return mach;
+ int size = m_bits[MachineType_base_level(machine)].getSize();
+ for (int j = 0; j < size; j++) {
+ if (m_bits[MachineType_base_level(machine)].isElement(j)) {
+ MachineID mach = {machine, j};
+ return mach;
+ }
}
- }
- ERROR_MSG("No smallest element of given MachineType.");
+ ERROR_MSG("No smallest element of given MachineType.");
}
-
// Returns true iff all bits are set
-bool NetDest::isBroadcast() const
+bool
+NetDest::isBroadcast() const
{
- for (int i=0; i<m_bits.size(); i++) {
- if (!m_bits[i].isBroadcast()) {
- return false;
+ for (int i = 0; i < m_bits.size(); i++) {
+ if (!m_bits[i].isBroadcast()) {
+ return false;
+ }
}
- }
- return true;
+ return true;
}
// Returns true iff no bits are set
-bool NetDest::isEmpty() const
+bool
+NetDest::isEmpty() const
{
- for (int i=0; i<m_bits.size(); i++) {
- if (!m_bits[i].isEmpty()) {
- return false;
+ for (int i = 0; i < m_bits.size(); i++) {
+ if (!m_bits[i].isEmpty()) {
+ return false;
+ }
}
- }
- return true;
+ return true;
}
// returns the logical OR of "this" set and orNetDest
-NetDest NetDest::OR(const NetDest& orNetDest) const
+NetDest
+NetDest::OR(const NetDest& orNetDest) const
{
- assert(m_bits.size() == orNetDest.getSize());
- NetDest result;
- for (int i=0; i<m_bits.size(); i++) {
- result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
- }
- return result;
+ assert(m_bits.size() == orNetDest.getSize());
+ NetDest result;
+ for (int i = 0; i < m_bits.size(); i++) {
+ result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
+ }
+ return result;
}
-
// returns the logical AND of "this" set and andNetDest
-NetDest NetDest::AND(const NetDest& andNetDest) const
+NetDest
+NetDest::AND(const NetDest& andNetDest) const
{
- assert(m_bits.size() == andNetDest.getSize());
- NetDest result;
- for (int i=0; i<m_bits.size(); i++) {
- result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
- }
- return result;
+ assert(m_bits.size() == andNetDest.getSize());
+ NetDest result;
+ for (int i = 0; i < m_bits.size(); i++) {
+ result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
+ }
+ return result;
}
// Returns true if the intersection of the two sets is non-empty
-bool NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
+bool
+NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
{
- assert(m_bits.size() == other_netDest.getSize());
- for (int i=0; i<m_bits.size(); i++) {
- if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) {
- return true;
+ assert(m_bits.size() == other_netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) {
+ return true;
+ }
}
- }
- return false;
+ return false;
}
-bool NetDest::isSuperset(const NetDest& test) const
+bool
+NetDest::isSuperset(const NetDest& test) const
{
- assert(m_bits.size() == test.getSize());
+ assert(m_bits.size() == test.getSize());
- for (int i=0; i<m_bits.size(); i++) {
- if (!m_bits[i].isSuperset(test.m_bits[i])) {
- return false;
+ for (int i = 0; i < m_bits.size(); i++) {
+ if (!m_bits[i].isSuperset(test.m_bits[i])) {
+ return false;
+ }
}
- }
- return true;
+ return true;
}
-bool NetDest::isElement(MachineID element) const
+bool
+NetDest::isElement(MachineID element) const
{
- return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
+ return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
}
-void NetDest::setSize()
+void
+NetDest::setSize()
{
- m_bits.setSize(MachineType_base_level(MachineType_NUM));
- assert(m_bits.size() == MachineType_NUM);
+ m_bits.setSize(MachineType_base_level(MachineType_NUM));
+ assert(m_bits.size() == MachineType_NUM);
- for (int i = 0; i < m_bits.size(); i++) {
- m_bits[i].setSize(MachineType_base_count((MachineType)i));
- }
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].setSize(MachineType_base_count((MachineType)i));
+ }
}
-void NetDest::print(ostream& out) const
+void
+NetDest::print(ostream& out) const
{
- out << "[NetDest (" << m_bits.size() << ") ";
+ out << "[NetDest (" << m_bits.size() << ") ";
- for (int i=0; i<m_bits.size(); i++) {
- for (int j=0; j<m_bits[i].getSize(); j++) {
- out << (bool) m_bits[i].isElement(j) << " ";
+ for (int i = 0; i < m_bits.size(); i++) {
+ for (int j = 0; j < m_bits[i].getSize(); j++) {
+ out << (bool) m_bits[i].isElement(j) << " ";
+ }
+ out << " - ";
}
- out << " - ";
- }
- out << "]";
+ out << "]";
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * Set.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
// NetDest specifies the network destination of a NetworkMessage
// This is backward compatible with the Set class that was previously
// used to specify network destinations.
// NetDest supports both node networks and component networks
-#ifndef NETDEST_H
-#define NETDEST_H
+#ifndef __MEM_RUBY_COMMON_NETDEST_HH__
+#define __MEM_RUBY_COMMON_NETDEST_HH__
#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Vector.hh"
#include "mem/ruby/common/Set.hh"
#include "mem/protocol/MachineType.hh"
-class Set;
-
-class NetDest {
-public:
- // Constructors
- // creates and empty set
- NetDest();
- explicit NetDest(int bit_size);
-
- NetDest& operator=(const Set& obj);
-
- // Destructor
- ~NetDest() { DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor"); }
-
- // Public Methods
- void add(MachineID newElement);
- void addNetDest(const NetDest& netDest);
- void addRandom();
- void setNetDest(MachineType machine, const Set& set);
- void remove(MachineID oldElement);
- void removeNetDest(const NetDest& netDest);
- void clear();
- void broadcast();
- void broadcast(MachineType machine);
- int count() const;
- bool isEqual(const NetDest& netDest);
-
- NetDest OR(const NetDest& orNetDest) const; // return the logical OR of this netDest and orNetDest
- NetDest AND(const NetDest& andNetDest) const; // return the logical AND of this netDest and andNetDest
-
- // Returns true if the intersection of the two netDests is non-empty
- bool intersectionIsNotEmpty(const NetDest& other_netDest) const;
-
- // Returns true if the intersection of the two netDests is empty
- bool intersectionIsEmpty(const NetDest& other_netDest) const;
-
- bool isSuperset(const NetDest& test) const;
- bool isSubset(const NetDest& test) const { return test.isSuperset(*this); }
- bool isElement(MachineID element) const;
- bool isBroadcast() const;
- bool isEmpty() const;
-
- //For Princeton Network
- Vector<NodeID> getAllDest();
-
- MachineID smallestElement() const;
- MachineID smallestElement(MachineType machine) const;
-
- void setSize();
- int getSize() const { return m_bits.size(); }
-
- // get element for a index
- NodeID elementAt(MachineID index);
-
- void print(ostream& out) const;
-
-private:
-
- // Private Methods
- // returns a value >= MachineType_base_level("this machine") and < MachineType_base_level("next highest machine")
- int vecIndex(MachineID m) const {
- int vec_index = MachineType_base_level(m.type);
- assert(vec_index < m_bits.size());
- return vec_index;
- }
-
- NodeID bitIndex(NodeID index) const {
- return index;
- }
-
- // Data Members (m_ prefix)
- Vector < Set > m_bits; // a Vector of bit vectors - i.e. Sets
-
+class NetDest
+{
+ public:
+ // Constructors
+ // creates and empty set
+ NetDest();
+ explicit NetDest(int bit_size);
+
+ NetDest& operator=(const Set& obj);
+
+ ~NetDest()
+ {
+ DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor");
+ }
+
+ void add(MachineID newElement);
+ void addNetDest(const NetDest& netDest);
+ void addRandom();
+ void setNetDest(MachineType machine, const Set& set);
+ void remove(MachineID oldElement);
+ void removeNetDest(const NetDest& netDest);
+ void clear();
+ void broadcast();
+ void broadcast(MachineType machine);
+ int count() const;
+ bool isEqual(const NetDest& netDest);
+
+ // return the logical OR of this netDest and orNetDest
+ NetDest OR(const NetDest& orNetDest) const;
+
+ // return the logical AND of this netDest and andNetDest
+ NetDest AND(const NetDest& andNetDest) const;
+
+ // Returns true if the intersection of the two netDests is non-empty
+ bool intersectionIsNotEmpty(const NetDest& other_netDest) const;
+
+ // Returns true if the intersection of the two netDests is empty
+ bool intersectionIsEmpty(const NetDest& other_netDest) const;
+
+ bool isSuperset(const NetDest& test) const;
+ bool isSubset(const NetDest& test) const { return test.isSuperset(*this); }
+ bool isElement(MachineID element) const;
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ // For Princeton Network
+ Vector<NodeID> getAllDest();
+
+ MachineID smallestElement() const;
+ MachineID smallestElement(MachineType machine) const;
+
+ void setSize();
+ int getSize() const { return m_bits.size(); }
+
+ // get element for a index
+ NodeID elementAt(MachineID index);
+
+ void print(ostream& out) const;
+
+ private:
+ // returns a value >= MachineType_base_level("this machine")
+ // and < MachineType_base_level("next highest machine")
+ int
+ vecIndex(MachineID m) const
+ {
+ int vec_index = MachineType_base_level(m.type);
+ assert(vec_index < m_bits.size());
+ return vec_index;
+ }
+
+ NodeID
+ bitIndex(NodeID index) const
+ {
+ return index;
+ }
+
+ Vector <Set> m_bits; // a Vector of bit vectors - i.e. Sets
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const NetDest& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const NetDest& obj)
+inline ostream&
+operator<<(ostream& out, const NetDest& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //NETDEST_H
+#endif // __MEM_RUBY_COMMON_NETDEST_HH__
Source('Driver.cc')
Source('Global.cc')
Source('Histogram.cc')
-Source('Message.cc')
Source('NetDest.cc')
Source('Set.cc', Werror=False)
Source('SubBlock.cc')
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
#include "mem/ruby/common/SubBlock.hh"
SubBlock::SubBlock(const Address& addr, int size)
{
- m_address = addr;
- setSize(size);
- for(int i=0; i<size; i++) {
- setByte(i, 0);
- }
+ m_address = addr;
+ setSize(size);
+ for (int i = 0; i < size; i++) {
+ setByte(i, 0);
+ }
}
-void SubBlock::internalMergeFrom(const DataBlock& data)
+void
+SubBlock::internalMergeFrom(const DataBlock& data)
{
- int size = getSize();
- assert(size > 0);
- int offset = m_address.getOffset();
- for(int i=0; i<size; i++) {
- this->setByte(i, data.getByte(offset+i));
- }
+ int size = getSize();
+ assert(size > 0);
+ int offset = m_address.getOffset();
+ for (int i = 0; i < size; i++) {
+ this->setByte(i, data.getByte(offset + i));
+ }
}
-void SubBlock::internalMergeTo(DataBlock& data) const
+void
+SubBlock::internalMergeTo(DataBlock& data) const
{
- int size = getSize();
- assert(size > 0);
- int offset = m_address.getOffset();
- for(int i=0; i<size; i++) {
- data.setByte(offset+i, this->getByte(i)); // This will detect crossing a cache line boundary
- }
+ int size = getSize();
+ assert(size > 0);
+ int offset = m_address.getOffset();
+ for (int i = 0; i < size; i++) {
+ // This will detect crossing a cache line boundary
+ data.setByte(offset + i, this->getByte(i));
+ }
}
-void SubBlock::print(ostream& out) const
+void
+SubBlock::print(ostream& out) const
{
- out << "[" << m_address << ", " << getSize() << ", " << m_data << "]";
+ out << "[" << m_address << ", " << getSize() << ", " << m_data << "]";
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- */
+#ifndef __MEM_RUBY_COMMON_SUBBLOCK_HH__
+#define __MEM_RUBY_COMMON_SUBBLOCK_HH__
-#ifndef SubBlock_H
-#define SubBlock_H
-
-#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Vector.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/DataBlock.hh"
-#include "mem/gems_common/Vector.hh"
-
-class SubBlock {
-public:
- // Constructors
- SubBlock() { }
- SubBlock(const Address& addr, int size);
+#include "mem/ruby/common/Global.hh"
- // Destructor
- ~SubBlock() { }
+class SubBlock
+{
+ public:
+ SubBlock() { }
+ SubBlock(const Address& addr, int size);
+ ~SubBlock() { }
- // Public Methods
- const Address& getAddress() const { return m_address; }
- void setAddress(const Address& addr) { m_address = addr; }
+ const Address& getAddress() const { return m_address; }
+ void setAddress(const Address& addr) { m_address = addr; }
- int getSize() const { return m_data.size(); }
- void setSize(int size) { m_data.setSize(size); }
- uint8 getByte(int offset) const { return m_data[offset]; }
- void setByte(int offset, uint8 data) { m_data[offset] = data; }
+ int getSize() const { return m_data.size(); }
+ void setSize(int size) { m_data.setSize(size); }
+ uint8 getByte(int offset) const { return m_data[offset]; }
+ void setByte(int offset, uint8 data) { m_data[offset] = data; }
- // Shorthands
- uint8 readByte() const { return getByte(0); }
- void writeByte(uint8 data) { setByte(0, data); }
+ // Shorthands
+ uint8 readByte() const { return getByte(0); }
+ void writeByte(uint8 data) { setByte(0, data); }
- // Merging to and from DataBlocks - We only need to worry about
- // updates when we are using DataBlocks
- void mergeTo(DataBlock& data) const { internalMergeTo(data); }
- void mergeFrom(const DataBlock& data) { internalMergeFrom(data); }
+ // Merging to and from DataBlocks - We only need to worry about
+ // updates when we are using DataBlocks
+ void mergeTo(DataBlock& data) const { internalMergeTo(data); }
+ void mergeFrom(const DataBlock& data) { internalMergeFrom(data); }
- void print(ostream& out) const;
-private:
+ void print(ostream& out) const;
- void internalMergeTo(DataBlock& data) const;
- void internalMergeFrom(const DataBlock& data);
+ private:
+ void internalMergeTo(DataBlock& data) const;
+ void internalMergeFrom(const DataBlock& data);
- // Data Members (m_ prefix)
- Address m_address;
- Vector<uint8_t> m_data;
+ // Data Members (m_ prefix)
+ Address m_address;
+ Vector<uint8_t> m_data;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const SubBlock& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const SubBlock& obj)
+inline ostream&
+operator<<(ostream& out, const SubBlock& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //SubBlock_H
+#endif // __MEM_RUBY_COMMON_SUBBLOCK_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
-#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/common/Consumer.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/eventqueue/RubyEventQueueNode.hh"
-
-// Class public method definitions
+#include "mem/ruby/system/System.hh"
RubyEventQueue::RubyEventQueue(EventQueue* eventq, Tick _clock)
: EventManager(eventq), m_clock(_clock)
{
}
-void RubyEventQueue::scheduleEvent(Consumer* consumer, Time timeDelta)
-{
- scheduleEventAbsolute(consumer, timeDelta + getTime());
+void
+RubyEventQueue::scheduleEvent(Consumer* consumer, Time timeDelta)
+{
+ scheduleEventAbsolute(consumer, timeDelta + getTime());
}
-void RubyEventQueue::scheduleEventAbsolute(Consumer* consumer, Time timeAbs)
+void
+RubyEventQueue::scheduleEventAbsolute(Consumer* consumer, Time timeAbs)
{
- // Check to see if this is a redundant wakeup
- ASSERT(consumer != NULL);
- if (!consumer->alreadyScheduled(timeAbs)) {
- // This wakeup is not redundant
- RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer, this);
- assert(timeAbs > getTime());
- schedule(thisNode, (timeAbs * m_clock));
- consumer->insertScheduledWakeupTime(timeAbs);
- }
+ // Check to see if this is a redundant wakeup
+ ASSERT(consumer != NULL);
+ if (!consumer->alreadyScheduled(timeAbs)) {
+ // This wakeup is not redundant
+ RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer, this);
+ assert(timeAbs > getTime());
+ schedule(thisNode, (timeAbs * m_clock));
+ consumer->insertScheduledWakeupTime(timeAbs);
+ }
}
-// Class private method definitions
-
void
RubyEventQueue::print(ostream& out) const
{
- out << "[Event Queue:]";
+ out << "[Event Queue:]";
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * $Id$
- *
- * Description: The RubyEventQueue class implements an event queue which
+ * The RubyEventQueue class implements an event queue which
* can be trigger events, allowing our simulation to be event driven.
*
* Currently, the only event we support is a Consumer being signaled
*
*/
-#ifndef RUBYEVENTQUEUE_H
-#define RUBYEVENTQUEUE_H
+#ifndef __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUE_HH__
+#define __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUE_HH__
#include <iostream>
template <class TYPE> class PrioHeap;
class RubyEventQueueNode;
-class RubyEventQueue : public EventManager {
-public:
- // Constructors
- RubyEventQueue(EventQueue* eventq, Tick _clock);
-
- // Destructor
- ~RubyEventQueue();
-
- // Public Methods
-
- Time getTime() const { return curTick/m_clock; }
- Tick getClock() const { return m_clock; }
- void scheduleEvent(Consumer* consumer, Time timeDelta);
- void scheduleEventAbsolute(Consumer* consumer, Time timeAbs);
- void print(std::ostream& out) const;
-
- void triggerEvents(Time t) { assert(0); }
- void triggerAllEvents() { assert(0); }
-
- // Private Methods
-private:
- // Private copy constructor and assignment operator
- RubyEventQueue(const RubyEventQueue& obj);
- RubyEventQueue& operator=(const RubyEventQueue& obj);
-
- // Data Members (m_ prefix)
- Tick m_clock;
+class RubyEventQueue : public EventManager
+{
+ public:
+ RubyEventQueue(EventQueue* eventq, Tick _clock);
+ ~RubyEventQueue();
+
+ Time getTime() const { return curTick/m_clock; }
+ Tick getClock() const { return m_clock; }
+ void scheduleEvent(Consumer* consumer, Time timeDelta);
+ void scheduleEventAbsolute(Consumer* consumer, Time timeAbs);
+ void print(std::ostream& out) const;
+
+ void triggerEvents(Time t) { assert(0); }
+ void triggerAllEvents() { assert(0); }
+
+ private:
+ // Private copy constructor and assignment operator
+ RubyEventQueue(const RubyEventQueue& obj);
+ RubyEventQueue& operator=(const RubyEventQueue& obj);
+
+ // Data Members (m_ prefix)
+ Tick m_clock;
};
-// Output operator declaration
-inline extern
-std::ostream& operator<<(std::ostream& out, const RubyEventQueue& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-inline extern
-std::ostream& operator<<(std::ostream& out, const RubyEventQueue& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const RubyEventQueue& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //EVENTQUEUE_H
+#endif // __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUE_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- */
-
#include "mem/ruby/eventqueue/RubyEventQueueNode.hh"
-void RubyEventQueueNode::print(std::ostream& out) const
+void
+RubyEventQueueNode::print(std::ostream& out) const
{
- out << "[";
- if (m_consumer_ptr != NULL) {
- out << " Consumer=" << m_consumer_ptr;
- } else {
- out << " Consumer=NULL";
- }
- out << "]";
+ out << "[";
+ if (m_consumer_ptr != NULL) {
+ out << " Consumer=" << m_consumer_ptr;
+ } else {
+ out << " Consumer=NULL";
+ }
+ out << "]";
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- */
-
-#ifndef RUBYEVENTQUEUENODE_H
-#define RUBYEVENTQUEUENODE_H
+#ifndef __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUENODE_HH__
+#define __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUENODE_HH__
#include <iostream>
+#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/Global.hh"
#include "sim/eventq.hh"
-#include "mem/ruby/common/Consumer.hh"
-//class Consumer;
-class RubyEventQueueNode : public Event {
-public:
- // Constructors
- RubyEventQueueNode(Consumer* _consumer, RubyEventQueue* _eventq)
- : m_consumer_ptr(_consumer), m_eventq_ptr(_eventq)
- {
- setFlags(AutoDelete);
- }
-
- // Destructor
- //~RubyEventQueueNode();
-
- // Public Methods
- void print(std::ostream& out) const;
- virtual void process()
- {
- m_consumer_ptr->wakeup();
- m_consumer_ptr->removeScheduledWakeupTime(m_eventq_ptr->getTime());
- }
- virtual const char *description() const { return "Ruby Event"; }
-
-private:
- // Private Methods
+class RubyEventQueueNode : public Event
+{
+ public:
+ RubyEventQueueNode(Consumer* _consumer, RubyEventQueue* _eventq)
+ : m_consumer_ptr(_consumer), m_eventq_ptr(_eventq)
+ {
+ setFlags(AutoDelete);
+ }
- // Default copy constructor and assignment operator
- // RubyEventQueueNode(const RubyEventQueueNode& obj);
+ void print(std::ostream& out) const;
+ virtual void
+ process()
+ {
+ m_consumer_ptr->wakeup();
+ m_consumer_ptr->removeScheduledWakeupTime(m_eventq_ptr->getTime());
+ }
+ virtual const char *description() const { return "Ruby Event"; }
- // Data Members (m_ prefix)
- Consumer* m_consumer_ptr;
- RubyEventQueue* m_eventq_ptr;
+ private:
+ Consumer* m_consumer_ptr;
+ RubyEventQueue* m_eventq_ptr;
};
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const RubyEventQueueNode& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const RubyEventQueueNode& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const RubyEventQueueNode& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //EVENTQUEUENODE_H
+#endif // __MEM_RUBY_EVENTQUEUE_EVENTQUEUENODE_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * AbstractBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef ABSTRACT_BLOOM_FILTER_H
-#define ABSTRACT_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
-class AbstractBloomFilter {
-public:
-
- virtual ~AbstractBloomFilter() {};
- virtual void clear() = 0;
- virtual void increment(const Address& addr) = 0;
- virtual void decrement(const Address& addr) = 0;
- virtual void merge(AbstractBloomFilter * other_filter) = 0;
- virtual void set(const Address& addr) = 0;
- virtual void unset(const Address& addr) = 0;
-
- virtual bool isSet(const Address& addr) = 0;
- virtual int getCount(const Address& addr) = 0;
- virtual int getTotalCount() = 0;
-
- virtual void print(ostream& out) const = 0;
-
- virtual int getIndex(const Address& addr) = 0;
- virtual int readBit(const int index) = 0;
- virtual void writeBit(const int index, const int value) = 0;
-
-private:
-
+class AbstractBloomFilter
+{
+ public:
+ virtual ~AbstractBloomFilter() {};
+ virtual void clear() = 0;
+ virtual void increment(const Address& addr) = 0;
+ virtual void decrement(const Address& addr) = 0;
+ virtual void merge(AbstractBloomFilter * other_filter) = 0;
+ virtual void set(const Address& addr) = 0;
+ virtual void unset(const Address& addr) = 0;
+
+ virtual bool isSet(const Address& addr) = 0;
+ virtual int getCount(const Address& addr) = 0;
+ virtual int getTotalCount() = 0;
+
+ virtual void print(ostream& out) const = 0;
+
+ virtual int getIndex(const Address& addr) = 0;
+ virtual int readBit(const int index) = 0;
+ virtual void writeBit(const int index, const int value) = 0;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * BlockBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/BlockBloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/BlockBloomFilter.hh"
BlockBloomFilter::BlockBloomFilter(string str)
{
- string tail(str);
- string head = string_split(tail, '_');
+ string tail(str);
+ string head = string_split(tail, '_');
- m_filter_size = atoi(head.c_str());
- m_filter_size_bits = log_int(m_filter_size);
+ m_filter_size = atoi(head.c_str());
+ m_filter_size_bits = log_int(m_filter_size);
- m_filter.setSize(m_filter_size);
+ m_filter.setSize(m_filter_size);
- clear();
+ clear();
}
-BlockBloomFilter::~BlockBloomFilter(){
+BlockBloomFilter::~BlockBloomFilter()
+{
}
-void BlockBloomFilter::clear()
+void
+BlockBloomFilter::clear()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
}
-void BlockBloomFilter::increment(const Address& addr)
+void
+BlockBloomFilter::increment(const Address& addr)
{
- // Not used
+ // Not used
}
-
-void BlockBloomFilter::decrement(const Address& addr)
+void
+BlockBloomFilter::decrement(const Address& addr)
{
- // Not used
+ // Not used
}
-void BlockBloomFilter::merge(AbstractBloomFilter * other_filter)
+void
+BlockBloomFilter::merge(AbstractBloomFilter * other_filter)
{
- // TODO
+ // TODO
}
-void BlockBloomFilter::set(const Address& addr)
+void
+BlockBloomFilter::set(const Address& addr)
{
- int i = get_index(addr);
- m_filter[i] = 1;
+ int i = get_index(addr);
+ m_filter[i] = 1;
}
-void BlockBloomFilter::unset(const Address& addr)
+void
+BlockBloomFilter::unset(const Address& addr)
{
- int i = get_index(addr);
- m_filter[i] = 0;
+ int i = get_index(addr);
+ m_filter[i] = 0;
}
-bool BlockBloomFilter::isSet(const Address& addr)
+bool
+BlockBloomFilter::isSet(const Address& addr)
{
- int i = get_index(addr);
- return (m_filter[i]);
+ int i = get_index(addr);
+ return (m_filter[i]);
}
-
-int BlockBloomFilter::getCount(const Address& addr)
+int
+BlockBloomFilter::getCount(const Address& addr)
{
- return m_filter[get_index(addr)];
+ return m_filter[get_index(addr)];
}
-int BlockBloomFilter::getTotalCount()
+int
+BlockBloomFilter::getTotalCount()
{
- int count = 0;
+ int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- if (m_filter[i]) {
- count++;
+ for (int i = 0; i < m_filter_size; i++) {
+ if (m_filter[i]) {
+ count++;
+ }
}
- }
- return count;
+ return count;
}
-int BlockBloomFilter::getIndex(const Address& addr)
+int
+BlockBloomFilter::getIndex(const Address& addr)
{
- return get_index(addr);
+ return get_index(addr);
}
-void BlockBloomFilter::print(ostream& out) const
+void
+BlockBloomFilter::print(ostream& out) const
{
}
-int BlockBloomFilter::readBit(const int index) {
- return m_filter[index];
+int
+BlockBloomFilter::readBit(const int index)
+{
+ return m_filter[index];
}
-void BlockBloomFilter::writeBit(const int index, const int value) {
- m_filter[index] = value;
+void
+BlockBloomFilter::writeBit(const int index, const int value)
+{
+ m_filter[index] = value;
}
-int BlockBloomFilter::get_index(const Address& addr)
+int
+BlockBloomFilter::get_index(const Address& addr)
{
- // Pull out some bit field ==> B1
- // Pull out additional bits, not the same as B1 ==> B2
- // XOR B1 and B2 to get hash index
- physical_address_t block_bits = addr.bitSelect( RubySystem::getBlockSizeBits(), 2*RubySystem::getBlockSizeBits() - 1);
- int offset = 5;
- physical_address_t other_bits = addr.bitSelect( 2*RubySystem::getBlockSizeBits() + offset, 2*RubySystem::getBlockSizeBits() + offset + m_filter_size_bits - 1);
- int index = block_bits ^ other_bits;
- assert(index < m_filter_size);
- return index;
+ // Pull out some bit field ==> B1
+ // Pull out additional bits, not the same as B1 ==> B2
+ // XOR B1 and B2 to get hash index
+ physical_address_t block_bits =
+ addr.bitSelect(RubySystem::getBlockSizeBits(),
+ 2 * RubySystem::getBlockSizeBits() - 1);
+ int offset = 5;
+ physical_address_t other_bits =
+ addr.bitSelect(2 * RubySystem::getBlockSizeBits() + offset,
+ 2 * RubySystem::getBlockSizeBits() + offset +
+ m_filter_size_bits - 1);
+ int index = block_bits ^ other_bits;
+ assert(index < m_filter_size);
+ return index;
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * BlockBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef BLOCK_BLOOM_FILTER_H
-#define BLOCK_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
-class BlockBloomFilter : public AbstractBloomFilter {
-public:
+class BlockBloomFilter : public AbstractBloomFilter
+{
+ public:
+ BlockBloomFilter(string config);
+ ~BlockBloomFilter();
- ~BlockBloomFilter();
- BlockBloomFilter(string config);
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
+ void print(ostream& out) const;
- void print(ostream& out) const;
+ private:
+ int get_index(const Address& addr);
-private:
+ Vector<int> m_filter;
+ int m_filter_size;
+ int m_filter_size_bits;
- int get_index(const Address& addr);
-
- Vector<int> m_filter;
- int m_filter_size;
- int m_filter_size_bits;
-
- int m_count_bits;
- int m_count;
+ int m_count_bits;
+ int m_count;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * BulkBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/BulkBloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/BulkBloomFilter.hh"
BulkBloomFilter::BulkBloomFilter(string str)
{
- string tail(str);
- string head = string_split(tail, '_');
+ string tail(str);
+ string head = string_split(tail, '_');
- m_filter_size = atoi(head.c_str());
- m_filter_size_bits = log_int(m_filter_size);
- // split the filter bits in half, c0 and c1
- m_sector_bits = m_filter_size_bits - 1;
+ m_filter_size = atoi(head.c_str());
+ m_filter_size_bits = log_int(m_filter_size);
+ // split the filter bits in half, c0 and c1
+ m_sector_bits = m_filter_size_bits - 1;
- m_temp_filter.setSize(m_filter_size);
- m_filter.setSize(m_filter_size);
- clear();
-
- // clear temp filter
- for(int i=0; i < m_filter_size; ++i){
- m_temp_filter[i] = 0;
- }
-}
-
-BulkBloomFilter::~BulkBloomFilter(){
+ m_temp_filter.setSize(m_filter_size);
+ m_filter.setSize(m_filter_size);
+ clear();
+ // clear temp filter
+ for (int i = 0; i < m_filter_size; ++i) {
+ m_temp_filter[i] = 0;
+ }
}
-void BulkBloomFilter::clear()
+BulkBloomFilter::~BulkBloomFilter()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
}
-void BulkBloomFilter::increment(const Address& addr)
+void
+BulkBloomFilter::clear()
{
- // Not used
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
}
-
-void BulkBloomFilter::decrement(const Address& addr)
+void
+BulkBloomFilter::increment(const Address& addr)
{
- // Not used
+ // Not used
}
-void BulkBloomFilter::merge(AbstractBloomFilter * other_filter)
+void
+BulkBloomFilter::decrement(const Address& addr)
{
- // TODO
+ // Not used
}
-void BulkBloomFilter::set(const Address& addr)
+void
+BulkBloomFilter::merge(AbstractBloomFilter * other_filter)
{
- // c0 contains the cache index bits
- int set_bits = m_sector_bits;
- int block_bits = RubySystem::getBlockSizeBits();
- int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1);
- // c1 contains the lower m_sector_bits permuted bits
- //Address permuted_bits = permute(addr);
- //int c1 = permuted_bits.bitSelect(0, set_bits-1);
- int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1);
- //ASSERT(c0 < (m_filter_size/2));
- //ASSERT(c0 + (m_filter_size/2) < m_filter_size);
- //ASSERT(c1 < (m_filter_size/2));
- // set v0 bit
- m_filter[c0 + (m_filter_size/2)] = 1;
- // set v1 bit
- m_filter[c1] = 1;
+ // TODO
}
-void BulkBloomFilter::unset(const Address& addr)
+void
+BulkBloomFilter::set(const Address& addr)
+{
+ // c0 contains the cache index bits
+ int set_bits = m_sector_bits;
+ int block_bits = RubySystem::getBlockSizeBits();
+ int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1);
+ // c1 contains the lower m_sector_bits permuted bits
+ //Address permuted_bits = permute(addr);
+ //int c1 = permuted_bits.bitSelect(0, set_bits-1);
+ int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1);
+ //ASSERT(c0 < (m_filter_size/2));
+ //ASSERT(c0 + (m_filter_size/2) < m_filter_size);
+ //ASSERT(c1 < (m_filter_size/2));
+ // set v0 bit
+ m_filter[c0 + (m_filter_size/2)] = 1;
+ // set v1 bit
+ m_filter[c1] = 1;
+}
+
+void
+BulkBloomFilter::unset(const Address& addr)
{
- // not used
+ // not used
}
-bool BulkBloomFilter::isSet(const Address& addr)
+bool
+BulkBloomFilter::isSet(const Address& addr)
{
- // c0 contains the cache index bits
- int set_bits = m_sector_bits;
- int block_bits = RubySystem::getBlockSizeBits();
- int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1);
- // c1 contains the lower 10 permuted bits
- //Address permuted_bits = permute(addr);
- //int c1 = permuted_bits.bitSelect(0, set_bits-1);
- int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1);
- //ASSERT(c0 < (m_filter_size/2));
- //ASSERT(c0 + (m_filter_size/2) < m_filter_size);
- //ASSERT(c1 < (m_filter_size/2));
- // set v0 bit
- m_temp_filter[c0 + (m_filter_size/2)] = 1;
- // set v1 bit
- m_temp_filter[c1] = 1;
+ // c0 contains the cache index bits
+ int set_bits = m_sector_bits;
+ int block_bits = RubySystem::getBlockSizeBits();
+ int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1);
+ // c1 contains the lower 10 permuted bits
+ //Address permuted_bits = permute(addr);
+ //int c1 = permuted_bits.bitSelect(0, set_bits-1);
+ int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1);
+ //ASSERT(c0 < (m_filter_size/2));
+ //ASSERT(c0 + (m_filter_size/2) < m_filter_size);
+ //ASSERT(c1 < (m_filter_size/2));
+ // set v0 bit
+ m_temp_filter[c0 + (m_filter_size/2)] = 1;
+ // set v1 bit
+ m_temp_filter[c1] = 1;
+
+ // perform filter intersection. If any c part is 0, no possibility
+ // of address being in signature. get first c intersection part
+ bool zero = false;
+ for (int i = 0; i < m_filter_size/2; ++i){
+ // get intersection of signatures
+ m_temp_filter[i] = m_temp_filter[i] && m_filter[i];
+ zero = zero || m_temp_filter[i];
+ }
+ zero = !zero;
+ if (zero) {
+ // one section is zero, no possiblility of address in signature
+ // reset bits we just set
+ m_temp_filter[c0 + (m_filter_size / 2)] = 0;
+ m_temp_filter[c1] = 0;
+ return false;
+ }
- // perform filter intersection. If any c part is 0, no possibility of address being in signature.
- // get first c intersection part
- bool zero = false;
- for(int i=0; i < m_filter_size/2; ++i){
- // get intersection of signatures
- m_temp_filter[i] = m_temp_filter[i] && m_filter[i];
- zero = zero || m_temp_filter[i];
- }
- zero = !zero;
- if(zero){
- // one section is zero, no possiblility of address in signature
- // reset bits we just set
- m_temp_filter[c0 + (m_filter_size/2)] = 0;
- m_temp_filter[c1] = 0;
- return false;
- }
-
- // check second section
- zero = false;
- for(int i=m_filter_size/2; i < m_filter_size; ++i){
- // get intersection of signatures
- m_temp_filter[i] = m_temp_filter[i] && m_filter[i];
- zero = zero || m_temp_filter[i];
- }
- zero = !zero;
- if(zero){
- // one section is zero, no possiblility of address in signature
- m_temp_filter[c0 + (m_filter_size/2)] = 0;
+ // check second section
+ zero = false;
+ for(int i = m_filter_size / 2; i < m_filter_size; ++i) {
+ // get intersection of signatures
+ m_temp_filter[i] = m_temp_filter[i] && m_filter[i];
+ zero = zero || m_temp_filter[i];
+ }
+ zero = !zero;
+ if (zero) {
+ // one section is zero, no possiblility of address in signature
+ m_temp_filter[c0 + (m_filter_size / 2)] = 0;
+ m_temp_filter[c1] = 0;
+ return false;
+ }
+ // one section has at least one bit set
+ m_temp_filter[c0 + (m_filter_size / 2)] = 0;
m_temp_filter[c1] = 0;
- return false;
- }
- // one section has at least one bit set
- m_temp_filter[c0 + (m_filter_size/2)] = 0;
- m_temp_filter[c1] = 0;
- return true;
+ return true;
}
-
-int BulkBloomFilter::getCount(const Address& addr)
+int
+BulkBloomFilter::getCount(const Address& addr)
{
- // not used
- return 0;
+ // not used
+ return 0;
}
-int BulkBloomFilter::getTotalCount()
+int
+BulkBloomFilter::getTotalCount()
{
- int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- if (m_filter[i]) {
- count++;
+ int count = 0;
+ for (int i = 0; i < m_filter_size; i++) {
+ if (m_filter[i]) {
+ count++;
+ }
}
- }
- return count;
+ return count;
}
-int BulkBloomFilter::getIndex(const Address& addr)
+int
+BulkBloomFilter::getIndex(const Address& addr)
{
- return get_index(addr);
+ return get_index(addr);
}
-int BulkBloomFilter::readBit(const int index) {
- return 0;
- // TODO
+int
+BulkBloomFilter::readBit(const int index)
+{
+ return 0;
+ // TODO
}
-void BulkBloomFilter::writeBit(const int index, const int value) {
- // TODO
+void
+BulkBloomFilter::writeBit(const int index, const int value)
+{
+ // TODO
}
-void BulkBloomFilter::print(ostream& out) const
+void
+BulkBloomFilter::print(ostream& out) const
{
}
-int BulkBloomFilter::get_index(const Address& addr)
+int
+BulkBloomFilter::get_index(const Address& addr)
{
- return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1);
+ return addr.bitSelect(RubySystem::getBlockSizeBits(),
+ RubySystem::getBlockSizeBits() +
+ m_filter_size_bits - 1);
}
-Address BulkBloomFilter::permute(const Address & addr){
- // permutes the original address bits according to Table 5
- int block_offset = RubySystem::getBlockSizeBits();
- physical_address_t part1 = addr.bitSelect( block_offset, block_offset + 6 );
- physical_address_t part2 = addr.bitSelect( block_offset + 9, block_offset + 9 );
- physical_address_t part3 = addr.bitSelect( block_offset + 11, block_offset + 11 );
- physical_address_t part4 = addr.bitSelect( block_offset + 17, block_offset + 17 );
- physical_address_t part5 = addr.bitSelect( block_offset + 7, block_offset + 8 );
- physical_address_t part6 = addr.bitSelect( block_offset + 10, block_offset + 10 );
- physical_address_t part7 = addr.bitSelect( block_offset + 12, block_offset + 12 );
- physical_address_t part8 = addr.bitSelect( block_offset + 13, block_offset + 13 );
- physical_address_t part9 = addr.bitSelect( block_offset + 15, block_offset + 16 );
- physical_address_t part10 = addr.bitSelect( block_offset + 18, block_offset + 20 );
- physical_address_t part11 = addr.bitSelect( block_offset + 14, block_offset + 14 );
-
- physical_address_t result = (part1 << 14 ) | (part2 << 13 ) | (part3 << 12 ) | (part4 << 11 ) | (part5 << 9) | (part6 << 8)
- | (part7 << 7) | (part8 << 6) | (part9 << 4) | (part10 << 1) | (part11);
- // assume 32 bit addresses (both virtual and physical)
- // select the remaining high-order 11 bits
- physical_address_t remaining_bits = (addr.bitSelect( block_offset + 21, 31 )) << 21;
- result = result | remaining_bits;
-
- return Address(result);
+Address
+BulkBloomFilter::permute(const Address & addr)
+{
+ // permutes the original address bits according to Table 5
+ int block_offset = RubySystem::getBlockSizeBits();
+ physical_address_t part1 = addr.bitSelect(block_offset, block_offset + 6),
+ part2 = addr.bitSelect(block_offset + 9, block_offset + 9),
+ part3 = addr.bitSelect(block_offset + 11, block_offset + 11),
+ part4 = addr.bitSelect(block_offset + 17, block_offset + 17),
+ part5 = addr.bitSelect(block_offset + 7, block_offset + 8),
+ part6 = addr.bitSelect(block_offset + 10, block_offset + 10),
+ part7 = addr.bitSelect(block_offset + 12, block_offset + 12),
+ part8 = addr.bitSelect(block_offset + 13, block_offset + 13),
+ part9 = addr.bitSelect(block_offset + 15, block_offset + 16),
+ part10 = addr.bitSelect(block_offset + 18, block_offset + 20),
+ part11 = addr.bitSelect(block_offset + 14, block_offset + 14);
+
+ physical_address_t result =
+ (part1 << 14) | (part2 << 13) | (part3 << 12) | (part4 << 11) |
+ (part5 << 9) | (part6 << 8) | (part7 << 7) | (part8 << 6) |
+ (part9 << 4) | (part10 << 1) | (part11);
+
+ // assume 32 bit addresses (both virtual and physical)
+ // select the remaining high-order 11 bits
+ physical_address_t remaining_bits =
+ addr.bitSelect(block_offset + 21, 31) << 21;
+ result = result | remaining_bits;
+
+ return Address(result);
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * BulkBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef BULK_BLOOM_FILTER_H
-#define BULK_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
-class BulkBloomFilter : public AbstractBloomFilter {
-public:
+class BulkBloomFilter : public AbstractBloomFilter
+{
+ public:
+ BulkBloomFilter(string config);
+ ~BulkBloomFilter();
- ~BulkBloomFilter();
- BulkBloomFilter(string config);
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
+ void print(ostream& out) const;
- void print(ostream& out) const;
+ private:
+ int get_index(const Address& addr);
+ Address permute(const Address & addr);
-private:
+ Vector<int> m_filter;
+ Vector<int> m_temp_filter;
- int get_index(const Address& addr);
- Address permute(const Address & addr);
+ int m_filter_size;
+ int m_filter_size_bits;
- Vector<int> m_filter;
- Vector<int> m_temp_filter;
+ int m_sector_bits;
- int m_filter_size;
- int m_filter_size_bits;
-
- int m_sector_bits;
-
- int m_count_bits;
- int m_count;
+ int m_count_bits;
+ int m_count;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * GenericBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
-
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/filters/BlockBloomFilter.hh"
+#include "mem/ruby/filters/BulkBloomFilter.hh"
#include "mem/ruby/filters/GenericBloomFilter.hh"
+#include "mem/ruby/filters/H3BloomFilter.hh"
#include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
-#include "mem/ruby/filters/NonCountingBloomFilter.hh"
-#include "mem/ruby/filters/BulkBloomFilter.hh"
-#include "mem/ruby/filters/BlockBloomFilter.hh"
-#include "mem/ruby/filters/MultiGrainBloomFilter.hh"
#include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
-#include "mem/ruby/filters/H3BloomFilter.hh"
+#include "mem/ruby/filters/MultiGrainBloomFilter.hh"
+#include "mem/ruby/filters/NonCountingBloomFilter.hh"
GenericBloomFilter::GenericBloomFilter(string config)
{
- string tail(config);
- string head = string_split(tail,'_');
-
- if (head == "LSB_Counting" ) {
- m_filter = new LSB_CountingBloomFilter(tail);
- }
- else if(head == "NonCounting" ) {
- m_filter = new NonCountingBloomFilter(tail);
- }
- else if(head == "Bulk" ) {
- m_filter = new BulkBloomFilter(tail);
- }
- else if(head == "Block") {
- m_filter = new BlockBloomFilter(tail);
- }
- else if(head == "Multigrain"){
- m_filter = new MultiGrainBloomFilter(tail);
- }
- else if(head == "MultiBitSel"){
- m_filter = new MultiBitSelBloomFilter(tail);
- }
- else if(head == "H3"){
- m_filter = new H3BloomFilter(tail);
- }
- else {
- assert(0);
- }
+ string tail(config);
+ string head = string_split(tail,'_');
+
+ if (head == "LSB_Counting" ) {
+ m_filter = new LSB_CountingBloomFilter(tail);
+ } else if(head == "NonCounting" ) {
+ m_filter = new NonCountingBloomFilter(tail);
+ } else if(head == "Bulk" ) {
+ m_filter = new BulkBloomFilter(tail);
+ } else if(head == "Block") {
+ m_filter = new BlockBloomFilter(tail);
+ } else if(head == "Multigrain"){
+ m_filter = new MultiGrainBloomFilter(tail);
+ } else if(head == "MultiBitSel"){
+ m_filter = new MultiBitSelBloomFilter(tail);
+ } else if(head == "H3"){
+ m_filter = new H3BloomFilter(tail);
+ } else {
+ assert(0);
+ }
}
GenericBloomFilter::~GenericBloomFilter()
{
- delete m_filter;
+ delete m_filter;
}
-void GenericBloomFilter::clear()
+void
+GenericBloomFilter::clear()
{
- m_filter->clear();
+ m_filter->clear();
}
-void GenericBloomFilter::increment(const Address& addr)
+void
+GenericBloomFilter::increment(const Address& addr)
{
- m_filter->increment(addr);
+ m_filter->increment(addr);
}
-void GenericBloomFilter::decrement(const Address& addr)
+void
+GenericBloomFilter::decrement(const Address& addr)
{
- m_filter->decrement(addr);
+ m_filter->decrement(addr);
}
-void GenericBloomFilter::merge(GenericBloomFilter * other_filter)
+void
+GenericBloomFilter::merge(GenericBloomFilter * other_filter)
{
- m_filter->merge(other_filter->getFilter());
+ m_filter->merge(other_filter->getFilter());
}
-void GenericBloomFilter::set(const Address& addr)
+void
+GenericBloomFilter::set(const Address& addr)
{
- m_filter->set(addr);
+ m_filter->set(addr);
}
-void GenericBloomFilter::unset(const Address& addr)
+void
+GenericBloomFilter::unset(const Address& addr)
{
- m_filter->unset(addr);
+ m_filter->unset(addr);
}
-bool GenericBloomFilter::isSet(const Address& addr)
+bool
+GenericBloomFilter::isSet(const Address& addr)
{
- return m_filter->isSet(addr);
+ return m_filter->isSet(addr);
}
-int GenericBloomFilter::getCount(const Address& addr)
+int
+GenericBloomFilter::getCount(const Address& addr)
{
- return m_filter->getCount(addr);
+ return m_filter->getCount(addr);
}
-int GenericBloomFilter::getTotalCount()
+int
+GenericBloomFilter::getTotalCount()
{
- return m_filter->getTotalCount();
+ return m_filter->getTotalCount();
}
-int GenericBloomFilter::getIndex(const Address& addr)
+int
+GenericBloomFilter::getIndex(const Address& addr)
{
- return m_filter->getIndex(addr);
+ return m_filter->getIndex(addr);
}
-int GenericBloomFilter::readBit(const int index) {
- return m_filter->readBit(index);
+int
+GenericBloomFilter::readBit(const int index)
+{
+ return m_filter->readBit(index);
}
-void GenericBloomFilter::writeBit(const int index, const int value) {
- m_filter->writeBit(index, value);
+void
+GenericBloomFilter::writeBit(const int index, const int value)
+{
+ m_filter->writeBit(index, value);
}
-void GenericBloomFilter::print(ostream& out) const
+void
+GenericBloomFilter::print(ostream& out) const
{
- return m_filter->print(out);
+ return m_filter->print(out);
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * GenericBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef GENERIC_BLOOM_FILTER_H
-#define GENERIC_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_GENERICBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_GENERICBLOOMFILTER_HH__
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
-class GenericBloomFilter {
-public:
-
- // Constructors
- GenericBloomFilter(string config);
-
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(GenericBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
- AbstractBloomFilter * getFilter(){
- return m_filter;
- }
-
- bool isSet(const Address& addr);
-
- int getCount(const Address& addr);
+class GenericBloomFilter
+{
+ public:
+ GenericBloomFilter(string config);
+ ~GenericBloomFilter();
- int getTotalCount();
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(GenericBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
+ AbstractBloomFilter *
+ getFilter()
+ {
+ return m_filter;
+ }
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
+ bool isSet(const Address& addr);
- void print(ostream& out) const;
- void printConfig(ostream& out) { out << "GenericBloomFilter" << endl; }
+ int getCount(const Address& addr);
- // Destructor
- ~GenericBloomFilter();
+ int getTotalCount();
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
-private:
+ void print(ostream& out) const;
+ void printConfig(ostream& out) { out << "GenericBloomFilter" << endl; }
- AbstractBloomFilter* m_filter;
+ private:
+ AbstractBloomFilter* m_filter;
};
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const GenericBloomFilter& obj)
+inline ostream&
+operator<<(ostream& out, const GenericBloomFilter& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-
-#endif
+#endif // __MEM_RUBY_FILTERS_GENERICBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NonCountingBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/H3BloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/H3BloomFilter.hh"
static int H3[64][16] = {
-{
-33268410,
-395488709,
-311024285,
-456111753,
-181495008,
-119997521,
-220697869,
-433891432,
-755927921,
-515226970,
-719448198,
-349842774,
-269183649,
-463275672,
-429800228,
-521598937
-},
-{
-628677802,
-820947732,
-809435975,
-1024657192,
-887631270,
-412050215,
-391365090,
-324227279,
-318338329,
-1038393087,
-489807930,
-387366128,
-518096428,
-324184340,
-429376066,
-447109279
-},
-{
-599747653,
-404960623,
-103933604,
-946416030,
-656460913,
-925957005,
-1047665689,
-163552053,
-88359290,
-841315415,
-899833584,
-1067336680,
-348549994,
-464045876,
-270252128,
-829897652
-},
-{
-215495230,
-966696438,
-82589012,
-750102795,
-909780866,
-920285789,
-769759214,
-331966823,
-939936006,
-439950703,
-883794828,
-1009277508,
-61634610,
-741444350,
-98689608,
-524144422
-},
-{
-93868534,
-196958667,
-774076619,
-327921978,
-122538783,
-879785030,
-690748527,
-3498564,
-83163077,
-1027963025,
-582088444,
-466152216,
-312424878,
-550064499,
-646612667,
-561099434
-},
-{
-1002047931,
-395477707,
-821317480,
-890482112,
-697094476,
-263813044,
-840275189,
-469664185,
-795625845,
-211504898,
-99204277,
-1004491153,
-725930417,
-1064479221,
-893834767,
-839719181
-},
-{
-278507126,
-985111995,
-706462983,
-1042178726,
-123281719,
-963778122,
-500881056,
-726291104,
-134293026,
-568379664,
-317050609,
-533470307,
-1022365922,
-197645211,
-315125721,
-634827678
-},
-{
-219227366,
-553960647,
-870169525,
-322232839,
-508322497,
-648672696,
-249405795,
-883596102,
-476433133,
-541372919,
-646647793,
-1042679515,
-43242483,
-600187508,
-499866821,
-135713210
-},
-{
-52837162,
-96966684,
-401840460,
-1071661176,
-733560065,
-150035417,
-341319946,
-811582750,
-636173904,
-519054065,
-196321433,
-1028294565,
-882204070,
-522965093,
-48884074,
-117810166
-},
-{
-650860353,
-789534698,
-328813544,
-473250022,
-143128306,
-173196006,
-846958825,
-174632187,
-683273509,
-405459497,
-787235556,
-773873501,
-240110267,
-426797736,
-92043842,
-711789240
-},
-{
-586637493,
-5059646,
-398035664,
-6686087,
-498300175,
-948278148,
-681227731,
-592751744,
-572019677,
-558044722,
-589368271,
-695745538,
-1073416749,
-529192035,
-550984939,
-1070620580
-},
-{
-102904663,
-647598516,
-758863940,
-313426443,
-76504114,
-1050747783,
-708436441,
-563815069,
-224107668,
-875925186,
-167675944,
-926209739,
-279737287,
-1040288182,
-768184312,
-371708956
-},
-{
-683968868,
-1027427757,
-180781926,
-742898864,
-624078545,
-645659833,
-577225838,
-987150210,
-723410002,
-224013421,
-993286634,
-33188488,
-247264323,
-888018697,
-38048664,
-189037096
-},
-{
-475612146,
-426739285,
-873726278,
-529192871,
-607715202,
-388486246,
-987001312,
-474493980,
-259747270,
-417465536,
-217062395,
-392858482,
-563810075,
-137852805,
-1051814153,
-72895217
-},
-{
-71277086,
-785496675,
-500608842,
-89633426,
-274085706,
-248467935,
-838061983,
-48106147,
-773662506,
-49545328,
-9071573,
-100739031,
-602018002,
-904371654,
-534132064,
-332211304
-},
-{
-401893602,
-735125342,
-775548339,
-210224843,
-256081130,
-482894412,
-350801633,
-1035713633,
-429458128,
-327281409,
-739927752,
-359327650,
-886942880,
-847691759,
-752417993,
-359445596
-},
-{
-267472014,
-1050659620,
-1068232362,
-1049684368,
-17130239,
-690524969,
-793224378,
-14455158,
-423092885,
-873853424,
-430535778,
-7867877,
-309731959,
-370260786,
-862353083,
-403906850
-},
-{
-993077283,
-218812656,
-389234651,
-393202875,
-413116501,
-263300295,
-470013158,
-592730725,
-441847172,
-732392823,
-407574059,
-875664777,
-271347307,
-792954404,
-554774761,
-1022424300
-},
-{
-675919719,
-637054073,
-784720745,
-149714381,
-813144874,
-502525801,
-635436670,
-1003196587,
-160786091,
-947509775,
-969788637,
-26854073,
-257964369,
-63898568,
-539767732,
-772364518
-},
-{
-943076868,
-1021732472,
-697575075,
-15843624,
-617573396,
-534113303,
-122953324,
-964873912,
-942995378,
-87830944,
-1012914818,
-455484661,
-592160054,
-599844284,
-810394353,
-836812568
-},
-{
-688992674,
-279465370,
-731582262,
-687883235,
-438178468,
-80493001,
-342701501,
-663561405,
-23360106,
-531315007,
-508931618,
-36294623,
-231216223,
-840438413,
-255665680,
-663205938
-},
-{
-857265418,
-552630887,
-8173237,
-792122963,
-210140052,
-823124938,
-667709953,
-751538219,
-991957789,
-462064153,
-19070176,
-726604748,
-714567823,
-151147895,
-1012619677,
-697114353
-},
-{
-467105652,
-683256174,
-702387467,
-28730434,
-549942998,
-48712701,
-960519696,
-1008345587,
-679267717,
-370932249,
-880419471,
-352141567,
-331640403,
-598772468,
-95160685,
-812053015
-},
-{
-1053491323,
-430526562,
-1014938507,
-109685515,
-765949103,
-177288303,
-1034642653,
-485421658,
-71850281,
-981034542,
-61620389,
-601367920,
-504420930,
-220599168,
-583051998,
-158735752
-},
-{
-103033901,
-522494916,
-658494760,
-959206022,
-931348143,
-834510661,
-21542994,
-189699884,
-679327018,
-171983002,
-96774168,
-456133168,
-543103352,
-923945936,
-970074188,
-643658485
-},
-{
-566379913,
-805798263,
-840662512,
-820206124,
-796507494,
-223712542,
-118811519,
-662246595,
-809326534,
-416471323,
-748027186,
-161169753,
-739149488,
-276330378,
-924837051,
-964873733
-},
-{
-585882743,
-135502711,
-3386031,
-625631285,
-1068193307,
-270342640,
-432739484,
-556606453,
-826419155,
-1038540977,
-158000202,
-69109538,
-207087256,
-298111218,
-678046259,
-184611498
-},
-{
-305310710,
-46237988,
-855726974,
-735975153,
-930663798,
-425764232,
-104362407,
-391371443,
-867622101,
-71645091,
-61824734,
-661902640,
-293738633,
-309416189,
-281710675,
-879317360
-},
-{
-398146324,
-398293087,
-689145387,
-1038451703,
-521637478,
-516134620,
-314658937,
-830334981,
-583400300,
-340083705,
-68029852,
-675389876,
-994635780,
-788959180,
-406967042,
-74403607
-},
-{
-69463153,
-744427484,
-191639960,
-590927798,
-969916795,
-546846769,
-728756758,
-889355646,
-520855076,
-136068426,
-776132410,
-189663815,
-252051082,
-533662856,
-362198652,
-1026161384
-},
-{
-584984279,
-1004834381,
-568439705,
-834508761,
-21812513,
-670870173,
-1052043300,
-341868768,
-473755574,
-124339439,
-36193947,
-437997647,
-137419489,
-58705193,
-337793711,
-340738909
-},
-{
-898051466,
-512792906,
-234874060,
-655358775,
-683745319,
-671676404,
-428888546,
-639928192,
-672697722,
-176477579,
-747020991,
-758211282,
-443045009,
-205395173,
-1016944273,
-5584717
-},
-{
-156038300,
-138620174,
-588466825,
-1061494056,
-1013672100,
-1064257198,
-881417791,
-839470738,
-83519030,
-100875683,
-237486447,
-461483733,
-681527127,
-777996147,
-574635362,
-815974538
-},
-{
-184168473,
-519509808,
-62531892,
-51821173,
-43787358,
-385711644,
-141325169,
-36069511,
-584183031,
-571372909,
-671503175,
-226486781,
-194932686,
-1045460970,
-753718579,
-331442433
-},
-{
-73065106,
-1015327221,
-630916840,
-1058053470,
-306737587,
-296343219,
-907194989,
-920172546,
-224516225,
-818625553,
-551143849,
-634570650,
-432966225,
-756438259,
-939564853,
-767999933
-},
-{
-884775648,
-394862257,
-446787794,
-219833788,
-727195727,
-728122304,
-249888353,
-732947974,
-289908868,
-448282580,
-618161877,
-898939716,
-739554163,
-860631799,
-1058977530,
-86916736
-},
-{
-143850006,
-352708694,
-200194048,
-979764914,
-629404175,
-546279766,
-72106714,
-860980514,
-313190585,
-897143111,
-308425797,
-953791785,
-349924906,
-221457005,
-950588925,
-908254505
-},
-{
-950032043,
-829868728,
-68623614,
-714624605,
-69760597,
-297275854,
-355894016,
-985369737,
-882852618,
-864071289,
-958512902,
-950910111,
-991368991,
-829645051,
-434698210,
-771350575
-},
-{
-552695074,
-319195551,
-80297396,
-496413831,
-944046531,
-621525571,
-617653363,
-416729825,
-441842808,
-9847464,
-99420657,
-1033914550,
-812966458,
-937053011,
-673390195,
-934577365
-},
-{
-1034695843,
-190969665,
-332900185,
-51897434,
-523888639,
-883512843,
-146908572,
-506785674,
-565814307,
-692255649,
-314052926,
-826386588,
-430691325,
-866927620,
-413880214,
-936474339
-},
-{
-129380164,
-741739952,
-1013703462,
-494392795,
-957214600,
-1010879043,
-931790677,
-94551922,
-988065869,
-120637871,
-882506912,
-395075379,
-210570485,
-812422692,
-910383687,
-817722285
-},
-{
-51850866,
-283408630,
-1053047202,
-858940389,
-818507731,
-477082181,
-353546901,
-993324368,
-407093779,
-231608253,
-1067319867,
-73159811,
-429792535,
-971320614,
-565699344,
-718823399
-},
-{
-408185106,
-491493570,
-596050720,
-310776444,
-703628192,
-454438809,
-523988035,
-728512200,
-686012353,
-976339656,
-72816924,
-116926720,
-165866591,
-452043792,
-866943072,
-968545481
-},
-{
-443231195,
-905907843,
-1061421320,
-746360489,
-1043120338,
-1069659155,
-463359031,
-688303227,
-186550710,
-155347339,
-1044842421,
-1005904570,
-69332909,
-706951903,
-422513657,
-882038450
-},
-{
-430990623,
-946501980,
-742556791,
-278398643,
-183759217,
-659404315,
-279754382,
-1069347846,
-843746517,
-222777670,
-990835599,
-548741637,
-129220580,
-1392170,
-1032654091,
-894058935
-},
-{
-452042227,
-751640705,
-259481376,
-765824585,
-145991469,
-1013683228,
-1055491225,
-536379588,
-392593350,
-913368594,
-1029429776,
-226857786,
-31505342,
-1054416381,
-32341741,
-687106649
-},
-{
-404750944,
-811417027,
-869530820,
-773491060,
-810901282,
-979340397,
-1036910290,
-461764404,
-834235095,
-765695033,
-604692390,
-452158120,
-928988098,
-442719218,
-1024059719,
-167723114
-},
-{
-974245177,
-1046377300,
-1003424287,
-787349855,
-336314155,
-875074696,
-1018462718,
-890313003,
-367376809,
-86355556,
-1020618772,
-890710345,
-444741481,
-373230261,
-767064947,
-840920177
-},
-{
-719581124,
-431808156,
-138301690,
-668222575,
-497413494,
-740492013,
-485033226,
-125301442,
-831265111,
-879071459,
-341690480,
-152975256,
-850330086,
-717444507,
-694225877,
-785340566
-},
-{
-1032766252,
-140959364,
-737474726,
-1062767538,
-364464647,
-331414723,
-356152634,
-642832379,
-158733632,
-374691640,
-285504811,
-345349905,
-876599880,
-476392727,
-479589210,
-606376325
-},
-{
-174997730,
-778177086,
-319164313,
-163614456,
-10331364,
-599358958,
-8331663,
-237538058,
-159173957,
-174533880,
-65588684,
-878222844,
-424467599,
-901803515,
-187504218,
-776690353
-},
-{
-803856182,
-965850321,
-694948067,
-218315960,
-358416571,
-683713254,
-178069303,
-428076035,
-686176454,
-579553217,
-357306738,
-315018080,
-886852373,
-568563910,
-896839725,
-257416821
-},
-{
-401650013,
-183289141,
-497957228,
-879734476,
-265024455,
-825794561,
-889237440,
-323359863,
-100258491,
-991414783,
-313986632,
-85847250,
-362520248,
-276103512,
-1041630342,
-525981595
-},
-{
-487732740,
-46201705,
-990837834,
-62744493,
-1067364756,
-58015363,
-690846283,
-680262648,
-997278956,
-469357861,
-432164624,
-996763915,
-211907847,
-167824295,
-144928194,
-454839915
-},
-{
-41404232,
-514493300,
-259546924,
-578217256,
-972345130,
-123299213,
-346040332,
-1014668104,
-520910639,
-579955198,
-36627803,
-179072921,
-547684341,
-598950511,
-269497394,
-854352266
-},
-{
-603906768,
-100863318,
-708837659,
-204175569,
-375560904,
-908375384,
-28314106,
-6303733,
-175283124,
-749851198,
-308667367,
-415293931,
-225365403,
-1032188331,
-977112710,
-819705229
-},
-{
-399767123,
-697985692,
-356790426,
-643687584,
-298624218,
-185095167,
-381653926,
-876816342,
-296720023,
-2205879,
-235816616,
-521850105,
-622753786,
-1021421218,
-726349744,
-256504902
-},
-{
-851245024,
-1022500222,
-511909628,
-313809625,
-99776025,
-39710175,
-798739932,
-741832408,
-140631966,
-898295927,
-607660421,
-870669312,
-1051422478,
-789055529,
-669113756,
-681943450
-},
-{
-853872755,
-491465269,
-503341472,
-98019440,
-258267420,
-335602837,
-320687824,
-1053324395,
-24932389,
-955011453,
-934255131,
-435625663,
-501568768,
-238967025,
-549987406,
-248619780
-},
-{
-411151284,
-576471205,
-757985419,
-544137226,
-968135693,
-877548443,
-194586894,
-74882373,
-248353663,
-21207540,
-273789651,
-853653916,
-861267970,
-533253322,
-3739570,
-661358586
-},
-{
-271430986,
-71390029,
-257643671,
-949329860,
-348156406,
-251939238,
-445808698,
-48269799,
-907589462,
-105677619,
-635451508,
-20805932,
-464874661,
-7542147,
-243619464,
-288304568
-},
-{
-368215982,
-530288964,
-770090421,
-660961164,
-614935537,
-630760399,
-931299233,
-794519275,
-779918979,
-401746493,
-561237006,
-1027202224,
-258968003,
-339508073,
-1050610516,
-1064307013
-},
-{
-1039172162,
-448331205,
-928997884,
-49813151,
-198712120,
-992335354,
-671024050,
-879525220,
-745915336,
-1038822580,
-138669665,
-917958819,
-681422342,
-792868818,
-924762727,
-816386174
-},
-{
-515190336,
-313808618,
-441296783,
-1022120897,
-792325033,
-354387581,
-59273006,
-280075434,
-411357221,
-665274694,
-4054464,
-1059046246,
-394261773,
-848616745,
-15446017,
-517723271
-}};
+ { 33268410, 395488709, 311024285, 456111753,
+ 181495008, 119997521, 220697869, 433891432,
+ 755927921, 515226970, 719448198, 349842774,
+ 269183649, 463275672, 429800228, 521598937, },
+
+ { 628677802, 820947732, 809435975, 1024657192,
+ 887631270, 412050215, 391365090, 324227279,
+ 318338329, 1038393087, 489807930, 387366128,
+ 518096428, 324184340, 429376066, 447109279, },
+
+ { 599747653, 404960623, 103933604, 946416030,
+ 656460913, 925957005, 1047665689, 163552053,
+ 88359290, 841315415, 899833584, 1067336680,
+ 348549994, 464045876, 270252128, 829897652, },
+
+ { 215495230, 966696438, 82589012, 750102795,
+ 909780866, 920285789, 769759214, 331966823,
+ 939936006, 439950703, 883794828, 1009277508,
+ 61634610, 741444350, 98689608, 524144422, },
+
+ { 93868534, 196958667, 774076619, 327921978,
+ 122538783, 879785030, 690748527, 3498564,
+ 83163077, 1027963025, 582088444, 466152216,
+ 312424878, 550064499, 646612667, 561099434, },
+
+ { 1002047931, 395477707, 821317480, 890482112,
+ 697094476, 263813044, 840275189, 469664185,
+ 795625845, 211504898, 99204277, 1004491153,
+ 725930417, 1064479221, 893834767, 839719181, },
+
+ { 278507126, 985111995, 706462983, 1042178726,
+ 123281719, 963778122, 500881056, 726291104,
+ 134293026, 568379664, 317050609, 533470307,
+ 1022365922, 197645211, 315125721, 634827678, },
+
+ { 219227366, 553960647, 870169525, 322232839,
+ 508322497, 648672696, 249405795, 883596102,
+ 476433133, 541372919, 646647793, 1042679515,
+ 43242483, 600187508, 499866821, 135713210, },
+
+ { 52837162, 96966684, 401840460, 1071661176,
+ 733560065, 150035417, 341319946, 811582750,
+ 636173904, 519054065, 196321433, 1028294565,
+ 882204070, 522965093, 48884074, 117810166, },
+
+ { 650860353, 789534698, 328813544, 473250022,
+ 143128306, 173196006, 846958825, 174632187,
+ 683273509, 405459497, 787235556, 773873501,
+ 240110267, 426797736, 92043842, 711789240, },
+
+ { 586637493, 5059646, 398035664, 6686087,
+ 498300175, 948278148, 681227731, 592751744,
+ 572019677, 558044722, 589368271, 695745538,
+ 1073416749, 529192035, 550984939, 1070620580, },
+
+ { 102904663, 647598516, 758863940, 313426443,
+ 76504114, 1050747783, 708436441, 563815069,
+ 224107668, 875925186, 167675944, 926209739,
+ 279737287, 1040288182, 768184312, 371708956, },
+
+ { 683968868, 1027427757, 180781926, 742898864,
+ 624078545, 645659833, 577225838, 987150210,
+ 723410002, 224013421, 993286634, 33188488,
+ 247264323, 888018697, 38048664, 189037096, },
+
+ { 475612146, 426739285, 873726278, 529192871,
+ 607715202, 388486246, 987001312, 474493980,
+ 259747270, 417465536, 217062395, 392858482,
+ 563810075, 137852805, 1051814153, 72895217, },
+
+ { 71277086, 785496675, 500608842, 89633426,
+ 274085706, 248467935, 838061983, 48106147,
+ 773662506, 49545328, 9071573, 100739031,
+ 602018002, 904371654, 534132064, 332211304, },
+
+ { 401893602, 735125342, 775548339, 210224843,
+ 256081130, 482894412, 350801633, 1035713633,
+ 429458128, 327281409, 739927752, 359327650,
+ 886942880, 847691759, 752417993, 359445596, },
+
+ { 267472014, 1050659620, 1068232362, 1049684368,
+ 17130239, 690524969, 793224378, 14455158,
+ 423092885, 873853424, 430535778, 7867877,
+ 309731959, 370260786, 862353083, 403906850, },
+
+ { 993077283, 218812656, 389234651, 393202875,
+ 413116501, 263300295, 470013158, 592730725,
+ 441847172, 732392823, 407574059, 875664777,
+ 271347307, 792954404, 554774761, 1022424300, },
+
+ { 675919719, 637054073, 784720745, 149714381,
+ 813144874, 502525801, 635436670, 1003196587,
+ 160786091, 947509775, 969788637, 26854073,
+ 257964369, 63898568, 539767732, 772364518, },
+
+ { 943076868, 1021732472, 697575075, 15843624,
+ 617573396, 534113303, 122953324, 964873912,
+ 942995378, 87830944, 1012914818, 455484661,
+ 592160054, 599844284, 810394353, 836812568, },
+
+ { 688992674, 279465370, 731582262, 687883235,
+ 438178468, 80493001, 342701501, 663561405,
+ 23360106, 531315007, 508931618, 36294623,
+ 231216223, 840438413, 255665680, 663205938, },
+
+ { 857265418, 552630887, 8173237, 792122963,
+ 210140052, 823124938, 667709953, 751538219,
+ 991957789, 462064153, 19070176, 726604748,
+ 714567823, 151147895, 1012619677, 697114353, },
+
+ { 467105652, 683256174, 702387467, 28730434,
+ 549942998, 48712701, 960519696, 1008345587,
+ 679267717, 370932249, 880419471, 352141567,
+ 331640403, 598772468, 95160685, 812053015, },
+
+ { 1053491323, 430526562, 1014938507, 109685515,
+ 765949103, 177288303, 1034642653, 485421658,
+ 71850281, 981034542, 61620389, 601367920,
+ 504420930, 220599168, 583051998, 158735752, },
+
+ { 103033901, 522494916, 658494760, 959206022,
+ 931348143, 834510661, 21542994, 189699884,
+ 679327018, 171983002, 96774168, 456133168,
+ 543103352, 923945936, 970074188, 643658485, },
+
+ { 566379913, 805798263, 840662512, 820206124,
+ 796507494, 223712542, 118811519, 662246595,
+ 809326534, 416471323, 748027186, 161169753,
+ 739149488, 276330378, 924837051, 964873733, },
+
+ { 585882743, 135502711, 3386031, 625631285,
+ 1068193307, 270342640, 432739484, 556606453,
+ 826419155, 1038540977, 158000202, 69109538,
+ 207087256, 298111218, 678046259, 184611498, },
+
+ { 305310710, 46237988, 855726974, 735975153,
+ 930663798, 425764232, 104362407, 391371443,
+ 867622101, 71645091, 61824734, 661902640,
+ 293738633, 309416189, 281710675, 879317360, },
+
+ { 398146324, 398293087, 689145387, 1038451703,
+ 521637478, 516134620, 314658937, 830334981,
+ 583400300, 340083705, 68029852, 675389876,
+ 994635780, 788959180, 406967042, 74403607, },
+
+ { 69463153, 744427484, 191639960, 590927798,
+ 969916795, 546846769, 728756758, 889355646,
+ 520855076, 136068426, 776132410, 189663815,
+ 252051082, 533662856, 362198652, 1026161384, },
+
+ { 584984279, 1004834381, 568439705, 834508761,
+ 21812513, 670870173, 1052043300, 341868768,
+ 473755574, 124339439, 36193947, 437997647,
+ 137419489, 58705193, 337793711, 340738909, },
+
+ { 898051466, 512792906, 234874060, 655358775,
+ 683745319, 671676404, 428888546, 639928192,
+ 672697722, 176477579, 747020991, 758211282,
+ 443045009, 205395173, 1016944273, 5584717, },
+
+ { 156038300, 138620174, 588466825, 1061494056,
+ 1013672100, 1064257198, 881417791, 839470738,
+ 83519030, 100875683, 237486447, 461483733,
+ 681527127, 777996147, 574635362, 815974538, },
+
+ { 184168473, 519509808, 62531892, 51821173,
+ 43787358, 385711644, 141325169, 36069511,
+ 584183031, 571372909, 671503175, 226486781,
+ 194932686, 1045460970, 753718579, 331442433, },
+
+ { 73065106, 1015327221, 630916840, 1058053470,
+ 306737587, 296343219, 907194989, 920172546,
+ 224516225, 818625553, 551143849, 634570650,
+ 432966225, 756438259, 939564853, 767999933, },
+
+ { 884775648, 394862257, 446787794, 219833788,
+ 727195727, 728122304, 249888353, 732947974,
+ 289908868, 448282580, 618161877, 898939716,
+ 739554163, 860631799, 1058977530, 86916736, },
+
+ { 143850006, 352708694, 200194048, 979764914,
+ 629404175, 546279766, 72106714, 860980514,
+ 313190585, 897143111, 308425797, 953791785,
+ 349924906, 221457005, 950588925, 908254505, },
+
+ { 950032043, 829868728, 68623614, 714624605,
+ 69760597, 297275854, 355894016, 985369737,
+ 882852618, 864071289, 958512902, 950910111,
+ 991368991, 829645051, 434698210, 771350575, },
+
+ { 552695074, 319195551, 80297396, 496413831,
+ 944046531, 621525571, 617653363, 416729825,
+ 441842808, 9847464, 99420657, 1033914550,
+ 812966458, 937053011, 673390195, 934577365, },
+
+ { 1034695843, 190969665, 332900185, 51897434,
+ 523888639, 883512843, 146908572, 506785674,
+ 565814307, 692255649, 314052926, 826386588,
+ 430691325, 866927620, 413880214, 936474339, },
+
+ { 129380164, 741739952, 1013703462, 494392795,
+ 957214600, 1010879043, 931790677, 94551922,
+ 988065869, 120637871, 882506912, 395075379,
+ 210570485, 812422692, 910383687, 817722285, },
+
+ { 51850866, 283408630, 1053047202, 858940389,
+ 818507731, 477082181, 353546901, 993324368,
+ 407093779, 231608253, 1067319867, 73159811,
+ 429792535, 971320614, 565699344, 718823399, },
+
+ { 408185106, 491493570, 596050720, 310776444,
+ 703628192, 454438809, 523988035, 728512200,
+ 686012353, 976339656, 72816924, 116926720,
+ 165866591, 452043792, 866943072, 968545481, },
+
+ { 443231195, 905907843, 1061421320, 746360489,
+ 1043120338, 1069659155, 463359031, 688303227,
+ 186550710, 155347339, 1044842421, 1005904570,
+ 69332909, 706951903, 422513657, 882038450, },
+
+ { 430990623, 946501980, 742556791, 278398643,
+ 183759217, 659404315, 279754382, 1069347846,
+ 843746517, 222777670, 990835599, 548741637,
+ 129220580, 1392170, 1032654091, 894058935, },
+
+ { 452042227, 751640705, 259481376, 765824585,
+ 145991469, 1013683228, 1055491225, 536379588,
+ 392593350, 913368594, 1029429776, 226857786,
+ 31505342, 1054416381, 32341741, 687106649, },
+
+ { 404750944, 811417027, 869530820, 773491060,
+ 810901282, 979340397, 1036910290, 461764404,
+ 834235095, 765695033, 604692390, 452158120,
+ 928988098, 442719218, 1024059719, 167723114, },
+
+ { 974245177, 1046377300, 1003424287, 787349855,
+ 336314155, 875074696, 1018462718, 890313003,
+ 367376809, 86355556, 1020618772, 890710345,
+ 444741481, 373230261, 767064947, 840920177, },
+
+ { 719581124, 431808156, 138301690, 668222575,
+ 497413494, 740492013, 485033226, 125301442,
+ 831265111, 879071459, 341690480, 152975256,
+ 850330086, 717444507, 694225877, 785340566, },
+
+ { 1032766252, 140959364, 737474726, 1062767538,
+ 364464647, 331414723, 356152634, 642832379,
+ 158733632, 374691640, 285504811, 345349905,
+ 876599880, 476392727, 479589210, 606376325, },
+
+ { 174997730, 778177086, 319164313, 163614456,
+ 10331364, 599358958, 8331663, 237538058,
+ 159173957, 174533880, 65588684, 878222844,
+ 424467599, 901803515, 187504218, 776690353, },
+
+ { 803856182, 965850321, 694948067, 218315960,
+ 358416571, 683713254, 178069303, 428076035,
+ 686176454, 579553217, 357306738, 315018080,
+ 886852373, 568563910, 896839725, 257416821, },
+
+ { 401650013, 183289141, 497957228, 879734476,
+ 265024455, 825794561, 889237440, 323359863,
+ 100258491, 991414783, 313986632, 85847250,
+ 362520248, 276103512, 1041630342, 525981595, },
+
+ { 487732740, 46201705, 990837834, 62744493,
+ 1067364756, 58015363, 690846283, 680262648,
+ 997278956, 469357861, 432164624, 996763915,
+ 211907847, 167824295, 144928194, 454839915, },
+
+ { 41404232, 514493300, 259546924, 578217256,
+ 972345130, 123299213, 346040332, 1014668104,
+ 520910639, 579955198, 36627803, 179072921,
+ 547684341, 598950511, 269497394, 854352266, },
+
+ { 603906768, 100863318, 708837659, 204175569,
+ 375560904, 908375384, 28314106, 6303733,
+ 175283124, 749851198, 308667367, 415293931,
+ 225365403, 1032188331, 977112710, 819705229, },
+
+ { 399767123, 697985692, 356790426, 643687584,
+ 298624218, 185095167, 381653926, 876816342,
+ 296720023, 2205879, 235816616, 521850105,
+ 622753786, 1021421218, 726349744, 256504902, },
+
+ { 851245024, 1022500222, 511909628, 313809625,
+ 99776025, 39710175, 798739932, 741832408,
+ 140631966, 898295927, 607660421, 870669312,
+ 1051422478, 789055529, 669113756, 681943450, },
+
+ { 853872755, 491465269, 503341472, 98019440,
+ 258267420, 335602837, 320687824, 1053324395,
+ 24932389, 955011453, 934255131, 435625663,
+ 501568768, 238967025, 549987406, 248619780, },
+
+ { 411151284, 576471205, 757985419, 544137226,
+ 968135693, 877548443, 194586894, 74882373,
+ 248353663, 21207540, 273789651, 853653916,
+ 861267970, 533253322, 3739570, 661358586, },
+
+ { 271430986, 71390029, 257643671, 949329860,
+ 348156406, 251939238, 445808698, 48269799,
+ 907589462, 105677619, 635451508, 20805932,
+ 464874661, 7542147, 243619464, 288304568, },
+
+ { 368215982, 530288964, 770090421, 660961164,
+ 614935537, 630760399, 931299233, 794519275,
+ 779918979, 401746493, 561237006, 1027202224,
+ 258968003, 339508073, 1050610516, 1064307013, },
+
+ { 1039172162, 448331205, 928997884, 49813151,
+ 198712120, 992335354, 671024050, 879525220,
+ 745915336, 1038822580, 138669665, 917958819,
+ 681422342, 792868818, 924762727, 816386174, },
+
+ { 515190336, 313808618, 441296783, 1022120897,
+ 792325033, 354387581, 59273006, 280075434,
+ 411357221, 665274694, 4054464, 1059046246,
+ 394261773, 848616745, 15446017, 517723271, },
+};
H3BloomFilter::H3BloomFilter(string str)
{
- //TODO: change this ugly init code...
- primes_list[0] = 9323;
- primes_list[1] = 11279;
- primes_list[2] = 10247;
- primes_list[3] = 30637;
- primes_list[4] = 25717;
- primes_list[5] = 43711;
-
- mults_list[0] = 255;
- mults_list[1] = 29;
- mults_list[2] = 51;
- mults_list[3] = 3;
- mults_list[4] = 77;
- mults_list[5] = 43;
-
- adds_list[0] = 841;
- adds_list[1] = 627;
- adds_list[2] = 1555;
- adds_list[3] = 241;
- adds_list[4] = 7777;
- adds_list[5] = 65931;
-
-
-
- string tail(str);
- string head = string_split(tail, '_');
-
- // head contains filter size, tail contains bit offset from block number
- m_filter_size = atoi(head.c_str());
-
- head = string_split(tail, '_');
- m_num_hashes = atoi(head.c_str());
-
- if(tail == "Regular") {
- isParallel = false;
- } else if (tail == "Parallel") {
- isParallel = true;
- } else {
- cout << "ERROR: Incorrect config string for MultiHash Bloom! :" << str << endl;
- assert(0);
- }
-
- m_filter_size_bits = log_int(m_filter_size);
-
- m_par_filter_size = m_filter_size/m_num_hashes;
- m_par_filter_size_bits = log_int(m_par_filter_size);
-
- m_filter.setSize(m_filter_size);
- clear();
+ //TODO: change this ugly init code...
+ primes_list[0] = 9323;
+ primes_list[1] = 11279;
+ primes_list[2] = 10247;
+ primes_list[3] = 30637;
+ primes_list[4] = 25717;
+ primes_list[5] = 43711;
+
+ mults_list[0] = 255;
+ mults_list[1] = 29;
+ mults_list[2] = 51;
+ mults_list[3] = 3;
+ mults_list[4] = 77;
+ mults_list[5] = 43;
+
+ adds_list[0] = 841;
+ adds_list[1] = 627;
+ adds_list[2] = 1555;
+ adds_list[3] = 241;
+ adds_list[4] = 7777;
+ adds_list[5] = 65931;
+
+ string tail(str);
+ string head = string_split(tail, '_');
+
+ // head contains filter size, tail contains bit offset from block number
+ m_filter_size = atoi(head.c_str());
+
+ head = string_split(tail, '_');
+ m_num_hashes = atoi(head.c_str());
+
+ if(tail == "Regular") {
+ isParallel = false;
+ } else if (tail == "Parallel") {
+ isParallel = true;
+ } else {
+ cout << "ERROR: Incorrect config string for MultiHash Bloom! :"
+ << str << endl;
+ assert(0);
+ }
+
+ m_filter_size_bits = log_int(m_filter_size);
+
+ m_par_filter_size = m_filter_size/m_num_hashes;
+ m_par_filter_size_bits = log_int(m_par_filter_size);
+
+ m_filter.setSize(m_filter_size);
+ clear();
}
-H3BloomFilter::~H3BloomFilter(){
+H3BloomFilter::~H3BloomFilter()
+{
}
-void H3BloomFilter::clear()
+void
+H3BloomFilter::clear()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
}
-void H3BloomFilter::increment(const Address& addr)
+void
+H3BloomFilter::increment(const Address& addr)
{
- // Not used
+ // Not used
}
-
-void H3BloomFilter::decrement(const Address& addr)
+void
+H3BloomFilter::decrement(const Address& addr)
{
- // Not used
+ // Not used
}
-void H3BloomFilter::merge(AbstractBloomFilter * other_filter){
- // assumes both filters are the same size!
- H3BloomFilter * temp = (H3BloomFilter*) other_filter;
- for(int i=0; i < m_filter_size; ++i){
- m_filter[i] |= (*temp)[i];
- }
-
+void
+H3BloomFilter::merge(AbstractBloomFilter *other_filter)
+{
+ // assumes both filters are the same size!
+ H3BloomFilter * temp = (H3BloomFilter*) other_filter;
+ for(int i = 0; i < m_filter_size; ++i){
+ m_filter[i] |= (*temp)[i];
+ }
}
-void H3BloomFilter::set(const Address& addr)
+void
+H3BloomFilter::set(const Address& addr)
{
- for (int i = 0; i < m_num_hashes; i++) {
- int idx = get_index(addr, i);
- m_filter[idx] = 1;
-
- //Profile hash value distribution
- //g_system_ptr->getProfiler()->getXactProfiler()->profileHashValue(i, idx); // gem5:Arka decomissiong of log_tm
- }
+ for (int i = 0; i < m_num_hashes; i++) {
+ int idx = get_index(addr, i);
+ m_filter[idx] = 1;
+ }
}
-void H3BloomFilter::unset(const Address& addr)
+void
+H3BloomFilter::unset(const Address& addr)
{
- cout << "ERROR: Unset should never be called in a Bloom filter";
- assert(0);
+ cout << "ERROR: Unset should never be called in a Bloom filter";
+ assert(0);
}
-bool H3BloomFilter::isSet(const Address& addr)
+bool
+H3BloomFilter::isSet(const Address& addr)
{
- bool res = true;
+ bool res = true;
- for (int i=0; i < m_num_hashes; i++) {
- int idx = get_index(addr, i);
- res = res && m_filter[idx];
- }
- return res;
+ for (int i = 0; i < m_num_hashes; i++) {
+ int idx = get_index(addr, i);
+ res = res && m_filter[idx];
+ }
+ return res;
}
-
-int H3BloomFilter::getCount(const Address& addr)
+int
+H3BloomFilter::getCount(const Address& addr)
{
- return isSet(addr)? 1: 0;
+ return isSet(addr)? 1: 0;
}
-int H3BloomFilter::getIndex(const Address& addr)
+int
+H3BloomFilter::getIndex(const Address& addr)
{
- return 0;
+ return 0;
}
-int H3BloomFilter::readBit(const int index) {
- return 0;
+int
+H3BloomFilter::readBit(const int index)
+{
+ return 0;
}
-void H3BloomFilter::writeBit(const int index, const int value) {
-
+void
+H3BloomFilter::writeBit(const int index, const int value)
+{
}
-int H3BloomFilter::getTotalCount()
+int
+H3BloomFilter::getTotalCount()
{
- int count = 0;
+ int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- count += m_filter[i];
- }
- return count;
+ for (int i = 0; i < m_filter_size; i++) {
+ count += m_filter[i];
+ }
+ return count;
}
-void H3BloomFilter::print(ostream& out) const
+void
+H3BloomFilter::print(ostream& out) const
{
}
-int H3BloomFilter::get_index(const Address& addr, int i)
+int
+H3BloomFilter::get_index(const Address& addr, int i)
{
- uint64 x = addr.getLineAddress();
- //uint64 y = (x*mults_list[i] + adds_list[i]) % primes_list[i];
- int y = hash_H3(x,i);
-
- if(isParallel) {
- return (y % m_par_filter_size) + i*m_par_filter_size;
- } else {
- return y % m_filter_size;
- }
+ uint64 x = addr.getLineAddress();
+ // uint64 y = (x*mults_list[i] + adds_list[i]) % primes_list[i];
+ int y = hash_H3(x,i);
+
+ if (isParallel) {
+ return (y % m_par_filter_size) + i*m_par_filter_size;
+ } else {
+ return y % m_filter_size;
+ }
}
-int H3BloomFilter::hash_H3(uint64 value, int index) {
- uint64 mask = 1;
- uint64 val = value;
- int result = 0;
-
- for(int i = 0; i < 64; i++) {
- if(val&mask) result ^= H3[i][index];
- val = val >> 1;
- }
- return result;
- }
+int
+H3BloomFilter::hash_H3(uint64 value, int index)
+{
+ uint64 mask = 1;
+ uint64 val = value;
+ int result = 0;
+
+ for (int i = 0; i < 64; i++) {
+ if(val&mask) result ^= H3[i][index];
+ val = val >> 1;
+ }
+ return result;
+}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * H3BloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef H3_BLOOM_FILTER_H
-#define H3_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
+#include "mem/ruby/profiler/Profiler.hh"
+#include "mem/ruby/system/System.hh"
-class H3BloomFilter : public AbstractBloomFilter {
-public:
-
- ~H3BloomFilter();
- H3BloomFilter(string config);
-
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
-
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
- void print(ostream& out) const;
-
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
-
- int operator[](const int index) const{
- return this->m_filter[index];
- }
+class H3BloomFilter : public AbstractBloomFilter
+{
+ public:
+ H3BloomFilter(string config);
+ ~H3BloomFilter();
-private:
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
- int get_index(const Address& addr, int hashNumber);
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+ void print(ostream& out) const;
- int hash_H3(uint64 value, int index);
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
- Vector<int> m_filter;
- int m_filter_size;
- int m_num_hashes;
- int m_filter_size_bits;
+ int
+ operator[](const int index) const
+ {
+ return this->m_filter[index];
+ }
- int m_par_filter_size;
- int m_par_filter_size_bits;
+ private:
+ int get_index(const Address& addr, int hashNumber);
- int m_count_bits;
- int m_count;
+ int hash_H3(uint64 value, int index);
+ Vector<int> m_filter;
+ int m_filter_size;
+ int m_num_hashes;
+ int m_filter_size_bits;
+ int m_par_filter_size;
+ int m_par_filter_size_bits;
- int primes_list[6];// = {9323,11279,10247,30637,25717,43711};
- int mults_list[6]; //= {255,29,51,3,77,43};
- int adds_list[6]; //= {841,627,1555,241,7777,65391};
+ int m_count_bits;
+ int m_count;
- bool isParallel;
+ int primes_list[6];// = {9323,11279,10247,30637,25717,43711};
+ int mults_list[6]; //= {255,29,51,3,77,43};
+ int adds_list[6]; //= {841,627,1555,241,7777,65391};
+ bool isParallel;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * LSB_CountingBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
LSB_CountingBloomFilter::LSB_CountingBloomFilter(string str)
{
- string tail(str);
- string head = string_split(tail, ':');
+ string tail(str);
+ string head = string_split(tail, ':');
- m_filter_size = atoi(head.c_str());
- m_filter_size_bits = log_int(m_filter_size);
+ m_filter_size = atoi(head.c_str());
+ m_filter_size_bits = log_int(m_filter_size);
- m_count = atoi(tail.c_str());
- m_count_bits = log_int(m_count);
+ m_count = atoi(tail.c_str());
+ m_count_bits = log_int(m_count);
- m_filter.setSize(m_filter_size);
- clear();
+ m_filter.setSize(m_filter_size);
+ clear();
}
-LSB_CountingBloomFilter::~LSB_CountingBloomFilter(){
+LSB_CountingBloomFilter::~LSB_CountingBloomFilter()
+{
}
-void LSB_CountingBloomFilter::clear()
+void
+LSB_CountingBloomFilter::clear()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
}
-void LSB_CountingBloomFilter::increment(const Address& addr)
+void
+LSB_CountingBloomFilter::increment(const Address& addr)
{
- int i = get_index(addr);
- if (m_filter[i] < m_count);
- m_filter[i] += 1;
+ int i = get_index(addr);
+ if (m_filter[i] < m_count)
+ m_filter[i] += 1;
}
-void LSB_CountingBloomFilter::decrement(const Address& addr)
+void
+LSB_CountingBloomFilter::decrement(const Address& addr)
{
- int i = get_index(addr);
- if (m_filter[i] > 0)
- m_filter[i] -= 1;
+ int i = get_index(addr);
+ if (m_filter[i] > 0)
+ m_filter[i] -= 1;
}
-void LSB_CountingBloomFilter::merge(AbstractBloomFilter * other_filter)
+void
+LSB_CountingBloomFilter::merge(AbstractBloomFilter * other_filter)
{
- // TODO
+ // TODO
}
-void LSB_CountingBloomFilter::set(const Address& addr)
+void
+LSB_CountingBloomFilter::set(const Address& addr)
{
- // TODO
+ // TODO
}
-void LSB_CountingBloomFilter::unset(const Address& addr)
+void
+LSB_CountingBloomFilter::unset(const Address& addr)
{
- // TODO
+ // TODO
}
-bool LSB_CountingBloomFilter::isSet(const Address& addr)
+bool
+LSB_CountingBloomFilter::isSet(const Address& addr)
{
- // TODO
- return false;
+ // TODO
+ return false;
}
-
-int LSB_CountingBloomFilter::getCount(const Address& addr)
+int
+LSB_CountingBloomFilter::getCount(const Address& addr)
{
- return m_filter[get_index(addr)];
+ return m_filter[get_index(addr)];
}
-int LSB_CountingBloomFilter::getTotalCount()
+int
+LSB_CountingBloomFilter::getTotalCount()
{
- int count = 0;
+ int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- count += m_filter[i];
- }
- return count;
+ for (int i = 0; i < m_filter_size; i++) {
+ count += m_filter[i];
+ }
+ return count;
}
-int LSB_CountingBloomFilter::getIndex(const Address& addr)
+int
+LSB_CountingBloomFilter::getIndex(const Address& addr)
{
- return get_index(addr);
+ return get_index(addr);
}
-void LSB_CountingBloomFilter::print(ostream& out) const
+void
+LSB_CountingBloomFilter::print(ostream& out) const
{
}
-int LSB_CountingBloomFilter::readBit(const int index) {
- return 0;
- // TODO
+int
+LSB_CountingBloomFilter::readBit(const int index)
+{
+ return 0;
+ // TODO
}
-void LSB_CountingBloomFilter::writeBit(const int index, const int value) {
- // TODO
+void
+LSB_CountingBloomFilter::writeBit(const int index, const int value)
+{
+ // TODO
}
-int LSB_CountingBloomFilter::get_index(const Address& addr)
+int
+LSB_CountingBloomFilter::get_index(const Address& addr)
{
- return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1);
+ return addr.bitSelect(RubySystem::getBlockSizeBits(),
+ RubySystem::getBlockSizeBits() +
+ m_filter_size_bits - 1);
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * LSB_CountingBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef LSB_COUNTING_BLOOM_FILTER_H
-#define LSB_COUNTING_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_LSBCOUNTINGBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_LSBCOUNTINGBLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
-class LSB_CountingBloomFilter : public AbstractBloomFilter {
-public:
+class LSB_CountingBloomFilter : public AbstractBloomFilter
+{
+ public:
+ LSB_CountingBloomFilter(string config);
+ ~LSB_CountingBloomFilter();
- ~LSB_CountingBloomFilter();
- LSB_CountingBloomFilter(string config);
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
+ void print(ostream& out) const;
- void print(ostream& out) const;
+ private:
+ int get_index(const Address& addr);
-private:
+ Vector<int> m_filter;
+ int m_filter_size;
+ int m_filter_size_bits;
- int get_index(const Address& addr);
-
- Vector<int> m_filter;
- int m_filter_size;
- int m_filter_size_bits;
-
- int m_count_bits;
- int m_count;
+ int m_count_bits;
+ int m_count;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_LSBCOUNTINGBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NonCountingBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
MultiBitSelBloomFilter::MultiBitSelBloomFilter(string str)
{
+ string tail(str);
+ string head = string_split(tail, '_');
- string tail(str);
- string head = string_split(tail, '_');
-
- // head contains filter size, tail contains bit offset from block number
- m_filter_size = atoi(head.c_str());
+ // head contains filter size, tail contains bit offset from block number
+ m_filter_size = atoi(head.c_str());
- head = string_split(tail, '_');
- m_num_hashes = atoi(head.c_str());
+ head = string_split(tail, '_');
+ m_num_hashes = atoi(head.c_str());
- head = string_split(tail, '_');
- m_skip_bits = atoi(head.c_str());
+ head = string_split(tail, '_');
+ m_skip_bits = atoi(head.c_str());
- if(tail == "Regular") {
- isParallel = false;
- } else if (tail == "Parallel") {
- isParallel = true;
- } else {
- cout << "ERROR: Incorrect config string for MultiBitSel Bloom! :" << str << endl;
- assert(0);
- }
+ if(tail == "Regular") {
+ isParallel = false;
+ } else if (tail == "Parallel") {
+ isParallel = true;
+ } else {
+ cout << "ERROR: Incorrect config string for MultiBitSel Bloom! :"
+ << str << endl;
+ assert(0);
+ }
- m_filter_size_bits = log_int(m_filter_size);
+ m_filter_size_bits = log_int(m_filter_size);
- m_par_filter_size = m_filter_size/m_num_hashes;
- m_par_filter_size_bits = log_int(m_par_filter_size);
+ m_par_filter_size = m_filter_size/m_num_hashes;
+ m_par_filter_size_bits = log_int(m_par_filter_size);
- m_filter.setSize(m_filter_size);
- clear();
+ m_filter.setSize(m_filter_size);
+ clear();
}
-MultiBitSelBloomFilter::~MultiBitSelBloomFilter(){
+MultiBitSelBloomFilter::~MultiBitSelBloomFilter()
+{
}
-void MultiBitSelBloomFilter::clear()
+void
+MultiBitSelBloomFilter::clear()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
}
-void MultiBitSelBloomFilter::increment(const Address& addr)
+void
+MultiBitSelBloomFilter::increment(const Address& addr)
{
- // Not used
+ // Not used
}
-void MultiBitSelBloomFilter::decrement(const Address& addr)
+void
+MultiBitSelBloomFilter::decrement(const Address& addr)
{
- // Not used
+ // Not used
}
-void MultiBitSelBloomFilter::merge(AbstractBloomFilter * other_filter){
- // assumes both filters are the same size!
- MultiBitSelBloomFilter * temp = (MultiBitSelBloomFilter*) other_filter;
- for(int i=0; i < m_filter_size; ++i){
- m_filter[i] |= (*temp)[i];
- }
-
+void
+MultiBitSelBloomFilter::merge(AbstractBloomFilter *other_filter)
+{
+ // assumes both filters are the same size!
+ MultiBitSelBloomFilter * temp = (MultiBitSelBloomFilter*) other_filter;
+ for(int i = 0; i < m_filter_size; ++i){
+ m_filter[i] |= (*temp)[i];
+ }
}
-void MultiBitSelBloomFilter::set(const Address& addr)
+void
+MultiBitSelBloomFilter::set(const Address& addr)
{
- for (int i = 0; i < m_num_hashes; i++) {
- int idx = get_index(addr, i);
- m_filter[idx] = 1;
-
- //Profile hash value distribution
- //g_system_ptr->getProfiler()->getXactProfiler()->profileHashValue(i, idx); //gem5:Arka for decomissioning of log_tm
- }
+ for (int i = 0; i < m_num_hashes; i++) {
+ int idx = get_index(addr, i);
+ m_filter[idx] = 1;
+ }
}
-void MultiBitSelBloomFilter::unset(const Address& addr)
+void
+MultiBitSelBloomFilter::unset(const Address& addr)
{
- cout << "ERROR: Unset should never be called in a Bloom filter";
- assert(0);
+ cout << "ERROR: Unset should never be called in a Bloom filter";
+ assert(0);
}
-bool MultiBitSelBloomFilter::isSet(const Address& addr)
+bool
+MultiBitSelBloomFilter::isSet(const Address& addr)
{
- bool res = true;
+ bool res = true;
- for (int i=0; i < m_num_hashes; i++) {
- int idx = get_index(addr, i);
- res = res && m_filter[idx];
- }
- return res;
+ for (int i=0; i < m_num_hashes; i++) {
+ int idx = get_index(addr, i);
+ res = res && m_filter[idx];
+ }
+ return res;
}
-
-int MultiBitSelBloomFilter::getCount(const Address& addr)
+int
+MultiBitSelBloomFilter::getCount(const Address& addr)
{
- return isSet(addr)? 1: 0;
+ return isSet(addr)? 1: 0;
}
-int MultiBitSelBloomFilter::getIndex(const Address& addr)
+int
+MultiBitSelBloomFilter::getIndex(const Address& addr)
{
- return 0;
+ return 0;
}
-int MultiBitSelBloomFilter::readBit(const int index) {
- return 0;
+int
+MultiBitSelBloomFilter::readBit(const int index)
+{
+ return 0;
}
-void MultiBitSelBloomFilter::writeBit(const int index, const int value) {
-
+void
+MultiBitSelBloomFilter::writeBit(const int index, const int value)
+{
}
-int MultiBitSelBloomFilter::getTotalCount()
+int
+MultiBitSelBloomFilter::getTotalCount()
{
- int count = 0;
+ int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- count += m_filter[i];
- }
- return count;
+ for (int i = 0; i < m_filter_size; i++) {
+ count += m_filter[i];
+ }
+ return count;
}
-void MultiBitSelBloomFilter::print(ostream& out) const
+void
+MultiBitSelBloomFilter::print(ostream& out) const
{
}
-int MultiBitSelBloomFilter::get_index(const Address& addr, int i)
+int
+MultiBitSelBloomFilter::get_index(const Address& addr, int i)
{
- // m_skip_bits is used to perform BitSelect after skipping some bits. Used to simulate BitSel hashing on larger than cache-line granularities
- uint64 x = (addr.getLineAddress()) >> m_skip_bits;
- int y = hash_bitsel(x, i, m_num_hashes, 30, m_filter_size_bits);
- //36-bit addresses, 6-bit cache lines
-
- if(isParallel) {
- return (y % m_par_filter_size) + i*m_par_filter_size;
- } else {
- return y % m_filter_size;
- }
-}
-
-
-int MultiBitSelBloomFilter::hash_bitsel(uint64 value, int index, int jump, int maxBits, int numBits) {
- uint64 mask = 1;
- int result = 0;
- int bit, i;
-
- for(i = 0; i < numBits; i++) {
- bit = (index + jump*i) % maxBits;
- if (value & (mask << bit)) result += mask << i;
- }
- return result;
+ // m_skip_bits is used to perform BitSelect after skipping some
+ // bits. Used to simulate BitSel hashing on larger than cache-line
+ // granularities
+ uint64 x = (addr.getLineAddress()) >> m_skip_bits;
+ int y = hash_bitsel(x, i, m_num_hashes, 30, m_filter_size_bits);
+ //36-bit addresses, 6-bit cache lines
+
+ if (isParallel) {
+ return (y % m_par_filter_size) + i*m_par_filter_size;
+ } else {
+ return y % m_filter_size;
+ }
+}
+
+int
+MultiBitSelBloomFilter::hash_bitsel(uint64 value, int index, int jump,
+ int maxBits, int numBits)
+{
+ uint64 mask = 1;
+ int result = 0;
+ int bit, i;
+
+ for (i = 0; i < numBits; i++) {
+ bit = (index + jump*i) % maxBits;
+ if (value & (mask << bit)) result += mask << i;
+ }
+ return result;
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * MultiBitSelBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef MULTIBITSEL_BLOOM_FILTER_H
-#define MULTIBITSEL_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
+#include "mem/ruby/profiler/Profiler.hh"
+#include "mem/ruby/system/System.hh"
-class MultiBitSelBloomFilter : public AbstractBloomFilter {
-public:
-
- ~MultiBitSelBloomFilter();
- MultiBitSelBloomFilter(string config);
-
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
-
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
- void print(ostream& out) const;
-
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
-
- int operator[](const int index) const{
- return this->m_filter[index];
- }
-
-private:
-
- int get_index(const Address& addr, int hashNumber);
-
- int hash_bitsel(uint64 value, int index, int jump, int maxBits, int numBits);
-
- Vector<int> m_filter;
- int m_filter_size;
- int m_num_hashes;
- int m_filter_size_bits;
- int m_skip_bits;
-
- int m_par_filter_size;
- int m_par_filter_size_bits;
-
- int m_count_bits;
- int m_count;
-
- bool isParallel;
-
+class MultiBitSelBloomFilter : public AbstractBloomFilter
+{
+ public:
+ MultiBitSelBloomFilter(string config);
+ ~MultiBitSelBloomFilter();
+
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
+
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+ void print(ostream& out) const;
+
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
+
+ int
+ operator[](const int index) const
+ {
+ return this->m_filter[index];
+ }
+
+ private:
+ int get_index(const Address& addr, int hashNumber);
+
+ int hash_bitsel(uint64 value, int index, int jump, int maxBits,
+ int numBits);
+
+ Vector<int> m_filter;
+ int m_filter_size;
+ int m_num_hashes;
+ int m_filter_size_bits;
+ int m_skip_bits;
+
+ int m_par_filter_size;
+ int m_par_filter_size_bits;
+
+ int m_count_bits;
+ int m_count;
+
+ bool isParallel;
};
-#endif
+#endif // __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * MultiGrainBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/MultiGrainBloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/MultiGrainBloomFilter.hh"
MultiGrainBloomFilter::MultiGrainBloomFilter(string str)
{
- string tail(str);
+ string tail(str);
- // split into the 2 filter sizes
- string head = string_split(tail, '_');
+ // split into the 2 filter sizes
+ string head = string_split(tail, '_');
- // head contains size of 1st bloom filter, tail contains size of 2nd bloom filter
+ // head contains size of 1st bloom filter, tail contains size of
+ // 2nd bloom filter
- m_filter_size = atoi(head.c_str());
- m_filter_size_bits = log_int(m_filter_size);
+ m_filter_size = atoi(head.c_str());
+ m_filter_size_bits = log_int(m_filter_size);
- m_page_filter_size = atoi(tail.c_str());
- m_page_filter_size_bits = log_int(m_page_filter_size);
+ m_page_filter_size = atoi(tail.c_str());
+ m_page_filter_size_bits = log_int(m_page_filter_size);
- m_filter.setSize(m_filter_size);
- m_page_filter.setSize(m_page_filter_size);
- clear();
+ m_filter.setSize(m_filter_size);
+ m_page_filter.setSize(m_page_filter_size);
+ clear();
}
-MultiGrainBloomFilter::~MultiGrainBloomFilter(){
+MultiGrainBloomFilter::~MultiGrainBloomFilter()
+{
}
-void MultiGrainBloomFilter::clear()
+void
+MultiGrainBloomFilter::clear()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
- for(int i=0; i < m_page_filter_size; ++i){
- m_page_filter[i] = 0;
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
+ for(int i=0; i < m_page_filter_size; ++i){
+ m_page_filter[i] = 0;
+ }
}
-void MultiGrainBloomFilter::increment(const Address& addr)
+void
+MultiGrainBloomFilter::increment(const Address& addr)
{
- // Not used
+ // Not used
}
-void MultiGrainBloomFilter::decrement(const Address& addr)
+void
+MultiGrainBloomFilter::decrement(const Address& addr)
{
- // Not used
+ // Not used
}
-void MultiGrainBloomFilter::merge(AbstractBloomFilter * other_filter)
+void
+MultiGrainBloomFilter::merge(AbstractBloomFilter *other_filter)
{
- // TODO
+ // TODO
}
-void MultiGrainBloomFilter::set(const Address& addr)
+void
+MultiGrainBloomFilter::set(const Address& addr)
{
- int i = get_block_index(addr);
- assert(i < m_filter_size);
- assert(get_page_index(addr) < m_page_filter_size);
- m_filter[i] = 1;
- m_page_filter[i] = 1;
+ int i = get_block_index(addr);
+ assert(i < m_filter_size);
+ assert(get_page_index(addr) < m_page_filter_size);
+ m_filter[i] = 1;
+ m_page_filter[i] = 1;
}
-void MultiGrainBloomFilter::unset(const Address& addr)
+void
+MultiGrainBloomFilter::unset(const Address& addr)
{
- // not used
+ // not used
}
-bool MultiGrainBloomFilter::isSet(const Address& addr)
+bool
+MultiGrainBloomFilter::isSet(const Address& addr)
{
- int i = get_block_index(addr);
- assert(i < m_filter_size);
- assert(get_page_index(addr) < m_page_filter_size);
- // we have to have both indices set
- return (m_filter[i] && m_page_filter[i]);
+ int i = get_block_index(addr);
+ assert(i < m_filter_size);
+ assert(get_page_index(addr) < m_page_filter_size);
+ // we have to have both indices set
+ return (m_filter[i] && m_page_filter[i]);
}
-int MultiGrainBloomFilter::getCount(const Address& addr)
+int
+MultiGrainBloomFilter::getCount(const Address& addr)
{
- // not used
- return 0;
+ // not used
+ return 0;
}
-int MultiGrainBloomFilter::getTotalCount()
+int
+MultiGrainBloomFilter::getTotalCount()
{
- int count = 0;
+ int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- count += m_filter[i];
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ count += m_filter[i];
+ }
- for(int i=0; i < m_page_filter_size; ++i){
- count += m_page_filter[i] = 0;
- }
+ for(int i=0; i < m_page_filter_size; ++i) {
+ count += m_page_filter[i] = 0;
+ }
- return count;
+ return count;
}
-int MultiGrainBloomFilter::getIndex(const Address& addr)
+int
+MultiGrainBloomFilter::getIndex(const Address& addr)
{
- return 0;
- // TODO
+ return 0;
+ // TODO
}
-int MultiGrainBloomFilter::readBit(const int index) {
- return 0;
- // TODO
+int
+MultiGrainBloomFilter::readBit(const int index)
+{
+ return 0;
+ // TODO
}
-void MultiGrainBloomFilter::writeBit(const int index, const int value) {
- // TODO
+void
+MultiGrainBloomFilter::writeBit(const int index, const int value)
+{
+ // TODO
}
-void MultiGrainBloomFilter::print(ostream& out) const
+void
+MultiGrainBloomFilter::print(ostream& out) const
{
}
-int MultiGrainBloomFilter::get_block_index(const Address& addr)
+int
+MultiGrainBloomFilter::get_block_index(const Address& addr)
{
- // grap a chunk of bits after byte offset
- return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1);
+ // grap a chunk of bits after byte offset
+ return addr.bitSelect(RubySystem::getBlockSizeBits(),
+ RubySystem::getBlockSizeBits() +
+ m_filter_size_bits - 1);
}
-int MultiGrainBloomFilter::get_page_index(const Address & addr)
+int
+MultiGrainBloomFilter::get_page_index(const Address & addr)
{
- // grap a chunk of bits after first chunk
- return addr.bitSelect( RubySystem::getBlockSizeBits() + m_filter_size_bits - 1,
- RubySystem::getBlockSizeBits() + m_filter_size_bits - 1 + m_page_filter_size_bits - 1);
+ int bits = RubySystem::getBlockSizeBits() + m_filter_size_bits - 1;
+
+ // grap a chunk of bits after first chunk
+ return addr.bitSelect(bits, bits + m_page_filter_size_bits - 1);
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * MultiGrainBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef MULTIGRAIN_BLOOM_FILTER_H
-#define MULTIGRAIN_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
-class MultiGrainBloomFilter : public AbstractBloomFilter {
-public:
+class MultiGrainBloomFilter : public AbstractBloomFilter
+{
+ public:
+ MultiGrainBloomFilter(string str);
+ ~MultiGrainBloomFilter();
- ~MultiGrainBloomFilter();
- MultiGrainBloomFilter(string str);
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
+ void print(ostream& out) const;
- void print(ostream& out) const;
+ private:
+ int get_block_index(const Address& addr);
+ int get_page_index(const Address & addr);
-private:
+ // The block filter
+ Vector<int> m_filter;
+ int m_filter_size;
+ int m_filter_size_bits;
+ // The page number filter
+ Vector<int> m_page_filter;
+ int m_page_filter_size;
+ int m_page_filter_size_bits;
- int get_block_index(const Address& addr);
- int get_page_index(const Address & addr);
-
- // The block filter
- Vector<int> m_filter;
- int m_filter_size;
- int m_filter_size_bits;
- // The page number filter
- Vector<int> m_page_filter;
- int m_page_filter_size;
- int m_page_filter_size_bits;
-
- int m_count_bits;
- int m_count;
+ int m_count_bits;
+ int m_count;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NonCountingBloomFilter.cc
- *
- * Description:
- *
- *
- */
-
-#include "mem/ruby/filters/NonCountingBloomFilter.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/filters/NonCountingBloomFilter.hh"
NonCountingBloomFilter::NonCountingBloomFilter(string str)
{
- string tail(str);
- string head = string_split(tail, '_');
+ string tail(str);
+ string head = string_split(tail, '_');
- // head contains filter size, tail contains bit offset from block number
- m_filter_size = atoi(head.c_str());
- m_offset = atoi(tail.c_str());
- m_filter_size_bits = log_int(m_filter_size);
+ // head contains filter size, tail contains bit offset from block number
+ m_filter_size = atoi(head.c_str());
+ m_offset = atoi(tail.c_str());
+ m_filter_size_bits = log_int(m_filter_size);
-
- m_filter.setSize(m_filter_size);
- clear();
+ m_filter.setSize(m_filter_size);
+ clear();
}
-NonCountingBloomFilter::~NonCountingBloomFilter(){
+NonCountingBloomFilter::~NonCountingBloomFilter()
+{
}
-void NonCountingBloomFilter::clear()
+void
+NonCountingBloomFilter::clear()
{
- for (int i = 0; i < m_filter_size; i++) {
- m_filter[i] = 0;
- }
+ for (int i = 0; i < m_filter_size; i++) {
+ m_filter[i] = 0;
+ }
}
-void NonCountingBloomFilter::increment(const Address& addr)
+void
+NonCountingBloomFilter::increment(const Address& addr)
{
- // Not used
+ // Not used
}
-
-void NonCountingBloomFilter::decrement(const Address& addr)
+void
+NonCountingBloomFilter::decrement(const Address& addr)
{
- // Not used
+ // Not used
}
-void NonCountingBloomFilter::merge(AbstractBloomFilter * other_filter){
- // assumes both filters are the same size!
- NonCountingBloomFilter * temp = (NonCountingBloomFilter*) other_filter;
- for(int i=0; i < m_filter_size; ++i){
- m_filter[i] |= (*temp)[i];
- }
-
+void
+NonCountingBloomFilter::merge(AbstractBloomFilter *other_filter)
+{
+ // assumes both filters are the same size!
+ NonCountingBloomFilter * temp = (NonCountingBloomFilter*) other_filter;
+ for(int i = 0; i < m_filter_size; ++i){
+ m_filter[i] |= (*temp)[i];
+ }
}
-void NonCountingBloomFilter::set(const Address& addr)
+void
+NonCountingBloomFilter::set(const Address& addr)
{
- int i = get_index(addr);
- m_filter[i] = 1;
+ int i = get_index(addr);
+ m_filter[i] = 1;
}
-void NonCountingBloomFilter::unset(const Address& addr)
+void
+NonCountingBloomFilter::unset(const Address& addr)
{
- int i = get_index(addr);
- m_filter[i] = 0;
+ int i = get_index(addr);
+ m_filter[i] = 0;
}
-bool NonCountingBloomFilter::isSet(const Address& addr)
+bool
+NonCountingBloomFilter::isSet(const Address& addr)
{
- int i = get_index(addr);
- return (m_filter[i]);
+ int i = get_index(addr);
+ return (m_filter[i]);
}
-int NonCountingBloomFilter::getCount(const Address& addr)
+int
+NonCountingBloomFilter::getCount(const Address& addr)
{
- return m_filter[get_index(addr)];
+ return m_filter[get_index(addr)];
}
-int NonCountingBloomFilter::getTotalCount()
+int
+NonCountingBloomFilter::getTotalCount()
{
- int count = 0;
+ int count = 0;
- for (int i = 0; i < m_filter_size; i++) {
- count += m_filter[i];
- }
- return count;
+ for (int i = 0; i < m_filter_size; i++) {
+ count += m_filter[i];
+ }
+ return count;
}
-void NonCountingBloomFilter::print(ostream& out) const
+void
+NonCountingBloomFilter::print(ostream& out) const
{
}
-int NonCountingBloomFilter::getIndex(const Address& addr)
+int
+NonCountingBloomFilter::getIndex(const Address& addr)
{
- return get_index(addr);
+ return get_index(addr);
}
-int NonCountingBloomFilter::readBit(const int index) {
- return m_filter[index];
+int
+NonCountingBloomFilter::readBit(const int index)
+{
+ return m_filter[index];
}
-void NonCountingBloomFilter::writeBit(const int index, const int value) {
- m_filter[index] = value;
+void
+NonCountingBloomFilter::writeBit(const int index, const int value)
+{
+ m_filter[index] = value;
}
-int NonCountingBloomFilter::get_index(const Address& addr)
+int
+NonCountingBloomFilter::get_index(const Address& addr)
{
- return addr.bitSelect( RubySystem::getBlockSizeBits() + m_offset,
- RubySystem::getBlockSizeBits() + m_offset + m_filter_size_bits - 1);
+ return addr.bitSelect(RubySystem::getBlockSizeBits() + m_offset,
+ RubySystem::getBlockSizeBits() + m_offset +
+ m_filter_size_bits - 1);
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NonCountingBloomFilter.hh
- *
- * Description:
- *
- *
- */
-
-#ifndef NONCOUNTING_BLOOM_FILTER_H
-#define NONCOUNTING_BLOOM_FILTER_H
+#ifndef __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__
+#define __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__
#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/filters/AbstractBloomFilter.hh"
-class NonCountingBloomFilter : public AbstractBloomFilter {
-public:
-
- ~NonCountingBloomFilter();
- NonCountingBloomFilter(string config);
-
- void clear();
- void increment(const Address& addr);
- void decrement(const Address& addr);
- void merge(AbstractBloomFilter * other_filter);
- void set(const Address& addr);
- void unset(const Address& addr);
-
- bool isSet(const Address& addr);
- int getCount(const Address& addr);
- int getTotalCount();
-
- int getIndex(const Address& addr);
- int readBit(const int index);
- void writeBit(const int index, const int value);
-
- void print(ostream& out) const;
-
- int operator[](const int index) const{
- return this->m_filter[index];
- }
-
-private:
-
- int get_index(const Address& addr);
-
- Vector<int> m_filter;
- int m_filter_size;
- int m_offset;
- int m_filter_size_bits;
-
- int m_count_bits;
- int m_count;
+class NonCountingBloomFilter : public AbstractBloomFilter
+{
+ public:
+ NonCountingBloomFilter(string config);
+ ~NonCountingBloomFilter();
+
+ void clear();
+ void increment(const Address& addr);
+ void decrement(const Address& addr);
+ void merge(AbstractBloomFilter * other_filter);
+ void set(const Address& addr);
+ void unset(const Address& addr);
+
+ bool isSet(const Address& addr);
+ int getCount(const Address& addr);
+ int getTotalCount();
+
+ int getIndex(const Address& addr);
+ int readBit(const int index);
+ void writeBit(const int index, const int value);
+
+ void print(ostream& out) const;
+
+ int
+ operator[](const int index) const
+ {
+ return this->m_filter[index];
+ }
+
+ private:
+ int get_index(const Address& addr);
+
+ Vector<int> m_filter;
+ int m_filter_size;
+ int m_offset;
+ int m_filter_size_bits;
+
+ int m_count_bits;
+ int m_count;
};
-
-#endif
+#endif // __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__
#include <algorithm>
#include "config/gems_root.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/libruby_internal.hh"
+#include "mem/ruby/recorder/Tracer.hh"
+#include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/system/System.hh"
-#include "mem/ruby/eventqueue/RubyEventQueue.hh"
-#include "mem/ruby/system/MemoryVector.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/recorder/Tracer.hh"
-string RubyRequestType_to_string(const RubyRequestType& obj)
-{
- switch(obj) {
- case RubyRequestType_IFETCH:
- return "IFETCH";
- case RubyRequestType_LD:
- return "LD";
- case RubyRequestType_ST:
- return "ST";
- case RubyRequestType_Locked_Read:
- return "Locked_Read";
- case RubyRequestType_Locked_Write:
- return "Locked_Write";
- case RubyRequestType_RMW_Read:
- return "RMW_Read";
- case RubyRequestType_RMW_Write:
- return "RMW_Write";
- case RubyRequestType_NULL:
- default:
- assert(0);
- return "";
- }
+string
+RubyRequestType_to_string(const RubyRequestType& obj)
+{
+ switch(obj) {
+ case RubyRequestType_IFETCH:
+ return "IFETCH";
+ case RubyRequestType_LD:
+ return "LD";
+ case RubyRequestType_ST:
+ return "ST";
+ case RubyRequestType_Locked_Read:
+ return "Locked_Read";
+ case RubyRequestType_Locked_Write:
+ return "Locked_Write";
+ case RubyRequestType_RMW_Read:
+ return "RMW_Read";
+ case RubyRequestType_RMW_Write:
+ return "RMW_Write";
+ case RubyRequestType_NULL:
+ default:
+ assert(0);
+ return "";
+ }
}
-RubyRequestType string_to_RubyRequestType(std::string str)
+RubyRequestType
+string_to_RubyRequestType(std::string str)
{
- if (str == "IFETCH")
- return RubyRequestType_IFETCH;
- else if (str == "LD")
- return RubyRequestType_LD;
- else if (str == "ST")
- return RubyRequestType_ST;
- else if (str == "Locked_Read")
- return RubyRequestType_Locked_Read;
- else if (str == "Locked_Write")
- return RubyRequestType_Locked_Write;
- else if (str == "RMW_Read")
- return RubyRequestType_RMW_Read;
- else if (str == "RMW_Write")
- return RubyRequestType_RMW_Write;
- else
- assert(0);
- return RubyRequestType_NULL;
+ if (str == "IFETCH")
+ return RubyRequestType_IFETCH;
+ else if (str == "LD")
+ return RubyRequestType_LD;
+ else if (str == "ST")
+ return RubyRequestType_ST;
+ else if (str == "Locked_Read")
+ return RubyRequestType_Locked_Read;
+ else if (str == "Locked_Write")
+ return RubyRequestType_Locked_Write;
+ else if (str == "RMW_Read")
+ return RubyRequestType_RMW_Read;
+ else if (str == "RMW_Write")
+ return RubyRequestType_RMW_Write;
+ else
+ assert(0);
+ return RubyRequestType_NULL;
}
-ostream& operator<<(ostream& out, const RubyRequestType& obj)
+ostream&
+operator<<(ostream& out, const RubyRequestType& obj)
{
- out << RubyRequestType_to_string(obj);
- out << flush;
- return out;
+ out << RubyRequestType_to_string(obj);
+ out << flush;
+ return out;
}
-ostream& operator<<(std::ostream& out, const RubyRequest& obj)
+ostream&
+operator<<(std::ostream& out, const RubyRequest& obj)
{
- out << hex << "0x" << obj.paddr << " data: 0x" << flush;
- for (int i = 0; i < obj.len; i++) {
- out << (int)obj.data[i];
- }
- out << dec << " type: " << RubyRequestType_to_string(obj.type) << endl;
- return out;
+ out << hex << "0x" << obj.paddr << " data: 0x" << flush;
+ for (int i = 0; i < obj.len; i++) {
+ out << (int)obj.data[i];
+ }
+ out << dec << " type: " << RubyRequestType_to_string(obj.type) << endl;
+ return out;
}
-vector<string> tokenizeString(string str, string delims)
+vector<string>
+tokenizeString(string str, string delims)
{
- vector<string> tokens;
- char* pch;
- char* tmp;
- const char* c_delims = delims.c_str();
- tmp = new char[str.length()+1];
- strcpy(tmp, str.c_str());
- pch = strtok(tmp, c_delims);
- while (pch != NULL) {
- string tmp_str(pch);
- if (tmp_str == "null") tmp_str = "";
- tokens.push_back(tmp_str);
+ vector<string> tokens;
+ char* pch;
+ char* tmp;
+ const char* c_delims = delims.c_str();
+ tmp = new char[str.length()+1];
+ strcpy(tmp, str.c_str());
+ pch = strtok(tmp, c_delims);
+ while (pch != NULL) {
+ string tmp_str(pch);
+ if (tmp_str == "null") tmp_str = "";
+ tokens.push_back(tmp_str);
- pch = strtok(NULL, c_delims);
- }
- delete [] tmp;
- return tokens;
+ pch = strtok(NULL, c_delims);
+ }
+ delete [] tmp;
+ return tokens;
}
-
/*
* The current state of M5/Ruby integration breaks the libruby
* interface. This code is ifdef'd out for now so that we can move
* later date.
*/
#if 0
-void libruby_init(const char* cfg_filename)
-{
- ifstream cfg_output(cfg_filename);
-
- vector<RubyObjConf> * sys_conf = new vector<RubyObjConf>;
-
- string line;
- getline(cfg_output, line) ;
- while ( !cfg_output.eof() ) {
- vector<string> tokens = tokenizeString(line, " ");
- assert(tokens.size() >= 2);
- vector<string> argv;
- for (size_t i=2; i<tokens.size(); i++) {
- std::replace(tokens[i].begin(), tokens[i].end(), '%', ' ');
- std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n');
- argv.push_back(tokens[i]);
+void
+libruby_init(const char* cfg_filename)
+{
+ ifstream cfg_output(cfg_filename);
+
+ vector<RubyObjConf> * sys_conf = new vector<RubyObjConf>;
+
+ string line;
+ getline(cfg_output, line) ;
+ while ( !cfg_output.eof() ) {
+ vector<string> tokens = tokenizeString(line, " ");
+ assert(tokens.size() >= 2);
+ vector<string> argv;
+ for (size_t i=2; i<tokens.size(); i++) {
+ std::replace(tokens[i].begin(), tokens[i].end(), '%', ' ');
+ std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n');
+ argv.push_back(tokens[i]);
+ }
+ sys_conf->push_back(RubyObjConf(tokens[0], tokens[1], argv));
+ tokens.clear();
+ argv.clear();
+ getline(cfg_output, line);
}
- sys_conf->push_back(RubyObjConf(tokens[0], tokens[1], argv));
- tokens.clear();
- argv.clear();
- getline(cfg_output, line);
- }
- RubySystem::create(*sys_conf);
- delete sys_conf;
+ RubySystem::create(*sys_conf);
+ delete sys_conf;
}
#endif
-RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id))
+RubyPortHandle
+libruby_get_port(const char* port_name,
+ void (*hit_callback)(int64_t access_id))
{
- //
- // Fix me: Hit callback is now a non-static member function pointer of
- // RubyPort and cannot be set to an arbitrary global function
- //
- return NULL;//static_cast<RubyPortHandle>(RubySystem::getPort(port_name, hit_callback));
+ //
+ // Fix me: Hit callback is now a non-static member function pointer of
+ // RubyPort and cannot be set to an arbitrary global function
+ //
+ return NULL;//static_cast<RubyPortHandle>(RubySystem::getPort(port_name, hit_callback));
}
RubyPortHandle libruby_get_port_by_name(const char* port_name)
return NULL;//static_cast<RubyPortHandle>(RubySystem::getPortOnly(port_name));
}
-void libruby_write_ram(uint64_t paddr, uint8_t* data, int len)
+void
+libruby_write_ram(uint64_t paddr, uint8_t* data, int len)
{
- RubySystem::getMemoryVector()->write(Address(paddr), data, len);
+ RubySystem::getMemoryVector()->write(Address(paddr), data, len);
}
-void libruby_read_ram(uint64_t paddr, uint8_t* data, int len)
+void
+libruby_read_ram(uint64_t paddr, uint8_t* data, int len)
{
- RubySystem::getMemoryVector()->read(Address(paddr), data, len);
+ RubySystem::getMemoryVector()->read(Address(paddr), data, len);
}
-int64_t libruby_issue_request(RubyPortHandle p, struct RubyRequest request)
+int64_t
+libruby_issue_request(RubyPortHandle p, struct RubyRequest request)
{
//
// Fix me: Ports should now be accessed using the python configuration
return 0;//return static_cast<RubyPort*>(p)->makeRequest(request);
}
-int libruby_tick(int n)
+int
+libruby_tick(int n)
{
- RubySystem::getEventQueue()->triggerEvents(RubySystem::getEventQueue()->getTime() + n);
- return 0;
+ RubyEventQueue *eventq = RubySystem::getEventQueue();
+ eventq->triggerEvents(eventq->getTime() + n);
+ return 0;
}
-void libruby_destroy()
+void
+libruby_destroy()
{
}
-const char* libruby_last_error()
+const char*
+libruby_last_error()
{
- return "";
+ return "";
}
-void libruby_print_config(std::ostream & out)
+void
+libruby_print_config(std::ostream & out)
{
- RubySystem::printConfig(out);
+ RubySystem::printConfig(out);
}
-void libruby_print_stats(std::ostream & out)
+void
+libruby_print_stats(std::ostream & out)
{
- RubySystem::printStats(out);
+ RubySystem::printStats(out);
}
-void libruby_playback_trace(char * trace_filename)
+void
+libruby_playback_trace(char * trace_filename)
{
- RubySystem::getTracer()->playbackTrace(trace_filename);
+ RubySystem::getTracer()->playbackTrace(trace_filename);
}
-void libruby_start_tracing(char * record_filename) {
- // start the trace
- RubySystem::getTracer()->startTrace(record_filename);
+void
+libruby_start_tracing(char * record_filename)
+{
+ // start the trace
+ RubySystem::getTracer()->startTrace(record_filename);
}
-void libruby_stop_tracing() {
- // start the trace
- RubySystem::getTracer()->stopTrace();
+void
+libruby_stop_tracing()
+{
+ // start the trace
+ RubySystem::getTracer()->stopTrace();
}
-uint64_t libruby_get_time() {
- return RubySystem::getCycleCount(0);
+uint64_t
+libruby_get_time()
+{
+ return RubySystem::getCycleCount(0);
}
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LIBRUBY_H
-#define LIBRUBY_H
+#ifndef __MEM_RUBY_LIBRUBY_HH__
+#define __MEM_RUBY_LIBRUBY_HH__
-#include <stdint.h>
#include <ostream>
+
+#include "base/types.hh"
#include "mem/packet.hh"
typedef void* RubyPortHandle;
RubyAccessMode_Device
};
-struct RubyRequest {
- uint64_t paddr;
- uint8_t* data;
- int len;
- uint64_t pc;
- RubyRequestType type;
- RubyAccessMode access_mode;
- PacketPtr pkt;
- unsigned proc_id;
-
- RubyRequest() {}
- RubyRequest(uint64_t _paddr,
- uint8_t* _data,
- int _len,
- uint64_t _pc,
- RubyRequestType _type,
- RubyAccessMode _access_mode,
- PacketPtr _pkt,
- unsigned _proc_id = 100)
- : paddr(_paddr),
- data(_data),
- len(_len),
- pc(_pc),
- type(_type),
- access_mode(_access_mode),
- pkt(_pkt),
- proc_id(_proc_id)
- {}
+struct RubyRequest
+{
+ uint64_t paddr;
+ uint8_t* data;
+ int len;
+ uint64_t pc;
+ RubyRequestType type;
+ RubyAccessMode access_mode;
+ PacketPtr pkt;
+ unsigned proc_id;
+
+ RubyRequest() {}
+ RubyRequest(uint64_t _paddr,
+ uint8_t* _data,
+ int _len,
+ uint64_t _pc,
+ RubyRequestType _type,
+ RubyAccessMode _access_mode,
+ PacketPtr _pkt,
+ unsigned _proc_id = 100)
+ : paddr(_paddr),
+ data(_data),
+ len(_len),
+ pc(_pc),
+ type(_type),
+ access_mode(_access_mode),
+ pkt(_pkt),
+ proc_id(_proc_id)
+ {}
};
std::ostream& operator<<(std::ostream& out, const RubyRequest& obj);
void libruby_init(const char* cfg_file);
/**
- * Tear down a configured system. Must be invoked after a call to libruby_init.
+ * Tear down a configured system. Must be invoked after a call to
+ * libruby_init.
*/
void libruby_destroy();
* this port to use when a request completes. Only one handle to a
* port is allowed at a time.
*/
-RubyPortHandle libruby_get_port(const char* name, void (*hit_callback)(int64_t access_id));
+RubyPortHandle libruby_get_port(const char* name,
+ void (*hit_callback)(int64_t access_id));
/**
* Retrieve a handle to a RubyPort object, identified by name in the
*/
RubyPortHandle libruby_get_port_by_name(const char* name);
-
/**
* issue_request returns a unique access_id to identify the ruby
* transaction. This access_id is later returned to the caller via
* ignores caches, and should be considered incoherent after
* simulation starts.
*/
-void libruby_write_ram(uint64_t paddr, uint8_t * data, int len);
+void libruby_write_ram(uint64_t paddr, uint8_t *data, int len);
/**
* reads data directory from Ruby's data array. Note that this
* ignores caches, and should be considered incoherent after
* simulation starts
*/
-void libruby_read_ram(uint64_t paddr, uint8_t * data, int len);
+void libruby_read_ram(uint64_t paddr, uint8_t *data, int len);
/**
* tick the system n cycles. Eventually, will return the number of
/**
* self explainitory
*/
-void libruby_print_config(std::ostream & out);
+void libruby_print_config(std::ostream &out);
/**
* self explainitory
*/
-void libruby_print_stats(std::ostream & out);
+void libruby_print_stats(std::ostream &out);
/**
* does not return until done
*/
-void libruby_playback_trace(char * trace_filename);
+void libruby_playback_trace(char *trace_filename);
/*
* enables the tracer and opens the trace file
*/
-void libruby_start_tracing(char * record_filename);
+void libruby_start_tracing(char *record_filename);
/*
* closes the trace file
* get time
*/
uint64_t libruby_get_time();
-#endif
+
+#endif // __MEM_RUBY_LIBRUBY_HH__
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LIBRUBY_INTERNAL_H
-#define LIBRUBY_INTERNAL_H
-
-#include "mem/ruby/libruby.hh"
+#ifndef __MEM_RUBY_LIBRUBY_INTERNAL_HH__
+#define __MEM_RUBY_LIBRUBY_INTERNAL_HH__
#include <ostream>
#include <string>
+#include "mem/ruby/libruby.hh"
+
std::string RubyRequestType_to_string(const RubyRequestType& obj);
RubyRequestType string_to_RubyRequestType(std::string);
std::ostream& operator<<(std::ostream& out, const RubyRequestType& obj);
-#endif
+#endif // __MEM_RUBY_LIBRUBY_INTERNAL_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- * Description: See AbstractCacheEntry.hh
- *
- */
-
#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
-AbstractCacheEntry::AbstractCacheEntry() {
- m_Address.setAddress(0);
- m_Permission = AccessPermission_NotPresent;
+AbstractCacheEntry::AbstractCacheEntry()
+{
+ m_Address.setAddress(0);
+ m_Permission = AccessPermission_NotPresent;
}
-// still need to define destructor for subclasses
-AbstractCacheEntry::~AbstractCacheEntry() {
+AbstractCacheEntry::~AbstractCacheEntry()
+{
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * $Id$
- *
- * Description: Common base class for a machine node.
- *
+ * Common base class for a machine node.
*/
-#ifndef AbstractCacheEntry_H
-#define AbstractCacheEntry_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCACHEENTRY_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCACHEENTRY_HH__
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/protocol/AccessPermission.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/AbstractEntry.hh"
class DataBlock;
-class AbstractCacheEntry : public AbstractEntry {
-public:
- // Constructors
- AbstractCacheEntry();
-
- // Destructor, prevent it from instantiation
- virtual ~AbstractCacheEntry() = 0;
+class AbstractCacheEntry : public AbstractEntry
+{
+ public:
+ AbstractCacheEntry();
+ virtual ~AbstractCacheEntry() = 0;
- // Data Members (m_ prefix)
- Address m_Address; // Address of this block, required by CacheMemory
- Time m_LastRef; // Last time this block was referenced, required by CacheMemory
- AccessPermission m_Permission; // Access permission for this block, required by CacheMemory
+ Address m_Address; // Address of this block, required by CacheMemory
+ Time m_LastRef; // Last time this block was referenced, required
+ // by CacheMemory
+ AccessPermission m_Permission; // Access permission for this
+ // block, required by CacheMemory
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const AbstractCacheEntry& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const AbstractCacheEntry& obj)
+inline ostream&
+operator<<(ostream& out, const AbstractCacheEntry& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //AbstractCacheEntry_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCACHEENTRY_HH__
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ABSTRACTCONTROLLER_H
-#define ABSTRACTCONTROLLER_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
#include "sim/sim_object.hh"
#include "params/RubyController.hh"
class MessageBuffer;
class Network;
-class AbstractController : public SimObject, public Consumer {
-public:
+class AbstractController : public SimObject, public Consumer
+{
+ public:
typedef RubyControllerParams Params;
AbstractController(const Params *p) : SimObject(p) {}
- // returns the number of controllers created of the specific subtype
- // virtual int getNumberOfControllers() const = 0;
- virtual MessageBuffer* getMandatoryQueue() const = 0;
- virtual const int & getVersion() const = 0;
- virtual const string toString() const = 0; // returns text version of controller type
- virtual const string getName() const = 0; // return instance name
- virtual const MachineType getMachineType() const = 0;
- virtual void blockOnQueue(Address, MessageBuffer*) = 0;
- virtual void unblock(Address) = 0;
- virtual void initNetworkPtr(Network* net_ptr) = 0;
-
- virtual void print(ostream & out) const = 0;
- virtual void printStats(ostream & out) const = 0;
- virtual void printConfig(ostream & out) const = 0;
- virtual void wakeup() = 0;
- // virtual void dumpStats(ostream & out) = 0;
- virtual void clearStats() = 0;
+ // returns the number of controllers created of the specific subtype
+ // virtual int getNumberOfControllers() const = 0;
+ virtual MessageBuffer* getMandatoryQueue() const = 0;
+ virtual const int & getVersion() const = 0;
+ virtual const string toString() const = 0; // returns text version of
+ // controller type
+ virtual const string getName() const = 0; // return instance name
+ virtual const MachineType getMachineType() const = 0;
+ virtual void blockOnQueue(Address, MessageBuffer*) = 0;
+ virtual void unblock(Address) = 0;
+ virtual void initNetworkPtr(Network* net_ptr) = 0;
+ virtual void print(ostream & out) const = 0;
+ virtual void printStats(ostream & out) const = 0;
+ virtual void printConfig(ostream & out) const = 0;
+ virtual void wakeup() = 0;
+ // virtual void dumpStats(ostream & out) = 0;
+ virtual void clearStats() = 0;
};
-#endif
+#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
#include "mem/ruby/slicc_interface/AbstractEntry.hh"
-// Must define constructor and destructor in subclasses
-AbstractEntry::AbstractEntry() {
+AbstractEntry::AbstractEntry()
+{
}
-AbstractEntry::~AbstractEntry() {
+AbstractEntry::~AbstractEntry()
+{
}
-
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef AbstractEntry_H
-#define AbstractEntry_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/protocol/AccessPermission.hh"
class DataBlock;
-class AbstractEntry {
-public:
- // Constructors
- AbstractEntry();
-
- // Destructor, prevent it from instantiation
- virtual ~AbstractEntry() = 0;
-
- // Public Methods
-
- // The methods below are those called by ruby runtime, add when it is
- // absolutely necessary and should all be virtual function.
- virtual DataBlock& getDataBlk() = 0;
-
+class AbstractEntry
+{
+ public:
+ AbstractEntry();
+ virtual ~AbstractEntry() = 0;
- virtual void print(ostream& out) const = 0;
+ // The methods below are those called by ruby runtime, add when it
+ // is absolutely necessary and should all be virtual function.
+ virtual DataBlock& getDataBlk() = 0;
+ virtual void print(ostream& out) const = 0;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const AbstractEntry& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const AbstractEntry& obj)
+inline ostream&
+operator<<(ostream& out, const AbstractEntry& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //AbstractEntry_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * $Id$
- *
- * Description: Define all possible protocol parameters and their
- * default value here. Normally, all parameters should
- * have default value "false" means the feature of the
- * protocol is turned off.
- *
+ * Define all possible protocol parameters and their default value
+ * here. Normally, all parameters should have default value "false"
+ * means the feature of the protocol is turned off.
*/
-#ifndef AbstractProtocol_H
-#define AbstractProtocol_H
-
-class AbstractProtocol {
-public:
- // Constructors
- AbstractProtocol() {};
+#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTPROTOCOL_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTPROTOCOL_HH__
- // Destructor, no instantiation
- // No definition also, so no subclass can be instantiated also
- virtual ~AbstractProtocol() = 0;
+class AbstractProtocol
+{
+ public:
+ AbstractProtocol() {}
- // Public Methods
+ virtual ~AbstractProtocol() = 0;
- // Data Members (m_ prefix)
- static const bool m_CMP = false ;
- static const bool m_TwoLevelCache = false ;
+ static const bool m_CMP = false ;
+ static const bool m_TwoLevelCache = false ;
};
-#endif //AbstractProtocol_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTPROTOCOL_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
-#ifndef MESSAGE_H
-#define MESSAGE_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_MESSAGE_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_MESSAGE_HH__
#include <iostream>
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/RefCnt.hh"
#include "mem/gems_common/RefCountable.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
class Message;
typedef RefCnt<Message> MsgPtr;
-class Message : public RefCountable {
-public:
- // Constructors
- Message() : RefCountable() { m_time = g_eventQueue_ptr->getTime(); m_LastEnqueueTime = g_eventQueue_ptr->getTime(); m_DelayedCycles = 0;}
-
- // Destructor
- virtual ~Message() { }
-
- // Public Methods
- virtual Message* clone() const = 0;
- virtual void destroy() = 0;
- virtual void print(std::ostream& out) const = 0;
-
- void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; }
- const int& getDelayedCycles() const {return m_DelayedCycles;}
- int& getDelayedCycles() {return m_DelayedCycles;}
- void setLastEnqueueTime(const Time& time) { m_LastEnqueueTime = time; }
- const Time& getLastEnqueueTime() const {return m_LastEnqueueTime;}
- Time& getLastEnqueueTime() {return m_LastEnqueueTime;}
-
- const Time& getTime() const { return m_time; }
- void setTime(const Time& new_time) { m_time = new_time; }
-private:
- // Private Methods
-
- // Data Members (m_ prefix)
- Time m_time;
- Time m_LastEnqueueTime; // my last enqueue time
- int m_DelayedCycles; // my delayed cycles
-
+class Message : public RefCountable
+{
+ public:
+ Message()
+ : RefCountable()
+ {
+ m_time = g_eventQueue_ptr->getTime();
+ m_LastEnqueueTime = g_eventQueue_ptr->getTime();
+ m_DelayedCycles = 0;
+ }
+
+ virtual ~Message() { }
+
+ virtual Message* clone() const = 0;
+ virtual void destroy() = 0;
+ virtual void print(std::ostream& out) const = 0;
+
+ void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; }
+ const int& getDelayedCycles() const {return m_DelayedCycles;}
+ int& getDelayedCycles() {return m_DelayedCycles;}
+ void setLastEnqueueTime(const Time& time) { m_LastEnqueueTime = time; }
+ const Time& getLastEnqueueTime() const {return m_LastEnqueueTime;}
+ Time& getLastEnqueueTime() {return m_LastEnqueueTime;}
+
+ const Time& getTime() const { return m_time; }
+ void setTime(const Time& new_time) { m_time = new_time; }
+
+ private:
+ Time m_time;
+ Time m_LastEnqueueTime; // my last enqueue time
+ int m_DelayedCycles; // my delayed cycles
};
-// Output operator declaration
-std::ostream& operator<<(std::ostream& out, const Message& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-std::ostream& operator<<(std::ostream& out, const Message& obj)
+inline std::ostream&
+operator<<(std::ostream& out, const Message& obj)
{
- obj.print(out);
- out << std::flush;
- return out;
+ obj.print(out);
+ out << std::flush;
+ return out;
}
-#endif //MESSAGE_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_MESSAGE_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * NetworkMessage.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef NetworkMessage_H
-#define NetworkMessage_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_NETWORKMESSAGE_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_NETWORKMESSAGE_HH__
-#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/RefCnt.hh"
#include "mem/gems_common/RefCountable.hh"
-#include "mem/ruby/slicc_interface/Message.hh"
#include "mem/protocol/MessageSizeType.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/NetDest.hh"
+#include "mem/ruby/slicc_interface/Message.hh"
class Address;
class NetworkMessage;
typedef RefCnt<NetworkMessage> NetMsgPtr;
-class NetworkMessage : public Message {
-public:
- // Constructors
- NetworkMessage()
- :Message()
+class NetworkMessage : public Message
+{
+ public:
+ NetworkMessage()
+ : Message()
{
- m_internal_dest_valid = false;
+ m_internal_dest_valid = false;
}
- // Destructor
- virtual ~NetworkMessage() { }
+ virtual ~NetworkMessage() { }
- // Public Methods
+ virtual const NetDest& getDestination() const = 0;
+ virtual NetDest& getDestination() = 0;
+ virtual const MessageSizeType& getMessageSize() const = 0;
+ virtual MessageSizeType& getMessageSize() = 0;
- virtual const NetDest& getDestination() const = 0;
- virtual NetDest& getDestination() = 0;
- virtual const MessageSizeType& getMessageSize() const = 0;
- virtual MessageSizeType& getMessageSize() = 0;
- // virtual const Address& getAddress() const = 0;
- // virtual Address& getAddress() = 0;
+ const NetDest&
+ getInternalDestination() const
+ {
+ if (m_internal_dest_valid == false)
+ return getDestination();
- const NetDest& getInternalDestination() const {
- if (m_internal_dest_valid == false) {
- return getDestination();
- } else {
- return m_internal_dest;
+ return m_internal_dest;
}
- }
- NetDest& getInternalDestination() {
- if (m_internal_dest_valid == false) {
- m_internal_dest = getDestination();
- m_internal_dest_valid = true;
+ NetDest&
+ getInternalDestination()
+ {
+ if (m_internal_dest_valid == false) {
+ m_internal_dest = getDestination();
+ m_internal_dest_valid = true;
+ }
+ return m_internal_dest;
}
- return m_internal_dest;
- }
-
- virtual void print(ostream& out) const = 0;
-private:
- // Private Methods
+ virtual void print(ostream& out) const = 0;
- // Data Members (m_ prefix)
- NetDest m_internal_dest;
- bool m_internal_dest_valid;
+ private:
+ NetDest m_internal_dest;
+ bool m_internal_dest_valid;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const NetworkMessage& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const NetworkMessage& obj)
+inline ostream&
+operator<<(ostream& out, const NetworkMessage& obj)
{
- obj.print(out);
- out << flush;
- return out;
+ obj.print(out);
+ out << flush;
+ return out;
}
-#endif //NetworkMessage_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_NETWORKMESSAGE_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
#include "mem/ruby/system/CacheMemory.hh"
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- */
-
-#ifndef COMPONENTMAPPINGFNS_H
-#define COMPONENTMAPPINGFNS_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_COMPONENTMAPPINGS_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_COMPONENTMAPPINGS_HH__
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/NodeID.hh"
-#include "mem/ruby/system/MachineID.hh"
+#include "mem/protocol/GenericMachineType.hh"
+#include "mem/protocol/MachineType.hh"
#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Set.hh"
+#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/NetDest.hh"
-#include "mem/protocol/GenericMachineType.hh"
+#include "mem/ruby/common/Set.hh"
#include "mem/ruby/system/DirectoryMemory.hh"
-#include "mem/protocol/MachineType.hh"
+#include "mem/ruby/system/MachineID.hh"
+#include "mem/ruby/system/NodeID.hh"
#ifdef MACHINETYPE_L1Cache
#define MACHINETYPE_L1CACHE_ENUM MachineType_L1Cache
// used to determine the home directory
// returns a value between 0 and total_directories_within_the_system
-inline
-NodeID map_Address_to_DirectoryNode(const Address& addr)
+inline NodeID
+map_Address_to_DirectoryNode(const Address& addr)
{
- return DirectoryMemory::mapAddressToDirectoryVersion(addr);
+ return DirectoryMemory::mapAddressToDirectoryVersion(addr);
}
// used to determine the home directory
// returns a value between 0 and total_directories_within_the_system
-inline
-MachineID map_Address_to_Directory(const Address &addr)
+inline MachineID
+map_Address_to_Directory(const Address &addr)
{
- MachineID mach = {MachineType_Directory, map_Address_to_DirectoryNode(addr)};
- return mach;
+ MachineID mach =
+ {MachineType_Directory, map_Address_to_DirectoryNode(addr)};
+ return mach;
}
-inline
-MachineID map_Address_to_DMA(const Address & addr)
+inline MachineID
+map_Address_to_DMA(const Address & addr)
{
- MachineID dma = {MACHINETYPE_DMA_ENUM, 0};
- return dma;
+ MachineID dma = {MACHINETYPE_DMA_ENUM, 0};
+ return dma;
}
-inline
-NetDest broadcast(MachineType type)
+inline NetDest
+broadcast(MachineType type)
{
- NetDest dest;
- for (int i=0; i<MachineType_base_count(type); i++) {
- MachineID mach = {type, i};
- dest.add(mach);
- }
- return dest;
+ NetDest dest;
+ for (int i = 0; i < MachineType_base_count(type); i++) {
+ MachineID mach = {type, i};
+ dest.add(mach);
+ }
+ return dest;
}
-inline
-MachineID mapAddressToRange(const Address & addr, MachineType type, int low_bit, int num_bits)
+inline MachineID
+mapAddressToRange(const Address & addr, MachineType type, int low_bit,
+ int num_bits)
{
- MachineID mach = {type, 0};
- if (num_bits == 0)
+ MachineID mach = {type, 0};
+ if (num_bits == 0)
+ return mach;
+ mach.num = addr.bitSelect(low_bit, low_bit + num_bits - 1);
return mach;
- mach.num = addr.bitSelect(low_bit, low_bit+num_bits-1);
- return mach;
}
-extern inline NodeID machineIDToNodeID(MachineID machID)
+inline NodeID
+machineIDToNodeID(MachineID machID)
{
- return machID.num;
+ return machID.num;
}
-extern inline MachineType machineIDToMachineType(MachineID machID)
+inline MachineType
+machineIDToMachineType(MachineID machID)
{
- return machID.type;
+ return machID.type;
}
-extern inline NodeID L1CacheMachIDToProcessorNum(MachineID machID)
+inline NodeID
+L1CacheMachIDToProcessorNum(MachineID machID)
{
- assert(machID.type == MachineType_L1Cache);
- return machID.num;
+ assert(machID.type == MachineType_L1Cache);
+ return machID.num;
}
-extern inline MachineID getL1MachineID(NodeID L1RubyNode)
+inline MachineID
+getL1MachineID(NodeID L1RubyNode)
{
- MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode};
- return mach;
+ MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode};
+ return mach;
}
-extern inline GenericMachineType ConvertMachToGenericMach(MachineType machType) {
- if (machType == MACHINETYPE_L1CACHE_ENUM) {
- return GenericMachineType_L1Cache;
- } else if (machType == MACHINETYPE_L2CACHE_ENUM) {
- return GenericMachineType_L2Cache;
- } else if (machType == MACHINETYPE_L3CACHE_ENUM) {
- return GenericMachineType_L3Cache;
- } else if (machType == MachineType_Directory) {
- return GenericMachineType_Directory;
- } else {
+inline GenericMachineType
+ConvertMachToGenericMach(MachineType machType)
+{
+ if (machType == MACHINETYPE_L1CACHE_ENUM)
+ return GenericMachineType_L1Cache;
+
+ if (machType == MACHINETYPE_L2CACHE_ENUM)
+ return GenericMachineType_L2Cache;
+
+ if (machType == MACHINETYPE_L3CACHE_ENUM)
+ return GenericMachineType_L3Cache;
+
+ if (machType == MachineType_Directory)
+ return GenericMachineType_Directory;
+
ERROR_MSG("cannot convert to a GenericMachineType");
return GenericMachineType_NULL;
- }
}
-extern inline int machineCount(MachineType machType) {
+inline int
+machineCount(MachineType machType)
+{
return MachineType_base_count(machType);
}
-#endif // COMPONENTMAPPINGFNS_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_COMPONENTMAPPINGS_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * slicc_util.cc
- *
- * Description: See slicc_util.hh
- *
- * $Id$
- *
- */
-
+#include "mem/protocol/Protocol.hh"
#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/profiler/AddressProfiler.hh"
-#include "mem/protocol/Protocol.hh"
-#include "mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh"
+#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
-// #include "TransactionInterfaceManager.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh"
+#include "mem/ruby/system/System.hh"
-void profile_request(int cache_state, Directory_State directory_state, GenericRequestType request_type)
+void
+profile_request(int cache_state, Directory_State directory_state,
+ GenericRequestType request_type)
{
- string requestStr = L1Cache_State_to_string(L1Cache_State(cache_state))+":"+
- Directory_State_to_string(directory_state)+":"+
- GenericRequestType_to_string(request_type);
- g_system_ptr->getProfiler()->profileRequest(requestStr);
+ string requestStr = L1Cache_State_to_string(L1Cache_State(cache_state))+
+ ":" +
+ Directory_State_to_string(directory_state) + ":" +
+ GenericRequestType_to_string(request_type);
+ g_system_ptr->getProfiler()->profileRequest(requestStr);
}
-void profile_request(const string& L1CacheState, const string& L2CacheState, const string& directoryState, const string& requestType)
+void
+profile_request(const string& L1CacheState, const string& L2CacheState,
+ const string& directoryState, const string& requestType)
{
- string requestStr = L1CacheState+":"+L2CacheState+":"+directoryState+":"+requestType;
- g_system_ptr->getProfiler()->profileRequest(requestStr);
+ string requestStr = L1CacheState + ":" + L2CacheState + ":" +
+ directoryState + ":" + requestType;
+
+ g_system_ptr->getProfiler()->profileRequest(requestStr);
}
-void profile_outstanding_request(int outstanding)
+void
+profile_outstanding_request(int outstanding)
{
- g_system_ptr->getProfiler()->profileOutstandingRequest(outstanding);
+ g_system_ptr->getProfiler()->profileOutstandingRequest(outstanding);
}
-void profile_average_latency_estimate(int latency)
+void
+profile_average_latency_estimate(int latency)
{
- g_system_ptr->getProfiler()->profileAverageLatencyEstimate(latency);
+ g_system_ptr->getProfiler()->profileAverageLatencyEstimate(latency);
}
-void profile_sharing(const Address& addr, AccessType type, NodeID requestor, const Set& sharers, const Set& owner)
+void
+profile_sharing(const Address& addr, AccessType type, NodeID requestor,
+ const Set& sharers, const Set& owner)
{
- g_system_ptr->getProfiler()->profileSharing(addr, type, requestor, sharers, owner);
+ g_system_ptr->getProfiler()->
+ profileSharing(addr, type, requestor, sharers, owner);
}
-void profileMsgDelay(int virtualNetwork, int delayCycles)
+void
+profileMsgDelay(int virtualNetwork, int delayCycles)
{
- g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles);
+ g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles);
}
-void profileGetX(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor)
+void
+profileGetX(const Address& datablock, const Address& PC, const Set& owner,
+ const Set& sharers, NodeID requestor)
{
- g_system_ptr->getProfiler()->getAddressProfiler()->profileGetX(datablock, PC, owner, sharers, requestor);
+ g_system_ptr->getProfiler()->getAddressProfiler()->
+ profileGetX(datablock, PC, owner, sharers, requestor);
}
-void profileGetS(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor)
+void
+profileGetS(const Address& datablock, const Address& PC, const Set& owner,
+ const Set& sharers, NodeID requestor)
{
- g_system_ptr->getProfiler()->getAddressProfiler()->profileGetS(datablock, PC, owner, sharers, requestor);
+ g_system_ptr->getProfiler()->getAddressProfiler()->
+ profileGetS(datablock, PC, owner, sharers, requestor);
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * slicc_util.hh
- *
- * Description: These are the functions that exported to slicc from ruby.
- *
- * $Id$
- *
+ * These are the functions that exported to slicc from ruby.
*/
-#ifndef RUBYSLICC_PROFILER_INTERFACE_H
-#define RUBYSLICC_PROFILER_INTERFACE_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_PROFILER_INTERFACE_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_PROFILER_INTERFACE_HH__
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/protocol/L1Cache_State.hh"
#include "mem/protocol/AccessType.hh"
-#include "mem/protocol/GenericRequestType.hh"
#include "mem/protocol/Directory_State.hh"
+#include "mem/protocol/GenericRequestType.hh"
+#include "mem/protocol/L1Cache_State.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/NodeID.hh"
class Set;
-void profile_request(int cache_state, Directory_State directory_state, GenericRequestType request_type);
+void profile_request(int cache_state, Directory_State directory_state,
+ GenericRequestType request_type);
void profile_outstanding_persistent_request(int outstanding);
void profile_outstanding_request(int outstanding);
-void profile_sharing(const Address& addr, AccessType type, NodeID requestor, const Set& sharers, const Set& owner);
-void profile_request(const string& L1CacheStateStr, const string& L2CacheStateStr, const string& directoryStateStr, const string& requestTypeStr);
+void profile_sharing(const Address& addr, AccessType type, NodeID requestor,
+ const Set& sharers, const Set& owner);
+void profile_request(const string& L1CacheStateStr,
+ const string& L2CacheStateStr,
+ const string& directoryStateStr,
+ const string& requestTypeStr);
void profile_miss(const CacheMsg& msg, NodeID id);
void profile_L1Cache_miss(const CacheMsg& msg, NodeID id);
-void profile_L2Cache_miss(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID l2cacheID);
+void profile_L2Cache_miss(GenericRequestType requestType, AccessModeType type,
+ int msgSize, PrefetchBit pfBit, NodeID l2cacheID);
void profile_token_retry(const Address& addr, AccessType type, int count);
void profile_filter_action(int action);
void profile_persistent_prediction(const Address& addr, AccessType type);
void profileMsgDelay(int virtualNetwork, int delayCycles);
void profile_multicast_retry(const Address& addr, int count);
-void profileGetX(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor);
-void profileGetS(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor);
+void profileGetX(const Address& datablock, const Address& PC, const Set& owner,
+ const Set& sharers, NodeID requestor);
+void profileGetS(const Address& datablock, const Address& PC, const Set& owner,
+ const Set& sharers, NodeID requestor);
void profileOverflow(const Address & addr, MachineID mach);
-#endif // RUBYSLICC_PROFILER_INTERFACE_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_PROFILER_INTERFACE_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * slicc_util.hh
- *
- * Description: These are the functions that exported to slicc from ruby.
- *
- * $Id$
- *
+ * These are the functions that exported to slicc from ruby.
*/
-#ifndef SLICC_UTIL_H
-#define SLICC_UTIL_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/system/NodeID.hh"
-#include "mem/ruby/system/MachineID.hh"
+#include "mem/protocol/AccessType.hh"
#include "mem/protocol/CacheMsg.hh"
-#include "mem/protocol/GenericRequestType.hh"
#include "mem/protocol/CacheRequestType.hh"
-#include "mem/protocol/AccessType.hh"
-#include "mem/protocol/MachineType.hh"
#include "mem/protocol/Directory_State.hh"
+#include "mem/protocol/GenericRequestType.hh"
#include "mem/protocol/L1Cache_State.hh"
+#include "mem/protocol/MachineType.hh"
#include "mem/protocol/MessageSizeType.hh"
-#include "mem/ruby/network/Network.hh"
#include "mem/protocol/PrefetchBit.hh"
-#include "mem/ruby/system/System.hh"
-
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/network/Network.hh"
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
+#include "mem/ruby/system/MachineID.hh"
+#include "mem/ruby/system/NodeID.hh"
+#include "mem/ruby/system/System.hh"
class Set;
class NetDest;
-extern inline int random(int n)
+inline int
+random(int n)
{
return random() % n;
}
-extern inline bool multicast_retry()
+inline bool
+multicast_retry()
{
- if (RubySystem::getRandomization()) {
- return (random() & 0x1);
- } else {
- return true;
- }
+ if (RubySystem::getRandomization()) {
+ return (random() & 0x1);
+ } else {
+ return true;
+ }
}
-extern inline int cache_state_to_int(L1Cache_State state)
+inline int
+cache_state_to_int(L1Cache_State state)
{
- return state;
+ return state;
}
-extern inline Time get_time()
+inline Time
+get_time()
{
- return g_eventQueue_ptr->getTime();
+ return g_eventQueue_ptr->getTime();
}
-extern inline Time zero_time()
+inline Time
+zero_time()
{
- return 0;
+ return 0;
}
-extern inline NodeID intToID(int nodenum)
+inline NodeID
+intToID(int nodenum)
{
- NodeID id = nodenum;
- return id;
+ NodeID id = nodenum;
+ return id;
}
-extern inline int IDToInt(NodeID id)
+inline int
+IDToInt(NodeID id)
{
- int nodenum = id;
- return nodenum;
+ int nodenum = id;
+ return nodenum;
}
-extern inline int addressToInt(Address addr)
+inline int
+addressToInt(Address addr)
{
- return (int) addr.getLineAddress();
+ return (int)addr.getLineAddress();
}
-extern inline bool long_enough_ago(Time event)
+inline bool
+long_enough_ago(Time event)
{
- return ((get_time() - event) > 200);
+ return ((get_time() - event) > 200);
}
-extern inline int getAddThenMod(int addend1, int addend2, int modulus)
+inline int
+getAddThenMod(int addend1, int addend2, int modulus)
{
- return (addend1 + addend2) % modulus;
+ return (addend1 + addend2) % modulus;
}
-extern inline Time getTimeModInt(Time time, int modulus)
+inline Time
+getTimeModInt(Time time, int modulus)
{
- return time % modulus;
+ return time % modulus;
}
-extern inline Time getTimePlusInt(Time addend1, int addend2)
+inline Time
+getTimePlusInt(Time addend1, int addend2)
{
- return (Time) addend1 + addend2;
+ return (Time) addend1 + addend2;
}
-extern inline Time getTimeMinusTime(Time t1, Time t2)
+inline Time
+getTimeMinusTime(Time t1, Time t2)
{
- ASSERT(t1 >= t2);
- return t1 - t2;
+ ASSERT(t1 >= t2);
+ return t1 - t2;
}
-extern inline Time getPreviousDelayedCycles(Time t1, Time t2)
+inline Time
+getPreviousDelayedCycles(Time t1, Time t2)
{
- if (RubySystem::getRandomization()) { // when randomizing delayed
- return 0;
- } else {
- return getTimeMinusTime(t1, t2);
- }
+ if (RubySystem::getRandomization()) { // when randomizing delayed
+ return 0;
+ } else {
+ return getTimeMinusTime(t1, t2);
+ }
}
-extern inline void WARN_ERROR_TIME(Time time)
+inline void
+WARN_ERROR_TIME(Time time)
{
- WARN_EXPR(time);
+ WARN_EXPR(time);
}
-// Return type for time_to_int is "Time" and not "int" so we get a 64-bit integer
-extern inline Time time_to_int(Time time)
+// Return type for time_to_int is "Time" and not "int" so we get a
+// 64-bit integer
+inline Time
+time_to_int(Time time)
{
- return time;
+ return time;
}
// Appends an offset to an address
-extern inline Address setOffset(Address addr, int offset)
+inline Address
+setOffset(Address addr, int offset)
{
- Address result = addr;
- result.setOffset(offset);
- return result;
+ Address result = addr;
+ result.setOffset(offset);
+ return result;
}
// Makes an address into a line address
-extern inline Address makeLineAddress(Address addr)
+inline Address
+makeLineAddress(Address addr)
{
- Address result = addr;
- result.makeLineAddress();
- return result;
+ Address result = addr;
+ result.makeLineAddress();
+ return result;
}
-extern inline int addressOffset(Address addr)
+inline int
+addressOffset(Address addr)
{
- return addr.getOffset();
+ return addr.getOffset();
}
-#endif //SLICC_UTIL_H
+#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RUBYSLICC_INCLUDES_H
-#define RUBYSLICC_INCLUDES_H
+#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_INCLUDES_HH__
+#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_INCLUDES_HH__
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
#include "mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh"
-#endif
+#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_INCLUDES_HH__
* 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__
* 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__
#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()
{
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;
}
* 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__
* 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()
{
* 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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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;
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)
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);
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__
* 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)
{
}
{
}
-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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * MemoryControl.cc
- *
* Description: This module simulates a basic DDR-style memory controller
* (and can easily be extended to do FB-DIMM as well).
*
* 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;
// 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;
}
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 *
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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
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__
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 << "]";
}
* 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__
* 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"
/**
* 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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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
{
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__
* 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"
* 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__
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
* 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)
assert(m_version != -1);
physmem = p->physmem;
-
+
m_controller = NULL;
m_mandatory_q_ptr = NULL;
physMemPort = NULL;
}
-void RubyPort::init()
+void
+RubyPort::init()
{
assert(m_controller != NULL);
m_mandatory_q_ptr = m_controller->getMandatoryQueue();
{
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)
{
ruby_port = _port;
}
-RubyPort::M5Port::M5Port(const std::string &_name,
+RubyPort::M5Port::M5Port(const std::string &_name,
RubyPort *_port)
: SimpleTimingPort(_name, _port)
{
return 0;
}
-
Tick
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()) {
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();
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");
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;
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;
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);
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);
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
* 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;
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);
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:
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)
{}
};
//
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;
PhysicalMemory* physmem;
};
-#endif
+#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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 *
{
return new Sequencer(this);
}
-
+
Sequencer::Sequencer(const Params *p)
: RubyPort(p), deadlockCheckEvent(this)
{
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;
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
}
-
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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;
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__
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
#include "mem/ruby/system/SparseMemory.hh"
-
-// ****************************************************************
-
-
SparseMemory::SparseMemory(int number_of_bits, int number_of_levels)
{
int even_level_bits;
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;
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
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));
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 {
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();
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;
}
}
// 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));
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;
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;
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;
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));
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));
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;
-
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
* 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;
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;
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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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;
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
// 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
* 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);
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*/
/*
- * 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,
*/
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
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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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;
}
-
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
* 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__