diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/Switch.hh --- a/src/mem/ruby/network/simple/Switch.hh Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/Switch.hh Sat Jul 25 10:44:39 2015 -0500 @@ -89,7 +89,8 @@ PerfectSwitch* m_perfect_switch; SimpleNetwork* m_network_ptr; std::vector m_throttles; - std::vector m_buffers_to_free; + std::vector m_port_buffers; + unsigned m_num_connected_buffers; // Statistical variables Stats::Formula m_avg_utilization; diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/Switch.cc --- a/src/mem/ruby/network/simple/Switch.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/Switch.cc Sat Jul 25 10:44:39 2015 -0500 @@ -43,6 +43,8 @@ Switch::Switch(const Params *p) : BasicRouter(p) { m_perfect_switch = new PerfectSwitch(m_id, this, p->virt_nets); + m_port_buffers = p->port_buffers; + m_num_connected_buffers = 0; } Switch::~Switch() @@ -53,7 +55,7 @@ deletePointers(m_throttles); // Delete MessageBuffers - deletePointers(m_buffers_to_free); + deletePointers(m_port_buffers); } void @@ -97,15 +99,10 @@ out[i]->setSender(this); } - MessageBuffer* buffer_ptr = new MessageBuffer; - // Make these queues ordered - buffer_ptr->setOrdering(true); - if (m_network_ptr->getBufferSize() > 0) { - buffer_ptr->resize(m_network_ptr->getBufferSize()); - } - + assert(m_num_connected_buffers < m_port_buffers.size()); + MessageBuffer* buffer_ptr = m_port_buffers[m_num_connected_buffers]; + m_num_connected_buffers++; intermediateBuffers.push_back(buffer_ptr); - m_buffers_to_free.push_back(buffer_ptr); buffer_ptr->setSender(this); buffer_ptr->setReceiver(this); @@ -188,8 +185,8 @@ Switch::functionalRead(Packet *pkt) { // Access the buffers in the switch for performing a functional read - for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { - if (m_buffers_to_free[i]->functionalRead(pkt)) { + for (unsigned int i = 0; i < m_port_buffers.size(); ++i) { + if (m_port_buffers[i]->functionalRead(pkt)) { return true; } } @@ -201,8 +198,8 @@ { // Access the buffers in the switch for performing a functional write uint32_t num_functional_writes = 0; - for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { - num_functional_writes += m_buffers_to_free[i]->functionalWrite(pkt); + for (unsigned int i = 0; i < m_port_buffers.size(); ++i) { + num_functional_writes += m_port_buffers[i]->functionalWrite(pkt); } return num_functional_writes; } diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/Throttle.cc --- a/src/mem/ruby/network/simple/Throttle.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/Throttle.cc Sat Jul 25 10:44:39 2015 -0500 @@ -100,7 +100,6 @@ in_ptr->setConsumer(this); string desc = "[Queue to Throttle " + to_string(m_sID) + " " + to_string(m_node) + "]"; - in_ptr->setDescription(desc); } } diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/slicc_interface/AbstractController.hh --- a/src/mem/ruby/slicc_interface/AbstractController.hh Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/slicc_interface/AbstractController.hh Sat Jul 25 10:44:39 2015 -0500 @@ -67,6 +67,7 @@ void unblock(Address); virtual MessageBuffer* getMandatoryQueue() const = 0; + virtual MessageBuffer* getMemoryQueue() const = 0; virtual AccessPermission getAccessPermission(const Address& addr) = 0; virtual void print(std::ostream & out) const = 0; @@ -97,8 +98,8 @@ virtual void collateStats() {fatal("collateStats() should be overridden!");} - //! Set the message buffer with given name. - virtual void setNetQueue(const std::string& name, MessageBuffer *b) = 0; + //! Initialize the message buffers. + virtual void initNetQueues() = 0; /** A function used to return the port associated with this bus object. */ BaseMasterPort& getMasterPort(const std::string& if_name, @@ -201,10 +202,6 @@ /* Master port to the memory controller. */ MemoryPort memoryPort; - // Message Buffer for storing the response received from the - // memory controller. - MessageBuffer *m_responseFromMemory_ptr; - // State that is stored in packets sent to the memory controller. struct SenderState : public Packet::SenderState { diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/slicc_interface/AbstractController.cc --- a/src/mem/ruby/slicc_interface/AbstractController.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/slicc_interface/AbstractController.cc Sat Jul 25 10:44:39 2015 -0500 @@ -39,16 +39,8 @@ m_number_of_TBEs(p->number_of_TBEs), m_transitions_per_cycle(p->transitions_per_cycle), m_buffer_size(p->buffer_size), m_recycle_latency(p->recycle_latency), - memoryPort(csprintf("%s.memory", name()), this, ""), - m_responseFromMemory_ptr(new MessageBuffer()) + memoryPort(csprintf("%s.memory", name()), this, "") { - // Set the sender pointer of the response message buffer from the - // memory controller. - // This pointer is used for querying for the current time. - m_responseFromMemory_ptr->setSender(this); - m_responseFromMemory_ptr->setReceiver(this); - m_responseFromMemory_ptr->setOrdering(false); - if (m_version == 0) { // Combine the statistics from all controllers // of this particular type. @@ -66,6 +58,9 @@ m_delayVCHistogram.push_back(new Stats::Histogram()); m_delayVCHistogram[i]->init(10); } + if (getMemoryQueue()) { + getMemoryQueue()->setSender(this); + } } void @@ -287,9 +282,6 @@ { int num_functional_writes = 0; - // Check the message buffer that runs from the memory to the controller. - num_functional_writes += m_responseFromMemory_ptr->functionalWrite(pkt); - // Check the buffer from the controller to the memory. if (memoryPort.checkFunctional(pkt)) { num_functional_writes++; @@ -303,6 +295,7 @@ void AbstractController::recvTimingResp(PacketPtr pkt) { + assert(getMemoryQueue()); assert(pkt->isResponse()); std::shared_ptr msg = std::make_shared(clockEdge()); @@ -327,7 +320,7 @@ panic("Incorrect packet type received from memory controller!"); } - m_responseFromMemory_ptr->enqueue(msg); + getMemoryQueue()->enqueue(msg); delete pkt; } diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/slicc/ast/ObjDeclAST.py --- a/src/mem/slicc/ast/ObjDeclAST.py Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/slicc/ast/ObjDeclAST.py Sat Jul 25 10:44:39 2015 -0500 @@ -47,16 +47,6 @@ type = self.type_ast.type - if type.isBuffer and "ordered" not in self: - self.error("Buffer object decls require an 'ordered' attribute") - - if "ordered" in self: - value = self["ordered"] - - if value not in ("true", "false"): - self.error("The 'ordered' attribute is '%s' " + \ - "must be 'true' or 'false'.", value) - if "random" in self: value = self["random"] if value not in ("true", "false"): diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/slicc/symbols/StateMachine.py --- a/src/mem/slicc/symbols/StateMachine.py Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/slicc/symbols/StateMachine.py Sat Jul 25 10:44:39 2015 -0500 @@ -210,10 +210,8 @@ dflt_str = str(param.rvalue.inline()) + ', ' if param.type_ast.type.c_ident == "MessageBuffer": - if param["network"] == "To": - code('${{param.ident}} = MasterPort(${dflt_str}"")') - else: - code('${{param.ident}} = SlavePort(${dflt_str}"")') + # The MessageBuffer MUST be instantiated in the protocol config + code('${{param.ident}} = Param.MessageBuffer("")') elif python_class_map.has_key(param.type_ast.type.c_ident): python_type = python_class_map[param.type_ast.type.c_ident] @@ -223,6 +221,13 @@ self.error("Unknown c++ to python class conversion for c++ " \ "type: '%s'. Please update the python_class_map " \ "in StateMachine.py", param.type_ast.type.c_ident) + + # Also add any MessageBuffers declared internally to the controller + # Note: This includes mandatory and memory queues + for var in self.objects: + if var.type.c_ident == "MessageBuffer": + code('${{var.ident}} = Param.MessageBuffer("")') + code.dedent() code.write(path, '%s.py' % py_ident) @@ -273,7 +278,8 @@ void init(); MessageBuffer* getMandatoryQueue() const; - void setNetQueue(const std::string& name, MessageBuffer *b); + MessageBuffer* getMemoryQueue() const; + void initNetQueues(); void print(std::ostream& out) const; void wakeup(); @@ -494,12 +500,6 @@ # include a sequencer, connect the it to the controller. # for param in self.config_parameters: - - # Do not initialize messgage buffers since they are initialized - # when the port based connections are made. - if param.type_ast.type.c_ident == "MessageBuffer": - continue - if param.pointer: code('m_${{param.ident}}_ptr = p->${{param.ident}};') else: @@ -509,9 +509,13 @@ code('m_${{param.ident}}_ptr->setController(this);') for var in self.objects: - if var.ident.find("mandatoryQueue") >= 0: + # Some MessageBuffers (e.g. mandatory and memory queues) are + # instantiated internally to StateMachines but exposed to + # components outside SLICC, so make sure to set up this + # controller as their receivers + if var.type.c_ident == "MessageBuffer": code(''' -m_${{var.ident}}_ptr = new ${{var.type.c_ident}}(); +m_${{var.ident}}_ptr = p->${{var.ident}}; m_${{var.ident}}_ptr->setReceiver(this); ''') @@ -532,7 +536,7 @@ } void -$c_ident::setNetQueue(const std::string& name, MessageBuffer *b) +$c_ident::initNetQueues() { MachineType machine_type = string_to_MachineType("${{self.ident}}"); int base M5_VAR_USED = MachineType_base_number(machine_type); @@ -550,15 +554,10 @@ vtype = var.type_ast.type vid = "m_%s_ptr" % var.ident - code(''' -if ("${{var.ident}}" == name) { - $vid = b; - assert($vid != NULL); -''') - code.indent() + code('assert($vid != NULL);') + # Network port object network = var["network"] - ordered = var["ordered"] if "virtual_network" in var: vnet = var["virtual_network"] @@ -568,8 +567,8 @@ vnet_dir_set.add((vnet,network)) code(''' -m_net_ptr->set${network}NetQueue(m_version + base, $ordered, $vnet, - "$vnet_type", b); +m_net_ptr->set${network}NetQueue(m_version + base, $vid->getOrdered(), $vnet, + "$vnet_type", $vid); ''') # Set the end if network == "To": @@ -577,34 +576,10 @@ else: code('$vid->setReceiver(this);') - # Set ordering - code('$vid->setOrdering(${{var["ordered"]}});') - - # Set randomization - if "random" in var: - # A buffer - code('$vid->setRandomization(${{var["random"]}});') - # Set Priority if "rank" in var: code('$vid->setPriority(${{var["rank"]}})') - # Set buffer size - code('$vid->resize(m_buffer_size);') - - if "recycle_latency" in var: - code('$vid->setRecycleLatency( ' \ - 'Cycles(${{var["recycle_latency"]}}));') - else: - code('$vid->setRecycleLatency(m_recycle_latency);') - - # set description (may be overriden later by port def) - code(''' -$vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{var.ident}}]"); -''') - code.dedent() - code('}\n') - code.dedent() code(''' } @@ -613,7 +588,7 @@ $c_ident::init() { // initialize objects - + initNetQueues(); ''') code.indent() @@ -629,7 +604,7 @@ code('(*$vid) = ${{var["default"]}};') else: # Normal Object - if var.ident.find("mandatoryQueue") < 0: + if var.type.c_ident != "MessageBuffer": th = var.get("template", "") expr = "%s = new %s%s" % (vid, vtype.c_ident, th) args = "" @@ -645,16 +620,6 @@ comment = "Type %s default" % vtype.ident code('*$vid = ${{vtype["default"]}}; // $comment') - # Set ordering - if "ordered" in var: - # A buffer - code('$vid->setOrdering(${{var["ordered"]}});') - - # Set randomization - if "random" in var: - # A buffer - code('$vid->setRandomization(${{var["random"]}});') - # Set Priority if vtype.isBuffer and "rank" in var: code('$vid->setPriority(${{var["rank"]}});') @@ -669,13 +634,6 @@ code('$vid->setSender(this);') code('$vid->setReceiver(this);') - if vtype.isBuffer: - if "recycle_latency" in var: - code('$vid->setRecycleLatency( ' \ - 'Cycles(${{var["recycle_latency"]}}));') - else: - code('$vid->setRecycleLatency(m_recycle_latency);') - # Set the prefetchers code() for prefetcher in self.prefetchers: @@ -685,8 +643,6 @@ for port in self.in_ports: # Set the queue consumers code('${{port.code}}.setConsumer(this);') - # Set the queue descriptions - code('${{port.code}}.setDescription("[Version " + to_string(m_version) + ", $ident, $port]");') # Initialize the transition profiling code() @@ -715,6 +671,11 @@ if port.code.find("mandatoryQueue_ptr") >= 0: mq_ident = "m_mandatoryQueue_ptr" + memq_ident = "NULL" + for port in self.in_ports: + if port.code.find("responseFromMemory_ptr") >= 0: + memq_ident = "m_responseFromMemory_ptr" + seq_ident = "NULL" for param in self.config_parameters: if param.ident == "sequencer": @@ -841,6 +802,12 @@ return $mq_ident; } +MessageBuffer* +$c_ident::getMemoryQueue() const +{ + return $memq_ident; +} + Sequencer* $c_ident::getSequencer() const { diff -r 89f4b96c887c -r 85b34fa1e87a src/python/swig/pyobject.cc --- a/src/python/swig/pyobject.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/python/swig/pyobject.cc Sat Jul 25 10:44:39 2015 -0500 @@ -102,21 +102,16 @@ // These could be objects from the ruby memory system. If yes, then at // least one of them should be an abstract controller. Do a type check. - AbstractController *ac1, *ac2; - ac1 = dynamic_cast(o1); - ac2 = dynamic_cast(o2); + MessageBuffer *mb1, *mb2; + mb1 = dynamic_cast(o1); + mb2 = dynamic_cast(o2); - if ((ac1 || ac2) && name1 != "memory" && name2 != "memory") { - MessageBuffer *b = new MessageBuffer(); - - // set the message buffer associated with the provided names - if (ac1) { - ac1->setNetQueue(name1, b); - } - if (ac2) { - ac2->setNetQueue(name2, b); - } - + if ((mb1 || mb2) && name1 != "memory" && name2 != "memory") { + // No need to connect anything here currently. MessageBuffer + // connections in Python only serve to print the connections in + // the config output. + // TODO: Add real ports to MessageBuffers and use MemObject connect + // code below to bind MessageBuffer senders and receivers return 1; } diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/SimpleNetwork.py --- a/src/mem/ruby/network/simple/SimpleNetwork.py Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/SimpleNetwork.py Sat Jul 25 10:44:39 2015 -0500 @@ -31,6 +31,7 @@ from m5.proxy import * from Network import RubyNetwork from BasicRouter import BasicRouter +from MessageBuffer import MessageBuffer class SimpleNetwork(RubyNetwork): type = 'SimpleNetwork' @@ -39,9 +40,48 @@ "default buffer size; 0 indicates infinite buffering"); endpoint_bandwidth = Param.Int(1000, "bandwidth adjustment factor"); adaptive_routing = Param.Bool(False, "enable adaptive routing"); + int_link_buffers = VectorParam.MessageBuffer("Buffers for int_links") + # int_links do not recycle buffers, so this parameter is not used. + # TODO: Move recycle_latency out of MessageBuffers and into controllers + recycle_latency = Param.Cycles(0, "") + + def setup_buffers(self): + # Note that all SimpleNetwork MessageBuffers are currently ordered + network_buffers = [] + for link in self.int_links: + # The network needs number_of_virtual_networks buffers per + # int_link port + for i in xrange(self.number_of_virtual_networks): + network_buffers.append(MessageBuffer(ordered = True)) + network_buffers.append(MessageBuffer(ordered = True)) + self.int_link_buffers = network_buffers + + # Also add buffers for all router-link connections + for router in self.routers: + router_buffers = [] + # Add message buffers to routers for each internal link connection + for link in self.int_links: + if link.node_a == router: + for i in xrange(self.number_of_virtual_networks): + router_buffers.append(MessageBuffer(ordered = True)) + if link.node_b == router: + for i in xrange(self.number_of_virtual_networks): + router_buffers.append(MessageBuffer(ordered = True)) + + # Add message buffers to routers for each external link connection + for link in self.ext_links: + # Routers can only be int_nodes on ext_links + if link.int_node in self.routers: + for i in xrange(self.number_of_virtual_networks): + router_buffers.append(MessageBuffer(ordered = True)) + router.port_buffers = router_buffers class Switch(BasicRouter): type = 'Switch' cxx_header = 'mem/ruby/network/simple/Switch.hh' virt_nets = Param.Int(Parent.number_of_virtual_networks, "number of virtual networks") + port_buffers = VectorParam.MessageBuffer("Port buffers") + # Ports do not recycle buffers, so this parameter is not used. + # TODO: Move recycle_latency out of MessageBuffers and into controllers + recycle_latency = Param.Cycles(0, "") diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/SimpleNetwork.cc --- a/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc Sat Jul 25 10:44:39 2015 -0500 @@ -62,6 +62,9 @@ m_switches.push_back(s); s->init_net_ptr(this); } + + m_int_link_buffers = p->int_link_buffers; + m_num_connected_buffers = 0; } void @@ -78,7 +81,7 @@ SimpleNetwork::~SimpleNetwork() { deletePointers(m_switches); - deletePointers(m_buffers_to_free); + deletePointers(m_int_link_buffers); } // From a switch to an endpoint node @@ -121,16 +124,10 @@ for (int i = 0; i < m_virtual_networks; i++) { // allocate a buffer - MessageBuffer* buffer_ptr = new MessageBuffer; - buffer_ptr->setOrdering(true); - - if (m_buffer_size > 0) { - buffer_ptr->resize(m_buffer_size); - } - + assert(m_num_connected_buffers < m_int_link_buffers.size()); + MessageBuffer* buffer_ptr = m_int_link_buffers[m_num_connected_buffers]; + m_num_connected_buffers++; queues[i] = buffer_ptr; - // remember to deallocate it - m_buffers_to_free.push_back(buffer_ptr); } // Connect it to the two switches @@ -236,8 +233,8 @@ } } - for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { - if (m_buffers_to_free[i]->functionalRead(pkt)) { + for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) { + if (m_int_link_buffers[i]->functionalRead(pkt)) { return true; } } @@ -254,8 +251,8 @@ num_functional_writes += m_switches[i]->functionalWrite(pkt); } - for (unsigned int i = 0; i < m_buffers_to_free.size(); ++i) { - num_functional_writes += m_buffers_to_free[i]->functionalWrite(pkt); + for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) { + num_functional_writes += m_int_link_buffers[i]->functionalWrite(pkt); } return num_functional_writes; } diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/SimpleNetwork.hh --- a/src/mem/ruby/network/simple/SimpleNetwork.hh Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/SimpleNetwork.hh Sat Jul 25 10:44:39 2015 -0500 @@ -93,7 +93,8 @@ SimpleNetwork& operator=(const SimpleNetwork& obj); std::vector m_switches; - std::vector m_buffers_to_free; + std::vector m_int_link_buffers; + int m_num_connected_buffers; std::vector m_endpoint_switches; int m_buffer_size; diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/MessageBuffer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/MessageBuffer.py Sat Jul 25 10:44:39 2015 -0500 @@ -0,0 +1,44 @@ +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# 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. +# +# Authors: Joel Hestness + +from m5.params import * +from m5.proxy import * +from m5.SimObject import SimObject + +class MessageBuffer(SimObject): + type = 'MessageBuffer' + cxx_class = 'MessageBuffer' + cxx_header = "mem/ruby/network/MessageBuffer.hh" + ordered = Param.Bool(False, "Whether the buffer is ordered") + buffer_size = Param.Unsigned(0, "Maximum number of entries to buffer \ + (0 allows infinite entries)") + recycle_latency = Param.Cycles(Parent.recycle_latency, "") + randomization = Param.Bool(False, "") + + master = MasterPort("Master port to MessageBuffer receiver") + slave = SlavePort("Slave port from MessageBuffer sender") diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/SConscript --- a/src/mem/ruby/network/SConscript Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/SConscript Sat Jul 25 10:44:39 2015 -0500 @@ -35,6 +35,7 @@ SimObject('BasicLink.py') SimObject('BasicRouter.py') +SimObject('MessageBuffer.py') SimObject('Network.py') Source('BasicLink.cc') diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/simple/PerfectSwitch.cc --- a/src/mem/ruby/network/simple/PerfectSwitch.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/simple/PerfectSwitch.cc Sat Jul 25 10:44:39 2015 -0500 @@ -76,13 +76,6 @@ for (int i = 0; i < in.size(); ++i) { if (in[i] != nullptr) { in[i]->setConsumer(this); - - string desc = - csprintf("[Queue from port %s %s %s to PerfectSwitch]", - to_string(m_switch_id), to_string(port), - to_string(i)); - - in[i]->setDescription(desc); in[i]->setIncomingLink(port); in[i]->setVnet(i); } diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/MessageBuffer.cc --- a/src/mem/ruby/network/MessageBuffer.cc Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/MessageBuffer.cc Sat Jul 25 10:44:39 2015 -0500 @@ -39,25 +39,25 @@ using namespace std; using m5::stl_helpers::operator<<; -MessageBuffer::MessageBuffer(const string &name) - : m_time_last_time_size_checked(0), m_time_last_time_enqueue(0), - m_time_last_time_pop(0), m_last_arrival_time(0) +MessageBuffer::MessageBuffer(const Params *p) + : SimObject(p), m_time_last_time_size_checked(0), + m_time_last_time_enqueue(0), m_time_last_time_pop(0), m_last_arrival_time(0) { m_msg_counter = 0; m_consumer = NULL; m_sender = NULL; m_receiver = NULL; - m_ordering_set = false; - m_strict_fifo = true; - m_max_size = 0; - m_randomization = true; + m_recycle_latency = p->recycle_latency; + m_strict_fifo = p->ordered; + m_max_size = p->buffer_size; + m_randomization = p->randomization; + m_size_last_time_size_checked = 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_stall_msg_map.clear(); m_input_link_id = 0; @@ -144,8 +144,6 @@ void MessageBuffer::enqueue(MsgPtr message, Cycles delta) { - assert(m_ordering_set); - // record current time incase we have a pop that also adjusts my size if (m_time_last_time_enqueue < m_sender->curCycle()) { m_msgs_this_cycle = 0; // first msg this cycle @@ -184,7 +182,7 @@ 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, + *this, name(), current_time, delta * m_sender->clockPeriod(), arrival_time, m_last_arrival_time); } @@ -352,7 +350,7 @@ vector copy(m_prio_heap); sort_heap(copy.begin(), copy.end(), greater()); - ccprintf(out, "%s] %s", copy, m_name); + ccprintf(out, "%s] %s", copy, name()); } bool @@ -420,3 +418,9 @@ return num_functional_writes; } + +MessageBuffer * +MessageBufferParams::create() +{ + return new MessageBuffer(this); +} diff -r 89f4b96c887c -r 85b34fa1e87a configs/ruby/Ruby.py --- a/configs/ruby/Ruby.py Sat Jul 25 10:44:05 2015 -0500 +++ b/configs/ruby/Ruby.py Sat Jul 25 10:44:39 2015 -0500 @@ -209,6 +209,11 @@ topology.makeTopology(options, network, IntLinkClass, ExtLinkClass, RouterClass) + if options.garnet_network is None: + assert(NetworkClass == SimpleNetwork) + assert(RouterClass == Switch) + network.setup_buffers() + if InterfaceClass != None: netifs = [InterfaceClass(id=i) for (i,n) in enumerate(network.ext_links)] network.netifs = netifs diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/protocol/RubySlicc_Defines.sm --- a/src/mem/protocol/RubySlicc_Defines.sm Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/protocol/RubySlicc_Defines.sm Sat Jul 25 10:44:39 2015 -0500 @@ -31,7 +31,6 @@ NodeID version; MachineID machineID; NodeID clusterID; -MessageBuffer responseFromMemory, ordered="false"; // Functions implemented in the AbstractController class for // making timing access to the memory maintained by the diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/SConscript --- a/src/mem/ruby/SConscript Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/SConscript Sat Jul 25 10:44:39 2015 -0500 @@ -37,6 +37,7 @@ Import('*') +DebugFlag('MessageBuffer') DebugFlag('ProtocolTrace') DebugFlag('RubyCache') DebugFlag('RubyCacheTrace') diff -r 89f4b96c887c -r 85b34fa1e87a src/mem/ruby/network/MessageBuffer.hh --- a/src/mem/ruby/network/MessageBuffer.hh Sat Jul 25 10:44:05 2015 -0500 +++ b/src/mem/ruby/network/MessageBuffer.hh Sat Jul 25 10:44:39 2015 -0500 @@ -41,20 +41,19 @@ #include #include +#include "debug/MessageBuffer.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/slicc_interface/Message.hh" #include "mem/packet.hh" +#include "params/MessageBuffer.hh" +#include "sim/sim_object.hh" -class MessageBuffer +class MessageBuffer : public SimObject { public: - MessageBuffer(const std::string &name = ""); - - std::string name() const { return m_name; } - - void setRecycleLatency(Cycles recycle_latency) - { m_recycle_latency = recycle_latency; } + typedef MessageBufferParams Params; + MessageBuffer(const Params *p); void reanalyzeMessages(const Address& addr); void reanalyzeAllMessages(); @@ -78,6 +77,7 @@ void setPriority(int rank) { m_priority_rank = rank; } void setConsumer(Consumer* consumer) { + DPRINTF(MessageBuffer, "Setting consumer: %s\n", *consumer); if (m_consumer != NULL) { fatal("Trying to connect %s to MessageBuffer %s. \ \n%s already connected. Check the cntrl_id's.\n", @@ -88,20 +88,21 @@ void setSender(ClockedObject* obj) { + DPRINTF(MessageBuffer, "Setting sender: %s\n", obj->name()); assert(m_sender == NULL || m_sender == obj); m_sender = obj; } void setReceiver(ClockedObject* obj) { + DPRINTF(MessageBuffer, "Setting receiver: %s\n", obj->name()); assert(m_receiver == NULL || m_receiver == obj); m_receiver = obj; } - void setDescription(const std::string& name) { m_name = name; } - std::string getDescription() { return m_name;} + Consumer* getConsumer() { return m_consumer; } - Consumer* getConsumer() { return m_consumer; } + bool getOrdered() { return m_strict_fifo; } //! Function for extracting the message at the head of the //! message queue. The function assumes that the queue is nonempty. @@ -124,16 +125,7 @@ void recycle(); bool isEmpty() const { return m_prio_heap.size() == 0; } - void - setOrdering(bool order) - { - m_strict_fifo = order; - m_ordering_set = true; - } - - void resize(unsigned int size) { m_max_size = size; } unsigned int getSize(); - void setRandomization(bool random_flag) { m_randomization = random_flag; } void clear(); void print(std::ostream& out) const; @@ -154,12 +146,12 @@ uint32_t functionalWrite(Packet *pkt); private: + //added by SS + Cycles m_recycle_latency; + void reanalyzeList(std::list &, Tick); private: - //added by SS - Cycles m_recycle_latency; - // Data Members (m_ prefix) //! The two ends of the buffer. ClockedObject* m_sender; @@ -174,7 +166,6 @@ typedef std::map< Address, std::list > StallMsgMapType; StallMsgMapType m_stall_msg_map; - std::string m_name; unsigned int m_max_size; Cycles m_time_last_time_size_checked; @@ -194,7 +185,6 @@ uint64 m_msg_counter; int m_priority_rank; bool m_strict_fifo; - bool m_ordering_set; bool m_randomization; int m_input_link_id;