changeset 470016acf37d in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=470016acf37d
description:
        ruby: connect two controllers using only message buffers
        This patch modifies ruby so that two controllers can be connected to 
each
        other with only message buffers in between. Before this patch, all the
        controllers had to be connected to the network  for them to communicate
        with each other. With this patch, one can have protocols where a 
controller
        is not connected to the network, but communicates with another 
controller
        through a message buffer.

diffstat:

 src/mem/ruby/slicc_interface/AbstractController.cc |   7 ++
 src/mem/ruby/slicc_interface/AbstractController.hh |  16 +++++
 src/mem/ruby/slicc_interface/Controller.py         |   4 +-
 src/mem/slicc/ast/ObjDeclAST.py                    |   3 +-
 src/mem/slicc/symbols/StateMachine.py              |  67 +++++++++++++++++----
 5 files changed, 80 insertions(+), 17 deletions(-)

diffs (204 lines):

diff -r 219ad5fe8c04 -r 470016acf37d 
src/mem/ruby/slicc_interface/AbstractController.cc
--- a/src/mem/ruby/slicc_interface/AbstractController.cc        Fri Mar 22 
15:53:23 2013 -0500
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc        Fri Mar 22 
15:53:23 2013 -0500
@@ -79,3 +79,10 @@
     m_delayHistogram.add(delay);
     m_delayVCHistogram[virtualNetwork].add(delay);
 }
+
+void
+AbstractController::connectWithPeer(AbstractController *c)
+{
+    getQueuesFromPeer(c);
+    c->getQueuesFromPeer(this);
+}
diff -r 219ad5fe8c04 -r 470016acf37d 
src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh        Fri Mar 22 
15:53:23 2013 -0500
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh        Fri Mar 22 
15:53:23 2013 -0500
@@ -97,12 +97,25 @@
     Histogram& getDelayVCHist(uint32_t index)
     { return m_delayVCHistogram[index]; }
 
+    MessageBuffer *getPeerQueue(uint32_t pid)
+    {
+        std::map<uint32_t, MessageBuffer *>::iterator it =
+                                        peerQueueMap.find(pid);
+        assert(it != peerQueueMap.end());
+        return (*it).second;
+    }
+
   protected:
     //! Profiles original cache requests including PUTs
     void profileRequest(const std::string &request);
     //! Profiles the delay associated with messages.
     void profileMsgDelay(uint32_t virtualNetwork, Cycles delay);
 
+    //! Function for connecting peer controllers
+    void connectWithPeer(AbstractController *);
+    virtual void getQueuesFromPeer(AbstractController *)
+    { fatal("getQueuesFromPeer() should be called only if implemented!"); }
+
   protected:
     int m_transitions_per_cycle;
     int m_buffer_size;
@@ -120,6 +133,9 @@
     int m_cur_in_port_rank;
     int m_number_of_TBEs;
 
+    //! Map from physical network number to the Message Buffer.
+    std::map<uint32_t, MessageBuffer*> peerQueueMap;
+
     //! Counter for the number of cycles when the transitions carried out
     //! were equal to the maximum allowed
     uint64_t m_fully_busy_cycles;
diff -r 219ad5fe8c04 -r 470016acf37d src/mem/ruby/slicc_interface/Controller.py
--- a/src/mem/ruby/slicc_interface/Controller.py        Fri Mar 22 15:53:23 
2013 -0500
+++ b/src/mem/ruby/slicc_interface/Controller.py        Fri Mar 22 15:53:23 
2013 -0500
@@ -42,4 +42,6 @@
     buffer_size = Param.Int(0, "max buffer size 0 means infinite")
     recycle_latency = Param.Cycles(10, "")
     number_of_TBEs = Param.Int(256, "")
-    ruby_system = Param.RubySystem("");
+    ruby_system = Param.RubySystem("")
+
+    peer = Param.RubyController(NULL, "")
diff -r 219ad5fe8c04 -r 470016acf37d src/mem/slicc/ast/ObjDeclAST.py
--- a/src/mem/slicc/ast/ObjDeclAST.py   Fri Mar 22 15:53:23 2013 -0500
+++ b/src/mem/slicc/ast/ObjDeclAST.py   Fri Mar 22 15:53:23 2013 -0500
@@ -41,7 +41,8 @@
     def generate(self):
         machineComponentSym = False
 
-        if "network" in self and "virtual_network" not in self:
+        if "network" in self and not ("virtual_network" in self or
+                                      "physical_network" in self) :
             self.error("Network queues require a 'virtual_network' attribute")
 
         type = self.type_ast.type
diff -r 219ad5fe8c04 -r 470016acf37d src/mem/slicc/symbols/StateMachine.py
--- a/src/mem/slicc/symbols/StateMachine.py     Fri Mar 22 15:53:23 2013 -0500
+++ b/src/mem/slicc/symbols/StateMachine.py     Fri Mar 22 15:53:23 2013 -0500
@@ -239,9 +239,12 @@
 ''')
 
         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
@@ -331,6 +334,8 @@
             if proto:
                 code('$proto')
 
+        if has_peer:
+            code('void getQueuesFromPeer(AbstractController *);')
         if self.EntryType != None:
             code('''
 
@@ -388,6 +393,7 @@
         code = self.symtab.codeFormatter()
         ident = self.ident
         c_ident = "%s_Controller" % self.ident
+        has_peer = False
 
         code('''
 /** \\file $c_ident.cc
@@ -515,7 +521,20 @@
 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);
+''')
         code.dedent()
         code('''
 }
@@ -549,10 +568,7 @@
                         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 = ""
@@ -593,21 +609,22 @@
                 # 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 the end
+                    if network == "To":
+                        code('$vid->setSender(this);')
+                    else:
+                        code('$vid->setReceiver(this);')
 
                 # Set ordering
                 if "ordered" in var:
@@ -1007,6 +1024,26 @@
 }
 ''')
 
+        # 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):
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to