ruby: slicc: code refactor
[gem5.git] / src / mem / slicc / symbols / StateMachine.py
index e6674325585f18a0811d27c31f1a4aa6486c66cd..d908f00c6b50542386f4246fc5008262a004a833 100644 (file)
@@ -75,8 +75,6 @@ class StateMachine(Symbol):
         self.objects = []
         self.TBEType   = None
         self.EntryType = None
-        self.message_buffer_names = []
-
 
     def __repr__(self):
         return "[StateMachine: %s]" % self.ident
@@ -175,10 +173,6 @@ class StateMachine(Symbol):
         self.printControllerCC(path, includes)
         self.printCSwitch(path)
         self.printCWakeup(path, includes)
-        self.printProfilerCC(path)
-        self.printProfilerHH(path)
-        self.printProfileDumperCC(path)
-        self.printProfileDumperHH(path)
 
     def printControllerPython(self, path):
         code = self.symtab.codeFormatter()
@@ -216,8 +210,6 @@ class $py_ident(RubyController):
         ident = self.ident
         c_ident = "%s_Controller" % self.ident
 
-        self.message_buffer_names = []
-
         code('''
 /** \\file $c_ident.hh
  *
@@ -232,8 +224,6 @@ class $py_ident(RubyController):
 #include <sstream>
 #include <string>
 
-#include "mem/protocol/${ident}_ProfileDumper.hh"
-#include "mem/protocol/${ident}_Profiler.hh"
 #include "mem/protocol/TransitionResult.hh"
 #include "mem/protocol/Types.hh"
 #include "mem/ruby/common/Consumer.hh"
@@ -243,9 +233,12 @@ class $py_ident(RubyController):
 ''')
 
         seen_types = set()
+        has_peer = False
         for var in self.objects:
             if var.type.ident not in seen_types and not var.type.isPrimitive:
                 code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
+            if "network" in var and "physical_network" in var:
+                has_peer = True
             seen_types.add(var.type.ident)
 
         # for adding information to the protocol debug trace
@@ -260,25 +253,26 @@ class $c_ident : public AbstractController
     static int getNumControllers();
     void init();
     MessageBuffer* getMandatoryQueue() const;
-    const int & getVersion() const;
     const std::string toString() const;
-    const std::string getName() const;
-    void stallBuffer(MessageBuffer* buf, Address addr);
-    void wakeUpBuffers(Address addr);
-    void wakeUpAllBuffers();
-    void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
+
     void print(std::ostream& out) const;
     void wakeup();
-    void printStats(std::ostream& out) const;
-    void clearStats();
-    void blockOnQueue(Address addr, MessageBuffer* port);
-    void unblock(Address addr);
+    void resetStats();
+    void regStats();
+    void collateStats();
+
     void recordCacheTrace(int cntrl, CacheRecorder* tr);
     Sequencer* getSequencer() const;
 
     bool functionalReadBuffers(PacketPtr&);
     uint32_t functionalWriteBuffers(PacketPtr&);
 
+    void countTransition(${ident}_State state, ${ident}_Event event);
+    void possibleTransition(${ident}_State state, ${ident}_Event event);
+    uint64 getEventCount(${ident}_Event event);
+    bool isPossible(${ident}_State state, ${ident}_Event event);
+    uint64 getTransitionCount(${ident}_State state, ${ident}_Event event);
+
 private:
 ''')
 
@@ -304,7 +298,7 @@ TransitionResult doTransition(${ident}_Event event,
 ''')
 
         code('''
-                              const Address& addr);
+                              const Address addr);
 
 TransitionResult doTransitionWorker(${ident}_Event event,
                                     ${ident}_State state,
@@ -323,8 +317,12 @@ TransitionResult doTransitionWorker(${ident}_Event event,
         code('''
                                     const Address& addr);
 
-static ${ident}_ProfileDumper s_profileDumper;
-${ident}_Profiler m_profiler;
+int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
+int m_event_counters[${ident}_Event_NUM];
+bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
+
+static std::vector<Stats::Vector *> eventVec;
+static std::vector<std::vector<Stats::Vector *> > transVec;
 static int m_num_controllers;
 
 // Internal functions
