summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/ruby/slicc_interface/AbstractController.cc7
-rw-r--r--src/mem/ruby/slicc_interface/AbstractController.hh16
-rw-r--r--src/mem/ruby/slicc_interface/Controller.py4
-rw-r--r--src/mem/slicc/ast/ObjDeclAST.py3
-rw-r--r--src/mem/slicc/symbols/StateMachine.py67
5 files changed, 80 insertions, 17 deletions
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc
index 9a0ee2b2b..1615f8c1d 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -79,3 +79,10 @@ AbstractController::profileMsgDelay(uint32_t virtualNetwork, Cycles delay)
m_delayHistogram.add(delay);
m_delayVCHistogram[virtualNetwork].add(delay);
}
+
+void
+AbstractController::connectWithPeer(AbstractController *c)
+{
+ getQueuesFromPeer(c);
+ c->getQueuesFromPeer(this);
+}
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh
index ba0c4b683..81ef3c52b 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -97,12 +97,25 @@ class AbstractController : public ClockedObject, public Consumer
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 @@ class AbstractController : public ClockedObject, public Consumer
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 --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py
index 5c2fd9b71..f8242322e 100644
--- a/src/mem/ruby/slicc_interface/Controller.py
+++ b/src/mem/ruby/slicc_interface/Controller.py
@@ -42,4 +42,6 @@ class RubyController(ClockedObject):
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 --git a/src/mem/slicc/ast/ObjDeclAST.py b/src/mem/slicc/ast/ObjDeclAST.py
index 4509b4527..6469bc25a 100644
--- a/src/mem/slicc/ast/ObjDeclAST.py
+++ b/src/mem/slicc/ast/ObjDeclAST.py
@@ -41,7 +41,8 @@ class ObjDeclAST(DeclAST):
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 --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
index d5965d46d..3f54a1cdb 100644
--- a/src/mem/slicc/symbols/StateMachine.py
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -239,9 +239,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
@@ -331,6 +334,8 @@ static int m_num_controllers;
if proto:
code('$proto')
+ if has_peer:
+ code('void getQueuesFromPeer(AbstractController *);')
if self.EntryType != None:
code('''
@@ -388,6 +393,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
@@ -515,7 +521,20 @@ m_dma_sequencer_ptr->setController(this);
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 @@ $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 = ""
@@ -593,21 +609,22 @@ $c_ident::init()
# 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 @@ $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):