diff options
author | Nilay Vaish <nilay@cs.wisc.edu> | 2013-01-14 10:04:21 -0600 |
---|---|---|
committer | Nilay Vaish <nilay@cs.wisc.edu> | 2013-01-14 10:04:21 -0600 |
commit | cf232de4615f0fe9435d6e92a1d6319c972a8c88 (patch) | |
tree | 539c365baf0b078b2fdbf820feeb89c1afee8726 /src | |
parent | cbbc4c7f6b4cb718cc3907b955f7ae527d2d0274 (diff) | |
download | gem5-cf232de4615f0fe9435d6e92a1d6319c972a8c88.tar.xz |
Ruby: use ClockedObject in Consumer class
Many Ruby structures inherit from the Consumer, which is used for scheduling
events. The Consumer used to relay on an Event Manager for scheduling events
and on g_system_ptr for time. With this patch, the Consumer will now use a
ClockedObject to schedule events and to query for current time. This resulted
in several structures being converted from SimObjects to ClockedObjects. Also,
the MessageBuffer class now requires a pointer to a ClockedObject so as to
query for time.
Diffstat (limited to 'src')
40 files changed, 155 insertions, 152 deletions
diff --git a/src/mem/protocol/RubySlicc_Profiler.sm b/src/mem/protocol/RubySlicc_Profiler.sm index 50fe41fe5..64f643054 100644 --- a/src/mem/protocol/RubySlicc_Profiler.sm +++ b/src/mem/protocol/RubySlicc_Profiler.sm @@ -47,4 +47,4 @@ void profile_outstanding_persistent_request(int outstanding); void profile_average_latency_estimate(int latency); // profile the total message delay of a message across a virtual network -void profileMsgDelay(int virtualNetwork, int delayCycles); +void profileMsgDelay(int virtualNetwork, Time delayCycles); diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index 20249942a..b4601e9e6 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -36,13 +36,12 @@ // external_type(MessageBuffer, buffer="yes", inport="yes", outport="yes"); - external_type(OutPort, primitive="yes"); structure(InPort, external = "yes", primitive="yes") { bool isReady(); void dequeue(); - int dequeue_getDelayCycles(); + Time dequeue_getDelayCycles(); void recycle(); bool isEmpty(); } diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index f960cc033..446586f5a 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -42,6 +42,8 @@ MessageBuffer::MessageBuffer(const string &name) { m_msg_counter = 0; m_consumer_ptr = NULL; + m_clockobj_ptr = NULL; + m_ordering_set = false; m_strict_fifo = true; m_size = 0; @@ -66,10 +68,10 @@ MessageBuffer::MessageBuffer(const string &name) int MessageBuffer::getSize() { - if (m_time_last_time_size_checked == g_system_ptr->getTime()) { + if (m_time_last_time_size_checked == m_clockobj_ptr->curCycle()) { return m_size_last_time_size_checked; } else { - m_time_last_time_size_checked = g_system_ptr->getTime(); + m_time_last_time_size_checked = m_clockobj_ptr->curCycle(); m_size_last_time_size_checked = m_size; return m_size; } @@ -89,11 +91,11 @@ MessageBuffer::areNSlotsAvailable(int n) // 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_system_ptr->getTime()) { + if (m_time_last_time_pop < m_clockobj_ptr->curCycle()) { // no pops this cycle - m_size is correct current_size = m_size; } else { - if (m_time_last_time_enqueue < g_system_ptr->getTime()) { + if (m_time_last_time_enqueue < m_clockobj_ptr->curCycle()) { // no enqueues this cycle - m_size_at_cycle_start is correct current_size = m_size_at_cycle_start; } else { @@ -155,9 +157,9 @@ MessageBuffer::enqueue(MsgPtr message, Time delta) m_size++; // record current time incase we have a pop that also adjusts my size - if (m_time_last_time_enqueue < g_system_ptr->getTime()) { + if (m_time_last_time_enqueue < m_clockobj_ptr->curCycle()) { m_msgs_this_cycle = 0; // first msg this cycle - m_time_last_time_enqueue = g_system_ptr->getTime(); + m_time_last_time_enqueue = m_clockobj_ptr->curCycle(); } m_msgs_this_cycle++; @@ -168,7 +170,7 @@ MessageBuffer::enqueue(MsgPtr message, Time delta) // Calculate the arrival time of the message, that is, the first // cycle the message can be dequeued. assert(delta>0); - Time current_time = g_system_ptr->getTime(); + Time current_time = m_clockobj_ptr->curCycle(); Time arrival_time = 0; if (!RubySystem::getRandomization() || (m_randomization == false)) { // No randomization @@ -191,11 +193,10 @@ MessageBuffer::enqueue(MsgPtr message, Time delta) if (arrival_time < m_last_arrival_time) { panic("FIFO ordering violated: %s name: %s current time: %d " "delta: %d arrival_time: %d last arrival_time: %d\n", - *this, m_name, - current_time * g_system_ptr->clockPeriod(), - delta * g_system_ptr->clockPeriod(), - arrival_time * g_system_ptr->clockPeriod(), - m_last_arrival_time * g_system_ptr->clockPeriod()); + *this, m_name, current_time * m_clockobj_ptr->clockPeriod(), + delta * m_clockobj_ptr->clockPeriod(), + arrival_time * m_clockobj_ptr->clockPeriod(), + m_last_arrival_time * m_clockobj_ptr->clockPeriod()); } } @@ -208,10 +209,10 @@ MessageBuffer::enqueue(MsgPtr message, Time delta) Message* msg_ptr = message.get(); assert(msg_ptr != NULL); - assert(g_system_ptr->getTime() >= msg_ptr->getLastEnqueueTime() && + assert(m_clockobj_ptr->curCycle() >= msg_ptr->getLastEnqueueTime() && "ensure we aren't dequeued early"); - msg_ptr->setDelayedCycles(g_system_ptr->getTime() - + msg_ptr->setDelayedCycles(m_clockobj_ptr->curCycle() - msg_ptr->getLastEnqueueTime() + msg_ptr->getDelayedCycles()); msg_ptr->setLastEnqueueTime(arrival_time); @@ -222,9 +223,8 @@ MessageBuffer::enqueue(MsgPtr message, Time delta) push_heap(m_prio_heap.begin(), m_prio_heap.end(), greater<MessageBufferNode>()); - DPRINTF(RubyQueue, "Enqueue with arrival_time %lld.\n", - arrival_time * g_system_ptr->clockPeriod()); - DPRINTF(RubyQueue, "Enqueue Message: %s.\n", (*(message.get()))); + DPRINTF(RubyQueue, "Enqueue arrival_time: %lld, Message: %s\n", + arrival_time * m_clockobj_ptr->clockPeriod(), *(message.get())); // Schedule the wakeup if (m_consumer_ptr != NULL) { @@ -235,18 +235,11 @@ MessageBuffer::enqueue(MsgPtr message, Time delta) } } -int +Time MessageBuffer::dequeue_getDelayCycles(MsgPtr& message) { - int delay_cycles = -1; // null value - dequeue(message); - - // get the delay cycles - delay_cycles = setAndReturnDelayCycles(message); - - assert(delay_cycles >= 0); - return delay_cycles; + return setAndReturnDelayCycles(message); } void @@ -259,21 +252,17 @@ MessageBuffer::dequeue(MsgPtr& message) DPRINTF(RubyQueue, "Enqueue message is %s\n", (*(message.get()))); } -int +Time MessageBuffer::dequeue_getDelayCycles() { - int delay_cycles = -1; // null value - // get MsgPtr of the message about to be dequeued MsgPtr message = m_prio_heap.front().m_msgptr; // get the delay cycles - delay_cycles = setAndReturnDelayCycles(message); - + Time delayCycles = setAndReturnDelayCycles(message); dequeue(); - assert(delay_cycles >= 0); - return delay_cycles; + return delayCycles; } void @@ -287,9 +276,9 @@ MessageBuffer::pop() // record previous size and time so the current buffer size isn't // adjusted until next cycle - if (m_time_last_time_pop < g_system_ptr->getTime()) { + if (m_time_last_time_pop < m_clockobj_ptr->curCycle()) { m_size_at_cycle_start = m_size; - m_time_last_time_pop = g_system_ptr->getTime(); + m_time_last_time_pop = m_clockobj_ptr->curCycle(); } m_size--; } @@ -315,11 +304,11 @@ MessageBuffer::recycle() MessageBufferNode node = m_prio_heap.front(); pop_heap(m_prio_heap.begin(), m_prio_heap.end(), greater<MessageBufferNode>()); - node.m_time = g_system_ptr->getTime() + m_recycle_latency; + node.m_time = m_clockobj_ptr->curCycle() + m_recycle_latency; m_prio_heap.back() = node; push_heap(m_prio_heap.begin(), m_prio_heap.end(), greater<MessageBufferNode>()); - m_consumer_ptr->scheduleEventAbsolute(g_system_ptr->getTime() + + m_consumer_ptr->scheduleEventAbsolute(m_clockobj_ptr->curCycle() + m_recycle_latency); } @@ -335,7 +324,7 @@ MessageBuffer::reanalyzeMessages(const Address& addr) // while(!m_stall_msg_map[addr].empty()) { m_msg_counter++; - MessageBufferNode msgNode(g_system_ptr->getTime() + 1, + MessageBufferNode msgNode(m_clockobj_ptr->curCycle() + 1, m_msg_counter, m_stall_msg_map[addr].front()); @@ -364,7 +353,7 @@ MessageBuffer::reanalyzeAllMessages() while(!(map_iter->second).empty()) { m_msg_counter++; - MessageBufferNode msgNode(g_system_ptr->getTime() + 1, + MessageBufferNode msgNode(m_clockobj_ptr->curCycle() + 1, m_msg_counter, (map_iter->second).front()); @@ -397,23 +386,19 @@ MessageBuffer::stallMessage(const Address& addr) (m_stall_msg_map[addr]).push_back(message); } -int +Time MessageBuffer::setAndReturnDelayCycles(MsgPtr msg_ptr) { - int delay_cycles = -1; // null value - // get the delay cycles of the message at the top of the queue // this function should only be called on dequeue // ensure the msg hasn't been enqueued - assert(msg_ptr->getLastEnqueueTime() <= g_system_ptr->getTime()); - msg_ptr->setDelayedCycles(g_system_ptr->getTime() - - msg_ptr->getLastEnqueueTime() + - msg_ptr->getDelayedCycles()); - delay_cycles = msg_ptr->getDelayedCycles(); + assert(msg_ptr->getLastEnqueueTime() <= m_clockobj_ptr->curCycle()); + msg_ptr->setDelayedCycles(m_clockobj_ptr->curCycle() - + msg_ptr->getLastEnqueueTime() + + msg_ptr->getDelayedCycles()); - assert(delay_cycles >= 0); - return delay_cycles; + return msg_ptr->getDelayedCycles(); } void @@ -440,7 +425,7 @@ bool MessageBuffer::isReady() const { return ((m_prio_heap.size() > 0) && - (m_prio_heap.front().m_time <= g_system_ptr->getTime())); + (m_prio_heap.front().m_time <= m_clockobj_ptr->curCycle())); } bool diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index c4fd7165d..581f03453 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -86,6 +86,12 @@ class MessageBuffer m_consumer_ptr = consumer_ptr; } + void setClockObj(ClockedObject* obj) + { + assert(m_clockobj_ptr == NULL); + m_clockobj_ptr = obj; + } + void setDescription(const std::string& name) { m_name = name; } std::string getDescription() { return m_name;} @@ -110,12 +116,13 @@ class MessageBuffer void enqueue(MsgPtr message) { enqueue(message, 1); } void enqueue(MsgPtr message, Time delta); - // void enqueueAbsolute(const MsgPtr& message, Time absolute_time); - int dequeue_getDelayCycles(MsgPtr& message); // returns delay - // cycles of the - // message + + //! returns delay ticks of the message. + Time dequeue_getDelayCycles(MsgPtr& message); void dequeue(MsgPtr& message); - int dequeue_getDelayCycles(); // returns delay cycles of the message + + //! returns delay cycles of the message + Time dequeue_getDelayCycles(); void dequeue() { pop(); } void pop(); void recycle(); @@ -156,16 +163,19 @@ class MessageBuffer int m_recycle_latency; // Private Methods - int setAndReturnDelayCycles(MsgPtr message); + Time 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 + //! Object used for querying time. + ClockedObject* m_clockobj_ptr; + //! Consumer to signal a wakeup(), can be NULL + Consumer* m_consumer_ptr; std::vector<MessageBufferNode> m_prio_heap; - + // use a std::map for the stalled messages as this container is // sorted and ensures a well-defined iteration order typedef std::map< Address, std::list<MsgPtr> > StallMsgMapType; diff --git a/src/mem/ruby/common/Consumer.cc b/src/mem/ruby/common/Consumer.cc index de6a8f448..a829f4d99 100644 --- a/src/mem/ruby/common/Consumer.cc +++ b/src/mem/ruby/common/Consumer.cc @@ -27,23 +27,21 @@ */ #include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" void Consumer::scheduleEvent(Time timeDelta) { - scheduleEventAbsolute(timeDelta + g_system_ptr->getTime()); + scheduleEventAbsolute(timeDelta + em->curCycle()); } void Consumer::scheduleEventAbsolute(Time timeAbs) { - Tick evt_time = g_system_ptr->clockPeriod() * timeAbs; + Tick evt_time = em->clockPeriod() * timeAbs; if (!alreadyScheduled(evt_time)) { // This wakeup is not redundant ConsumerEvent *evt = new ConsumerEvent(this); - assert(timeAbs > g_system_ptr->getTime()); + assert(timeAbs > em->curCycle()); em->schedule(evt, evt_time); insertScheduledWakeupTime(evt_time); diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh index a10abf362..9e089e992 100644 --- a/src/mem/ruby/common/Consumer.hh +++ b/src/mem/ruby/common/Consumer.hh @@ -39,12 +39,12 @@ #include <set> #include "mem/ruby/common/TypeDefines.hh" -#include "sim/eventq.hh" +#include "sim/clocked_object.hh" class Consumer { public: - Consumer(EventManager *_em) + Consumer(ClockedObject *_em) : m_last_scheduled_wakeup(0), m_last_wakeup(0), em(_em) { } @@ -95,7 +95,7 @@ class Consumer Tick m_last_scheduled_wakeup; std::set<Tick> m_scheduled_wakeups; Tick m_last_wakeup; - EventManager *em; + ClockedObject *em; class ConsumerEvent : public Event { diff --git a/src/mem/ruby/network/BasicRouter.cc b/src/mem/ruby/network/BasicRouter.cc index a6972afe2..96564ad0f 100644 --- a/src/mem/ruby/network/BasicRouter.cc +++ b/src/mem/ruby/network/BasicRouter.cc @@ -29,7 +29,7 @@ #include "mem/ruby/network/BasicRouter.hh" BasicRouter::BasicRouter(const Params *p) - : SimObject(p) + : ClockedObject(p) { m_id = p->router_id; } diff --git a/src/mem/ruby/network/BasicRouter.hh b/src/mem/ruby/network/BasicRouter.hh index 220d3527a..fa0a417cc 100644 --- a/src/mem/ruby/network/BasicRouter.hh +++ b/src/mem/ruby/network/BasicRouter.hh @@ -34,9 +34,9 @@ #include <vector> #include "params/BasicRouter.hh" -#include "sim/sim_object.hh" +#include "sim/clocked_object.hh" -class BasicRouter : public SimObject +class BasicRouter : public ClockedObject { public: typedef BasicRouterParams Params; diff --git a/src/mem/ruby/network/BasicRouter.py b/src/mem/ruby/network/BasicRouter.py index 0c8e5cb54..c487e8632 100644 --- a/src/mem/ruby/network/BasicRouter.py +++ b/src/mem/ruby/network/BasicRouter.py @@ -28,9 +28,9 @@ # Brad Beckmann from m5.params import * -from m5.SimObject import SimObject +from ClockedObject import ClockedObject -class BasicRouter(SimObject): +class BasicRouter(ClockedObject): type = 'BasicRouter' cxx_header = "mem/ruby/network/BasicRouter.hh" router_id = Param.Int("ID in relation to other routers") diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index 5c025db2a..c681dc5fe 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -37,7 +37,7 @@ uint32_t Network::m_control_msg_size; uint32_t Network::m_data_msg_size; Network::Network(const Params *p) - : SimObject(p) + : ClockedObject(p) { m_virtual_networks = p->number_of_virtual_networks; m_topology_ptr = p->topology; diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh index 9236a2207..a59caebbd 100644 --- a/src/mem/ruby/network/Network.hh +++ b/src/mem/ruby/network/Network.hh @@ -49,14 +49,14 @@ #include "mem/protocol/MessageSizeType.hh" #include "mem/ruby/common/TypeDefines.hh" #include "params/RubyNetwork.hh" -#include "sim/sim_object.hh" +#include "sim/clocked_object.hh" class NetDest; class MessageBuffer; class Throttle; class Topology; -class Network : public SimObject +class Network : public ClockedObject { public: typedef RubyNetworkParams Params; diff --git a/src/mem/ruby/network/Network.py b/src/mem/ruby/network/Network.py index 4bc35b30c..a1313a841 100644 --- a/src/mem/ruby/network/Network.py +++ b/src/mem/ruby/network/Network.py @@ -29,6 +29,7 @@ from m5.params import * from m5.SimObject import SimObject +from ClockedObject import ClockedObject from BasicLink import BasicLink class Topology(SimObject): @@ -42,7 +43,7 @@ class Topology(SimObject): print_config = Param.Bool(False, "display topology config in the stats file") -class RubyNetwork(SimObject): +class RubyNetwork(ClockedObject): type = 'RubyNetwork' cxx_class = 'Network' cxx_header = "mem/ruby/network/Network.hh" diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py index e5de4ecaf..bbd785e2c 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py @@ -30,10 +30,10 @@ from m5.params import * from m5.proxy import * -from m5.SimObject import SimObject +from ClockedObject import ClockedObject from BasicLink import BasicIntLink, BasicExtLink -class NetworkLink_d(SimObject): +class NetworkLink_d(ClockedObject): type = 'NetworkLink_d' cxx_header = "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" link_id = Param.Int(Parent.link_id, "link id") diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc index b0538d19f..62bee1850 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc @@ -116,6 +116,7 @@ NetworkInterface_d::addNode(vector<MessageBuffer *>& in, // the protocol injects messages into the NI inNode_ptr[j]->setConsumer(this); + inNode_ptr[j]->setClockObj(m_net_ptr); } } diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc index 432097a91..6d12fc30e 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc @@ -32,7 +32,7 @@ #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" NetworkLink_d::NetworkLink_d(const Params *p) - : SimObject(p), Consumer(this) + : ClockedObject(p), Consumer(this) { m_latency = p->link_latency; channel_width = p->channel_width; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh index 61dfe5c52..f27e60757 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh @@ -39,11 +39,11 @@ #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/orion/NetworkPower.hh" #include "params/NetworkLink_d.hh" -#include "sim/sim_object.hh" +#include "sim/clocked_object.hh" class GarnetNetwork_d; -class NetworkLink_d : public SimObject, public Consumer +class NetworkLink_d : public ClockedObject, public Consumer { public: typedef NetworkLink_dParams Params; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh b/src/mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh index a2d6db60b..23a1a91be 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh +++ b/src/mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh @@ -38,7 +38,7 @@ class FlexibleConsumer : public Consumer { public: - FlexibleConsumer(EventManager *em) : Consumer(em) {} + FlexibleConsumer(ClockedObject *em) : Consumer(em) {} virtual bool isBufferNotFull(int vc, int inport) { return true; } virtual void grant_vc(int out_port, int vc, Time grant_time) {} virtual void release_vc(int out_port, int vc, Time release_time) {} diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py index d5b55c1ec..41049884f 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py +++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetLink.py @@ -30,10 +30,10 @@ from m5.params import * from m5.proxy import * -from m5.SimObject import SimObject +from ClockedObject import ClockedObject from BasicLink import BasicIntLink, BasicExtLink -class NetworkLink(SimObject): +class NetworkLink(ClockedObject): type = 'NetworkLink' cxx_header = "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh" link_id = Param.Int(Parent.link_id, "link id") diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc index 99cb44871..9e4c1ef9a 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc @@ -106,6 +106,7 @@ NetworkInterface::addNode(vector<MessageBuffer*>& in, // protocol injects messages into the NI for (int j = 0; j < m_virtual_networks; j++) { inNode_ptr[j]->setConsumer(this); + inNode_ptr[j]->setClockObj(m_net_ptr); } } diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc index 86f44b918..2d94f6484 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc @@ -32,7 +32,7 @@ #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh" NetworkLink::NetworkLink(const Params *p) - : SimObject(p), FlexibleConsumer(this) + : ClockedObject(p), FlexibleConsumer(this) { linkBuffer = new flitBuffer(); m_in_port = 0; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh index d28fd27fc..45dbe7f52 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh @@ -39,11 +39,11 @@ #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "params/NetworkLink.hh" -#include "sim/sim_object.hh" +#include "sim/clocked_object.hh" class GarnetNetwork; -class NetworkLink : public SimObject, public FlexibleConsumer +class NetworkLink : public ClockedObject, public FlexibleConsumer { public: typedef NetworkLinkParams Params; diff --git a/src/mem/ruby/network/simple/PerfectSwitch.cc b/src/mem/ruby/network/simple/PerfectSwitch.cc index b38b6d539..37035f95f 100644 --- a/src/mem/ruby/network/simple/PerfectSwitch.cc +++ b/src/mem/ruby/network/simple/PerfectSwitch.cc @@ -68,7 +68,7 @@ PerfectSwitch::init(SimpleNetwork *network_ptr) } void -PerfectSwitch::addInPort(const vector<MessageBuffer*>& in) +PerfectSwitch::addInPort(const vector<MessageBuffer*>& in, Switch *sw) { assert(in.size() == m_virtual_networks); NodeID port = m_in.size(); @@ -76,6 +76,8 @@ PerfectSwitch::addInPort(const vector<MessageBuffer*>& in) for (int j = 0; j < m_virtual_networks; j++) { m_in[port][j]->setConsumer(this); + m_in[port][j]->setClockObj(sw); + string desc = csprintf("[Queue from port %s %s %s to PerfectSwitch]", to_string(m_switch_id), to_string(port), to_string(j)); m_in[port][j]->setDescription(desc); diff --git a/src/mem/ruby/network/simple/PerfectSwitch.hh b/src/mem/ruby/network/simple/PerfectSwitch.hh index 695c848bc..ffd1f84ba 100644 --- a/src/mem/ruby/network/simple/PerfectSwitch.hh +++ b/src/mem/ruby/network/simple/PerfectSwitch.hh @@ -63,7 +63,7 @@ class PerfectSwitch : public Consumer { return csprintf("PerfectSwitch-%i", m_switch_id); } void init(SimpleNetwork *); - void addInPort(const std::vector<MessageBuffer*>& in); + void addInPort(const std::vector<MessageBuffer*>& in, Switch *); void addOutPort(const std::vector<MessageBuffer*>& out, const NetDest& routing_table_entry); void clearRoutingTables(); diff --git a/src/mem/ruby/network/simple/Switch.cc b/src/mem/ruby/network/simple/Switch.cc index 1bb944f91..d9abc4cc7 100644 --- a/src/mem/ruby/network/simple/Switch.cc +++ b/src/mem/ruby/network/simple/Switch.cc @@ -67,7 +67,7 @@ Switch::init() void Switch::addInPort(const vector<MessageBuffer*>& in) { - m_perfect_switch_ptr->addInPort(in); + m_perfect_switch_ptr->addInPort(in, this); } void @@ -97,7 +97,7 @@ Switch::addOutPort(const vector<MessageBuffer*>& out, m_perfect_switch_ptr->addOutPort(intermediateBuffers, routing_table_entry); // Hook the queues to the Throttle - throttle_ptr->addLinks(intermediateBuffers, out); + throttle_ptr->addLinks(intermediateBuffers, out, this); } void diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc index 653791c29..b591cc81b 100644 --- a/src/mem/ruby/network/simple/Throttle.cc +++ b/src/mem/ruby/network/simple/Throttle.cc @@ -50,7 +50,7 @@ static int network_message_to_size(NetworkMessage* net_msg_ptr); Throttle::Throttle(int sID, NodeID node, int link_latency, int link_bandwidth_multiplier, int endpoint_bandwidth, - EventManager *em) + ClockedObject *em) : Consumer(em) { init(node, link_latency, link_bandwidth_multiplier, endpoint_bandwidth); @@ -59,7 +59,7 @@ Throttle::Throttle(int sID, NodeID node, int link_latency, Throttle::Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier, int endpoint_bandwidth, - EventManager *em) + ClockedObject *em) : Consumer(em) { init(node, link_latency, link_bandwidth_multiplier, endpoint_bandwidth); @@ -93,11 +93,11 @@ Throttle::clear() void Throttle::addLinks(const std::vector<MessageBuffer*>& in_vec, - const std::vector<MessageBuffer*>& out_vec) + const std::vector<MessageBuffer*>& out_vec, ClockedObject *em) { assert(in_vec.size() == out_vec.size()); for (int i=0; i<in_vec.size(); i++) { - addVirtualNetwork(in_vec[i], out_vec[i]); + addVirtualNetwork(in_vec[i], out_vec[i], em); } m_message_counters.resize(MessageSizeType_NUM); @@ -110,7 +110,8 @@ Throttle::addLinks(const std::vector<MessageBuffer*>& in_vec, } void -Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr) +Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr, + ClockedObject *em) { m_units_remaining.push_back(0); m_in.push_back(in_ptr); @@ -118,6 +119,8 @@ Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr) // Set consumer and description m_in[m_vnets]->setConsumer(this); + m_in[m_vnets]->setClockObj(em); + string desc = "[Queue to Throttle " + to_string(m_sID) + " " + to_string(m_node) + "]"; m_in[m_vnets]->setDescription(desc); diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh index b86a247d2..077382041 100644 --- a/src/mem/ruby/network/simple/Throttle.hh +++ b/src/mem/ruby/network/simple/Throttle.hh @@ -54,16 +54,16 @@ class Throttle : public Consumer public: Throttle(int sID, NodeID node, int link_latency, int link_bandwidth_multiplier, int endpoint_bandwidth, - EventManager *em); + ClockedObject *em); Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier, - int endpoint_bandwidth, EventManager *em); + int endpoint_bandwidth, ClockedObject *em); ~Throttle() {} std::string name() { return csprintf("Throttle-%i", m_sID); } void addLinks(const std::vector<MessageBuffer*>& in_vec, - const std::vector<MessageBuffer*>& out_vec); + const std::vector<MessageBuffer*>& out_vec, ClockedObject *em); void wakeup(); void printStats(std::ostream& out) const; @@ -90,7 +90,8 @@ class Throttle : public Consumer private: void init(NodeID node, int link_latency, int link_bandwidth_multiplier, int endpoint_bandwidth); - void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr); + void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr, + ClockedObject *em); void linkUtilized(double ratio) { m_links_utilized += ratio; } // Private copy constructor and assignment operator diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc index 9f5fb4fd9..9a01ce45a 100644 --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -137,7 +137,7 @@ Profiler::wakeup() } //g_system_ptr->getNetwork()->printStats(out); - schedule(m_event, g_system_ptr->clockEdge(Cycles(m_stats_period ))); + schedule(m_event, g_system_ptr->clockEdge(Cycles(m_stats_period))); } void @@ -571,7 +571,7 @@ Profiler::profileSharing(const Address& addr, AccessType type, } void -Profiler::profileMsgDelay(int virtualNetwork, int delayCycles) +Profiler::profileMsgDelay(uint32_t virtualNetwork, Time delayCycles) { assert(virtualNetwork < m_delayedCyclesVCHistograms.size()); m_delayedCyclesHistogram.add(delayCycles); diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index c83c4e37a..5f78f279b 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -152,7 +152,7 @@ class Profiler : public SimObject void sequencerRequests(int num) { m_sequencer_requests.add(num); } - void profileMsgDelay(int virtualNetwork, int delayCycles); + void profileMsgDelay(uint32_t virtualNetwork, Time delayCycles); void print(std::ostream& out) const; diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index ac48db0c7..359512afc 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -30,7 +30,7 @@ #include "mem/ruby/system/System.hh" AbstractController::AbstractController(const Params *p) - : SimObject(p), Consumer(this) + : ClockedObject(p), Consumer(this) { m_version = p->version; m_transitions_per_cycle = p->transitions_per_cycle; diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 16b881b1f..40356cac5 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -41,12 +41,12 @@ #include "mem/ruby/system/MachineID.hh" #include "mem/packet.hh" #include "params/RubyController.hh" -#include "sim/sim_object.hh" +#include "sim/clocked_object.hh" class MessageBuffer; class Network; -class AbstractController : public SimObject, public Consumer +class AbstractController : public ClockedObject, public Consumer { public: typedef RubyControllerParams Params; diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py index 9787b5ce7..aa8f35145 100644 --- a/src/mem/ruby/slicc_interface/Controller.py +++ b/src/mem/ruby/slicc_interface/Controller.py @@ -28,9 +28,9 @@ # Brad Beckmann from m5.params import * -from m5.SimObject import SimObject +from ClockedObject import ClockedObject -class RubyController(SimObject): +class RubyController(ClockedObject): type = 'RubyController' cxx_class = 'AbstractController' cxx_header = "mem/ruby/slicc_interface/AbstractController.hh" diff --git a/src/mem/ruby/slicc_interface/Message.hh b/src/mem/ruby/slicc_interface/Message.hh index 7b94a01e2..201ec4b60 100644 --- a/src/mem/ruby/slicc_interface/Message.hh +++ b/src/mem/ruby/slicc_interface/Message.hh @@ -73,12 +73,11 @@ class Message : public RefCounted virtual bool functionalWrite(Packet *pkt) = 0; //{ fatal("Write functional access not implemented!"); } - void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; } - const int& getDelayedCycles() const {return m_DelayedCycles;} - int& getDelayedCycles() {return m_DelayedCycles;} + void setDelayedCycles(const Time cycles) { m_DelayedCycles = cycles; } + const Time getDelayedCycles() const {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 getLastEnqueueTime() const {return m_LastEnqueueTime;} const Time& getTime() const { return m_time; } void setTime(const Time& new_time) { m_time = new_time; } diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc index 508c27794..2dd8671a1 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc +++ b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc @@ -66,7 +66,7 @@ profile_sharing(const Address& addr, AccessType type, NodeID requestor, } void -profileMsgDelay(int virtualNetwork, int delayCycles) +profileMsgDelay(uint32_t virtualNetwork, Time delayCycles) { g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles); } @@ -86,6 +86,3 @@ profileGetS(const Address& datablock, const Address& PC, const Set& owner, g_system_ptr->getProfiler()->getAddressProfiler()-> profileGetS(datablock, PC, owner, sharers, requestor); } - - - diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh index 596b00fbe..799671435 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh @@ -55,7 +55,7 @@ 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 profile_average_latency_estimate(int latency); -void profileMsgDelay(int virtualNetwork, int delayCycles); +void profileMsgDelay(uint32_t virtualNetwork, Time delayCycles); void profile_multicast_retry(const Address& addr, int count); void profileGetX(const Address& datablock, const Address& PC, const Set& owner, diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh index 5c6adb0ab..fb77eadb2 100644 --- a/src/mem/ruby/system/MemoryControl.hh +++ b/src/mem/ruby/system/MemoryControl.hh @@ -60,6 +60,8 @@ class MemoryControl : public ClockedObject, public Consumer virtual void setConsumer(Consumer* consumer_ptr) = 0; virtual Consumer* getConsumer() = 0; + virtual void setClockObj(ClockedObject* consumer_ptr) {} + virtual void setDescription(const std::string& name) = 0; virtual std::string getDescription() = 0; diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index a45dfc98d..9e3fd6864 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -88,7 +88,7 @@ Sequencer::wakeup() assert(getDrainState() != Drainable::Draining); // Check for deadlock of any of the requests - Time current_time = g_system_ptr->getTime(); + Time current_time = curCycle(); // Check across all outstanding requests int total_outstanding = 0; @@ -130,8 +130,7 @@ Sequencer::wakeup() if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking - schedule(deadlockCheckEvent, - g_system_ptr->clockPeriod() * m_deadlock_threshold + curTick()); + schedule(deadlockCheckEvent, clockEdge(m_deadlock_threshold)); } } @@ -211,8 +210,7 @@ Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type) // See if we should schedule a deadlock check if (!deadlockCheckEvent.scheduled() && getDrainState() != Drainable::Draining) { - schedule(deadlockCheckEvent, - g_system_ptr->clockPeriod() * m_deadlock_threshold + curTick()); + schedule(deadlockCheckEvent, clockEdge(m_deadlock_threshold)); } Address line_addr(pkt->getAddr()); @@ -242,8 +240,7 @@ Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type) m_writeRequestTable.insert(default_entry); if (r.second) { RequestTable::iterator i = r.first; - i->second = new SequencerRequest(pkt, request_type, - g_system_ptr->getTime()); + i->second = new SequencerRequest(pkt, request_type, curCycle()); m_outstanding_count++; } else { // There is an outstanding write request for the cache line @@ -263,8 +260,7 @@ Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type) if (r.second) { RequestTable::iterator i = r.first; - i->second = new SequencerRequest(pkt, request_type, - g_system_ptr->getTime()); + i->second = new SequencerRequest(pkt, request_type, curCycle()); m_outstanding_count++; } else { // There is an outstanding read request for the cache line @@ -480,8 +476,8 @@ Sequencer::hitCallback(SequencerRequest* srequest, m_dataCache_ptr->setMRU(request_line_address); } - assert(g_system_ptr->getTime() >= issued_time); - Time miss_latency = g_system_ptr->getTime() - issued_time; + assert(curCycle() >= issued_time); + Time miss_latency = curCycle() - issued_time; // Profile the miss latency for all non-zero demand misses if (miss_latency != 0) { @@ -489,18 +485,14 @@ Sequencer::hitCallback(SequencerRequest* srequest, if (mach == GenericMachineType_L1Cache_wCC) { g_system_ptr->getProfiler()->missLatencyWcc(issued_time, - initialRequestTime, - forwardRequestTime, - firstResponseTime, - g_system_ptr->getTime()); + initialRequestTime, forwardRequestTime, + firstResponseTime, curCycle()); } if (mach == GenericMachineType_Directory) { g_system_ptr->getProfiler()->missLatencyDir(issued_time, - initialRequestTime, - forwardRequestTime, - firstResponseTime, - g_system_ptr->getTime()); + initialRequestTime, forwardRequestTime, + firstResponseTime, curCycle()); } DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n", diff --git a/src/mem/ruby/system/TimerTable.cc b/src/mem/ruby/system/TimerTable.cc index 6702411a5..992401c50 100644 --- a/src/mem/ruby/system/TimerTable.cc +++ b/src/mem/ruby/system/TimerTable.cc @@ -33,6 +33,8 @@ TimerTable::TimerTable() { m_consumer_ptr = NULL; + m_clockobj_ptr = NULL; + m_next_valid = false; m_next_address = Address(0); m_next_time = 0; @@ -48,7 +50,7 @@ TimerTable::isReady() const updateNext(); } assert(m_next_valid); - return (g_system_ptr->getTime() >= m_next_time); + return (m_clockobj_ptr->curCycle() >= m_next_time); } const Address& @@ -69,7 +71,7 @@ TimerTable::set(const Address& address, Time relative_latency) assert(address == line_address(address)); assert(relative_latency > 0); assert(!m_map.count(address)); - Time ready_time = g_system_ptr->getTime() + relative_latency; + Time ready_time = m_clockobj_ptr->curCycle() + relative_latency; m_map[address] = ready_time; assert(m_consumer_ptr != NULL); m_consumer_ptr->scheduleEventAbsolute(ready_time); diff --git a/src/mem/ruby/system/TimerTable.hh b/src/mem/ruby/system/TimerTable.hh index 4335b6605..ecd95ee19 100644 --- a/src/mem/ruby/system/TimerTable.hh +++ b/src/mem/ruby/system/TimerTable.hh @@ -49,6 +49,12 @@ class TimerTable m_consumer_ptr = consumer_ptr; } + void setClockObj(ClockedObject* obj) + { + assert(m_clockobj_ptr == NULL); + m_clockobj_ptr = obj; + } + void setDescription(const std::string& name) { @@ -78,7 +84,12 @@ class TimerTable 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() + + //! Object used for querying time. + ClockedObject* m_clockobj_ptr; + //! Consumer to signal a wakeup() + Consumer* m_consumer_ptr; + std::string m_name; }; diff --git a/src/mem/slicc/ast/AST.py b/src/mem/slicc/ast/AST.py index 9e3844445..6eaa452cc 100644 --- a/src/mem/slicc/ast/AST.py +++ b/src/mem/slicc/ast/AST.py @@ -55,6 +55,6 @@ class AST(PairContainer): code = self.slicc.codeFormatter() code(''' panic("Runtime Error at ${{self.location}}, Ruby Time: %d, %s.\\n", - g_system_ptr->getTime(), $message); + curCycle(), $message); ''') return code diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 6c85480ab..c676574cc 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -527,6 +527,8 @@ $c_ident::init() { MachineType machine_type; int base; + machine_type = string_to_MachineType("${{var.machine.ident}}"); + base = MachineType_base_number(machine_type); m_machineID.type = MachineType_${ident}; m_machineID.num = m_version; @@ -592,8 +594,6 @@ $c_ident::init() assert var.machine is not None code(''' -machine_type = string_to_MachineType("${{var.machine.ident}}"); -base = MachineType_base_number(machine_type); $vid = m_net_ptr->get${network}NetQueue(m_version + base, $ordered, $vnet, "$vnet_type"); ''') @@ -638,15 +638,14 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v for prefetcher in self.prefetchers: code('${{prefetcher.code}}.setController(this);') - # Set the queue consumers code() for port in self.in_ports: + # Set the queue consumers code('${{port.code}}.setConsumer(this);') - - # Set the queue descriptions - code() - for port in self.in_ports: + # Set the queue descriptions code('${{port.code}}.setDescription("[Version " + to_string(m_version) + ", $ident, $port]");') + # Set the clock object + code('${{port.code}}.setClockObj(this);') # Initialize the transition profiling code() @@ -1139,7 +1138,7 @@ ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State next_state = state; DPRINTF(RubyGenerated, "%s, Time: %lld, state: %s, event: %s, addr: %s\\n", - *this, g_system_ptr->getTime(), ${ident}_State_to_string(state), + *this, curCycle(), ${ident}_State_to_string(state), ${ident}_Event_to_string(event), addr); TransitionResult result = @@ -1312,7 +1311,7 @@ if (!checkResourceAvailable(%s_RequestType_%s, addr)) { default: fatal("Invalid transition\\n" "%s time: %d addr: %s event: %s state: %s\\n", - name(), g_system_ptr->getTime(), addr, event, state); + name(), curCycle(), addr, event, state); } return TransitionResult_Valid; } |