@@ -335,6 +333,8 @@ static int m_num_controllers;
             if proto:
                 code('$proto')
 
+        if has_peer:
+            code('void getQueuesFromPeer(AbstractController *);')
         if self.EntryType != None:
             code('''
 
@@ -351,6 +351,7 @@ void set_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${ident}_TBE* m_new_tbe);
 void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr);
 ''')
 
+        # Prototype the actions that the controller can take
         code('''
 
 // Actions
@@ -358,15 +359,19 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr);
         if self.TBEType != None and self.EntryType != None:
             for action in self.actions.itervalues():
                 code('/** \\brief ${{action.desc}} */')
-                code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr);')
+                code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& '
+                     'm_tbe_ptr, ${{self.EntryType.c_ident}}*& '
+                     'm_cache_entry_ptr, const Address& addr);')
         elif self.TBEType != None:
             for action in self.actions.itervalues():
                 code('/** \\brief ${{action.desc}} */')
-                code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, const Address& addr);')
+                code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& '
+                     'm_tbe_ptr, const Address& addr);')
         elif self.EntryType != None:
             for action in self.actions.itervalues():
                 code('/** \\brief ${{action.desc}} */')
-                code('void ${{action.ident}}(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr);')
+                code('void ${{action.ident}}(${{self.EntryType.c_ident}}*& '
+                     'm_cache_entry_ptr, const Address& addr);')
         else:
             for action in self.actions.itervalues():
                 code('/** \\brief ${{action.desc}} */')
@@ -381,9 +386,6 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr);
             th = var.get("template", "")
             code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;')
 
-            if var.type.ident == "MessageBuffer":
-                self.message_buffer_names.append("m_%s_ptr" % var.c_ident)
-
         code.dedent()
         code('};')
         code('#endif // __${ident}_CONTROLLER_H__')
@@ -395,6 +397,7 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr);
         code = self.symtab.codeFormatter()
         ident = self.ident
         c_ident = "%s_Controller" % self.ident
+        has_peer = False
 
         code('''
 /** \\file $c_ident.cc
@@ -436,6 +439,8 @@ using namespace std;
                 code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
             seen_types.add(var.type.ident)
 
+        num_in_ports = len(self.in_ports)
+
         code('''
 $c_ident *
 ${c_ident}Params::create()
@@ -444,82 +449,73 @@ ${c_ident}Params::create()
 }
 
 int $c_ident::m_num_controllers = 0;
-${ident}_ProfileDumper $c_ident::s_profileDumper;
+std::vector<Stats::Vector *>  $c_ident::eventVec;
+std::vector<std::vector<Stats::Vector *> >  $c_ident::transVec;
 
 // for adding information to the protocol debug trace
 stringstream ${ident}_transitionComment;
+
+#ifndef NDEBUG
 #define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
+#else
+#define APPEND_TRANSITION_COMMENT(str) do {} while (0)
+#endif
 
 /** \\brief constructor */
 $c_ident::$c_ident(const Params *p)
     : AbstractController(p)
 {
-    m_name = "${ident}";
+    m_machineID.type = MachineType_${ident};
+    m_machineID.num = m_version;
+    m_num_controllers++;
+
+    m_in_ports = $num_in_ports;
 ''')
-        #
-        # max_port_rank is used to size vectors and thus should be one plus the
-        # largest port rank
-        #
-        max_port_rank = self.in_ports[0].pairs["max_port_rank"] + 1
-        code('    m_max_in_port_rank = $max_port_rank;')
         code.indent()
 
         #
         # After initializing the universal machine parameters, initialize the
-        # this machines config parameters.  Also detemine if these configuration
-        # params include a sequencer.  This information will be used later for
-        # contecting the sequencer back to the L1 cache controller.
+        # this machines config parameters.  Also if these configuration params
+        # include a sequencer, connect the it to the controller.
         #
-        contains_dma_sequencer = False
-        sequencers = []
         for param in self.config_parameters:
-            if param.name == "dma_sequencer":
-                contains_dma_sequencer = True
-            elif re.compile("sequencer").search(param.name):
-                sequencers.append(param.name)
             if param.pointer:
                 code('m_${{param.name}}_ptr = p->${{param.name}};')
             else:
                 code('m_${{param.name}} = p->${{param.name}};')
-
-        #
-        # For the l1 cache controller, add the special atomic support which 
-        # includes passing the sequencer a pointer to the controller.
-        #
-        if self.ident == "L1Cache":
-            if not sequencers:
-                self.error("The L1Cache controller must include the sequencer " \
-                           "configuration parameter")
-
-            for seq in sequencers:
-                code('''
-m_${{seq}}_ptr->setController(this);
-    ''')
-
-        else:
-            for seq in sequencers:
-                code('''
-m_${{seq}}_ptr->setController(this);
-    ''')
-
-        #
-        # For the DMA controller, pass the sequencer a pointer to the
-        # controller.
-        #
-        if self.ident == "DMA":
-            if not contains_dma_sequencer:
-                self.error("The DMA controller must include the sequencer " \
-                           "configuration parameter")
-
-            code('''
-m_dma_sequencer_ptr->setController(this);
-''')
+            if re.compile("sequencer").search(param.name):
+                code('m_${{param.name}}_ptr->setController(this);')
             
-        code('m_num_controllers++;')
         for var in self.objects:
             if var.ident.find("mandatoryQueue") >= 0:
-                code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();')
+                code('''
+m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();
+m_${{var.c_ident}}_ptr->setReceiver(this);
+''')
+            else:
+                if "network" in var and "physical_network" in var and \
+                   var["network"] == "To":
+                    has_peer = True
+                    code('''
+m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();
+peerQueueMap[${{var["physical_network"]}}] = m_${{var.c_ident}}_ptr;
+m_${{var.c_ident}}_ptr->setSender(this);
+''')
 
+        code('''
+if (p->peer != NULL)
+    connectWithPeer(p->peer);
+
+for (int state = 0; state < ${ident}_State_NUM; state++) {
+    for (int event = 0; event < ${ident}_Event_NUM; event++) {
+        m_possible[state][event] = false;
+        m_counters[state][event] = 0;
+    }
+}
+for (int event = 0; event < ${ident}_Event_NUM; event++) {
+    m_event_counters[event] = 0;
+}
+''')
         code.dedent()
         code('''
 }
@@ -527,17 +523,10 @@ m_dma_sequencer_ptr->setController(this);
 void
 $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;
+    MachineType machine_type = string_to_MachineType("${{var.machine.ident}}");
+    int base M5_VAR_USED = MachineType_base_number(machine_type);
 
     // initialize objects
-    m_profiler.setVersion(m_version);
-    s_profileDumper.registerProfiler(&m_profiler);
 
 ''')
 
@@ -553,10 +542,7 @@ $c_ident::init()
                         code('(*$vid) = ${{var["default"]}};')
                 else:
                     # Normal Object
-                    # added by SS
-                    if "factory" in var:
-                        code('$vid = ${{var["factory"]}};')
-                    elif var.ident.find("mandatoryQueue") < 0:
+                    if var.ident.find("mandatoryQueue") < 0:
                         th = var.get("template", "")
                         expr = "%s  = new %s%s" % (vid, vtype.c_ident, th)
                         args = ""
@@ -573,7 +559,7 @@ $c_ident::init()
                         code('*$vid = ${{vtype["default"]}}; // $comment')
 
                     # Set ordering
-                    if "ordered" in var and "trigger_queue" not in var:
+                    if "ordered" in var:
                         # A buffer
                         code('$vid->setOrdering(${{var["ordered"]}});')
 
@@ -583,23 +569,39 @@ $c_ident::init()
                         code('$vid->setRandomization(${{var["random"]}});')
 
                     # Set Priority
-                    if vtype.isBuffer and \
-                           "rank" in var and "trigger_queue" not in var:
+                    if vtype.isBuffer and "rank" in var:
                         code('$vid->setPriority(${{var["rank"]}});')
 
+                    # Set sender and receiver for trigger queue
+                    if var.ident.find("triggerQueue") >= 0:
+                        code('$vid->setSender(this);')
+                        code('$vid->setReceiver(this);')
+                    elif vtype.c_ident == "TimerTable":
+                        code('$vid->setClockObj(this);')
+                    elif var.ident.find("optionalQueue") >= 0:
+                        code('$vid->setSender(this);')
+                        code('$vid->setReceiver(this);')
+
             else:
                 # Network port object
                 network = var["network"]
                 ordered =  var["ordered"]
-                vnet = var["virtual_network"]
-                vnet_type = var["vnet_type"]
 
-                assert var.machine is not None
-                code('''
+                if "virtual_network" in var:
+                    vnet = var["virtual_network"]
+                    vnet_type = var["vnet_type"]
+
+                    assert var.machine is not None
+                    code('''
 $vid = m_net_ptr->get${network}NetQueue(m_version + base, $ordered, $vnet, "$vnet_type");
+assert($vid != NULL);
 ''')
 
-                code('assert($vid != NULL);')
+                    # Set the end
+                    if network == "To":
+                        code('$vid->setSender(this);')
+                    else:
+                        code('$vid->setReceiver(this);')
 
                 # Set ordering
                 if "ordered" in var:
@@ -647,8 +649,6 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v
             code('${{port.code}}.setConsumer(this);')
             # 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()
@@ -663,24 +663,19 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v
             if not stall:
                 state = "%s_State_%s" % (self.ident, trans.state.ident)
                 event = "%s_Event_%s" % (self.ident, trans.event.ident)
-                code('m_profiler.possibleTransition($state, $event);')
+                code('possibleTransition($state, $event);')
 
         code.dedent()
         code('''
     AbstractController::init();
-    clearStats();
+    resetStats();
 }
 ''')
 
-        has_mandatory_q = False
+        mq_ident = "NULL"
         for port in self.in_ports:
             if port.code.find("mandatoryQueue_ptr") >= 0:
-                has_mandatory_q = True
-
-        if has_mandatory_q:
-            mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident
-        else:
-            mq_ident = "NULL"
+                mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident
 
         seq_ident = "NULL"
         for param in self.config_parameters:
@@ -689,120 +684,133 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v
                 seq_ident = "m_%s_ptr" % param.name
 
         code('''
-int
-$c_ident::getNumControllers()
+
+void
+$c_ident::regStats()
 {
-    return m_num_controllers;
+    AbstractController::regStats();
+
+    if (m_version == 0) {
+        for (${ident}_Event event = ${ident}_Event_FIRST;
+             event < ${ident}_Event_NUM; ++event) {
+            Stats::Vector *t = new Stats::Vector();
+            t->init(m_num_controllers);
+            t->name(g_system_ptr->name() + ".${c_ident}." +
+                ${ident}_Event_to_string(event));
+            t->flags(Stats::pdf | Stats::total | Stats::oneline |
+                     Stats::nozero);
+
+            eventVec.push_back(t);
+        }
+
+        for (${ident}_State state = ${ident}_State_FIRST;
+             state < ${ident}_State_NUM; ++state) {
+
+            transVec.push_back(std::vector<Stats::Vector *>());
+
+            for (${ident}_Event event = ${ident}_Event_FIRST;
+                 event < ${ident}_Event_NUM; ++event) {
+
+                Stats::Vector *t = new Stats::Vector();
+                t->init(m_num_controllers);
+                t->name(g_system_ptr->name() + ".${c_ident}." +
+                        ${ident}_State_to_string(state) +
+                        "." + ${ident}_Event_to_string(event));
+
+                t->flags(Stats::pdf | Stats::total | Stats::oneline |
+                         Stats::nozero);
+                transVec[state].push_back(t);
+            }
+        }
+    }
 }
 
-MessageBuffer*
-$c_ident::getMandatoryQueue() const
+void
+$c_ident::collateStats()
 {
-    return $mq_ident;
+    for (${ident}_Event event = ${ident}_Event_FIRST;
+         event < ${ident}_Event_NUM; ++event) {
+        for (unsigned int i = 0; i < m_num_controllers; ++i) {
+            std::map<uint32_t, AbstractController *>::iterator it =
+                                g_abs_controls[MachineType_${ident}].find(i);
+            assert(it != g_abs_controls[MachineType_${ident}].end());
+            (*eventVec[event])[i] =
+                (($c_ident *)(*it).second)->getEventCount(event);
+        }
+    }
+
+    for (${ident}_State state = ${ident}_State_FIRST;
+         state < ${ident}_State_NUM; ++state) {
+
+        for (${ident}_Event event = ${ident}_Event_FIRST;
+             event < ${ident}_Event_NUM; ++event) {
+
+            for (unsigned int i = 0; i < m_num_controllers; ++i) {
+                std::map<uint32_t, AbstractController *>::iterator it =
+                                g_abs_controls[MachineType_${ident}].find(i);
+                assert(it != g_abs_controls[MachineType_${ident}].end());
+                (*transVec[state][event])[i] =
+                    (($c_ident *)(*it).second)->getTransitionCount(state, event);
+            }
+        }
+    }
 }
 
-Sequencer*
-$c_ident::getSequencer() const
+void
+$c_ident::countTransition(${ident}_State state, ${ident}_Event event)
 {
-    return $seq_ident;
+    assert(m_possible[state][event]);
+    m_counters[state][event]++;
+    m_event_counters[event]++;
 }
-
-const int &
-$c_ident::getVersion() const
+void
+$c_ident::possibleTransition(${ident}_State state,
+                             ${ident}_Event event)
 {
-    return m_version;
+    m_possible[state][event] = true;
 }
 
-const string
-$c_ident::toString() const
+uint64
+$c_ident::getEventCount(${ident}_Event event)
 {
-    return "$c_ident";
+    return m_event_counters[event];
 }
 
-const string
-$c_ident::getName() const
+bool
+$c_ident::isPossible(${ident}_State state, ${ident}_Event event)
 {
-    return m_name;
+    return m_possible[state][event];
 }
 
-void
-$c_ident::stallBuffer(MessageBuffer* buf, Address addr)
+uint64
+$c_ident::getTransitionCount(${ident}_State state,
+                             ${ident}_Event event)
 {
-    if (m_waiting_buffers.count(addr) == 0) {
-        MsgVecType* msgVec = new MsgVecType;
-        msgVec->resize(m_max_in_port_rank, NULL);
-        m_waiting_buffers[addr] = msgVec;
-    }
-    (*(m_waiting_buffers[addr]))[m_cur_in_port_rank] = buf;
+    return m_counters[state][event];
 }
 
-void
-$c_ident::wakeUpBuffers(Address addr)
+int
+$c_ident::getNumControllers()
 {
-    if (m_waiting_buffers.count(addr) > 0) {
-        //
-        // Wake up all possible lower rank (i.e. lower priority) buffers that could
-        // be waiting on this message.
-        //
-        for (int in_port_rank = m_cur_in_port_rank - 1;
-             in_port_rank >= 0;
-             in_port_rank--) {
-            if ((*(m_waiting_buffers[addr]))[in_port_rank] != NULL) {
-                (*(m_waiting_buffers[addr]))[in_port_rank]->reanalyzeMessages(addr);
-            }
-        }
-        delete m_waiting_buffers[addr];
-        m_waiting_buffers.erase(addr);
-    }
+    return m_num_controllers;
 }
 
-void
-$c_ident::wakeUpAllBuffers()
+MessageBuffer*
+$c_ident::getMandatoryQueue() const
 {
-    //
-    // Wake up all possible buffers that could be waiting on any message.
-    //
-
-    std::vector<MsgVecType*> wokeUpMsgVecs;
-    
-    if(m_waiting_buffers.size() > 0) {
-        for (WaitingBufType::iterator buf_iter = m_waiting_buffers.begin();
-             buf_iter != m_waiting_buffers.end();
-             ++buf_iter) {
-             for (MsgVecType::iterator vec_iter = buf_iter->second->begin();
-                  vec_iter != buf_iter->second->end();
-                  ++vec_iter) {
-                  if (*vec_iter != NULL) {
-                      (*vec_iter)->reanalyzeAllMessages();
-                  }
-             }
-             wokeUpMsgVecs.push_back(buf_iter->second);
-        }
-
-        for (std::vector<MsgVecType*>::iterator wb_iter = wokeUpMsgVecs.begin();
-             wb_iter != wokeUpMsgVecs.end();
-             ++wb_iter) {
-             delete (*wb_iter);
-        }
-
-        m_waiting_buffers.clear();
-    }
+    return $mq_ident;
 }
 
-void
-$c_ident::blockOnQueue(Address addr, MessageBuffer* port)
+Sequencer*
+$c_ident::getSequencer() const
 {
-    m_is_blocking = true;
-    m_block_map[addr] = port;
+    return $seq_ident;
 }
 
-void
-$c_ident::unblock(Address addr)
+const string
+$c_ident::toString() const
 {
-    m_block_map.erase(addr);
-    if (m_block_map.size() == 0) {
-       m_is_blocking = false;
-    }
+    return "$c_ident";
 }
 
 void
@@ -811,42 +819,19 @@ $c_ident::print(ostream& out) const
     out << "[$c_ident " << m_version << "]";
 }
 
-void
-$c_ident::printStats(ostream& out) const
+void $c_ident::resetStats()
 {
-''')
-        #
-        # Cache and Memory Controllers have specific profilers associated with
-        # them.  Print out these stats before dumping state transition stats.
-        #
-        for param in self.config_parameters:
-            if param.type_ast.type.ident == "CacheMemory" or \
-               param.type_ast.type.ident == "DirectoryMemory" or \
-                   param.type_ast.type.ident == "MemoryControl":
-                assert(param.pointer)
-                code('    m_${{param.ident}}_ptr->printStats(out);')
-
-        code('''
-    if (m_version == 0) {
-        s_profileDumper.dumpStats(out);
+    for (int state = 0; state < ${ident}_State_NUM; state++) {
+        for (int event = 0; event < ${ident}_Event_NUM; event++) {
+            m_counters[state][event] = 0;
+        }
     }
-}
 
-void $c_ident::clearStats() {
-''')
-        #
-        # Cache and Memory Controllers have specific profilers associated with
-        # them.  These stats must be cleared too.
-        #
-        for param in self.config_parameters:
-            if param.type_ast.type.ident == "CacheMemory" or \
-                   param.type_ast.type.ident == "MemoryControl":
-                assert(param.pointer)
-                code('    m_${{param.ident}}_ptr->clearStats();')
+    for (int event = 0; event < ${ident}_Event_NUM; event++) {
+        m_event_counters[event] = 0;
+    }
 
-        code('''
-    m_profiler.clearStats();
-    AbstractController::clearStats();
+    AbstractController::resetStats();
 }
 ''')
 
@@ -1001,6 +986,26 @@ $c_ident::functionalWriteBuffers(PacketPtr& pkt)
 }
 ''')
 
+        # Check if this controller has a peer, if yes then write the
+        # function for connecting to the peer.
+        if has_peer:
+            code('''
+
+void
+$c_ident::getQueuesFromPeer(AbstractController *peer)
+{
+''')
+            for var in self.objects:
+                if "network" in var and "physical_network" in var and \
+                   var["network"] == "From":
+                    code('''
+m_${{var.c_ident}}_ptr = peer->getPeerQueue(${{var["physical_network"]}});
+assert(m_${{var.c_ident}}_ptr != NULL);
+m_${{var.c_ident}}_ptr->setReceiver(this);
+
+''')
+            code('}')
+
         code.write(path, "%s.cc" % c_ident)
 
     def printCWakeup(self, path, includes):
@@ -1072,9 +1077,9 @@ ${ident}_Controller::wakeup()
             code.indent()
             code('// ${ident}InPort $port')
             if port.pairs.has_key("rank"):
-                code('m_cur_in_port_rank = ${{port.pairs["rank"]}};')
+                code('m_cur_in_port = ${{port.pairs["rank"]}};')
             else:
-                code('m_cur_in_port_rank = 0;')
+                code('m_cur_in_port = 0;')
             code('${{port["c_code_in_port"]}}')
             code.dedent()
 
@@ -1130,7 +1135,7 @@ ${ident}_Controller::doTransition(${ident}_Event event,
                                   ${{self.TBEType.c_ident}}* m_tbe_ptr,
 ''')
         code('''
-                                  const Address &addr)
+                                  const Address addr)
 {
 ''')
         if self.TBEType != None and self.EntryType != None:
@@ -1164,7 +1169,7 @@ ${ident}_Controller::doTransition(${ident}_Event event,
     if (result == TransitionResult_Valid) {
         DPRINTF(RubyGenerated, "next_state: %s\\n",
                 ${ident}_State_to_string(next_state));
-        m_profiler.countTransition(state, event);
+        countTransition(state, event);
         DPRINTFR(ProtocolTrace, "%15d %3s %10s%20s %6s>%-6s %s %s\\n",
                  curTick(), m_version, "${ident}",
                  ${ident}_Event_to_string(event),
@@ -1326,222 +1331,6 @@ if (!checkResourceAvailable(%s_RequestType_%s, addr)) {
 ''')
         code.write(path, "%s_Transitions.cc" % self.ident)
 
-    def printProfileDumperHH(self, path):
-        code = self.symtab.codeFormatter()
-        ident = self.ident
-
-        code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#ifndef __${ident}_PROFILE_DUMPER_HH__
-#define __${ident}_PROFILE_DUMPER_HH__
-
-#include <cassert>
-#include <iostream>
-#include <vector>
-
-#include "${ident}_Event.hh"
-#include "${ident}_Profiler.hh"
-
-typedef std::vector<${ident}_Profiler *> ${ident}_profilers;
-
-class ${ident}_ProfileDumper
-{
-  public:
-    ${ident}_ProfileDumper();
-    void registerProfiler(${ident}_Profiler* profiler);
-    void dumpStats(std::ostream& out) const;
-
-  private:
-    ${ident}_profilers m_profilers;
-};
-
-#endif // __${ident}_PROFILE_DUMPER_HH__
-''')
-        code.write(path, "%s_ProfileDumper.hh" % self.ident)
-
-    def printProfileDumperCC(self, path):
-        code = self.symtab.codeFormatter()
-        ident = self.ident
-
-        code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#include "mem/protocol/${ident}_ProfileDumper.hh"
-
-${ident}_ProfileDumper::${ident}_ProfileDumper()
-{
-}
-
-void
-${ident}_ProfileDumper::registerProfiler(${ident}_Profiler* profiler)
-{
-    m_profilers.push_back(profiler);
-}
-
-void
-${ident}_ProfileDumper::dumpStats(std::ostream& out) const
-{
-    out << " --- ${ident} ---\\n";
-    out << " - Event Counts -\\n";
-    for (${ident}_Event event = ${ident}_Event_FIRST;
-         event < ${ident}_Event_NUM;
-         ++event) {
-        out << (${ident}_Event) event << " [";
-        uint64 total = 0;
-        for (int i = 0; i < m_profilers.size(); i++) {
-             out << m_profilers[i]->getEventCount(event) << " ";
-             total += m_profilers[i]->getEventCount(event);
-        }
-        out << "] " << total << "\\n";
-    }
-    out << "\\n";
-    out << " - Transitions -\\n";
-    for (${ident}_State state = ${ident}_State_FIRST;
-         state < ${ident}_State_NUM;
-         ++state) {
-        for (${ident}_Event event = ${ident}_Event_FIRST;
-             event < ${ident}_Event_NUM;
-             ++event) {
-            if (m_profilers[0]->isPossible(state, event)) {
-                out << (${ident}_State) state << "  "
-                    << (${ident}_Event) event << " [";
-                uint64 total = 0;
-                for (int i = 0; i < m_profilers.size(); i++) {
-                     out << m_profilers[i]->getTransitionCount(state, event) << " ";
-                     total += m_profilers[i]->getTransitionCount(state, event);
-                }
-                out << "] " << total << "\\n";
-            }
-        }
-        out << "\\n";
-    }
-}
-''')
-        code.write(path, "%s_ProfileDumper.cc" % self.ident)
-
-    def printProfilerHH(self, path):
-        code = self.symtab.codeFormatter()
-        ident = self.ident
-
-        code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#ifndef __${ident}_PROFILER_HH__
-#define __${ident}_PROFILER_HH__
-
-#include <cassert>
-#include <iostream>
-
-#include "mem/protocol/${ident}_Event.hh"
-#include "mem/protocol/${ident}_State.hh"
-#include "mem/ruby/common/TypeDefines.hh"
-
-class ${ident}_Profiler
-{
-  public:
-    ${ident}_Profiler();
-    void setVersion(int version);
-    void countTransition(${ident}_State state, ${ident}_Event event);
-    void possibleTransition(${ident}_State state, ${ident}_Event event);
-    uint64 getEventCount(${ident}_Event event);
-    bool isPossible(${ident}_State state, ${ident}_Event event);
-    uint64 getTransitionCount(${ident}_State state, ${ident}_Event event);
-    void clearStats();
-
-  private:
-    int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
-    int m_event_counters[${ident}_Event_NUM];
-    bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
-    int m_version;
-};
-
-#endif // __${ident}_PROFILER_HH__
-''')
-        code.write(path, "%s_Profiler.hh" % self.ident)
-
-    def printProfilerCC(self, path):
-        code = self.symtab.codeFormatter()
-        ident = self.ident
-
-        code('''
-// Auto generated C++ code started by $__file__:$__line__
-// ${ident}: ${{self.short}}
-
-#include <cassert>
-
-#include "mem/protocol/${ident}_Profiler.hh"
-
-${ident}_Profiler::${ident}_Profiler()
-{
-    for (int state = 0; state < ${ident}_State_NUM; state++) {
-        for (int event = 0; event < ${ident}_Event_NUM; event++) {
-            m_possible[state][event] = false;
-            m_counters[state][event] = 0;
-        }
-    }
-    for (int event = 0; event < ${ident}_Event_NUM; event++) {
-        m_event_counters[event] = 0;
-    }
-}
-
-void
-${ident}_Profiler::setVersion(int version)
-{
-    m_version = version;
-}
-
-void
-${ident}_Profiler::clearStats()
-{
-    for (int state = 0; state < ${ident}_State_NUM; state++) {
-        for (int event = 0; event < ${ident}_Event_NUM; event++) {
-            m_counters[state][event] = 0;
-        }
-    }
-
-    for (int event = 0; event < ${ident}_Event_NUM; event++) {
-        m_event_counters[event] = 0;
-    }
-}
-void
-${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
-{
-    assert(m_possible[state][event]);
-    m_counters[state][event]++;
-    m_event_counters[event]++;
-}
-void
-${ident}_Profiler::possibleTransition(${ident}_State state,
-                                      ${ident}_Event event)
-{
-    m_possible[state][event] = true;
-}
-
-uint64
-${ident}_Profiler::getEventCount(${ident}_Event event)
-{
-    return m_event_counters[event];
-}
-
-bool
-${ident}_Profiler::isPossible(${ident}_State state, ${ident}_Event event)
-{
-    return m_possible[state][event];
-}
-
-uint64
-${ident}_Profiler::getTransitionCount(${ident}_State state,
-                                      ${ident}_Event event)
-{
-    return m_counters[state][event];
-}
-
-''')
-        code.write(path, "%s_Profiler.cc" % self.ident)
 
     # **************************
     # ******* HTML Files *******