summaryrefslogtreecommitdiff
path: root/src/mem/ruby/network
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
committerNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
commit2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch)
tree708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/ruby/network
parentc70241810d4e4f523f173c1646b008dc40faad8e (diff)
downloadgem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother.
Diffstat (limited to 'src/mem/ruby/network')
-rw-r--r--src/mem/ruby/network/Network.hh148
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh17
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc349
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh142
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc95
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh172
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh54
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc351
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh96
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc103
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh91
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc46
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh86
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc111
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh95
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc167
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh101
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc93
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh61
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc230
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh82
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc98
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh73
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc271
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh86
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc92
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh119
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc88
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh87
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc134
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh166
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh50
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc307
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh117
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc75
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh61
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh123
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc306
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh98
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc147
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh88
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc60
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh55
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/Router.cc389
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/Router.hh98
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc47
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh56
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flit.cc113
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flit.hh97
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc104
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh78
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/netconfig.defaults8
-rw-r--r--src/mem/ruby/network/orion/NetworkPower.cc430
-rw-r--r--src/mem/ruby/network/orion/NetworkPower.hh32
-rw-r--r--src/mem/ruby/network/orion/SIM_port.hh172
-rw-r--r--src/mem/ruby/network/orion/SIM_power.hh384
-rw-r--r--src/mem/ruby/network/orion/SIM_power_test.hh285
-rw-r--r--src/mem/ruby/network/orion/parm_technology.hh474
-rw-r--r--src/mem/ruby/network/orion/power_arbiter.cc392
-rw-r--r--src/mem/ruby/network/orion/power_arbiter.hh90
-rw-r--r--src/mem/ruby/network/orion/power_array.cc2158
-rw-r--r--src/mem/ruby/network/orion/power_array.hh394
-rw-r--r--src/mem/ruby/network/orion/power_bus.cc215
-rw-r--r--src/mem/ruby/network/orion/power_bus.hh64
-rw-r--r--src/mem/ruby/network/orion/power_crossbar.cc365
-rw-r--r--src/mem/ruby/network/orion/power_crossbar.hh81
-rw-r--r--src/mem/ruby/network/orion/power_ll.cc270
-rw-r--r--src/mem/ruby/network/orion/power_ll.hh53
-rw-r--r--src/mem/ruby/network/orion/power_router_init.cc260
-rw-r--r--src/mem/ruby/network/orion/power_router_init.hh126
-rw-r--r--src/mem/ruby/network/orion/power_static.cc46
-rw-r--r--src/mem/ruby/network/orion/power_static.hh39
-rw-r--r--src/mem/ruby/network/orion/power_utils.cc157
-rw-r--r--src/mem/ruby/network/orion/power_utils.hh35
-rw-r--r--src/mem/ruby/network/simple/Network_Files/GarnetFileMaker.py45
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt78
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-4.txt56
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-8.txt61
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-1_L2Banks-16_Memories-16.txt190
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt90
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-4.txt78
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-32_Memories-4.txt123
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-16.txt78
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-4.txt66
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-1_Memories-1.txt10
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-256_Memories-1.txt780
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-32_Memories-1.txt107
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-64_Memories-1.txt204
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-1_L2Banks-2_Memories-2.txt15
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-2_L2Banks-2_Memories-2.txt15
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-16.txt148
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-4.txt126
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-1_L2Banks-4_Memories-4.txt28
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-4_L2Banks-4_Memories-4.txt24
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-7_ProcsPerChip-7_L2Banks-7_Memories-7.txt139
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-1_L2Banks-8_Memories-8.txt66
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-4_L2Banks-8_Memories-8.txt46
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt412
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-8_Memories-8.txt44
-rw-r--r--src/mem/ruby/network/simple/Network_Files/NetworkFileMaker.py44
-rw-r--r--src/mem/ruby/network/simple/Network_Files/TLC_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt367
-rw-r--r--src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt74
-rw-r--r--src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt101
-rw-r--r--src/mem/ruby/network/simple/PerfectSwitch.cc319
-rw-r--r--src/mem/ruby/network/simple/PerfectSwitch.hh118
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.cc257
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.hh157
-rw-r--r--src/mem/ruby/network/simple/Switch.cc205
-rw-r--r--src/mem/ruby/network/simple/Switch.hh105
-rw-r--r--src/mem/ruby/network/simple/Throttle.cc291
-rw-r--r--src/mem/ruby/network/simple/Throttle.hh124
-rw-r--r--src/mem/ruby/network/simple/Topology.cc801
-rw-r--r--src/mem/ruby/network/simple/Topology.hh126
113 files changed, 19021 insertions, 0 deletions
diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh
new file mode 100644
index 000000000..662e54e93
--- /dev/null
+++ b/src/mem/ruby/network/Network.hh
@@ -0,0 +1,148 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Network.h
+ *
+ * Description: The Network class is the base class for classes that
+ * implement the interconnection network between components
+ * (processor/cache components and memory/directory components). The
+ * interconnection network as described here is not a physical
+ * network, but a programming concept used to implement all
+ * communication between components. Thus parts of this 'network'
+ * will model the on-chip connections between cache controllers and
+ * directory controllers as well as the links between chip and network
+ * switches.
+ *
+ * $Id$
+ * */
+
+#ifndef NETWORK_H
+#define NETWORK_H
+
+#include "Global.hh"
+#include "NodeID.hh"
+#include "MessageSizeType.hh"
+
+class NetDest;
+class MessageBuffer;
+class Throttle;
+
+class Network {
+public:
+ // Constructors
+ Network() {}
+
+ // Destructor
+ virtual ~Network() {}
+
+ // Public Methods
+
+ static Network* createNetwork(int nodes);
+
+ // returns the queue requested for the given component
+ virtual MessageBuffer* getToNetQueue(NodeID id, bool ordered, int netNumber) = 0;
+ virtual MessageBuffer* getFromNetQueue(NodeID id, bool ordered, int netNumber) = 0;
+ virtual const Vector<Throttle*>* getThrottles(NodeID id) const { return NULL; }
+
+ virtual int getNumNodes() {return 1;}
+
+ virtual void makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration) = 0;
+ virtual void makeInLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration) = 0;
+ virtual void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration) = 0;
+
+ virtual void reset() = 0;
+
+ virtual void printStats(ostream& out) const = 0;
+ virtual void clearStats() = 0;
+ virtual void printConfig(ostream& out) const = 0;
+ virtual void print(ostream& out) const = 0;
+
+private:
+
+ // Private Methods
+ // Private copy constructor and assignment operator
+ Network(const Network& obj);
+ Network& operator=(const Network& obj);
+
+ // Data Members (m_ prefix)
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Network& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Network& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+// Code to map network message size types to an integer number of bytes
+const int CONTROL_MESSAGE_SIZE = 8;
+const int DATA_MESSAGE_SIZE = (64+8);
+
+extern inline
+int MessageSizeType_to_int(MessageSizeType size_type)
+{
+ switch(size_type) {
+ case MessageSizeType_Undefined:
+ ERROR_MSG("Can't convert Undefined MessageSizeType to integer");
+ break;
+ case MessageSizeType_Control:
+ case MessageSizeType_Request_Control:
+ case MessageSizeType_Reissue_Control:
+ case MessageSizeType_Response_Control:
+ case MessageSizeType_Writeback_Control:
+ case MessageSizeType_Forwarded_Control:
+ case MessageSizeType_Invalidate_Control:
+ case MessageSizeType_Unblock_Control:
+ case MessageSizeType_Persistent_Control:
+ case MessageSizeType_Completion_Control:
+ return CONTROL_MESSAGE_SIZE;
+ break;
+ case MessageSizeType_Data:
+ case MessageSizeType_Response_Data:
+ case MessageSizeType_ResponseLocal_Data:
+ case MessageSizeType_ResponseL2hit_Data:
+ case MessageSizeType_Writeback_Data:
+ return DATA_MESSAGE_SIZE;
+ break;
+ default:
+ ERROR_MSG("Invalid range for type MessageSizeType");
+ break;
+ }
+ return 0;
+}
+
+#endif //NETWORK_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
new file mode 100644
index 000000000..e3a9b7d2d
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
@@ -0,0 +1,17 @@
+/*
+ * CreditLink_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+#ifndef CREDIT_LINK_D_H
+#define CREDIT_LINK_D_H
+
+#include "NetworkLink_d.hh"
+
+class CreditLink_d : public NetworkLink_d {
+public:
+ CreditLink_d(int id):NetworkLink_d(id) {}
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
new file mode 100644
index 000000000..43f9a31bd
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * GarnetNetwork_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "GarnetNetwork_d.hh"
+#include "MachineType.hh"
+#include "NetworkInterface_d.hh"
+#include "MessageBuffer.hh"
+#include "Router_d.hh"
+#include "Topology.hh"
+#include "NetworkLink_d.hh"
+#include "CreditLink_d.hh"
+#include "NetDest.hh"
+
+GarnetNetwork_d::GarnetNetwork_d(int nodes)
+{
+ m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
+ m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS; // Number of virtual networks = number of message classes in the coherence protocol
+ m_ruby_start = 0;
+ m_flits_recieved = 0;
+ m_flits_injected = 0;
+ m_network_latency = 0.0;
+ m_queueing_latency = 0.0;
+
+ m_router_ptr_vector.clear();
+
+ // Allocate to and from queues
+ m_toNetQueues.setSize(m_nodes); // Queues that are getting messages from protocol
+ m_fromNetQueues.setSize(m_nodes); // Queues that are feeding the protocol
+ m_in_use.setSize(m_virtual_networks);
+ m_ordered.setSize(m_virtual_networks);
+ for (int i = 0; i < m_virtual_networks; i++)
+ {
+ m_in_use[i] = false;
+ m_ordered[i] = false;
+ }
+
+ for (int node = 0; node < m_nodes; node++)
+ {
+ //Setting how many vitual message buffers will there be per Network Queue
+ m_toNetQueues[node].setSize(m_virtual_networks);
+ m_fromNetQueues[node].setSize(m_virtual_networks);
+
+ for (int j = 0; j < m_virtual_networks; j++)
+ {
+ m_toNetQueues[node][j] = new MessageBuffer(); // Instantiating the Message Buffers that interact with the coherence protocol
+ m_fromNetQueues[node][j] = new MessageBuffer();
+ }
+ }
+
+ // Setup the network switches
+ m_topology_ptr = new Topology(this, m_nodes);
+
+ int number_of_routers = m_topology_ptr->numSwitches();
+ for (int i=0; i<number_of_routers; i++) {
+ m_router_ptr_vector.insertAtBottom(new Router_d(i, this));
+ }
+
+ for (int i=0; i < m_nodes; i++) {
+ NetworkInterface_d *ni = new NetworkInterface_d(i, m_virtual_networks, this);
+ ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
+ m_ni_ptr_vector.insertAtBottom(ni);
+ }
+ m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
+ for(int i = 0; i < m_router_ptr_vector.size(); i++)
+ {
+ m_router_ptr_vector[i]->init();
+ }
+}
+
+GarnetNetwork_d::~GarnetNetwork_d()
+{
+ for (int i = 0; i < m_nodes; i++)
+ {
+ m_toNetQueues[i].deletePointers();
+ m_fromNetQueues[i].deletePointers();
+ }
+ m_router_ptr_vector.deletePointers();
+ m_ni_ptr_vector.deletePointers();
+ m_link_ptr_vector.deletePointers();
+ m_creditlink_ptr_vector.deletePointers();
+ delete m_topology_ptr;
+}
+
+void GarnetNetwork_d::reset()
+{
+ for (int node = 0; node < m_nodes; node++)
+ {
+ for (int j = 0; j < m_virtual_networks; j++)
+ {
+ m_toNetQueues[node][j]->clear();
+ m_fromNetQueues[node][j]->clear();
+ }
+ }
+}
+
+/*
+ * This function creates a link from the Network Interface (NI) into the Network.
+ * It creates a Network Link from the NI to a Router and a Credit Link from
+ * the Router to the NI
+*/
+
+void GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration)
+{
+ assert(src < m_nodes);
+
+ if(!isReconfiguration)
+ {
+ NetworkLink_d *net_link = new NetworkLink_d(m_link_ptr_vector.size(), link_latency, this);
+ CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size());
+ m_link_ptr_vector.insertAtBottom(net_link);
+ m_creditlink_ptr_vector.insertAtBottom(credit_link);
+
+ m_router_ptr_vector[dest]->addInPort(net_link, credit_link);
+ m_ni_ptr_vector[src]->addOutPort(net_link, credit_link);
+ }
+ else
+ {
+ ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
+ // do nothing
+ }
+}
+
+/*
+ * This function creates a link from the Network to a NI.
+ * It creates a Network Link from a Router to the NI and
+ * a Credit Link from NI to the Router
+*/
+
+void GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ assert(dest < m_nodes);
+ assert(src < m_router_ptr_vector.size());
+ assert(m_router_ptr_vector[src] != NULL);
+
+ if(!isReconfiguration)
+ {
+ NetworkLink_d *net_link = new NetworkLink_d(m_link_ptr_vector.size(), link_latency, this);
+ CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size());
+ m_link_ptr_vector.insertAtBottom(net_link);
+ m_creditlink_ptr_vector.insertAtBottom(credit_link);
+
+ m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, link_weight, credit_link);
+ m_ni_ptr_vector[dest]->addInPort(net_link, credit_link);
+ }
+ else
+ {
+ ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
+ //do nothing
+ }
+}
+
+/*
+ * This function creates a internal network links
+*/
+
+void GarnetNetwork_d::makeInternalLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ if(!isReconfiguration)
+ {
+ NetworkLink_d *net_link = new NetworkLink_d(m_link_ptr_vector.size(), link_latency, this);
+ CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size());
+ m_link_ptr_vector.insertAtBottom(net_link);
+ m_creditlink_ptr_vector.insertAtBottom(credit_link);
+
+ m_router_ptr_vector[dest]->addInPort(net_link, credit_link);
+ m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, link_weight, credit_link);
+ }
+ else
+ {
+ ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
+ // do nothing
+ }
+}
+
+void GarnetNetwork_d::checkNetworkAllocation(NodeID id, bool ordered, int network_num)
+{
+ ASSERT(id < m_nodes);
+ ASSERT(network_num < m_virtual_networks);
+
+ if (ordered)
+ {
+ m_ordered[network_num] = true;
+ }
+ m_in_use[network_num] = true;
+}
+
+MessageBuffer* GarnetNetwork_d::getToNetQueue(NodeID id, bool ordered, int network_num)
+{
+ checkNetworkAllocation(id, ordered, network_num);
+ return m_toNetQueues[id][network_num];
+}
+
+MessageBuffer* GarnetNetwork_d::getFromNetQueue(NodeID id, bool ordered, int network_num)
+{
+ checkNetworkAllocation(id, ordered, network_num);
+ return m_fromNetQueues[id][network_num];
+}
+
+void GarnetNetwork_d::clearStats()
+{
+ m_ruby_start = g_eventQueue_ptr->getTime();
+}
+
+Time GarnetNetwork_d::getRubyStartTime()
+{
+ return m_ruby_start;
+}
+
+void GarnetNetwork_d::printStats(ostream& out) const
+{ double average_link_utilization = 0;
+ Vector<double > average_vc_load;
+ average_vc_load.setSize(m_virtual_networks*NetworkConfig::getVCsPerClass());
+
+ for(int i = 0; i < m_virtual_networks*NetworkConfig::getVCsPerClass(); i++)
+ {
+ average_vc_load[i] = 0;
+ }
+
+ out << endl;
+ out << "Network Stats" << endl;
+ out << "-------------" << endl;
+ out << endl;
+ for(int i = 0; i < m_link_ptr_vector.size(); i++)
+ {
+ average_link_utilization += (double(m_link_ptr_vector[i]->getLinkUtilization())) / (double(g_eventQueue_ptr->getTime()-m_ruby_start));
+
+ Vector<int > vc_load = m_link_ptr_vector[i]->getVcLoad();
+ for(int j = 0; j < vc_load.size(); j++)
+ {
+ assert(vc_load.size() == NetworkConfig::getVCsPerClass()*m_virtual_networks);
+ average_vc_load[j] += vc_load[j];
+ }
+ }
+ average_link_utilization = average_link_utilization/m_link_ptr_vector.size();
+ out << "Average Link Utilization :: " << average_link_utilization << " flits/cycle" << endl;
+ out << "-------------" << endl;
+
+ for(int i = 0; i < NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ {
+ average_vc_load[i] = (double(average_vc_load[i]) / (double(g_eventQueue_ptr->getTime()) - m_ruby_start));
+ out << "Average VC Load [" << i << "] = " << average_vc_load[i] << " flits/cycle " << endl;
+ }
+ out << "-------------" << endl;
+
+ // out << "Total flits injected = " << m_flits_injected << endl;
+ // out << "Total flits recieved = " << m_flits_recieved << endl;
+ out << "Average network latency = " << ((double) m_network_latency/ (double) m_flits_recieved)<< endl;
+ // out << "Average queueing latency = " << ((double) m_queueing_latency/ (double) m_flits_recieved)<< endl;
+ // out << "Average latency = " << ((double) (m_queueing_latency + m_network_latency) / (double) m_flits_recieved)<< endl;
+ out << "-------------" << endl;
+
+ double m_total_link_power = 0.0;
+ double m_total_router_power = 0.0;
+
+ for(int i = 0; i < m_link_ptr_vector.size(); i++)
+ {
+ m_total_link_power += m_link_ptr_vector[i]->calculate_power();
+ }
+
+ for(int i = 0; i < m_router_ptr_vector.size(); i++)
+ {
+ m_total_router_power += m_router_ptr_vector[i]->calculate_power();
+ }
+ out << "Total Link Power = " << m_total_link_power << " W " << endl;
+ out << "Total Router Power = " << m_total_router_power << " W " <<endl;
+ out << "-------------" << endl;
+}
+
+void GarnetNetwork_d::printConfig(ostream& out) const
+{
+ out << endl;
+ out << "Network Configuration" << endl;
+ out << "---------------------" << endl;
+ out << "network: GarnetNetwork_d" << endl;
+ out << "topology: " << g_NETWORK_TOPOLOGY << endl;
+ out << endl;
+
+ for (int i = 0; i < m_virtual_networks; i++)
+ {
+ out << "virtual_net_" << i << ": ";
+ if (m_in_use[i])
+ {
+ out << "active, ";
+ if (m_ordered[i])
+ {
+ out << "ordered" << endl;
+ }
+ else
+ {
+ out << "unordered" << endl;
+ }
+ }
+ else
+ {
+ out << "inactive" << endl;
+ }
+ }
+ out << endl;
+
+ for(int i = 0; i < m_ni_ptr_vector.size(); i++)
+ {
+ m_ni_ptr_vector[i]->printConfig(out);
+ }
+ for(int i = 0; i < m_router_ptr_vector.size(); i++)
+ {
+ m_router_ptr_vector[i]->printConfig(out);
+ }
+ if (g_PRINT_TOPOLOGY)
+ {
+ m_topology_ptr->printConfig(out);
+ }
+}
+
+void GarnetNetwork_d::print(ostream& out) const
+{
+ out << "[GarnetNetwork_d]";
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
new file mode 100644
index 000000000..34486eab8
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * GarnetNetwork_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef GARNETNETWORK_D_H
+#define GARNETNETWORK_D_H
+
+#include "NetworkHeader.hh"
+#include "Vector.hh"
+#include "NetworkConfig.hh"
+#include "Network.hh"
+
+class NetworkInterface_d;
+class MessageBuffer;
+class Router_d;
+class Topology;
+class NetDest;
+class NetworkLink_d;
+class CreditLink_d;
+
+class GarnetNetwork_d : public Network{
+public:
+ GarnetNetwork_d(int nodes);
+
+ ~GarnetNetwork_d();
+
+ int getNumNodes(){ return m_nodes;}
+
+ // returns the queue requested for the given component
+ MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num);
+ MessageBuffer* getFromNetQueue(NodeID id, bool ordered, int network_num);
+
+ void clearStats();
+ void printStats(ostream& out) const;
+ void printConfig(ostream& out) const;
+ void print(ostream& out) const;
+
+ inline void increment_injected_flits()
+ {
+ m_flits_injected++;
+ }
+ inline void increment_recieved_flits()
+ {
+ m_flits_recieved++;
+ }
+ inline void increment_network_latency(Time latency)
+ {
+ m_network_latency += latency;
+ }
+ inline void increment_queueing_latency(Time latency)
+ {
+ m_queueing_latency += latency;
+ }
+
+ bool isVNetOrdered(int vnet)
+ {
+ return m_ordered[vnet];
+ }
+ bool validVirtualNetwork(int vnet) { return m_in_use[vnet]; }
+
+ Time getRubyStartTime();
+
+ void reset();
+
+ // Methods used by Topology to setup the network
+ void makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
+ void makeInLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration);
+ void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
+
+private:
+ void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
+
+// Private copy constructor and assignment operator
+ GarnetNetwork_d(const GarnetNetwork_d& obj);
+ GarnetNetwork_d& operator=(const GarnetNetwork_d& obj);
+
+/***********Data Members*************/
+ int m_virtual_networks;
+ int m_nodes;
+ int m_flits_recieved, m_flits_injected;
+ double m_network_latency, m_queueing_latency;
+
+ Vector<bool> m_in_use;
+ Vector<bool> m_ordered;
+
+ Vector<Vector<MessageBuffer*> > m_toNetQueues;
+ Vector<Vector<MessageBuffer*> > m_fromNetQueues;
+
+ Vector<Router_d *> m_router_ptr_vector; // All Routers in Network
+ Vector<NetworkLink_d *> m_link_ptr_vector; // All links in the network
+ Vector<CreditLink_d *> m_creditlink_ptr_vector; // All links in the network
+ Vector<NetworkInterface_d *> m_ni_ptr_vector; // All NI's in Network
+
+ Topology* m_topology_ptr;
+ Time m_ruby_start;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const GarnetNetwork_d& obj);
+
+// ******************* Definitions *******************
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const GarnetNetwork_d& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //GARNETNETWORK_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc
new file mode 100644
index 000000000..bedd801d5
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * InputUnit_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "InputUnit_d.hh"
+#include "Router_d.hh"
+
+InputUnit_d::InputUnit_d(int id, Router_d *router)
+{
+ m_id = id;
+ m_router = router;
+ m_num_vcs = m_router->get_num_vcs();
+
+ m_num_buffer_reads = 0;
+ m_num_buffer_writes = 0;
+
+ creditQueue = new flitBuffer_d();
+ // Instantiating the virtual channels
+ m_vcs.setSize(m_num_vcs);
+ for(int i=0; i < m_num_vcs; i++)
+ {
+ m_vcs[i] = new VirtualChannel_d(i);
+ }
+}
+
+InputUnit_d::~InputUnit_d()
+{
+ delete creditQueue;
+ m_vcs.deletePointers();
+}
+
+void InputUnit_d::wakeup()
+{
+ flit_d *t_flit;
+ if(m_in_link->isReady())
+ {
+ t_flit = m_in_link->consumeLink();
+ int vc = t_flit->get_vc();
+ if((t_flit->get_type() == HEAD_) || (t_flit->get_type() == HEAD_TAIL_))
+ {
+ assert(m_vcs[vc]->get_state() == IDLE_);
+ m_router->route_req(t_flit, this, vc); // Do the route computation for this vc
+ m_vcs[vc]->set_enqueue_time(g_eventQueue_ptr->getTime());
+ }
+ else
+ {
+ t_flit->advance_stage(SA_);
+ m_router->swarb_req();
+ }
+ m_vcs[vc]->insertFlit(t_flit); // write flit into input buffer
+ m_num_buffer_writes++;
+ m_num_buffer_reads++; // same as read because any flit that is written will be read only once
+ }
+}
+
+
+void InputUnit_d::printConfig(ostream& out)
+{
+ out << endl;
+ out << "InputUnit Configuration" << endl;
+ out << "---------------------" << endl;
+ out << "id = " << m_id << endl;
+ out << "In link is " << m_in_link->get_id() << endl;
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh
new file mode 100644
index 000000000..c22363fb1
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * InputUnit_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef INPUT_UNIT_D_H
+#define INPUT_UNIT_D_H
+
+#include "NetworkHeader.hh"
+#include "flitBuffer_d.hh"
+#include "Consumer.hh"
+#include "Vector.hh"
+#include "VirtualChannel_d.hh"
+#include "NetworkLink_d.hh"
+#include "CreditLink_d.hh"
+
+class Router_d;
+
+class InputUnit_d : public Consumer {
+public:
+ InputUnit_d(int id, Router_d *router);
+ ~InputUnit_d();
+
+ void wakeup();
+ void printConfig(ostream& out);
+ flitBuffer_d* getCreditQueue() { return creditQueue; }
+ void print(ostream& out) const {};
+
+ inline int get_inlink_id()
+ {
+ return m_in_link->get_id();
+ }
+
+ inline void set_vc_state(VC_state_type state, int vc)
+ {
+ m_vcs[vc]->set_state(state);
+ }
+ inline void set_enqueue_time(int invc, Time time)
+ {
+ m_vcs[invc]->set_enqueue_time(time);
+ }
+ inline Time get_enqueue_time(int invc)
+ {
+ return m_vcs[invc]->get_enqueue_time();
+ }
+ inline void update_credit(int in_vc, int credit)
+ {
+ m_vcs[in_vc]->update_credit(credit);
+ }
+
+ inline bool has_credits(int vc)
+ {
+ return m_vcs[vc]->has_credits();
+ }
+
+ inline void increment_credit(int in_vc, bool free_signal)
+ {
+ flit_d *t_flit = new flit_d(in_vc, free_signal);
+ creditQueue->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(m_credit_link, 1);
+ }
+
+ inline int get_outvc(int invc)
+ {
+ return m_vcs[invc]->get_outvc();
+ }
+
+ inline void updateRoute(int vc, int outport)
+ {
+ m_vcs[vc]->set_outport(outport);
+ m_vcs[vc]->set_state(VC_AB_);
+ }
+
+ inline void grant_vc(int in_vc, int out_vc)
+ {
+ m_vcs[in_vc]->grant_vc(out_vc);
+ }
+
+ inline flit_d* peekTopFlit(int vc)
+ {
+ return m_vcs[vc]->peekTopFlit();
+ }
+
+ inline flit_d* getTopFlit(int vc)
+ {
+ return m_vcs[vc]->getTopFlit();
+ }
+
+ inline bool need_stage(int vc, VC_state_type state, flit_stage stage)
+ {
+ return m_vcs[vc]->need_stage(state, stage);
+ }
+
+ inline bool need_stage_nextcycle(int vc, VC_state_type state, flit_stage stage)
+ {
+ return m_vcs[vc]->need_stage_nextcycle(state, stage);
+ }
+
+ inline bool isReady(int invc)
+ {
+ return m_vcs[invc]->isReady();
+ }
+
+ inline int get_route(int vc)
+ {
+ return m_vcs[vc]->get_route();
+ }
+ inline void set_in_link(NetworkLink_d *link)
+ {
+ m_in_link = link;
+ }
+
+ inline void set_credit_link(CreditLink_d *credit_link)
+ {
+ m_credit_link = credit_link;
+ }
+
+ inline double get_buf_read_count()
+ {
+ return m_num_buffer_reads;
+ }
+
+ inline double get_buf_write_count()
+ {
+ return m_num_buffer_writes;
+ }
+
+private:
+ int m_id;
+ int m_num_vcs;
+ double m_num_buffer_writes, m_num_buffer_reads;
+
+ Router_d *m_router;
+ NetworkLink_d *m_in_link;
+ CreditLink_d *m_credit_link;
+ flitBuffer_d *creditQueue;
+
+ // Virtual channels
+ Vector<VirtualChannel_d *> m_vcs; // [vc]
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh
new file mode 100644
index 000000000..6a212ce99
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkHeader.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef NETWORK_HEADER_H
+#define NETWORK_HEADER_H
+
+#include "Global.hh"
+#include "NodeID.hh"
+
+using namespace std;
+using namespace __gnu_cxx;
+
+enum flit_type {HEAD_, BODY_, TAIL_, HEAD_TAIL_, NUM_FLIT_TYPE_};
+enum VC_state_type {IDLE_, VC_AB_, ACTIVE_, NUM_VC_STATE_TYPE_};
+enum flit_stage {I_, VA_, SA_, ST_, LT_, NUM_FLIT_STAGE_};
+
+#define NETCONFIG_DEFAULTS "netconfig.defaults"
+
+#define INFINITE_ 10000
+
+#endif
+
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
new file mode 100644
index 000000000..edf2d4b95
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkInterface_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "NetworkInterface_d.hh"
+#include "MessageBuffer.hh"
+#include "flitBuffer_d.hh"
+#include "NetworkMessage.hh"
+
+NetworkInterface_d::NetworkInterface_d(int id, int virtual_networks, GarnetNetwork_d *network_ptr)
+{
+ m_id = id;
+ m_net_ptr = network_ptr;
+ m_virtual_networks = virtual_networks;
+ m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_num_vcs = m_vc_per_vnet*m_virtual_networks;
+
+ m_vc_round_robin = 0;
+ m_ni_buffers.setSize(m_num_vcs);
+ m_ni_enqueue_time.setSize(m_num_vcs);
+ inNode_ptr.setSize(m_virtual_networks);
+ outNode_ptr.setSize(m_virtual_networks);
+ creditQueue = new flitBuffer_d();
+
+ for(int i =0; i < m_num_vcs; i++)
+ {
+ m_ni_buffers[i] = new flitBuffer_d(); // instantiating the NI flit buffers
+ m_ni_enqueue_time[i] = INFINITE_;
+ }
+ m_vc_allocator.setSize(m_virtual_networks); // 1 allocator per virtual net
+ for(int i = 0; i < m_virtual_networks; i++)
+ {
+ m_vc_allocator[i] = 0;
+ }
+
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ m_out_vc_state.insertAtBottom(new OutVcState_d(i));
+ m_out_vc_state[i]->setState(IDLE_, g_eventQueue_ptr->getTime());
+ }
+}
+
+NetworkInterface_d::~NetworkInterface_d()
+{
+ m_out_vc_state.deletePointers();
+ m_ni_buffers.deletePointers();
+ delete creditQueue;
+ delete outSrcQueue;
+}
+
+void NetworkInterface_d::addInPort(NetworkLink_d *in_link, CreditLink_d *credit_link)
+{
+ inNetLink = in_link;
+ in_link->setLinkConsumer(this);
+ m_ni_credit_link = credit_link;
+ credit_link->setSourceQueue(creditQueue);
+}
+
+void NetworkInterface_d::addOutPort(NetworkLink_d *out_link, CreditLink_d *credit_link)
+{
+ m_credit_link = credit_link;
+ credit_link->setLinkConsumer(this);
+
+ outNetLink = out_link;
+ outSrcQueue = new flitBuffer_d();
+ out_link->setSourceQueue(outSrcQueue);
+}
+
+void NetworkInterface_d::addNode(Vector<MessageBuffer*>& in, Vector<MessageBuffer*>& out)
+{
+ ASSERT(in.size() == m_virtual_networks);
+ inNode_ptr = in;
+ outNode_ptr = out;
+ for (int j = 0; j < m_virtual_networks; j++)
+ {
+ inNode_ptr[j]->setConsumer(this); // So that protocol injects messages into the NI
+ }
+}
+
+bool NetworkInterface_d::flitisizeMessage(MsgPtr msg_ptr, int vnet)
+{
+ NetworkMessage *net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
+ NetDest net_msg_dest = net_msg_ptr->getInternalDestination();
+ Vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); // gets all the destinations associated with this message.
+
+ int num_flits = (int) ceil((double) MessageSizeType_to_int(net_msg_ptr->getMessageSize())/NetworkConfig::getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
+
+ for(int ctr = 0; ctr < dest_nodes.size(); ctr++) // loop because we will be converting all multicast messages into unicast messages
+ {
+ int vc = calculateVC(vnet); // this will return a free output virtual channel
+ if(vc == -1)
+ {
+ return false ;
+ }
+ MsgPtr new_msg_ptr = *(msg_ptr.ref());
+ NodeID destID = dest_nodes[ctr];
+
+ NetworkMessage *new_net_msg_ptr = dynamic_cast<NetworkMessage*>(new_msg_ptr.ref());
+ if(dest_nodes.size() > 1)
+ {
+ NetDest personal_dest;
+ for(int m = 0; m < (int) MachineType_NUM; m++)
+ {
+ if((destID >= MachineType_base_number((MachineType) m)) && destID < MachineType_base_number((MachineType) (m+1)))
+ {
+ // calculating the NetDest associated with this destination ID
+ personal_dest.clear();
+ personal_dest.add((MachineID) {(MachineType) m, (destID - MachineType_base_number((MachineType) m))});
+ new_net_msg_ptr->getInternalDestination() = personal_dest;
+ break;
+ }
+ }
+ net_msg_dest.removeNetDest(personal_dest);
+ net_msg_ptr->getInternalDestination().removeNetDest(personal_dest); // removing the destination from the original message to reflect that a message with this particular destination has been flitisized and an output vc is acquired
+ }
+ for(int i = 0; i < num_flits; i++)
+ {
+ m_net_ptr->increment_injected_flits();
+ flit_d *fl = new flit_d(i, vc, vnet, num_flits, new_msg_ptr);
+ fl->set_delay(g_eventQueue_ptr->getTime() - (msg_ptr.ref())->getTime());
+ m_ni_buffers[vc]->insert(fl);
+ }
+ m_ni_enqueue_time[vc] = g_eventQueue_ptr->getTime();
+ m_out_vc_state[vc]->setState(ACTIVE_, g_eventQueue_ptr->getTime());
+ }
+ return true ;
+}
+
+// Looking for a free output vc
+int NetworkInterface_d::calculateVC(int vnet)
+{
+ for(int i = 0; i < m_vc_per_vnet; i++)
+ {
+ int delta = m_vc_allocator[vnet];
+ m_vc_allocator[vnet]++;
+ if(m_vc_allocator[vnet] == m_vc_per_vnet)
+ m_vc_allocator[vnet] = 0;
+
+ if(m_out_vc_state[(vnet*m_vc_per_vnet) + delta]->isInState(IDLE_, g_eventQueue_ptr->getTime()))
+ {
+ return ((vnet*m_vc_per_vnet) + delta);
+ }
+ }
+ return -1;
+}
+
+/*
+ * The NI wakeup checks whether there are any ready messages in the protocol buffer. If yes,
+ * it picks that up, flitisizes it into a number of flits and puts it into an output buffer
+ * and schedules the output link. On a wakeup it also checks whether there are flits in the
+ * input link. If yes, it picks them up and if the flit is a tail, the NI inserts the
+ * corresponding message into the protocol buffer. It also checks for credits being sent
+ * by the downstream router.
+ */
+
+void NetworkInterface_d::wakeup()
+{
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, m_id);
+ DEBUG_MSG(NETWORK_COMP, MedPrio, "NI WOKE UP");
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, g_eventQueue_ptr->getTime());
+
+ MsgPtr msg_ptr;
+
+ //Checking for messages coming from the protocol
+ for (int vnet = 0; vnet < m_virtual_networks; vnet++) // can pick up a message/cycle for each virtual net
+ {
+ while(inNode_ptr[vnet]->isReady()) // Is there a message waiting
+ {
+ msg_ptr = inNode_ptr[vnet]->peekMsgPtr();
+ if(flitisizeMessage(msg_ptr, vnet))
+ {
+ inNode_ptr[vnet]->pop();
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ scheduleOutputLink();
+ checkReschedule();
+
+/*********** Picking messages destined for this NI **********/
+
+ if(inNetLink->isReady())
+ {
+ flit_d *t_flit = inNetLink->consumeLink();
+ bool free_signal = false;
+ if(t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_)
+ {
+ free_signal = true;
+ if(!NetworkConfig::isNetworkTesting()) // When we are doing network only testing, the messages do not have to be buffered into the message buffers
+ {
+ outNode_ptr[t_flit->get_vnet()]->enqueue(t_flit->get_msg_ptr(), 1); // enqueueing for protocol buffer. This is not required when doing network only testing
+ }
+ }
+ flit_d *credit_flit = new flit_d(t_flit->get_vc(), free_signal); // Simply send a credit back since we are not buddering this flit in the NI
+ creditQueue->insert(credit_flit);
+ g_eventQueue_ptr->scheduleEvent(m_ni_credit_link, 1);
+
+ m_net_ptr->increment_recieved_flits();
+ int network_delay = g_eventQueue_ptr->getTime() - t_flit->get_enqueue_time();
+ int queueing_delay = t_flit->get_delay();
+ m_net_ptr->increment_network_latency(network_delay);
+ m_net_ptr->increment_queueing_latency(queueing_delay);
+ delete t_flit;
+ }
+
+ /****************** Checking for credit link *******/
+
+ if(m_credit_link->isReady())
+ {
+ flit_d *t_flit = m_credit_link->consumeLink();
+ m_out_vc_state[t_flit->get_vc()]->increment_credit();
+ if(t_flit->is_free_signal())
+ {
+ m_out_vc_state[t_flit->get_vc()]->setState(IDLE_, g_eventQueue_ptr->getTime());
+ }
+ delete t_flit;
+ }
+}
+
+// This function look at the NI buffers and if some buffer has flits which are ready to traverse the link in the next cycle and also the downstream output vc associated with this flit has buffers left, the link is scheduled for the next cycle
+
+void NetworkInterface_d::scheduleOutputLink()
+{
+ int vc = m_vc_round_robin;
+ m_vc_round_robin++;
+ if(m_vc_round_robin == m_num_vcs)
+ m_vc_round_robin = 0;
+
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ vc++;
+ if(vc == m_num_vcs)
+ vc = 0;
+ if(m_ni_buffers[vc]->isReady() && m_out_vc_state[vc]->has_credits()) // models buffer backpressure
+ {
+ bool is_candidate_vc = true;
+ int t_vnet = get_vnet(vc);
+ int vc_base = t_vnet * m_vc_per_vnet;
+
+ if(m_net_ptr->isVNetOrdered(t_vnet))
+ {
+ for (int vc_offset = 0; vc_offset < m_vc_per_vnet; vc_offset++)
+ {
+ int t_vc = vc_base + vc_offset;
+ if(m_ni_buffers[t_vc]->isReady())
+ {
+ if(m_ni_enqueue_time[t_vc] < m_ni_enqueue_time[vc])
+ {
+ is_candidate_vc = false;
+ break;
+ }
+ }
+ }
+ }
+ if(!is_candidate_vc)
+ continue;
+
+ m_out_vc_state[vc]->decrement_credit();
+ flit_d *t_flit = m_ni_buffers[vc]->getTopFlit(); // Just removing the flit
+ t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
+ outSrcQueue->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(outNetLink, 1); // schedule the out link
+
+ if(t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_)
+ {
+ m_ni_enqueue_time[vc] = INFINITE_;
+ }
+ return;
+ }
+ }
+}
+
+int NetworkInterface_d::get_vnet(int vc)
+{
+ for(int i = 0; i < NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ {
+ if(vc >= (i*m_vc_per_vnet) && vc < ((i+1)*m_vc_per_vnet))
+ {
+ return i;
+ }
+ }
+ ERROR_MSG("Could not determine vc");
+ return -1;
+}
+
+void NetworkInterface_d::checkReschedule()
+{
+ for(int vnet = 0; vnet < m_virtual_networks; vnet++)
+ {
+ if(inNode_ptr[vnet]->isReady()) // Is there a message waiting
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+ for(int vc = 0; vc < m_num_vcs; vc++)
+ {
+ if(m_ni_buffers[vc]->isReadyForNext())
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+}
+
+void NetworkInterface_d::printConfig(ostream& out) const
+{
+ out << "[Network Interface " << m_id << "] - ";
+ out << "[inLink " << inNetLink->get_id() << "] - ";
+ out << "[outLink " << outNetLink->get_id() << "]" << endl;
+}
+
+void NetworkInterface_d::print(ostream& out) const
+{
+ out << "[Network Interface]";
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh
new file mode 100644
index 000000000..c776d343c
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkInterface_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef NET_INTERFACE_D_H
+#define NET_INTERFACE_D_H
+
+#include "NetworkHeader.hh"
+#include "GarnetNetwork_d.hh"
+#include "Vector.hh"
+#include "Consumer.hh"
+#include "Message.hh"
+#include "NetworkLink_d.hh"
+#include "CreditLink_d.hh"
+#include "OutVcState_d.hh"
+
+class NetworkMessage;
+class MessageBuffer;
+class flitBuffer_d;
+
+class NetworkInterface_d : public Consumer {
+public:
+ NetworkInterface_d(int id, int virtual_networks, GarnetNetwork_d* network_ptr);
+
+ ~NetworkInterface_d();
+
+ void addInPort(NetworkLink_d *in_link, CreditLink_d *credit_link);
+ void addOutPort(NetworkLink_d *out_link, CreditLink_d *credit_link);
+
+ void wakeup();
+ void addNode(Vector<MessageBuffer *> &inNode, Vector<MessageBuffer *> &outNode);
+ void printConfig(ostream& out) const;
+ void print(ostream& out) const;
+ int get_vnet(int vc);
+
+private:
+/**************Data Members*************/
+ GarnetNetwork_d *m_net_ptr;
+ int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
+ NodeID m_id;
+ Vector<OutVcState_d *> m_out_vc_state;
+ Vector<int > m_vc_allocator;
+ int m_vc_round_robin; // For round robin scheduling
+ flitBuffer_d *outSrcQueue; // For modelling link contention
+ flitBuffer_d *creditQueue;
+
+ NetworkLink_d *inNetLink;
+ NetworkLink_d *outNetLink;
+ CreditLink_d *m_credit_link;
+ CreditLink_d *m_ni_credit_link;
+
+ // Input Flit Buffers
+ Vector<flitBuffer_d *> m_ni_buffers; // The flit buffers which will serve the Consumer
+ Vector<Time > m_ni_enqueue_time;
+
+ Vector<MessageBuffer *> inNode_ptr; // The Message buffers that takes messages from the protocol
+ Vector<MessageBuffer *> outNode_ptr; // The Message buffers that provides messages to the protocol
+
+ bool flitisizeMessage(MsgPtr msg_ptr, int vnet);
+ int calculateVC(int vnet);
+ void scheduleOutputLink();
+ void checkReschedule();
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
new file mode 100644
index 000000000..26794ebf2
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkLink_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "NetworkLink_d.hh"
+#include "NetworkConfig.hh"
+#include "GarnetNetwork_d.hh"
+
+NetworkLink_d::NetworkLink_d(int id)
+{
+ m_id = id;
+ m_latency = 1;
+ m_flit_width = NetworkConfig::getFlitSize();
+
+ linkBuffer = new flitBuffer_d();
+ m_link_utilized = 0;
+ m_vc_load.setSize(NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS);
+
+ for(int i = 0; i < NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ m_vc_load[i] = 0;
+}
+
+NetworkLink_d::NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr)
+{
+ m_net_ptr = net_ptr;
+ m_id = id;
+ m_latency = link_latency;
+ linkBuffer = new flitBuffer_d();
+ m_link_utilized = 0;
+ m_vc_load.setSize(NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS);
+
+ for(int i = 0; i < NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ m_vc_load[i] = 0;
+}
+
+NetworkLink_d::~NetworkLink_d()
+{
+ delete linkBuffer;
+}
+
+void NetworkLink_d::setLinkConsumer(Consumer *consumer)
+{
+ link_consumer = consumer;
+}
+
+void NetworkLink_d::setSourceQueue(flitBuffer_d *srcQueue)
+{
+ link_srcQueue = srcQueue;
+}
+
+void NetworkLink_d::wakeup()
+{
+ if(link_srcQueue->isReady())
+ {
+ flit_d *t_flit = link_srcQueue->getTopFlit();
+ t_flit->set_time(g_eventQueue_ptr->getTime() + m_latency);
+ linkBuffer->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(link_consumer, m_latency);
+ m_link_utilized++;
+ m_vc_load[t_flit->get_vc()]++;
+ }
+}
+
+Vector<int> NetworkLink_d::getVcLoad()
+{
+ return m_vc_load;
+}
+
+int NetworkLink_d::getLinkUtilization()
+{
+ return m_link_utilized;
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
new file mode 100644
index 000000000..40695331e
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkLink_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef NETWORK_LINK_D_H
+#define NETWORK_LINK_D_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+#include "flitBuffer_d.hh"
+#include "PrioHeap.hh"
+#include "power_bus.hh"
+
+class GarnetNetwork_d;
+
+class NetworkLink_d : public Consumer {
+public:
+ NetworkLink_d(int id);
+ ~NetworkLink_d();
+
+ NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr);
+ void setLinkConsumer(Consumer *consumer);
+ void setSourceQueue(flitBuffer_d *srcQueue);
+ void print(ostream& out) const{}
+ int getLinkUtilization();
+ Vector<int> getVcLoad();
+ int get_id(){return m_id;}
+ void wakeup();
+
+ double calculate_offline_power(power_bus*);
+ double calculate_power();
+
+ inline bool isReady()
+ {
+ return linkBuffer->isReady();
+ }
+ inline flit_d* peekLink()
+ {
+ return linkBuffer->peekTopFlit();
+ }
+ inline flit_d* consumeLink()
+ {
+ return linkBuffer->getTopFlit();
+ }
+
+protected:
+ int m_id;
+ int m_latency;
+ GarnetNetwork_d *m_net_ptr;
+
+ flitBuffer_d *linkBuffer;
+ Consumer *link_consumer;
+ flitBuffer_d *link_srcQueue;
+ int m_link_utilized;
+ Vector<int > m_vc_load;
+ int m_flit_width;
+};
+
+#endif
+
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
new file mode 100644
index 000000000..32cf8a51d
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * OutVCState_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "OutVcState_d.hh"
+#include "NetworkConfig.hh"
+#include "EventQueue.hh"
+
+OutVcState_d::OutVcState_d(int id)
+{
+ m_id = id;
+ m_vc_state = IDLE_;
+ m_time = g_eventQueue_ptr->getTime();
+ m_credit_count = NetworkConfig::getBufferSize();
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
new file mode 100644
index 000000000..8c07ec796
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * OutVCState_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef OUT_VC_STATE_D_H
+#define OUT_VC_STATE_D_H
+
+#include "NetworkHeader.hh"
+
+class OutVcState_d {
+public:
+ OutVcState_d(int id);
+
+ int get_inport() {return m_in_port; }
+ int get_invc() { return m_in_vc; }
+ int get_credit_count() {return m_credit_count; }
+ void set_inport(int port) {m_in_port = port; }
+ void set_invc(int vc) {m_in_vc = vc; }
+
+ inline bool isInState(VC_state_type state, Time request_time)
+ {
+ return ((m_vc_state == state) && (request_time >= m_time) );
+ }
+
+ inline void setState(VC_state_type state, Time time)
+ {
+ m_vc_state = state;
+ m_time = time;
+ }
+
+ inline bool has_credits()
+ {
+ return (m_credit_count > 0);
+ }
+
+ inline void increment_credit()
+ {
+ m_credit_count++;
+ }
+
+ inline void decrement_credit()
+ {
+ m_credit_count--;
+ }
+
+private:
+ int m_id ;
+ Time m_time;
+ VC_state_type m_vc_state;
+ int m_in_port;
+ int m_in_vc;
+ int m_credit_count;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
new file mode 100644
index 000000000..43096c314
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * OutputUnit_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "OutputUnit_d.hh"
+#include "Router_d.hh"
+#include "NetworkConfig.hh"
+
+OutputUnit_d::OutputUnit_d(int id, Router_d *router)
+{
+ m_id = id;
+ m_router = router;
+ m_num_vcs = m_router->get_num_vcs();
+ m_out_buffer = new flitBuffer_d();
+
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ m_outvc_state.insertAtBottom(new OutVcState_d(i));
+ }
+}
+
+OutputUnit_d::~OutputUnit_d()
+{
+ delete m_out_buffer;
+ m_outvc_state.deletePointers();
+}
+
+void OutputUnit_d::decrement_credit(int out_vc)
+{
+ m_outvc_state[out_vc]->decrement_credit();
+ m_router->update_incredit(m_outvc_state[out_vc]->get_inport(), m_outvc_state[out_vc]->get_invc(), m_outvc_state[out_vc]->get_credit_count());
+}
+
+void OutputUnit_d::wakeup()
+{
+ if(m_credit_link->isReady())
+ {
+ flit_d *t_flit = m_credit_link->consumeLink();
+ int out_vc = t_flit->get_vc();
+ m_outvc_state[out_vc]->increment_credit();
+ m_router->update_incredit(m_outvc_state[out_vc]->get_inport(), m_outvc_state[out_vc]->get_invc(), m_outvc_state[out_vc]->get_credit_count());
+
+ if(t_flit->is_free_signal())
+ set_vc_state(IDLE_, out_vc);
+
+ delete t_flit;
+ }
+}
+
+flitBuffer_d* OutputUnit_d::getOutQueue()
+{
+ return m_out_buffer;
+}
+
+void OutputUnit_d::set_out_link(NetworkLink_d *link)
+{
+ m_out_link = link;
+}
+
+void OutputUnit_d::set_credit_link(CreditLink_d *credit_link)
+{
+ m_credit_link = credit_link;
+}
+
+void OutputUnit_d::update_vc(int vc, int in_port, int in_vc)
+{
+ m_outvc_state[vc]->setState(ACTIVE_, g_eventQueue_ptr->getTime() + 1);
+ m_outvc_state[vc]->set_inport(in_port);
+ m_outvc_state[vc]->set_invc(in_vc);
+ m_router->update_incredit(in_port, in_vc, m_outvc_state[vc]->get_credit_count());
+}
+
+void OutputUnit_d::printConfig(ostream& out)
+{
+ out << endl;
+ out << "OutputUnit Configuration" << endl;
+ out << "---------------------" << endl;
+ out << "id = " << m_id << endl;
+ out << "Out link is " << m_out_link->get_id() << endl;
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh
new file mode 100644
index 000000000..f23c06559
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * OutputUnit_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef OUTPUT_UNIT_D_H
+#define OUTPUT_UNIT_D_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+#include "flitBuffer_d.hh"
+#include "OutVcState_d.hh"
+#include "NetworkLink_d.hh"
+#include "CreditLink_d.hh"
+
+class Router_d;
+
+class OutputUnit_d : public Consumer {
+public:
+ OutputUnit_d(int id, Router_d *router);
+ ~OutputUnit_d();
+ void set_out_link(NetworkLink_d *link);
+ void set_credit_link(CreditLink_d *credit_link);
+ void wakeup();
+ flitBuffer_d* getOutQueue();
+ void printConfig(ostream& out);
+ void update_vc(int vc, int in_port, int in_vc);
+ void print(ostream& out) const {};
+ int get_credit_cnt(int vc) { return m_outvc_state[vc]->get_credit_count(); }
+ void decrement_credit(int out_vc);
+
+ inline int get_outlink_id()
+ {
+ return m_out_link->get_id();
+ }
+
+ inline void set_vc_state(VC_state_type state, int vc)
+ {
+ m_outvc_state[vc]->setState(state, g_eventQueue_ptr->getTime() + 1);
+ }
+ inline bool is_vc_idle(int vc)
+ {
+ return (m_outvc_state[vc]->isInState(IDLE_, g_eventQueue_ptr->getTime()) );
+ }
+ inline void insert_flit(flit_d *t_flit)
+ {
+ m_out_buffer->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(m_out_link, 1);
+ }
+
+
+
+private:
+ int m_id;
+ int m_num_vcs;
+ Router_d *m_router;
+ NetworkLink_d *m_out_link;
+ CreditLink_d *m_credit_link;
+
+ flitBuffer_d *m_out_buffer; // This is for the network link to consume
+ Vector<OutVcState_d *> m_outvc_state; // vc state of downstream router
+
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
new file mode 100644
index 000000000..4f61487c7
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Router_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "Router_d.hh"
+#include "GarnetNetwork_d.hh"
+#include "NetworkLink_d.hh"
+#include "CreditLink_d.hh"
+#include "InputUnit_d.hh"
+#include "OutputUnit_d.hh"
+#include "RoutingUnit_d.hh"
+#include "VCallocator_d.hh"
+#include "SWallocator_d.hh"
+#include "Switch_d.hh"
+
+Router_d::Router_d(int id, GarnetNetwork_d *network_ptr)
+{
+ m_id = id;
+ m_network_ptr = network_ptr;
+ m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS;
+ m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_num_vcs = m_virtual_networks*m_vc_per_vnet;
+ m_flit_width = NetworkConfig::getFlitSize();
+
+ m_routing_unit = new RoutingUnit_d(this);
+ m_vc_alloc = new VCallocator_d(this);
+ m_sw_alloc = new SWallocator_d(this);
+ m_switch = new Switch_d(this);
+
+ m_input_unit.clear();
+ m_output_unit.clear();
+
+ buf_read_count = 0;
+ buf_write_count = 0;
+ crossbar_count = 0;
+ vc_local_arbit_count = 0;
+ vc_global_arbit_count = 0;
+ sw_local_arbit_count = 0;
+ sw_global_arbit_count = 0;
+}
+
+Router_d::~Router_d()
+{
+ m_input_unit.deletePointers();
+ m_output_unit.deletePointers();
+ delete m_routing_unit;
+ delete m_vc_alloc;
+ delete m_sw_alloc;
+ delete m_switch;
+}
+
+void Router_d::init()
+{
+ m_vc_alloc->init();
+ m_sw_alloc->init();
+ m_switch->init();
+}
+
+void Router_d::addInPort(NetworkLink_d *in_link, CreditLink_d *credit_link)
+{
+ int port_num = m_input_unit.size();
+ InputUnit_d *input_unit = new InputUnit_d(port_num, this);
+
+ input_unit->set_in_link(in_link);
+ input_unit->set_credit_link(credit_link);
+ in_link->setLinkConsumer(input_unit);
+ credit_link->setSourceQueue(input_unit->getCreditQueue());
+
+ m_input_unit.insertAtBottom(input_unit);
+}
+
+void Router_d::addOutPort(NetworkLink_d *out_link, const NetDest& routing_table_entry, int link_weight, CreditLink_d *credit_link)
+{
+ int port_num = m_output_unit.size();
+ OutputUnit_d *output_unit = new OutputUnit_d(port_num, this);
+
+ output_unit->set_out_link(out_link);
+ output_unit->set_credit_link(credit_link);
+ credit_link->setLinkConsumer(output_unit);
+ out_link->setSourceQueue(output_unit->getOutQueue());
+
+ m_output_unit.insertAtBottom(output_unit);
+
+ m_routing_unit->addRoute(routing_table_entry);
+ m_routing_unit->addWeight(link_weight);
+}
+
+void Router_d::route_req(flit_d *t_flit, InputUnit_d *in_unit, int invc)
+{
+ m_routing_unit->RC_stage(t_flit, in_unit, invc);
+}
+void Router_d::vcarb_req()
+{
+ g_eventQueue_ptr->scheduleEvent(m_vc_alloc, 1);
+}
+void Router_d::swarb_req()
+{
+ g_eventQueue_ptr->scheduleEvent(m_sw_alloc, 1);
+}
+void Router_d::update_incredit(int in_port, int in_vc, int credit)
+{
+ m_input_unit[in_port]->update_credit(in_vc, credit);
+}
+void Router_d::update_sw_winner(int inport, flit_d *t_flit)
+{
+ m_switch->update_sw_winner(inport, t_flit);
+ g_eventQueue_ptr->scheduleEvent(m_switch, 1);
+}
+
+void Router_d::calculate_performance_numbers()
+{
+ for(int i = 0; i < m_input_unit.size(); i++)
+ {
+ buf_read_count += m_input_unit[i]->get_buf_read_count();
+ buf_write_count += m_input_unit[i]->get_buf_write_count();
+ }
+ crossbar_count = m_switch->get_crossbar_count();
+ vc_local_arbit_count = m_vc_alloc->get_local_arbit_count();
+ vc_global_arbit_count = m_vc_alloc->get_global_arbit_count();
+ sw_local_arbit_count = m_sw_alloc->get_local_arbit_count();
+ sw_global_arbit_count = m_sw_alloc->get_global_arbit_count();
+}
+
+void Router_d::printConfig(ostream& out)
+{
+ out << "[Router " << m_id << "] :: " << endl;
+ out << "[inLink - ";
+ for(int i = 0;i < m_input_unit.size(); i++)
+ out << m_input_unit[i]->get_inlink_id() << " - ";
+ out << "]" << endl;
+ out << "[outLink - ";
+ for(int i = 0;i < m_output_unit.size(); i++)
+ out << m_output_unit[i]->get_outlink_id() << " - ";
+ out << "]" << endl;
+}
+
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh
new file mode 100644
index 000000000..215055ea6
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Router_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+#ifndef ROUTER_D_H
+#define ROUTER_D_H
+
+#include "NetworkHeader.hh"
+#include "Vector.hh"
+#include "flit_d.hh"
+#include "NetDest.hh"
+#include "power_router_init.hh"
+
+class GarnetNetwork_d;
+class NetworkLink_d;
+class CreditLink_d;
+class InputUnit_d;
+class OutputUnit_d;
+class RoutingUnit_d;
+class VCallocator_d;
+class SWallocator_d;
+class Switch_d;
+
+class Router_d {
+public:
+ Router_d(int id, GarnetNetwork_d *network_ptr);
+
+ ~Router_d();
+
+ void init();
+ void addInPort(NetworkLink_d *link, CreditLink_d *credit_link);
+ void addOutPort(NetworkLink_d *link, const NetDest& routing_table_entry, int link_weight, CreditLink_d *credit_link);
+ int get_num_vcs() { return m_num_vcs; }
+ int get_vc_per_vnet() {return m_vc_per_vnet; }
+ int get_num_inports() { return m_input_unit.size(); }
+ int get_num_outports() { return m_output_unit.size(); }
+ void printConfig(ostream& out);
+ int get_id() { return m_id; }
+ GarnetNetwork_d* get_net_ptr() { return m_network_ptr; }
+
+ Vector<InputUnit_d *>& get_inputUnit_ref() { return m_input_unit; }
+ Vector<OutputUnit_d *>& get_outputUnit_ref() { return m_output_unit; }
+
+ void update_sw_winner(int inport, flit_d *t_flit);
+ void update_incredit(int in_port, int in_vc, int credit);
+ void route_req(flit_d *t_flit, InputUnit_d* in_unit, int invc);
+ void vcarb_req();
+ void swarb_req();
+
+ void power_router_initialize(power_router *router, power_router_info *info);
+ double calculate_power();
+ double calculate_offline_power(power_router*, power_router_info*);
+ void calculate_performance_numbers();
+
+private:
+ int m_id;
+ int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
+ GarnetNetwork_d *m_network_ptr;
+ int m_flit_width;
+
+ double buf_read_count, buf_write_count, crossbar_count, vc_local_arbit_count, vc_global_arbit_count, sw_local_arbit_count, sw_global_arbit_count;
+
+ Vector<InputUnit_d *> m_input_unit;
+ Vector<OutputUnit_d *> m_output_unit;
+ RoutingUnit_d *m_routing_unit;
+ VCallocator_d *m_vc_alloc;
+ SWallocator_d *m_sw_alloc;
+ Switch_d *m_switch;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc
new file mode 100644
index 000000000..ccced1d05
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Routingunit_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "RoutingUnit_d.hh"
+#include "Router_d.hh"
+#include "InputUnit_d.hh"
+#include "NetworkMessage.hh"
+
+RoutingUnit_d::RoutingUnit_d(Router_d *router)
+{
+ m_router = router;
+ m_routing_table.clear();
+ m_weight_table.clear();
+}
+
+void RoutingUnit_d::addRoute(const NetDest& routing_table_entry)
+{
+ m_routing_table.insertAtBottom(routing_table_entry);
+}
+
+void RoutingUnit_d::addWeight(int link_weight)
+{
+ m_weight_table.insertAtBottom(link_weight);
+}
+
+void RoutingUnit_d::RC_stage(flit_d *t_flit, InputUnit_d *in_unit, int invc)
+{
+ int outport = routeCompute(t_flit);
+ in_unit->updateRoute(invc, outport);
+ t_flit->advance_stage(VA_);
+ m_router->vcarb_req();
+}
+
+int RoutingUnit_d::routeCompute(flit_d *t_flit)
+{
+ MsgPtr msg_ptr = t_flit->get_msg_ptr();
+ NetworkMessage* net_msg_ptr = NULL;
+ net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
+ NetDest msg_destination = net_msg_ptr->getInternalDestination();
+
+ int output_link = -1;
+ int min_weight = INFINITE_;
+
+ for(int link = 0; link < m_routing_table.size(); link++)
+ {
+ if (msg_destination.intersectionIsNotEmpty(m_routing_table[link]))
+ {
+ if(m_weight_table[link] >= min_weight)
+ continue;
+ output_link = link;
+ min_weight = m_weight_table[link];
+ }
+ }
+ if(output_link == -1)
+ {
+ ERROR_MSG("Fatal Error:: No Route exists from this Router.");
+ exit(0);
+ }
+ return output_link;
+
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh
new file mode 100644
index 000000000..f6eb9f906
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Routerunit_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef ROUTING_UNIT_D_H
+#define ROUTING_UNIT_D_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+#include "flit_d.hh"
+#include "NetDest.hh"
+
+class InputUnit_d;
+class Router_d;
+
+class RoutingUnit_d {
+public:
+ RoutingUnit_d(Router_d *router);
+ void addRoute(const NetDest& routing_table_entry);
+ int routeCompute(flit_d *t_flit);
+ void addWeight(int link_weight);
+ void RC_stage(flit_d *t_flit, InputUnit_d *in_unit, int invc);
+
+private:
+ Router_d *m_router;
+ Vector<NetDest > m_routing_table;
+ Vector<int > m_weight_table;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
new file mode 100644
index 000000000..7f6507047
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * SWallocator_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "SWallocator_d.hh"
+#include "Router_d.hh"
+#include "InputUnit_d.hh"
+#include "OutputUnit_d.hh"
+#include "GarnetNetwork_d.hh"
+
+SWallocator_d::SWallocator_d(Router_d *router)
+{
+ m_router = router;
+ m_num_vcs = m_router->get_num_vcs();
+ m_vc_per_vnet = m_router->get_vc_per_vnet();
+
+ m_local_arbiter_activity = 0;
+ m_global_arbiter_activity = 0;
+}
+
+void SWallocator_d::init()
+{
+ m_input_unit = m_router->get_inputUnit_ref();
+ m_output_unit = m_router->get_outputUnit_ref();
+
+ m_num_inports = m_router->get_num_inports();
+ m_num_outports = m_router->get_num_outports();
+ m_round_robin_outport.setSize(m_num_outports);
+ m_round_robin_inport.setSize(m_num_inports);
+ m_port_req.setSize(m_num_outports);
+ m_vc_winners.setSize(m_num_outports);
+
+ for(int i = 0; i < m_num_inports; i++)
+ {
+ m_round_robin_inport[i] = 0;
+ }
+
+ for(int i = 0; i < m_num_outports; i++)
+ {
+ m_port_req[i].setSize(m_num_inports);
+ m_vc_winners[i].setSize(m_num_inports);
+
+ m_round_robin_outport[i] = 0;
+
+ for(int j = 0; j < m_num_inports; j++)
+ {
+ m_port_req[i][j] = false; // [outport][inport]
+ }
+ }
+}
+
+void SWallocator_d::wakeup()
+{
+ arbitrate_inports(); // First stage of allocation
+ arbitrate_outports(); // Second stage of allocation
+
+ clear_request_vector();
+ check_for_wakeup();
+
+}
+
+void SWallocator_d::arbitrate_inports()
+{
+ // First I will do round robin arbitration on a set of input vc requests
+ for(int inport = 0; inport < m_num_inports; inport++)
+ {
+ int invc = m_round_robin_inport[inport];
+ m_round_robin_inport[inport]++;
+
+ if(m_round_robin_inport[inport] >= m_num_vcs)
+ m_round_robin_inport[inport] = 0;
+ for(int j = 0; j < m_num_vcs; j++)
+ {
+ invc++;
+ if(invc >= m_num_vcs)
+ invc = 0;
+ if(m_input_unit[inport]->need_stage(invc, ACTIVE_, SA_) && m_input_unit[inport]->has_credits(invc))
+ {
+ if(is_candidate_inport(inport, invc))
+ {
+ int outport = m_input_unit[inport]->get_route(invc);
+ m_local_arbiter_activity++;
+ m_port_req[outport][inport] = true;
+ m_vc_winners[outport][inport]= invc;
+ break; // got one vc winner for this port
+ }
+ }
+ }
+ }
+}
+
+bool SWallocator_d::is_candidate_inport(int inport, int invc)
+{
+ int outport = m_input_unit[inport]->get_route(invc);
+ int t_enqueue_time = m_input_unit[inport]->get_enqueue_time(invc);
+ int t_vnet = get_vnet(invc);
+ int vc_base = t_vnet*m_vc_per_vnet;
+ if((m_router->get_net_ptr())->isVNetOrdered(t_vnet))
+ {
+ for(int vc_offset = 0; vc_offset < m_vc_per_vnet; vc_offset++)
+ {
+ int temp_vc = vc_base + vc_offset;
+ if(m_input_unit[inport]->need_stage(temp_vc, ACTIVE_, SA_) && (m_input_unit[inport]->get_route(temp_vc) == outport) && (m_input_unit[inport]->get_enqueue_time(temp_vc) < t_enqueue_time))
+ {
+ return false;
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+
+void SWallocator_d::arbitrate_outports()
+{
+// now I have a set of input vc requests for output vcs. Again do round robin arbitration on these requests
+ for(int outport = 0; outport < m_num_outports; outport++)
+ {
+ int in_port = m_round_robin_outport[outport];
+ m_round_robin_outport[outport]++;
+
+ if(m_round_robin_outport[outport] >= m_num_outports)
+ m_round_robin_outport[outport] = 0;
+
+ for(int inport = 0; inport < m_num_inports; inport++)
+ {
+ in_port++;
+ if(in_port >= m_num_inports)
+ in_port = 0;
+ if(m_port_req[outport][in_port]) // This Inport has a request this cycle for this port
+ {
+ m_port_req[outport][in_port] = false;
+ int invc = m_vc_winners[outport][in_port];
+ int outvc = m_input_unit[in_port]->get_outvc(invc);
+ flit_d *t_flit = m_input_unit[in_port]->getTopFlit(invc); // removes flit from Input Unit
+ t_flit->advance_stage(ST_);
+ t_flit->set_vc(outvc);
+ t_flit->set_outport(outport);
+ t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
+ m_output_unit[outport]->decrement_credit(outvc);
+ m_router->update_sw_winner(in_port, t_flit);
+ m_global_arbiter_activity++;
+
+ if((t_flit->get_type() == TAIL_) || t_flit->get_type() == HEAD_TAIL_)
+ {
+ m_input_unit[in_port]->increment_credit(invc, true); // Send a credit back along with the information that this VC is not idle
+ assert(m_input_unit[in_port]->isReady(invc) == false); // This Input VC should now be empty
+
+ m_input_unit[in_port]->set_vc_state(IDLE_, invc);
+ m_input_unit[in_port]->set_enqueue_time(invc, INFINITE_);
+ }
+ else
+ {
+ m_input_unit[in_port]->increment_credit(invc, false); // Send a credit back but do not indicate that the VC is idle
+ }
+ break; // got a in request for this outport
+ }
+ }
+ }
+}
+
+void SWallocator_d::check_for_wakeup()
+{
+ for(int i = 0; i < m_num_inports; i++)
+ {
+ for(int j = 0; j < m_num_vcs; j++)
+ {
+ if(m_input_unit[i]->need_stage_nextcycle(j, ACTIVE_, SA_))
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+ }
+}
+
+int SWallocator_d::get_vnet(int invc)
+{
+ for(int i = 0; i < NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ {
+ if(invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet))
+ {
+ return i;
+ }
+ }
+ ERROR_MSG("Could not determine vc");
+ return -1;
+}
+
+void SWallocator_d::clear_request_vector()
+{
+ for(int i = 0; i < m_num_outports; i++)
+ {
+ for(int j = 0; j < m_num_inports; j++)
+ {
+ m_port_req[i][j] = false;
+ }
+ }
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh
new file mode 100644
index 000000000..ed8389650
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * SWallocator_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef SW_ALLOCATOR_D_H
+#define SW_ALLOCATOR_D_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+
+class Router_d;
+class InputUnit_d;
+class OutputUnit_d;
+
+class SWallocator_d : public Consumer {
+public:
+ SWallocator_d(Router_d *router);
+ void wakeup();
+ void init();
+ void clear_request_vector();
+ void check_for_wakeup();
+ int get_vnet (int invc);
+ void print(ostream& out) const {};
+ void arbitrate_inports();
+ void arbitrate_outports();
+ bool is_candidate_inport(int inport, int invc);
+ inline double get_local_arbit_count()
+ {
+ return m_local_arbiter_activity;
+ }
+ inline double get_global_arbit_count()
+ {
+ return m_global_arbiter_activity;
+ }
+
+private:
+ int m_num_inports, m_num_outports;
+ int m_num_vcs, m_vc_per_vnet;
+
+ double m_local_arbiter_activity, m_global_arbiter_activity;
+
+ Router_d *m_router;
+ Vector<int > m_round_robin_outport;
+ Vector<int > m_round_robin_inport;
+ Vector<Vector<bool > > m_port_req;
+ Vector<Vector<int > > m_vc_winners; // a list for each outport
+ Vector<InputUnit_d *> m_input_unit;
+ Vector<OutputUnit_d *> m_output_unit;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc
new file mode 100644
index 000000000..be5469696
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Switch_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "Switch_d.hh"
+#include "Router_d.hh"
+#include "OutputUnit_d.hh"
+
+Switch_d::Switch_d(Router_d *router)
+{
+ m_router = router;
+ m_num_vcs = m_router->get_num_vcs();
+ m_crossbar_activity = 0;
+}
+
+Switch_d::~Switch_d()
+{
+ m_switch_buffer.deletePointers();
+}
+
+void Switch_d::init()
+{
+ m_output_unit = m_router->get_outputUnit_ref();
+
+ m_num_inports = m_router->get_num_inports();
+ m_switch_buffer.setSize(m_num_inports);
+ for(int i = 0; i < m_num_inports; i++)
+ {
+ m_switch_buffer[i] = new flitBuffer_d();
+ }
+}
+
+void Switch_d::wakeup()
+{
+ DEBUG_MSG(NETWORK_COMP, HighPrio, "Switch woke up");
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, g_eventQueue_ptr->getTime());
+
+ for(int inport = 0; inport < m_num_inports; inport++)
+ {
+ if(!m_switch_buffer[inport]->isReady())
+ continue;
+ flit_d *t_flit = m_switch_buffer[inport]->peekTopFlit();
+ if(t_flit->is_stage(ST_))
+ {
+ int outport = t_flit->get_outport();
+ t_flit->advance_stage(LT_);
+ t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
+ m_output_unit[outport]->insert_flit(t_flit); // This will take care of waking up the Network Link
+ m_switch_buffer[inport]->getTopFlit();
+ m_crossbar_activity++;
+ }
+ }
+ check_for_wakeup();
+}
+
+void Switch_d::check_for_wakeup()
+{
+ for(int inport = 0; inport < m_num_inports; inport++)
+ {
+ if(m_switch_buffer[inport]->isReadyForNext())
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ break;
+ }
+ }
+}
+
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh
new file mode 100644
index 000000000..63f3995f5
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Switch_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef SWITCH_D_H
+#define SWITCH_D_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+#include "flitBuffer_d.hh"
+
+class Router_d;
+class OutputUnit_d;
+
+class Switch_d : public Consumer {
+public:
+ Switch_d(Router_d *router);
+ ~Switch_d();
+ void wakeup();
+ void init();
+ void check_for_wakeup();
+ void print(ostream& out) const {};
+ inline void update_sw_winner(int inport, flit_d *t_flit)
+ {
+ m_switch_buffer[inport]->insert(t_flit);
+ }
+ inline double get_crossbar_count()
+ {
+ return m_crossbar_activity;
+ }
+
+
+private:
+ int m_num_vcs;
+ int m_num_inports;
+ double m_crossbar_activity;
+ Router_d *m_router;
+ Vector<flitBuffer_d *> m_switch_buffer;
+ Vector<OutputUnit_d *> m_output_unit;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
new file mode 100644
index 000000000..b444ebc02
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * VCallocator_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "NetworkConfig.hh"
+#include "VCallocator_d.hh"
+#include "Router_d.hh"
+#include "InputUnit_d.hh"
+#include "OutputUnit_d.hh"
+#include "GarnetNetwork_d.hh"
+
+VCallocator_d::VCallocator_d(Router_d *router)
+{
+ m_router = router;
+ m_num_vcs = m_router->get_num_vcs();
+ m_vc_per_vnet = m_router->get_vc_per_vnet();
+ m_local_arbiter_activity = 0;
+ m_global_arbiter_activity = 0;
+}
+
+void VCallocator_d::init()
+{
+ m_input_unit = m_router->get_inputUnit_ref();
+ m_output_unit = m_router->get_outputUnit_ref();
+
+ m_num_inports = m_router->get_num_inports();
+ m_num_outports = m_router->get_num_outports();
+ m_round_robin_invc.setSize(m_num_inports);
+ m_round_robin_outvc.setSize(m_num_outports);
+ m_outvc_req.setSize(m_num_outports);
+ m_outvc_is_req.setSize(m_num_outports);
+
+ for(int i = 0; i < m_num_inports; i++)
+ {
+ m_round_robin_invc[i].setSize(m_num_vcs);
+
+ for(int j = 0; j < m_num_vcs; j++)
+ {
+ m_round_robin_invc[i][j] = 0;
+ }
+ }
+
+ for(int i = 0; i < m_num_outports; i++)
+ {
+ m_round_robin_outvc[i].setSize(m_num_vcs);
+ m_outvc_req[i].setSize(m_num_vcs);
+ m_outvc_is_req[i].setSize(m_num_vcs);
+
+ for(int j = 0; j < m_num_vcs; j++)
+ {
+ m_round_robin_outvc[i][j].first = 0;
+ m_round_robin_outvc[i][j].second = 0;
+ m_outvc_is_req[i][j] = false;
+
+ m_outvc_req[i][j].setSize(m_num_inports);
+
+ for(int k = 0; k < m_num_inports; k++)
+ {
+ m_outvc_req[i][j][k].setSize(m_num_vcs);
+ for(int l = 0; l < m_num_vcs; l++)
+ {
+ m_outvc_req[i][j][k][l] = false;
+ }
+ }
+ }
+ }
+}
+
+void VCallocator_d::clear_request_vector()
+{
+ for(int i = 0; i < m_num_outports; i++)
+ {
+ for(int j = 0; j < m_num_vcs; j++)
+ {
+ if(!m_outvc_is_req[i][j])
+ continue;
+ m_outvc_is_req[i][j] = false;
+ for(int k = 0; k < m_num_inports; k++)
+ {
+ for(int l = 0; l < m_num_vcs; l++)
+ {
+ m_outvc_req[i][j][k][l] = false;
+ }
+ }
+ }
+ }
+}
+
+void VCallocator_d::wakeup()
+{
+ arbitrate_invcs(); // First stage of allocation
+ arbitrate_outvcs(); // Second stage of allocation
+
+ clear_request_vector();
+ check_for_wakeup();
+}
+
+bool VCallocator_d::is_invc_candidate(int inport_iter, int invc_iter)
+{
+ int outport = m_input_unit[inport_iter]->get_route(invc_iter);
+ int vnet = get_vnet(invc_iter);
+ int t_enqueue_time = m_input_unit[inport_iter]->get_enqueue_time(invc_iter);
+
+ int invc_base = vnet*m_vc_per_vnet;
+
+ if((m_router->get_net_ptr())->isVNetOrdered(vnet))
+ {
+ for(int vc_offset = 0; vc_offset < m_vc_per_vnet; vc_offset++)
+ {
+ int temp_vc = invc_base + vc_offset;
+ if(m_input_unit[inport_iter]->need_stage(temp_vc, VC_AB_, VA_) && (m_input_unit[inport_iter]->get_route(temp_vc) == outport) && (m_input_unit[inport_iter]->get_enqueue_time(temp_vc) < t_enqueue_time))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void VCallocator_d::select_outvc(int inport_iter, int invc_iter)
+{
+ int outport = m_input_unit[inport_iter]->get_route(invc_iter);
+ int vnet = get_vnet(invc_iter);
+ int outvc_base = vnet*m_vc_per_vnet;
+ int num_vcs_per_vnet = m_vc_per_vnet;
+
+ int outvc_offset = m_round_robin_invc[inport_iter][invc_iter];
+ m_round_robin_invc[inport_iter][invc_iter]++;
+
+ if(m_round_robin_invc[inport_iter][invc_iter] >= num_vcs_per_vnet)
+ m_round_robin_invc[inport_iter][invc_iter] = 0;
+
+ for(int outvc_offset_iter = 0; outvc_offset_iter < num_vcs_per_vnet; outvc_offset_iter++)
+ {
+ outvc_offset++;
+ if(outvc_offset >= num_vcs_per_vnet)
+ outvc_offset = 0;
+ int outvc = outvc_base + outvc_offset;
+ if(m_output_unit[outport]->is_vc_idle(outvc))
+ {
+ m_local_arbiter_activity++;
+ m_outvc_req[outport][outvc][inport_iter][invc_iter] = true;
+ if(!m_outvc_is_req[outport][outvc])
+ m_outvc_is_req[outport][outvc] = true;
+ return; // out vc acquired
+ }
+ }
+}
+
+void VCallocator_d::arbitrate_invcs()
+{
+ for(int inport_iter = 0; inport_iter < m_num_inports; inport_iter++)
+ {
+ for(int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++)
+ {
+ if(m_input_unit[inport_iter]->need_stage(invc_iter, VC_AB_, VA_))
+ {
+ if(!is_invc_candidate(inport_iter, invc_iter))
+ continue;
+
+ select_outvc(inport_iter, invc_iter);
+ }
+ }
+ }
+}
+
+void VCallocator_d::arbitrate_outvcs()
+{
+ for(int outport_iter = 0; outport_iter < m_num_outports; outport_iter++)
+ {
+ for(int outvc_iter = 0; outvc_iter < m_num_vcs; outvc_iter++)
+ {
+ if(!m_outvc_is_req[outport_iter][outvc_iter]) // No requests for this outvc in this cycle
+ continue;
+
+ int inport = m_round_robin_outvc[outport_iter][outvc_iter].first;
+ int invc_offset = m_round_robin_outvc[outport_iter][outvc_iter].second;
+ int vnet = get_vnet(outvc_iter);
+ int invc_base = vnet*m_vc_per_vnet;
+ int num_vcs_per_vnet = m_vc_per_vnet;
+
+ m_round_robin_outvc[outport_iter][outvc_iter].second++;
+ if(m_round_robin_outvc[outport_iter][outvc_iter].second >= num_vcs_per_vnet)
+ {
+ m_round_robin_outvc[outport_iter][outvc_iter].second = 0;
+ m_round_robin_outvc[outport_iter][outvc_iter].first++;
+ if(m_round_robin_outvc[outport_iter][outvc_iter].first >= m_num_inports)
+ m_round_robin_outvc[outport_iter][outvc_iter].first = 0;
+ }
+ for(int in_iter = 0; in_iter < m_num_inports*num_vcs_per_vnet; in_iter++)
+ {
+ invc_offset++;
+ if(invc_offset >= num_vcs_per_vnet)
+ {
+ invc_offset = 0;
+ inport++;
+ if(inport >= m_num_inports)
+ inport = 0;
+ }
+ int invc = invc_base + invc_offset;
+ if(m_outvc_req[outport_iter][outvc_iter][inport][invc])
+ {
+ m_global_arbiter_activity++;
+ m_input_unit[inport]->grant_vc(invc, outvc_iter);
+ m_output_unit[outport_iter]->update_vc(outvc_iter, inport, invc);
+ m_router->swarb_req();
+ break;
+ }
+ }
+ }
+ }
+}
+
+int VCallocator_d::get_vnet(int invc)
+{
+ for(int i = 0; i < NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ {
+ if(invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet))
+ {
+ return i;
+ }
+ }
+ ERROR_MSG("Could not determine vc");
+ return -1;
+}
+
+void VCallocator_d::check_for_wakeup()
+{
+ for(int i = 0; i < m_num_inports; i++)
+ {
+ for(int j = 0; j < m_num_vcs; j++)
+ {
+ if(m_input_unit[i]->need_stage_nextcycle(j, VC_AB_, VA_))
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+ }
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh
new file mode 100644
index 000000000..fc1bf1340
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * VCallocator_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef VC_ALLOCATOR_D_H
+#define VC_ALLOCATOR_D_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+
+class Router_d;
+class InputUnit_d;
+class OutputUnit_d;
+
+class VCallocator_d : public Consumer {
+public:
+ VCallocator_d(Router_d *router);
+ void init();
+ void wakeup();
+ void check_for_wakeup();
+ void clear_request_vector();
+ int get_vnet(int invc);
+ void print(ostream& out) const {};
+ void arbitrate_invcs();
+ void arbitrate_outvcs();
+ bool is_invc_candidate(int inport_iter, int invc_iter);
+ void select_outvc(int inport_iter, int invc_iter);
+ inline double get_local_arbit_count()
+ {
+ return m_local_arbiter_activity;
+ }
+ inline double get_global_arbit_count()
+ {
+ return m_global_arbiter_activity;
+ }
+
+private:
+ int m_num_vcs, m_vc_per_vnet;
+ int m_num_inports;
+ int m_num_outports;
+
+ double m_local_arbiter_activity, m_global_arbiter_activity;
+
+ Router_d *m_router;
+ Vector<Vector <int > > m_round_robin_invc; // First stage of arbitration where all vcs select an output vc to content for
+ Vector<Vector <pair<int, int> > > m_round_robin_outvc; // Arbiter for every output vc
+ Vector<Vector<Vector<Vector<bool > > > > m_outvc_req; // [outport][outvc][inpotr][invc]. set true in the first phase of allocation
+ Vector<Vector<bool > > m_outvc_is_req;
+
+ Vector<InputUnit_d *> m_input_unit ;
+ Vector<OutputUnit_d *> m_output_unit ;
+
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc
new file mode 100644
index 000000000..60c6bef2a
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * VirtualChannel_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "VirtualChannel_d.hh"
+
+VirtualChannel_d::VirtualChannel_d(int id)
+{
+ m_id = id;
+ m_input_buffer = new flitBuffer_d();
+ m_vc_state.first = IDLE_;
+ m_vc_state.second = g_eventQueue_ptr->getTime();
+ m_enqueue_time = INFINITE_;
+}
+
+VirtualChannel_d::~VirtualChannel_d()
+{
+ delete m_input_buffer;
+}
+
+void VirtualChannel_d::set_outport(int outport)
+{
+ route = outport;
+}
+
+void VirtualChannel_d::grant_vc(int out_vc)
+{
+ m_output_vc = out_vc;
+ m_vc_state.first = ACTIVE_;
+ m_vc_state.second = g_eventQueue_ptr->getTime() + 1;
+ flit_d *t_flit = m_input_buffer->peekTopFlit();
+ t_flit->advance_stage(SA_);
+}
+
+bool VirtualChannel_d::need_stage(VC_state_type state, flit_stage stage)
+{
+ if((m_vc_state.first == state) && (g_eventQueue_ptr->getTime() >= m_vc_state.second))
+ {
+ if(m_input_buffer->isReady())
+ {
+ flit_d *t_flit = m_input_buffer->peekTopFlit();
+ return(t_flit->is_stage(stage)) ;
+ }
+ }
+ return false;
+
+}
+
+bool VirtualChannel_d::need_stage_nextcycle(VC_state_type state, flit_stage stage)
+{
+ if((m_vc_state.first == state) && ((g_eventQueue_ptr->getTime()+1) >= m_vc_state.second))
+ {
+ if(m_input_buffer->isReadyForNext())
+ {
+ flit_d *t_flit = m_input_buffer->peekTopFlit();
+ return(t_flit->is_next_stage(stage)) ;
+ }
+ }
+ return false;
+}
+
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh
new file mode 100644
index 000000000..111837122
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * VirtualChannel_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef VIRTUAL_CHANNEL_D_H
+#define VIRTUAL_CHANNEL_D_H
+
+#include "NetworkHeader.hh"
+#include "flitBuffer_d.hh"
+
+class VirtualChannel_d {
+public:
+ VirtualChannel_d(int id);
+ ~VirtualChannel_d();
+
+ bool need_stage(VC_state_type state, flit_stage stage);
+ bool need_stage_nextcycle(VC_state_type state, flit_stage stage);
+ void set_outport(int outport);
+ void grant_vc(int out_vc);
+
+ inline Time get_enqueue_time()
+ {
+ return m_enqueue_time;
+ }
+
+ inline void set_enqueue_time(Time time)
+ {
+ m_enqueue_time = time;
+ }
+
+ inline VC_state_type get_state()
+ {
+ return m_vc_state.first;
+ }
+ inline int get_outvc()
+ {
+ return m_output_vc;
+ }
+ inline bool isReady()
+ {
+ return m_input_buffer->isReady();
+ }
+ inline bool has_credits()
+ {
+ return (m_credit_count > 0);
+ }
+ inline int get_route()
+ {
+ return route;
+ }
+ inline void update_credit(int credit)
+ {
+ m_credit_count = credit;
+ }
+ inline void increment_credit()
+ {
+ m_credit_count++;
+ }
+ inline void insertFlit(flit_d *t_flit)
+ {
+ m_input_buffer->insert(t_flit);
+ }
+ inline void set_state(VC_state_type m_state)
+ {
+ m_vc_state.first = m_state;
+ m_vc_state.second = g_eventQueue_ptr->getTime() + 1;
+ }
+
+ inline flit_d* peekTopFlit()
+ {
+ return m_input_buffer->peekTopFlit();
+ }
+
+ inline flit_d* getTopFlit()
+ {
+ return m_input_buffer->getTopFlit();
+ }
+
+private:
+ int m_id;
+ flitBuffer_d *m_input_buffer;
+ pair<VC_state_type, Time> m_vc_state; // I/R/V/A/C
+ int route;
+ Time m_enqueue_time;
+ int m_output_vc;
+ int m_credit_count;
+};
+#endif
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc
new file mode 100644
index 000000000..e5e7226a2
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flitBuffer_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "flitBuffer_d.hh"
+
+flitBuffer_d::flitBuffer_d()
+{
+ max_size = INFINITE_;
+}
+
+flitBuffer_d::flitBuffer_d(int maximum_size)
+{
+ max_size = maximum_size;
+}
+
+bool flitBuffer_d::isEmpty()
+{
+ return (m_buffer.size() == 0);
+}
+
+bool flitBuffer_d::isReady()
+{
+ if(m_buffer.size() != 0 )
+ {
+ flit_d *t_flit = m_buffer.peekMin();
+ if(t_flit->get_time() <= g_eventQueue_ptr->getTime())
+ return true;
+ }
+ return false;
+}
+
+bool flitBuffer_d::isReadyForNext()
+{
+ if(m_buffer.size() != 0 )
+ {
+ flit_d *t_flit = m_buffer.peekMin();
+ if(t_flit->get_time() <= (g_eventQueue_ptr->getTime() + 1))
+ return true;
+ }
+ return false;
+}
+
+void flitBuffer_d::print(ostream& out) const
+{
+ out << "[flitBuffer: ";
+ out << m_buffer.size() << "] " << endl;
+}
+
+bool flitBuffer_d::isFull()
+{
+ return (m_buffer.size() >= max_size);
+}
+void flitBuffer_d::setMaxSize(int maximum)
+{
+ max_size = maximum;
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh
new file mode 100644
index 000000000..7e7d07a5a
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flitBuffer_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef FLIT_BUFFER_D_H
+#define FLIT_BUFFER_D_H
+
+#include "NetworkHeader.hh"
+#include "PrioHeap.hh"
+#include "flit_d.hh"
+
+class flitBuffer_d {
+public:
+ flitBuffer_d();
+ flitBuffer_d(int maximum_size);
+
+ bool isReady();
+ bool isReadyForNext();
+ bool isEmpty();
+ void print(ostream& out) const;
+ bool isFull();
+ void setMaxSize(int maximum);
+
+ inline flit_d* getTopFlit()
+ {
+ return m_buffer.extractMin();
+ }
+ inline flit_d* peekTopFlit()
+ {
+ return m_buffer.peekMin();
+ }
+ inline void insert(flit_d *flt)
+ {
+ m_buffer.insert(flt);
+ }
+ /**********Data Members*********/
+private:
+ PrioHeap <flit_d *> m_buffer;
+ int size, max_size;
+};
+
+ostream& operator<<(ostream& out, const flitBuffer_d& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const flitBuffer_d& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif
+
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc
new file mode 100644
index 000000000..e049c5537
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flit_d.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "flit_d.hh"
+
+flit_d::flit_d(int id, int vc, int vnet, int size, MsgPtr msg_ptr)
+{
+ m_size = size;
+ m_msg_ptr = msg_ptr;
+ m_enqueue_time = g_eventQueue_ptr->getTime();
+ m_time = g_eventQueue_ptr->getTime();
+ m_id = id;
+ m_vnet = vnet;
+ m_vc = vc;
+ m_stage.first = I_;
+ m_stage.second = m_time;
+
+ if(size == 1)
+ {
+ m_type = HEAD_TAIL_;
+ return;
+ }
+ if(id == 0)
+ m_type = HEAD_;
+ else if(id == (size - 1))
+ m_type = TAIL_;
+ else
+ m_type = BODY_;
+}
+
+flit_d::flit_d(int vc, bool is_free_signal)
+{
+ m_id = 0;
+ m_vc = vc;
+ m_is_free_signal = is_free_signal;
+ m_time = g_eventQueue_ptr->getTime();
+}
+/*
+int flit_d::get_size()
+{
+ return m_size;
+}
+Time flit_d::get_enqueue_time()
+{
+ return m_enqueue_time;
+}
+int flit_d::get_id()
+{
+ return m_id;
+}
+Time flit_d::get_time()
+{
+ return m_time;
+}
+void flit_d::set_time(Time time)
+{
+ m_time = time;
+}
+int flit_d::get_vnet()
+{
+ return m_vnet;
+}
+int flit_d::get_vc()
+{
+ return m_vc;
+}
+void flit_d::set_vc(int vc)
+{
+ m_vc = vc;
+}
+MsgPtr& flit_d::get_msg_ptr()
+{
+ return m_msg_ptr;
+}
+flit_type flit_d::get_type()
+{
+ return m_type;
+}
+bool flit_d::is_stage(flit_stage t_stage)
+{
+ return ((m_stage.first == t_stage) && (g_eventQueue_ptr->getTime() >= m_stage.second));
+}
+bool flit_d::is_next_stage(flit_stage t_stage)
+{
+ return ((m_stage.first == t_stage) && ((g_eventQueue_ptr->getTime()+1) >= m_stage.second));
+}
+void flit_d::advance_stage(flit_stage t_stage)
+{
+ m_stage.first = t_stage;
+ m_stage.second = g_eventQueue_ptr->getTime() + 1;
+}
+*/
+void flit_d::print(ostream& out) const
+{
+ out << "[flit:: ";
+ out << "Id=" << m_id << " ";
+ out << "Type=" << m_type << " ";
+ out << "Vnet=" << m_vnet << " ";
+ out << "VC=" << m_vc << " ";
+ out << "Enqueue Time=" << m_enqueue_time << " ";
+ out << "]";
+}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh
new file mode 100644
index 000000000..9a47e964f
--- /dev/null
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flit_d.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+
+#ifndef FLIT_D_H
+#define FLIT_D_H
+
+#include "NetworkHeader.hh"
+#include "Message.hh"
+
+class flit_d {
+public:
+ flit_d(int id, int vc, int vnet, int size, MsgPtr msg_ptr);
+ flit_d(int vc, bool is_free_signal);
+ void set_outport(int port) { m_outport = port; }
+ int get_outport() {return m_outport; }
+ void print(ostream& out) const;
+ bool is_free_signal()
+ {
+ return m_is_free_signal;
+ }
+
+ inline int get_size()
+ {
+ return m_size;
+ }
+ inline Time get_enqueue_time()
+ {
+ return m_enqueue_time;
+ }
+ inline int get_id()
+ {
+ return m_id;
+ }
+ inline Time get_time()
+ {
+ return m_time;
+ }
+ inline void set_time(Time time)
+ {
+ m_time = time;
+ }
+ inline int get_vnet()
+ {
+ return m_vnet;
+ }
+ inline int get_vc()
+ {
+ return m_vc;
+ }
+ inline void set_vc(int vc)
+ {
+ m_vc = vc;
+ }
+ inline MsgPtr& get_msg_ptr()
+ {
+ return m_msg_ptr;
+ }
+ inline flit_type get_type()
+ {
+ return m_type;
+ }
+ inline bool is_stage(flit_stage t_stage)
+ {
+ return ((m_stage.first == t_stage) && (g_eventQueue_ptr->getTime() >= m_stage.second));
+ }
+ inline bool is_next_stage(flit_stage t_stage)
+ {
+ return ((m_stage.first == t_stage) && ((g_eventQueue_ptr->getTime()+1) >= m_stage.second));
+ }
+ inline void advance_stage(flit_stage t_stage)
+ {
+ m_stage.first = t_stage;
+ m_stage.second = g_eventQueue_ptr->getTime() + 1;
+ }
+ inline pair<flit_stage, Time> get_stage()
+ {
+ return m_stage;
+ }
+ inline void set_delay(int delay)
+ {
+ src_delay = delay;
+ }
+
+ inline int get_delay()
+ {
+ return src_delay;
+ }
+
+
+private:
+ /************Data Members*************/
+ int m_id;
+ int m_vnet;
+ int m_vc;
+ int m_size;
+ bool m_is_free_signal;
+ Time m_enqueue_time, m_time;
+ flit_type m_type;
+ MsgPtr m_msg_ptr;
+ int m_outport;
+ int src_delay;
+ pair<flit_stage, Time> m_stage;
+
+};
+
+inline extern bool node_less_then_eq(flit_d* n1, flit_d* n2);
+
+inline extern
+bool node_less_then_eq(flit_d* n1, flit_d* n2)
+{
+ if (n1->get_time() == n2->get_time()) {
+// ASSERT(n1->flit_id != n2->flit_id);
+ return (n1->get_id() <= n2->get_id());
+ } else {
+ return (n1->get_time() <= n2->get_time());
+ }
+}
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const flit_d& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const flit_d& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh
new file mode 100644
index 000000000..773d00323
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * FlexibleConsumer.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+#ifndef FLEXIBLE_CONSUMER_H
+#define FLEXIBLE_CONSUMER_H
+
+#include "Consumer.hh"
+#include "NetworkHeader.hh"
+#include "NetDest.hh"
+
+class FlexibleConsumer : public Consumer {
+public:
+ 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) {}
+ virtual void request_vc(int vc, int in_port, NetDest destination, Time request_time) {}
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
new file mode 100644
index 000000000..3d7c555b5
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * GarnetNetwork.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "GarnetNetwork.hh"
+#include "MachineType.hh"
+#include "NetworkInterface.hh"
+#include "MessageBuffer.hh"
+#include "Router.hh"
+#include "Topology.hh"
+#include "SimpleNetwork.hh"
+#include "GarnetNetwork_d.hh"
+#include "NetworkLink.hh"
+#include "NetDest.hh"
+
+// calls new to abstract away from the network
+Network* Network::createNetwork(int nodes)
+{
+ NetworkConfig::readNetConfig();
+ // Instantiate a network depending on what kind of network is requested
+ if(NetworkConfig::isGarnetNetwork())
+ {
+ if(NetworkConfig::isDetailNetwork())
+ return new GarnetNetwork_d(nodes);
+ else
+ return new GarnetNetwork(nodes);
+ }
+ else
+ return new SimpleNetwork(nodes);
+}
+
+GarnetNetwork::GarnetNetwork(int nodes)
+{
+ m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
+ m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS; // Number of virtual networks = number of message classes in the coherence protocol
+ m_ruby_start = 0;
+
+ // Allocate to and from queues
+ m_toNetQueues.setSize(m_nodes); // Queues that are getting messages from protocol
+ m_fromNetQueues.setSize(m_nodes); // Queues that are feeding the protocol
+ m_in_use.setSize(m_virtual_networks);
+ m_ordered.setSize(m_virtual_networks);
+ for (int i = 0; i < m_virtual_networks; i++)
+ {
+ m_in_use[i] = false;
+ m_ordered[i] = false;
+ }
+
+ for (int node = 0; node < m_nodes; node++)
+ {
+ //Setting how many vitual message buffers will there be per Network Queue
+ m_toNetQueues[node].setSize(m_virtual_networks);
+ m_fromNetQueues[node].setSize(m_virtual_networks);
+
+ for (int j = 0; j < m_virtual_networks; j++)
+ {
+ m_toNetQueues[node][j] = new MessageBuffer(); // Instantiating the Message Buffers that interact with the coherence protocol
+ m_fromNetQueues[node][j] = new MessageBuffer();
+ }
+ }
+
+ // Setup the network switches
+ m_topology_ptr = new Topology(this, m_nodes);
+
+ int number_of_routers = m_topology_ptr->numSwitches();
+ for (int i=0; i<number_of_routers; i++) {
+ m_router_ptr_vector.insertAtBottom(new Router(i, this));
+ }
+
+ for (int i=0; i < m_nodes; i++) {
+ NetworkInterface *ni = new NetworkInterface(i, m_virtual_networks, this);
+ ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
+ m_ni_ptr_vector.insertAtBottom(ni);
+ }
+ m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
+}
+
+GarnetNetwork::~GarnetNetwork()
+{
+ for (int i = 0; i < m_nodes; i++)
+ {
+ m_toNetQueues[i].deletePointers();
+ m_fromNetQueues[i].deletePointers();
+ }
+ m_router_ptr_vector.deletePointers();
+ m_ni_ptr_vector.deletePointers();
+ m_link_ptr_vector.deletePointers();
+ delete m_topology_ptr;
+}
+
+void GarnetNetwork::reset()
+{
+ for (int node = 0; node < m_nodes; node++)
+ {
+ for (int j = 0; j < m_virtual_networks; j++)
+ {
+ m_toNetQueues[node][j]->clear();
+ m_fromNetQueues[node][j]->clear();
+ }
+ }
+}
+
+void GarnetNetwork::makeInLink(NodeID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration)
+{
+ assert(src < m_nodes);
+
+ if(!isReconfiguration)
+ {
+ NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(), link_latency, this);
+ m_link_ptr_vector.insertAtBottom(net_link);
+ m_router_ptr_vector[dest]->addInPort(net_link);
+ m_ni_ptr_vector[src]->addOutPort(net_link);
+ }
+ else
+ {
+ ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
+ // do nothing
+ }
+}
+
+void GarnetNetwork::makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ assert(dest < m_nodes);
+ assert(src < m_router_ptr_vector.size());
+ assert(m_router_ptr_vector[src] != NULL);
+
+ if(!isReconfiguration)
+ {
+ NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(), link_latency, this);
+ m_link_ptr_vector.insertAtBottom(net_link);
+ m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, link_weight);
+ m_ni_ptr_vector[dest]->addInPort(net_link);
+ }
+ else
+ {
+ ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
+ //do nothing
+ }
+}
+
+void GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ if(!isReconfiguration)
+ {
+ NetworkLink *net_link = new NetworkLink(m_link_ptr_vector.size(), link_latency, this);
+ m_link_ptr_vector.insertAtBottom(net_link);
+ m_router_ptr_vector[dest]->addInPort(net_link);
+ m_router_ptr_vector[src]->addOutPort(net_link, routing_table_entry, link_weight);
+ }
+ else
+ {
+ ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
+ // do nothing
+ }
+
+}
+
+void GarnetNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num)
+{
+ ASSERT(id < m_nodes);
+ ASSERT(network_num < m_virtual_networks);
+
+ if (ordered)
+ {
+ m_ordered[network_num] = true;
+ }
+ m_in_use[network_num] = true;
+}
+
+MessageBuffer* GarnetNetwork::getToNetQueue(NodeID id, bool ordered, int network_num)
+{
+ checkNetworkAllocation(id, ordered, network_num);
+ return m_toNetQueues[id][network_num];
+}
+
+MessageBuffer* GarnetNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num)
+{
+ checkNetworkAllocation(id, ordered, network_num);
+ return m_fromNetQueues[id][network_num];
+}
+
+void GarnetNetwork::clearStats()
+{
+ m_ruby_start = g_eventQueue_ptr->getTime();
+}
+
+Time GarnetNetwork::getRubyStartTime()
+{
+ return m_ruby_start;
+}
+
+void GarnetNetwork::printStats(ostream& out) const
+{ double average_link_utilization = 0;
+ Vector<double > average_vc_load;
+ average_vc_load.setSize(m_virtual_networks*NetworkConfig::getVCsPerClass());
+
+ for(int i = 0; i < m_virtual_networks*NetworkConfig::getVCsPerClass(); i++)
+ {
+ average_vc_load[i] = 0;
+ }
+
+ out << endl;
+ out << "Network Stats" << endl;
+ out << "-------------" << endl;
+ out << endl;
+ for(int i = 0; i < m_link_ptr_vector.size(); i++)
+ {
+ average_link_utilization += m_link_ptr_vector[i]->getLinkUtilization();
+ Vector<int > vc_load = m_link_ptr_vector[i]->getVcLoad();
+ for(int j = 0; j < vc_load.size(); j++)
+ {
+ assert(vc_load.size() == NetworkConfig::getVCsPerClass()*m_virtual_networks);
+ average_vc_load[j] += vc_load[j];
+ }
+ }
+ average_link_utilization = average_link_utilization/m_link_ptr_vector.size();
+ out << "Average Link Utilization :: " << average_link_utilization << " flits/cycle" <<endl;
+ out << "-------------" << endl;
+
+ for(int i = 0; i < NetworkConfig::getVCsPerClass()*m_virtual_networks; i++)
+ {
+ average_vc_load[i] = (double(average_vc_load[i]) / (double(g_eventQueue_ptr->getTime()) - m_ruby_start));
+ out << "Average VC Load [" << i << "] = " << average_vc_load[i] << " flits/cycle" << endl;
+ }
+ out << "-------------" << endl;
+}
+
+void GarnetNetwork::printConfig(ostream& out) const
+{
+ out << endl;
+ out << "Network Configuration" << endl;
+ out << "---------------------" << endl;
+ out << "network: GARNET_NETWORK" << endl;
+ out << "topology: " << g_NETWORK_TOPOLOGY << endl;
+ out << endl;
+
+ for (int i = 0; i < m_virtual_networks; i++)
+ {
+ out << "virtual_net_" << i << ": ";
+ if (m_in_use[i])
+ {
+ out << "active, ";
+ if (m_ordered[i])
+ {
+ out << "ordered" << endl;
+ }
+ else
+ {
+ out << "unordered" << endl;
+ }
+ }
+ else
+ {
+ out << "inactive" << endl;
+ }
+ }
+ out << endl;
+
+ for(int i = 0; i < m_ni_ptr_vector.size(); i++)
+ {
+ m_ni_ptr_vector[i]->printConfig(out);
+ }
+ for(int i = 0; i < m_router_ptr_vector.size(); i++)
+ {
+ m_router_ptr_vector[i]->printConfig(out);
+ }
+ if (g_PRINT_TOPOLOGY)
+ {
+ m_topology_ptr->printConfig(out);
+ }
+}
+
+void GarnetNetwork::print(ostream& out) const
+{
+ out << "[GarnetNetwork]";
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
new file mode 100644
index 000000000..cb9a8908a
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * GarnetNetwork.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef GARNET_NETWORK_H
+#define GARNET_NETWORK_H
+
+#include "NetworkHeader.hh"
+#include "Vector.hh"
+#include "NetworkConfig.hh"
+#include "Network.hh"
+
+class NetworkInterface;
+class MessageBuffer;
+class Router;
+class Topology;
+class NetDest;
+class NetworkLink;
+
+class GarnetNetwork : public Network{
+public:
+ GarnetNetwork(int nodes);
+
+ ~GarnetNetwork();
+
+ // returns the queue requested for the given component
+ MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num);
+ MessageBuffer* getFromNetQueue(NodeID id, bool ordered, int network_num);
+
+ void clearStats();
+ void printStats(ostream& out) const;
+ void printConfig(ostream& out) const;
+ void print(ostream& out) const;
+
+ bool isVNetOrdered(int vnet) { return m_ordered[vnet]; }
+ bool validVirtualNetwork(int vnet) { return m_in_use[vnet]; }
+
+ Time getRubyStartTime();
+ int getNumNodes(){ return m_nodes; }
+
+ void reset();
+
+ // Methods used by Topology to setup the network
+ void makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
+ void makeInLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration);
+ void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
+
+private:
+ void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
+
+// Private copy constructor and assignment operator
+ GarnetNetwork(const GarnetNetwork& obj);
+ GarnetNetwork& operator=(const GarnetNetwork& obj);
+
+/***********Data Members*************/
+ int m_virtual_networks;
+ int m_nodes;
+
+ Vector<bool> m_in_use;
+ Vector<bool> m_ordered;
+
+ Vector<Vector<MessageBuffer*> > m_toNetQueues;
+ Vector<Vector<MessageBuffer*> > m_fromNetQueues;
+
+ Vector<Router *> m_router_ptr_vector; // All Routers in Network
+ Vector<NetworkLink *> m_link_ptr_vector; // All links in the network
+ Vector<NetworkInterface *> m_ni_ptr_vector; // All NI's in Network
+
+ Topology* m_topology_ptr;
+ Time m_ruby_start;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const GarnetNetwork& obj);
+
+// ******************* Definitions *******************
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const GarnetNetwork& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //NETWORK_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc
new file mode 100644
index 000000000..52090cb2b
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * InVCState.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "InVcState.hh"
+
+InVcState::InVcState(int id)
+{
+ m_id = id;
+ m_vc_state = IDLE_;
+}
+
+bool InVcState::isInState(VC_state_type state, Time request_time)
+{
+ return ((m_vc_state == state) && (request_time >= m_time) );
+}
+
+void InVcState::setRoute(int route)
+{
+ m_route = route;
+}
+
+void InVcState::setState(VC_state_type state, Time time)
+{
+ m_vc_state = state;
+ m_time = time;
+}
+
+void InVcState::grant_vc(int out_vc, Time grant_time)
+{
+ m_vc_state = ACTIVE_;
+ m_time = grant_time;
+ m_output_vc = out_vc;
+}
+
+int InVcState::get_outport()
+{
+ return m_route;
+}
+
+int InVcState::get_outvc()
+{
+ return m_output_vc;
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh
new file mode 100644
index 000000000..efbd0d513
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ *
+ * InVCState.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef IN_VC_STATE_H
+#define IN_VC_STATE_H
+
+#include "NetworkHeader.hh"
+
+class InVcState {
+public:
+ InVcState(int id);
+
+ void setRoute(int route);
+ void setState(VC_state_type state, Time time);
+ int get_outport();
+ int get_outvc();
+ void grant_vc(int out_vc, Time grant_time);
+ bool isInState(VC_state_type state, Time time);
+
+private:
+ int m_id;
+ int m_route;
+ int m_output_vc;
+ VC_state_type m_vc_state;
+ Time m_time;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
new file mode 100644
index 000000000..53dd67563
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkConfig.h
+ *
+ * Description: This header file is used to define all configuration parameters required by the interconnection network.
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef NETWORKCONFIG_H
+#define NETWORKCONFIG_H
+
+#include "NetworkHeader.hh"
+#include "util.hh"
+#include "RubyConfig.hh"
+
+class NetworkConfig {
+ public:
+ static bool isGarnetNetwork() {return g_GARNET_NETWORK; }
+ static bool isDetailNetwork() {return g_DETAIL_NETWORK; }
+ static int isNetworkTesting() {return g_NETWORK_TESTING; }
+ static int getFlitSize() {return g_FLIT_SIZE; }
+ static int getNumPipeStages() {return g_NUM_PIPE_STAGES; }
+ static int getVCsPerClass() {return g_VCS_PER_CLASS; }
+ static int getBufferSize() {return g_BUFFER_SIZE; }
+ // This is no longer used. See config/rubyconfig.defaults to set Garnet parameters.
+ static void readNetConfig()
+ {
+ /*
+ string filename = "network/garnet-flexible-pipeline/";
+ filename += NETCONFIG_DEFAULTS;
+
+ if (g_SIMICS) {
+ filename = "../../../ruby/"+filename;
+ }
+ ifstream NetconfigFile( filename.c_str(), ios::in);
+ if(!NetconfigFile.is_open())
+ {
+ cout << filename << endl;
+ cerr << "Network Configuration file cannot be opened\n";
+ exit(1);
+ }
+
+ string line = "";
+
+ while(!NetconfigFile.eof())
+ {
+ getline(NetconfigFile, line, '\n');
+ string var = string_split(line, ':');
+
+ if(!var.compare("g_GARNET_NETWORK"))
+ {
+ if(!line.compare("true"))
+ g_GARNET_NETWORK = true;
+ else
+ g_GARNET_NETWORK = false;
+ }
+ if(!var.compare("g_DETAIL_NETWORK"))
+ {
+ if(!line.compare("true"))
+ g_DETAIL_NETWORK = true;
+ else
+ g_DETAIL_NETWORK = false;
+ }
+ if(!var.compare("g_NETWORK_TESTING"))
+ {
+ if(!line.compare("true"))
+ g_NETWORK_TESTING = true;
+ else
+ g_NETWORK_TESTING = false;
+ }
+ if(!var.compare("g_FLIT_SIZE"))
+ g_FLIT_SIZE = atoi(line.c_str());
+ if(!var.compare("g_NUM_PIPE_STAGES"))
+ g_NUM_PIPE_STAGES = atoi(line.c_str());
+ if(!var.compare("g_VCS_PER_CLASS"))
+ g_VCS_PER_CLASS = atoi(line.c_str());
+ if(!var.compare("g_BUFFER_SIZE"))
+ g_BUFFER_SIZE = atoi(line.c_str());
+ }
+ NetconfigFile.close();
+ */
+ /*
+ cout << "g_GARNET_NETWORK = " << g_GARNET_NETWORK << endl;
+ cout << "g_DETAIL_NETWORK = " << g_DETAIL_NETWORK << endl;
+ cout << "g_NETWORK_TESTING = " << g_NETWORK_TESTING << endl;
+ cout << "g_FLIT_SIZE = " << g_FLIT_SIZE << endl;
+ cout << "g_NUM_PIPE_STAGES = " << g_NUM_PIPE_STAGES << endl;
+ cout << "g_VCS_PER_CLASS= " << g_VCS_PER_CLASS << endl;
+ cout << "g_BUFFER_SIZE = " << g_BUFFER_SIZE << endl;
+ */
+ }
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
new file mode 100644
index 000000000..3dfb5b4b9
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkInterface.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "NetworkInterface.hh"
+#include "MessageBuffer.hh"
+#include "flitBuffer.hh"
+#include "NetworkMessage.hh"
+
+NetworkInterface::NetworkInterface(int id, int virtual_networks, GarnetNetwork *network_ptr)
+{
+ m_id = id;
+ m_net_ptr = network_ptr;
+ m_virtual_networks = virtual_networks;
+ m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_num_vcs = m_vc_per_vnet*m_virtual_networks;
+
+ m_vc_round_robin = 0;
+ m_ni_buffers.setSize(m_num_vcs);
+ inNode_ptr.setSize(m_virtual_networks);
+ outNode_ptr.setSize(m_virtual_networks);
+
+ for(int i =0; i < m_num_vcs; i++)
+ m_ni_buffers[i] = new flitBuffer(); // instantiating the NI flit buffers
+
+ m_vc_allocator.setSize(m_virtual_networks);
+ for(int i = 0; i < m_virtual_networks; i++)
+ {
+ m_vc_allocator[i] = 0;
+ }
+
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ m_out_vc_state.insertAtBottom(new OutVcState(i));
+ m_out_vc_state[i]->setState(IDLE_, g_eventQueue_ptr->getTime());
+ }
+}
+
+NetworkInterface::~NetworkInterface()
+{
+ m_out_vc_state.deletePointers();
+ m_ni_buffers.deletePointers();
+ delete outSrcQueue;
+}
+
+void NetworkInterface::addInPort(NetworkLink *in_link)
+{
+ inNetLink = in_link;
+ in_link->setLinkConsumer(this);
+}
+
+void NetworkInterface::addOutPort(NetworkLink *out_link)
+{
+ outNetLink = out_link;
+ outSrcQueue = new flitBuffer();
+ out_link->setSourceQueue(outSrcQueue);
+ out_link->setSource(this);
+}
+
+void NetworkInterface::addNode(Vector<MessageBuffer*>& in, Vector<MessageBuffer*>& out)
+{
+ ASSERT(in.size() == m_virtual_networks);
+ inNode_ptr = in;
+ outNode_ptr = out;
+ for (int j = 0; j < m_virtual_networks; j++)
+ {
+ inNode_ptr[j]->setConsumer(this); // So that protocol injects messages into the NI
+ }
+}
+
+void NetworkInterface::request_vc(int in_vc, int in_port, NetDest destination, Time request_time)
+{
+ inNetLink->grant_vc_link(in_vc, request_time);
+}
+
+bool NetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet)
+{
+ NetworkMessage *net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
+ NetDest net_msg_dest = net_msg_ptr->getInternalDestination();
+ Vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); // gets all the destinations associated with this message.
+ int num_flits = (int) ceil((double) MessageSizeType_to_int(net_msg_ptr->getMessageSize())/NetworkConfig::getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
+
+ for(int ctr = 0; ctr < dest_nodes.size(); ctr++) // loop because we will be converting all multicast messages into unicast messages
+ {
+ int vc = calculateVC(vnet); // this will return a free output virtual channel
+
+ if(vc == -1)
+ {
+ // did not find a free output vc
+ return false ;
+ }
+ MsgPtr new_msg_ptr = *(msg_ptr.ref());
+ NodeID destID = dest_nodes[ctr];
+
+ NetworkMessage *new_net_msg_ptr = dynamic_cast<NetworkMessage*>(new_msg_ptr.ref());
+ if(dest_nodes.size() > 1)
+ {
+ NetDest personal_dest;
+ for(int m = 0; m < (int) MachineType_NUM; m++)
+ {
+ if((destID >= MachineType_base_number((MachineType) m)) && destID < MachineType_base_number((MachineType) (m+1)))
+ {
+ // calculating the NetDest associated with this destination ID
+ personal_dest.clear();
+ personal_dest.add((MachineID) {(MachineType) m, (destID - MachineType_base_number((MachineType) m))});
+ new_net_msg_ptr->getInternalDestination() = personal_dest;
+ break;
+ }
+ }
+ net_msg_dest.removeNetDest(personal_dest);
+ net_msg_ptr->getInternalDestination().removeNetDest(personal_dest); // removing the destination from the original message to reflect that a message with this particular destination has been flitisized and an output vc is acquired
+ }
+ for(int i = 0; i < num_flits; i++)
+ {
+ flit *fl = new flit(i, vc, vnet, num_flits, new_msg_ptr);
+ m_ni_buffers[vc]->insert(fl);
+ }
+
+ m_out_vc_state[vc]->setState(VC_AB_, g_eventQueue_ptr->getTime());
+ outNetLink->request_vc_link(vc, new_net_msg_ptr->getInternalDestination(), g_eventQueue_ptr->getTime()); // setting an output vc request for the next hop. It is only when an output vc is acquired at the next hop that this flit will be ready to traverse the link and into the next hop
+ }
+
+ return true ;
+}
+
+// An output vc has been granted at the next hop to one of the vc's. We have to update the state of the vc to reflect this
+void NetworkInterface::grant_vc(int out_port, int vc, Time grant_time)
+{
+
+ assert(m_out_vc_state[vc]->isInState(VC_AB_, grant_time));
+ m_out_vc_state[vc]->grant_vc(grant_time);
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+}
+
+// The tail flit corresponding to this vc has been buffered at the next hop and thus this vc is now free
+void NetworkInterface::release_vc(int out_port, int vc, Time release_time)
+{
+ assert(m_out_vc_state[vc]->isInState(ACTIVE_, release_time));
+ m_out_vc_state[vc]->setState(IDLE_, release_time);
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+}
+
+// Looking for a free output vc
+int NetworkInterface::calculateVC(int vnet)
+{
+ int vc_per_vnet;
+ if(m_net_ptr->isVNetOrdered(vnet))
+ vc_per_vnet = 1;
+ else
+ vc_per_vnet = m_vc_per_vnet;
+
+ for(int i = 0; i < vc_per_vnet; i++)
+ {
+ int delta = m_vc_allocator[vnet];
+ m_vc_allocator[vnet]++;
+ if(m_vc_allocator[vnet] == vc_per_vnet)
+ m_vc_allocator[vnet] = 0;
+
+ if(m_out_vc_state[(vnet*m_vc_per_vnet) + delta]->isInState(IDLE_, g_eventQueue_ptr->getTime()))
+ {
+ return ((vnet*m_vc_per_vnet) + delta);
+ }
+ }
+ return -1;
+}
+
+/*
+ * The NI wakeup checks whether there are any ready messages in the protocol buffer. If yes, it picks that up, flitisizes it into a number of flits and puts it into an output
+ * buffer and schedules the output link.
+ * On a wakeup it also checks whether there are flits in the input link. If yes, it picks them up and if the flit is a tail, the NI inserts the corresponding message into
+ * the protocol buffer.
+ */
+
+void NetworkInterface::wakeup()
+{
+ MsgPtr msg_ptr;
+
+ //Checking for messages coming from the protocol
+ for (int vnet = 0; vnet < m_virtual_networks; vnet++) // can pick up a message/cycle for each virtual net
+ {
+ while(inNode_ptr[vnet]->isReady()) // Is there a message waiting
+ {
+ msg_ptr = inNode_ptr[vnet]->peekMsgPtr();
+ if(flitisizeMessage(msg_ptr, vnet))
+ {
+ inNode_ptr[vnet]->pop();
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ scheduleOutputLink();
+ checkReschedule();
+
+/*********** Picking messages destined for this NI **********/
+
+ if(inNetLink->isReady())
+ {
+ flit *t_flit = inNetLink->consumeLink();
+ if(t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_)
+ {
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, m_id);
+ DEBUG_MSG(NETWORK_COMP, HighPrio, "Message got delivered");
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, g_eventQueue_ptr->getTime());
+ if(!NetworkConfig::isNetworkTesting()) // When we are doing network only testing, the messages do not have to be buffered into the message buffers
+ {
+ outNode_ptr[t_flit->get_vnet()]->enqueue(t_flit->get_msg_ptr(), 1); // enqueueing for protocol buffer. This is not required when doing network only testing
+ }
+ inNetLink->release_vc_link(t_flit->get_vc(), g_eventQueue_ptr->getTime() + 1); // signal the upstream router that this vc can be freed now
+ }
+ delete t_flit;
+ }
+}
+
+// This function look at the NI buffers and if some buffer has flits which are ready to traverse the link in the next cycle and also the downstream output vc associated with this flit has buffers left, the link is scheduled for the next cycle
+void NetworkInterface::scheduleOutputLink()
+{
+ int vc = m_vc_round_robin;
+ m_vc_round_robin++;
+ if(m_vc_round_robin == m_num_vcs)
+ m_vc_round_robin = 0;
+
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ vc++;
+ if(vc == m_num_vcs)
+ vc = 0;
+ if(m_ni_buffers[vc]->isReady())
+ {
+ if(m_out_vc_state[vc]->isInState(ACTIVE_, g_eventQueue_ptr->getTime()) && outNetLink->isBufferNotFull_link(vc)) // models buffer backpressure
+ {
+ flit *t_flit = m_ni_buffers[vc]->getTopFlit(); // Just removing the flit
+ t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
+ outSrcQueue->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(outNetLink, 1); // schedule the out link
+ return;
+ }
+ }
+ }
+}
+
+void NetworkInterface::checkReschedule()
+{
+ for(int vnet = 0; vnet < m_virtual_networks; vnet++)
+ {
+ if(inNode_ptr[vnet]->isReady()) // Is there a message waiting
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+ for(int vc = 0; vc < m_num_vcs; vc++)
+ {
+ if(m_ni_buffers[vc]->isReadyForNext())
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+}
+
+void NetworkInterface::printConfig(ostream& out) const
+{
+ out << "[Network Interface " << m_id << "] - ";
+ out << "[inLink " << inNetLink->get_id() << "] - ";
+ out << "[outLink " << outNetLink->get_id() << "]" << endl;
+}
+
+void NetworkInterface::print(ostream& out) const
+{
+ out << "[Network Interface]";
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh
new file mode 100644
index 000000000..d7932432b
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkInterface.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+#ifndef NET_INTERFACE_H
+#define NET_INTERFACE_H
+
+#include "NetworkHeader.hh"
+#include "GarnetNetwork.hh"
+#include "Vector.hh"
+#include "FlexibleConsumer.hh"
+#include "Message.hh"
+#include "NetworkLink.hh"
+#include "OutVcState.hh"
+
+class NetworkMessage;
+class MessageBuffer;
+class flitBuffer;
+
+class NetworkInterface : public FlexibleConsumer {
+public:
+ NetworkInterface(int id, int virtual_networks, GarnetNetwork* network_ptr);
+
+ ~NetworkInterface();
+
+ void addInPort(NetworkLink *in_link);
+ void addOutPort(NetworkLink *out_link);
+
+ void wakeup();
+ void addNode(Vector<MessageBuffer *> &inNode, Vector<MessageBuffer *> &outNode);
+ void grant_vc(int out_port, int vc, Time grant_time);
+ void release_vc(int out_port, int vc, Time release_time);
+ bool isBufferNotFull(int vc, int inport)
+ {
+ return true;
+ }
+ void request_vc(int in_vc, int in_port, NetDest destination, Time request_time);
+
+ void printConfig(ostream& out) const;
+ void print(ostream& out) const;
+
+private:
+/**************Data Members*************/
+ GarnetNetwork *m_net_ptr;
+ int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
+ NodeID m_id;
+
+ Vector<OutVcState *> m_out_vc_state;
+ Vector<int > m_vc_allocator;
+ int m_vc_round_robin; // For round robin scheduling
+ flitBuffer *outSrcQueue; // For modelling link contention
+
+ NetworkLink *inNetLink;
+ NetworkLink *outNetLink;
+
+ // Input Flit Buffers
+ Vector<flitBuffer *> m_ni_buffers; // The flit buffers which will serve the Consumer
+
+ Vector<MessageBuffer *> inNode_ptr; // The Message buffers that takes messages from the protocol
+ Vector<MessageBuffer *> outNode_ptr; // The Message buffers that provides messages to the protocol
+
+ bool flitisizeMessage(MsgPtr msg_ptr, int vnet);
+ int calculateVC(int vnet);
+ void scheduleOutputLink();
+ void checkReschedule();
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
new file mode 100644
index 000000000..e586ece9e
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkLink.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "NetworkLink.hh"
+#include "NetworkConfig.hh"
+#include "GarnetNetwork.hh"
+
+NetworkLink::NetworkLink(int id, int latency, GarnetNetwork *net_ptr)
+{
+ m_id = id;
+ linkBuffer = new flitBuffer();
+ m_in_port = 0;
+ m_out_port = 0;
+ m_link_utilized = 0;
+ m_net_ptr = net_ptr;
+ m_latency = latency;
+ int num_net = NUMBER_OF_VIRTUAL_NETWORKS;
+ int num_vc = NetworkConfig::getVCsPerClass();
+ m_vc_load.setSize(num_net*num_vc);
+
+ for(int i = 0; i < num_net*num_vc; i++)
+ m_vc_load[i] = 0;
+}
+
+NetworkLink::~NetworkLink()
+{
+ delete linkBuffer;
+}
+
+int NetworkLink::get_id()
+{
+ return m_id;
+}
+
+void NetworkLink::setLinkConsumer(FlexibleConsumer *consumer)
+{
+ link_consumer = consumer;
+}
+
+void NetworkLink::setSourceQueue(flitBuffer *srcQueue)
+{
+ link_srcQueue = srcQueue;
+}
+
+void NetworkLink::setSource(FlexibleConsumer *source)
+{
+ link_source = source;
+}
+void NetworkLink::request_vc_link(int vc, NetDest destination, Time request_time)
+{
+ link_consumer->request_vc(vc, m_in_port, destination, request_time);
+}
+bool NetworkLink::isBufferNotFull_link(int vc)
+{
+ return link_consumer->isBufferNotFull(vc, m_in_port);
+}
+
+void NetworkLink::grant_vc_link(int vc, Time grant_time)
+{
+ link_source->grant_vc(m_out_port, vc, grant_time);
+}
+
+void NetworkLink::release_vc_link(int vc, Time release_time)
+{
+ link_source->release_vc(m_out_port, vc, release_time);
+}
+
+Vector<int> NetworkLink::getVcLoad()
+{
+ return m_vc_load;
+}
+
+double NetworkLink::getLinkUtilization()
+{
+ Time m_ruby_start = m_net_ptr->getRubyStartTime();
+ return (double(m_link_utilized)) / (double(g_eventQueue_ptr->getTime()-m_ruby_start));
+}
+
+bool NetworkLink::isReady()
+{
+ return linkBuffer->isReady();
+}
+
+void NetworkLink::setInPort(int port)
+{
+ m_in_port = port;
+}
+
+void NetworkLink::setOutPort(int port)
+{
+ m_out_port = port;
+}
+
+void NetworkLink::wakeup()
+{
+ if(link_srcQueue->isReady())
+ {
+ flit *t_flit = link_srcQueue->getTopFlit();
+ t_flit->set_time(g_eventQueue_ptr->getTime() + m_latency);
+ linkBuffer->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(link_consumer, m_latency);
+ m_link_utilized++;
+ m_vc_load[t_flit->get_vc()]++;
+ }
+}
+
+flit* NetworkLink::peekLink()
+{
+ return linkBuffer->peekTopFlit();
+}
+
+flit* NetworkLink::consumeLink()
+{
+ return linkBuffer->getTopFlit();
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh
new file mode 100644
index 000000000..cdea89d79
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetworkLink.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+#ifndef NETWORK_LINK_H
+#define NETWORK_LINK_H
+
+#include "NetworkHeader.hh"
+#include "FlexibleConsumer.hh"
+#include "flitBuffer.hh"
+#include "PrioHeap.hh"
+#include "NetDest.hh"
+
+class GarnetNetwork;
+
+class NetworkLink : public FlexibleConsumer {
+public:
+ NetworkLink();
+ NetworkLink(int id, int latency, GarnetNetwork *net_ptr);
+ ~NetworkLink();
+
+ void setLinkConsumer(FlexibleConsumer *consumer);
+ void setSourceQueue(flitBuffer *srcQueue);
+ flit* peekLink();
+ flit* consumeLink();
+
+ void print(ostream& out) const {}
+
+ bool is_vc_ready(flit *t_flit);
+
+ int get_id();
+ void setInPort(int port);
+ void setOutPort(int port);
+ void wakeup();
+ bool isReady();
+ void grant_vc_link(int vc, Time grant_time);
+ void release_vc_link(int vc, Time release_time);
+ void request_vc_link(int vc, NetDest destination, Time request_time);
+ bool isBufferNotFull_link(int vc);
+ void setSource(FlexibleConsumer *source);
+ double getLinkUtilization();
+ Vector<int> getVcLoad();
+
+protected:
+ int m_id, m_latency;
+ int m_in_port, m_out_port;
+ int m_link_utilized;
+ Vector<int > m_vc_load;
+ GarnetNetwork *m_net_ptr;
+
+ flitBuffer *linkBuffer;
+ FlexibleConsumer *link_consumer;
+ FlexibleConsumer *link_source;
+ flitBuffer *link_srcQueue;
+};
+
+#endif
+
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc
new file mode 100644
index 000000000..5d43a7821
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * OutVCState.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "OutVcState.hh"
+
+OutVcState::OutVcState(int id)
+{
+ m_id = id;
+ m_vc_state = IDLE_;
+}
+
+bool OutVcState::isInState(VC_state_type state, Time request_time)
+{
+ return ((m_vc_state == state) && (request_time >= m_time) );
+}
+
+void OutVcState::grant_vc(Time grant_time)
+{
+ m_time = grant_time;
+ m_vc_state = ACTIVE_;
+}
+
+void OutVcState::setState(VC_state_type state, Time time)
+{
+ m_vc_state = state;
+ m_time = time;
+}
+
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh
new file mode 100644
index 000000000..81120ee8c
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * OutVCState.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef OUT_VC_STATE_H
+#define OUT_VC_STATE_H
+
+#include "NetworkHeader.hh"
+
+class OutVcState {
+public:
+ OutVcState(int id);
+
+ bool isInState(VC_state_type state, Time request_time);
+ void setState(VC_state_type state, Time time);
+ void grant_vc(Time grant_time);
+
+private:
+ int m_id ;
+ Time m_time;
+ VC_state_type m_vc_state;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
new file mode 100644
index 000000000..4809d43ed
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Router.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "Router.hh"
+#include "NetworkMessage.hh"
+#include "InVcState.hh"
+#include "OutVcState.hh"
+#include "VCarbiter.hh"
+
+Router::Router(int id, GarnetNetwork *network_ptr)
+{
+ m_id = id;
+ m_net_ptr = network_ptr;
+ m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS;
+ m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_round_robin_inport = 0;
+ m_round_robin_start = 0;
+ m_num_vcs = m_vc_per_vnet*m_virtual_networks;
+ m_vc_arbiter = new VCarbiter(this);
+}
+
+Router::~Router()
+{
+ for (int i = 0; i < m_in_link.size(); i++)
+ {
+ m_in_vc_state[i].deletePointers();
+ }
+ for (int i = 0; i < m_out_link.size(); i++)
+ {
+ m_out_vc_state[i].deletePointers();
+ m_router_buffers[i].deletePointers();
+ }
+ m_out_src_queue.deletePointers();
+ delete m_vc_arbiter;
+
+}
+
+void Router::addInPort(NetworkLink *in_link)
+{
+ int port = m_in_link.size();
+ Vector<InVcState *> in_vc_vector;
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ in_vc_vector.insertAtBottom(new InVcState(i));
+ in_vc_vector[i]->setState(IDLE_, g_eventQueue_ptr->getTime());
+ }
+ m_in_vc_state.insertAtBottom(in_vc_vector);
+ m_in_link.insertAtBottom(in_link);
+ in_link->setLinkConsumer(this);
+ in_link->setInPort(port);
+
+ int start = 0;
+ m_round_robin_invc.insertAtBottom(start);
+
+}
+
+void Router::addOutPort(NetworkLink *out_link, const NetDest& routing_table_entry, int link_weight)
+{
+ int port = m_out_link.size();
+ out_link->setOutPort(port);
+ int start = 0;
+ m_vc_round_robin.insertAtBottom(start);
+
+ m_out_src_queue.insertAtBottom(new flitBuffer());
+
+ m_out_link.insertAtBottom(out_link);
+ m_routing_table.insertAtBottom(routing_table_entry);
+ out_link->setSourceQueue(m_out_src_queue[port]);
+ out_link->setSource(this);
+
+ Vector<flitBuffer *> intermediateQueues;
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ intermediateQueues.insertAtBottom(new flitBuffer(NetworkConfig::getBufferSize()));
+ }
+ m_router_buffers.insertAtBottom(intermediateQueues);
+
+ Vector<OutVcState *> out_vc_vector;
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ out_vc_vector.insertAtBottom(new OutVcState(i));
+ out_vc_vector[i]->setState(IDLE_, g_eventQueue_ptr->getTime());
+ }
+ m_out_vc_state.insertAtBottom(out_vc_vector);
+ m_link_weights.insertAtBottom(link_weight);
+}
+
+bool Router::isBufferNotFull(int vc, int inport)
+{
+ int outport = m_in_vc_state[inport][vc]->get_outport();
+ int outvc = m_in_vc_state[inport][vc]->get_outvc();
+
+ return (!m_router_buffers[outport][outvc]->isFull());
+}
+
+// A request for an output vc has been placed by an upstream Router/NI. This has to be updated and arbitration performed
+void Router::request_vc(int in_vc, int in_port, NetDest destination, Time request_time)
+{
+ assert(m_in_vc_state[in_port][in_vc]->isInState(IDLE_, request_time));
+
+ int outport = getRoute(destination);
+ m_in_vc_state[in_port][in_vc]->setRoute(outport);
+ m_in_vc_state[in_port][in_vc]->setState(VC_AB_, request_time);
+ assert(request_time >= g_eventQueue_ptr->getTime());
+ if(request_time > g_eventQueue_ptr->getTime())
+ g_eventQueue_ptr->scheduleEventAbsolute(m_vc_arbiter, request_time);
+ else
+ vc_arbitrate();
+}
+
+void Router::vc_arbitrate()
+{
+ int inport = m_round_robin_inport;
+ m_round_robin_inport++;
+ if(m_round_robin_inport == m_in_link.size())
+ m_round_robin_inport = 0;
+
+ for(int port_iter = 0; port_iter < m_in_link.size(); port_iter++)
+ {
+ inport++;
+ if(inport >= m_in_link.size())
+ inport = 0;
+ int invc = m_round_robin_invc[inport];
+ m_round_robin_invc[inport]++;
+
+ if(m_round_robin_invc[inport] >= m_num_vcs)
+ m_round_robin_invc[inport] = 0;
+ for(int vc_iter = 0; vc_iter < m_num_vcs; vc_iter++)
+ {
+ invc++;
+ if(invc >= m_num_vcs)
+ invc = 0;
+ InVcState *in_vc_state = m_in_vc_state[inport][invc];
+
+ if(in_vc_state->isInState(VC_AB_, g_eventQueue_ptr->getTime()))
+ {
+ int outport = in_vc_state->get_outport();
+ Vector<int > valid_vcs = get_valid_vcs(invc);
+ for(int valid_vc_iter = 0; valid_vc_iter < valid_vcs.size(); valid_vc_iter++)
+ {
+ if(m_out_vc_state[outport][valid_vcs[valid_vc_iter]]->isInState(IDLE_, g_eventQueue_ptr->getTime()))
+ {
+ in_vc_state->grant_vc(valid_vcs[valid_vc_iter], g_eventQueue_ptr->getTime());
+ m_in_link[inport]->grant_vc_link(invc, g_eventQueue_ptr->getTime());
+ m_out_vc_state[outport][valid_vcs[valid_vc_iter]]->setState(VC_AB_, g_eventQueue_ptr->getTime());
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+Vector<int > Router::get_valid_vcs(int invc)
+{
+ Vector<int > vc_list;
+
+ for(int vnet = 0; vnet < m_virtual_networks; vnet++)
+ {
+ if(invc >= (vnet*m_vc_per_vnet) && invc < ((vnet+1)*m_vc_per_vnet))
+ {
+ int base = vnet*m_vc_per_vnet;
+ int vc_per_vnet;
+ if(m_net_ptr->isVNetOrdered(vnet))
+ vc_per_vnet = 1;
+ else
+ vc_per_vnet = m_vc_per_vnet;
+
+ for(int offset = 0; offset < vc_per_vnet; offset++)
+ {
+ vc_list.insertAtBottom(base+offset);
+ }
+ break;
+ }
+ }
+ return vc_list;
+}
+
+void Router::grant_vc(int out_port, int vc, Time grant_time)
+{
+ assert(m_out_vc_state[out_port][vc]->isInState(VC_AB_, grant_time));
+ m_out_vc_state[out_port][vc]->grant_vc(grant_time);
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+}
+
+void Router::release_vc(int out_port, int vc, Time release_time)
+{
+ assert(m_out_vc_state[out_port][vc]->isInState(ACTIVE_, release_time));
+ m_out_vc_state[out_port][vc]->setState(IDLE_, release_time);
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+}
+
+// This function calculated the output port for a particular destination.
+int Router::getRoute(NetDest destination)
+{
+ int output_link = -1;
+ int min_weight = INFINITE_;
+ for(int link = 0; link < m_routing_table.size(); link++)
+ {
+ if (destination.intersectionIsNotEmpty(m_routing_table[link]))
+ {
+ if((m_link_weights[link] >= min_weight))
+ continue;
+ output_link = link;
+ min_weight = m_link_weights[link];
+ }
+ }
+ return output_link;
+}
+
+void Router::routeCompute(flit *m_flit, int inport)
+{
+ int invc = m_flit->get_vc();
+ int outport = m_in_vc_state[inport][invc]->get_outport();
+ int outvc = m_in_vc_state[inport][invc]->get_outvc();
+
+ assert(NetworkConfig::getNumPipeStages() >= 1);
+ m_flit->set_time(g_eventQueue_ptr->getTime() + (NetworkConfig::getNumPipeStages() - 1)); // Becasuse 1 cycle will be consumed in scheduling the output link
+ m_flit->set_vc(outvc);
+ m_router_buffers[outport][outvc]->insert(m_flit);
+
+ if(NetworkConfig::getNumPipeStages() > 1)
+ g_eventQueue_ptr->scheduleEvent(this, NetworkConfig::getNumPipeStages() -1 );
+ if((m_flit->get_type() == HEAD_) || (m_flit->get_type() == HEAD_TAIL_))
+ {
+ NetDest destination = dynamic_cast<NetworkMessage*>(m_flit->get_msg_ptr().ref())->getInternalDestination();
+ if(NetworkConfig::getNumPipeStages() > 1)
+ {
+ m_out_vc_state[outport][outvc]->setState(VC_AB_, g_eventQueue_ptr->getTime() + 1);
+ m_out_link[outport]->request_vc_link(outvc, destination, g_eventQueue_ptr->getTime() + 1);
+ }
+ else
+ {
+ m_out_vc_state[outport][outvc]->setState(VC_AB_, g_eventQueue_ptr->getTime());
+ m_out_link[outport]->request_vc_link(outvc, destination, g_eventQueue_ptr->getTime());
+ }
+ }
+ if((m_flit->get_type() == TAIL_) || (m_flit->get_type() == HEAD_TAIL_))
+ {
+ m_in_vc_state[inport][invc]->setState(IDLE_, g_eventQueue_ptr->getTime() + 1);
+ m_in_link[inport]->release_vc_link(invc, g_eventQueue_ptr->getTime() + 1);
+ }
+}
+
+void Router::wakeup()
+{
+ flit *t_flit;
+
+ int incoming_port = m_round_robin_start; // This is for round-robin scheduling of incoming ports
+ m_round_robin_start++;
+ if (m_round_robin_start >= m_in_link.size()) {
+ m_round_robin_start = 0;
+ }
+
+ for(int port = 0; port < m_in_link.size(); port++)
+ {
+ // Round robin scheduling
+ incoming_port++;
+ if(incoming_port >= m_in_link.size())
+ incoming_port = 0;
+ if(m_in_link[incoming_port]->isReady()) // checking the incoming link
+ {
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, m_id);
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, g_eventQueue_ptr->getTime());
+ t_flit = m_in_link[incoming_port]->peekLink();
+ routeCompute(t_flit, incoming_port);
+ m_in_link[incoming_port]->consumeLink();
+ }
+ }
+ scheduleOutputLinks();
+ checkReschedule(); // This is for flits lying in the router buffers
+ vc_arbitrate();
+ check_arbiter_reschedule();
+}
+
+void Router::scheduleOutputLinks()
+{
+ for(int port = 0; port < m_out_link.size(); port++)
+ {
+ int vc_tolookat = m_vc_round_robin[port];
+ m_vc_round_robin[port]++;
+ if(m_vc_round_robin[port] == m_num_vcs)
+ m_vc_round_robin[port] = 0;
+
+ for(int i = 0; i < m_num_vcs; i++)
+ {
+ vc_tolookat++;
+ if(vc_tolookat == m_num_vcs)
+ vc_tolookat = 0;
+
+ if(m_router_buffers[port][vc_tolookat]->isReady())
+ {
+ if(m_out_vc_state[port][vc_tolookat]->isInState(ACTIVE_, g_eventQueue_ptr->getTime()) && m_out_link[port]->isBufferNotFull_link(vc_tolookat))
+ // models buffer backpressure
+ {
+ flit *t_flit = m_router_buffers[port][vc_tolookat]->getTopFlit();
+ t_flit->set_time(g_eventQueue_ptr->getTime() + 1 );
+ m_out_src_queue[port]->insert(t_flit);
+ g_eventQueue_ptr->scheduleEvent(m_out_link[port], 1);
+ break; // done for this port
+ }
+ }
+ }
+ }
+}
+
+void Router::checkReschedule()
+{
+ for(int port = 0; port < m_out_link.size(); port++)
+ {
+ for(int vc = 0; vc < m_num_vcs; vc++)
+ {
+ if(m_router_buffers[port][vc]->isReadyForNext())
+ {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ return;
+ }
+ }
+ }
+}
+
+void Router::check_arbiter_reschedule()
+{
+ for(int port = 0; port < m_in_link.size(); port++)
+ {
+ for(int vc = 0; vc < m_num_vcs; vc++)
+ {
+ if(m_in_vc_state[port][vc]->isInState(VC_AB_, g_eventQueue_ptr->getTime() + 1))
+ {
+ g_eventQueue_ptr->scheduleEvent(m_vc_arbiter, 1);
+ return;
+ }
+ }
+ }
+}
+
+void Router::printConfig(ostream& out) const
+{
+ out << "[Router " << m_id << "] :: " << endl;
+ out << "[inLink - ";
+ for(int i = 0;i < m_in_link.size(); i++)
+ out << m_in_link[i]->get_id() << " - ";
+ out << "]" << endl;
+ out << "[outLink - ";
+ for(int i = 0;i < m_out_link.size(); i++)
+ out << m_out_link[i]->get_id() << " - ";
+ out << "]" << endl;
+/* out << "---------- routing table -------------" << endl;
+ for(int i =0; i < m_routing_table.size(); i++)
+ out << m_routing_table[i] << endl;
+*/
+}
+
+void Router::print(ostream& out) const
+{
+ out << "[Router]";
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh
new file mode 100644
index 000000000..c0d91e0dd
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Router.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef ROUTER_H
+#define ROUTER_H
+
+#include "NetworkHeader.hh"
+#include "GarnetNetwork.hh"
+#include "FlexibleConsumer.hh"
+#include "PrioHeap.hh"
+#include "NetworkLink.hh"
+#include "NetDest.hh"
+#include "flitBuffer.hh"
+#include "InVcState.hh"
+#include "OutVcState.hh"
+
+class VCarbiter;
+
+class Router : public FlexibleConsumer {
+public:
+ Router(int id, GarnetNetwork *network_ptr);
+
+ ~Router();
+
+ void addInPort(NetworkLink *in_link);
+ void addOutPort(NetworkLink *out_link, const NetDest& routing_table_entry, int link_weight);
+ void wakeup();
+ void request_vc(int in_vc, int in_port, NetDest destination, Time request_time);
+ bool isBufferNotFull(int vc, int inport);
+ void grant_vc(int out_port, int vc, Time grant_time);
+ void release_vc(int out_port, int vc, Time release_time);
+ void vc_arbitrate();
+
+ void printConfig(ostream& out) const;
+ void print(ostream& out) const;
+
+private:
+/***************Data Members******************/
+ int m_id;
+ int m_virtual_networks, m_num_vcs, m_vc_per_vnet;
+ GarnetNetwork *m_net_ptr;
+ Vector<int > m_vc_round_robin; // For scheduling of out source queues
+ int m_round_robin_inport, m_round_robin_start; // for vc arbitration
+ Vector<int > m_round_robin_invc; // For every outport. for vc arbitration
+
+ Vector<Vector<flitBuffer *> > m_router_buffers; // These are essentially output buffers
+ Vector<flitBuffer *> m_out_src_queue; // These are source queues for the output link
+ Vector<NetworkLink *> m_in_link;
+ Vector<NetworkLink *> m_out_link;
+ Vector<Vector<InVcState * > > m_in_vc_state;
+ Vector<Vector<OutVcState * > > m_out_vc_state;
+ Vector<NetDest> m_routing_table;
+ Vector<int > m_link_weights;
+ VCarbiter *m_vc_arbiter;
+
+/*********** Private methods *************/
+ int getRoute(NetDest destination);
+ Vector<int > get_valid_vcs(int invc);
+ void routeCompute(flit *m_flit, int inport);
+ void checkReschedule();
+ void check_arbiter_reschedule();
+ void scheduleOutputLinks();
+};
+
+#endif
+
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc
new file mode 100644
index 000000000..7ebd83de3
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * VCarbiter.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "VCarbiter.hh"
+#include "Router.hh"
+
+VCarbiter::VCarbiter(Router *router)
+{
+ m_router = router;
+}
+
+void VCarbiter::wakeup()
+{
+ m_router->vc_arbitrate();
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh
new file mode 100644
index 000000000..10368f2b4
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * VCarbiter.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef VC_ARBITER_H
+#define VC_ARBITER_H
+
+#include "NetworkHeader.hh"
+#include "Consumer.hh"
+
+class Router;
+
+class VCarbiter : public Consumer{
+public:
+ VCarbiter(Router *router);
+ ~VCarbiter() {}
+
+ void print(ostream& out) const {}
+ void wakeup();
+
+private:
+ Router *m_router;
+};
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc
new file mode 100644
index 000000000..f3cba2035
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flit.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "flit.hh"
+
+flit::flit(int id, int vc, int vnet, int size, MsgPtr msg_ptr)
+{
+ m_size = size;
+ m_msg_ptr = msg_ptr;
+ m_enqueue_time = g_eventQueue_ptr->getTime();
+ m_time = g_eventQueue_ptr->getTime();
+ m_id = id;
+ m_vnet = vnet;
+ m_vc = vc;
+
+ if(size == 1)
+ {
+ m_type = HEAD_TAIL_;
+ return;
+ }
+ if(id == 0)
+ m_type = HEAD_;
+ else if(id == (size - 1))
+ m_type = TAIL_;
+ else
+ m_type = BODY_;
+}
+
+int flit::get_size()
+{
+ return m_size;
+}
+int flit::get_id()
+{
+ return m_id;
+}
+Time flit::get_time()
+{
+ return m_time;
+}
+
+Time flit::get_enqueue_time()
+{
+ return m_enqueue_time;
+}
+void flit::set_time(Time time)
+{
+ m_time = time;
+}
+
+int flit::get_vnet()
+{
+ return m_vnet;
+}
+int flit::get_vc()
+{
+ return m_vc;
+}
+void flit::set_vc(int vc)
+{
+ m_vc = vc;
+}
+MsgPtr& flit::get_msg_ptr()
+{
+ return m_msg_ptr;
+}
+flit_type flit::get_type()
+{
+ return m_type;
+}
+
+void flit::print(ostream& out) const
+{
+ out << "[flit:: ";
+ out << "Id=" << m_id << " ";
+ out << "Type=" << m_type << " ";
+ out << "Vnet=" << m_vnet << " ";
+ out << "VC=" << m_vc << " ";
+ out << "Enqueue Time=" << m_enqueue_time << " ";
+ out << "]";
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh
new file mode 100644
index 000000000..fc8042cfc
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flit.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "NetworkHeader.hh"
+#include "Message.hh"
+
+#ifndef FLIT_H
+#define FLIT_H
+
+class flit {
+public:
+ flit(int id, int vc, int vnet, int size, MsgPtr msg_ptr);
+
+ int get_size();
+ int get_id();
+ Time get_time();
+ Time get_enqueue_time();
+ void set_time(Time time);
+ int get_vnet();
+ int get_vc();
+ void set_vc(int vc);
+ MsgPtr& get_msg_ptr();
+ flit_type get_type();
+ void print(ostream&out) const;
+
+private:
+/************Data Members*************/
+ int m_id;
+ int m_vnet;
+ int m_vc;
+ int m_size;
+ Time m_enqueue_time, m_time;
+ flit_type m_type;
+ MsgPtr m_msg_ptr;
+
+};
+
+inline extern bool node_less_then_eq(flit* n1, flit* n2);
+
+inline extern
+bool node_less_then_eq(flit* n1, flit* n2)
+{
+ if (n1->get_time() == n2->get_time()) {
+// ASSERT(n1->flit_id != n2->flit_id);
+ return (n1->get_id() <= n2->get_id());
+ } else {
+ return (n1->get_time() <= n2->get_time());
+ }
+}
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const flit& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const flit& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc
new file mode 100644
index 000000000..e0fb26e0a
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flitBuffer.C
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#include "flitBuffer.hh"
+
+flitBuffer::flitBuffer()
+{
+ max_size = INFINITE_;
+}
+
+flitBuffer::flitBuffer(int maximum_size)
+{
+ max_size = maximum_size;
+}
+
+bool flitBuffer::isEmpty()
+{
+ return (m_buffer.size() == 0);
+}
+
+bool flitBuffer::isReady()
+{
+ if(m_buffer.size() != 0 )
+ {
+ flit *t_flit = m_buffer.peekMin();
+ if(t_flit->get_time() <= g_eventQueue_ptr->getTime())
+ return true;
+ }
+ return false;
+}
+
+bool flitBuffer::isReadyForNext()
+{
+ if(m_buffer.size() != 0 )
+ {
+ flit *t_flit = m_buffer.peekMin();
+ if(t_flit->get_time() <= (g_eventQueue_ptr->getTime() + 1))
+ return true;
+ }
+ return false;
+}
+
+bool flitBuffer::isFull()
+{
+ return (m_buffer.size() >= max_size);
+}
+
+void flitBuffer::setMaxSize(int maximum)
+{
+ max_size = maximum;
+}
+
+flit* flitBuffer:: getTopFlit()
+{
+ return m_buffer.extractMin();
+}
+
+flit* flitBuffer::peekTopFlit()
+{
+ return m_buffer.peekMin();
+}
+
+void flitBuffer::insert(flit *flt)
+{
+ m_buffer.insert(flt);
+}
+
+void flitBuffer::print(ostream& out) const
+{
+ out << "[flitBuffer: ";
+ out << m_buffer.size() << "] " << endl;
+}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh
new file mode 100644
index 000000000..1eb122a51
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * flitBuffer.h
+ *
+ * Niket Agarwal, Princeton University
+ *
+ * */
+
+#ifndef FLIT_BUFFER_H
+#define FLIT_BUFFER_H
+
+#include "NetworkHeader.hh"
+#include "PrioHeap.hh"
+#include "flit.hh"
+
+class flitBuffer {
+public:
+ flitBuffer();
+ flitBuffer(int maximum_size);
+
+ bool isReady();
+ bool isReadyForNext();
+ bool isFull();
+ bool isEmpty();
+ void setMaxSize(int maximum);
+ flit *getTopFlit();
+ flit *peekTopFlit();
+ void insert(flit *flt);
+ void print(ostream& out) const;
+
+/**********Data Members*********/
+private:
+ PrioHeap <flit *> m_buffer;
+ int size, max_size;
+};
+
+ostream& operator<<(ostream& out, const flitBuffer& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const flitBuffer& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif
+
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/netconfig.defaults b/src/mem/ruby/network/garnet-flexible-pipeline/netconfig.defaults
new file mode 100644
index 000000000..e60f1921d
--- /dev/null
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/netconfig.defaults
@@ -0,0 +1,8 @@
+// Note: You should set Garnet's parameters in config/rubyconfig.defaults and not here
+g_GARNET_NETWORK:true
+g_DETAIL_NETWORK:true
+g_NETWORK_TESTING:false
+g_FLIT_SIZE:16
+g_NUM_PIPE_STAGES:4
+g_VCS_PER_CLASS:4
+g_BUFFER_SIZE:4
diff --git a/src/mem/ruby/network/orion/NetworkPower.cc b/src/mem/ruby/network/orion/NetworkPower.cc
new file mode 100644
index 000000000..6e5994071
--- /dev/null
+++ b/src/mem/ruby/network/orion/NetworkPower.cc
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "power_router_init.hh"
+#include "power_array.hh"
+#include "power_crossbar.hh"
+#include "power_arbiter.hh"
+#include "power_bus.hh"
+#include "NetworkPower.hh"
+#include "Router_d.hh"
+#include "NetworkLink_d.hh"
+#include "GarnetNetwork_d.hh"
+#include "SIM_port.hh"
+#include "parm_technology.hh"
+
+/* --------- Static energy calculation functions ------------ */
+
+//Input buffer
+double SIM_reg_stat_energy(power_array_info *info, power_array *arr, double n_read, double n_write)
+{
+ double Eavg = 0, Eatomic, Estruct, Estatic;
+
+
+ /* decoder */
+ if (info->row_dec_model) {
+ //row decoder
+ Estruct = 0;
+ /* assume switch probability 0.5 for address bits */
+ //input
+ Eatomic = arr->row_dec.e_chg_addr * arr->row_dec.n_bits * SWITCHING_FACTOR * (n_read + n_write);
+ Estruct += Eatomic;
+
+ //output
+ Eatomic = arr->row_dec.e_chg_output * (n_read + n_write);
+ Estruct += Eatomic;
+
+ /* assume all 1st-level decoders change output */
+ //internal node
+ Eatomic = arr->row_dec.e_chg_l1 * arr->row_dec.n_in_2nd * (n_read + n_write);
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+ }
+
+ /* wordline */
+ Estruct = 0;
+ //read
+ Eatomic = arr->data_wordline.e_read * n_read;
+ Estruct += Eatomic;
+ //write
+ Eatomic = arr->data_wordline.e_write * n_write;
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+
+ /* bitlines */
+ Estruct = 0;
+ //read
+ if (arr->data_bitline.end == 2) {
+ Eatomic = arr->data_bitline.e_col_read * info->eff_data_cols * n_read;
+ }
+ else {
+ /* assume switch probability 0.5 for single-ended bitlines */
+ Eatomic = arr->data_bitline.e_col_read * info->eff_data_cols * SWITCHING_FACTOR * n_read;
+ }
+
+ Estruct += Eatomic;
+ //write
+ /* assume switch probability 0.5 for write bitlines */
+ Eatomic = arr->data_bitline.e_col_write * info->data_width * SWITCHING_FACTOR * n_write;
+ Estruct += Eatomic;
+ //precharge
+ Eatomic = arr->data_bitline_pre.e_charge * info->eff_data_cols * n_read;
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+
+ /* memory cells */
+ Estruct = 0;
+
+ /* assume switch probability 0.5 for memory cells */
+ Eatomic = arr->data_mem.e_switch * info->data_width * SWITCHING_FACTOR * n_write;
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+
+ /* sense amplifier */
+ if (info->data_end == 2) {
+ Estruct = 0;
+
+ Eatomic = arr->data_amp.e_access * info->eff_data_cols * n_read;
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+ }
+
+ /* output driver */
+ if (info->outdrv_model) {
+ Estruct = 0;
+ //enable
+ Eatomic = arr->outdrv.e_select * n_read;
+ Estruct += Eatomic;
+ //data
+ /* same switch probability as bitlines */
+ Eatomic = arr->outdrv.e_chg_data * arr->outdrv.item_width * SWITCHING_FACTOR * info->n_item * info->assoc * n_read;
+ Estruct += Eatomic;
+ //output 1
+ /* assume 1 and 0 are uniformly distributed */
+ if (arr->outdrv.e_out_1 >= arr->outdrv.e_out_0 ) {
+ Eatomic = arr->outdrv.e_out_1 * arr->outdrv.item_width * SWITCHING_FACTOR * n_read;
+ Estruct += Eatomic;
+ }
+ //output 0
+ if (arr->outdrv.e_out_1 < arr->outdrv.e_out_0) {
+ Eatomic = arr->outdrv.e_out_0 * arr->outdrv.item_width * SWITCHING_FACTOR * n_read;
+ Estruct += Eatomic;
+ }
+
+ Eavg += Estruct;
+ }
+
+ /* static power */
+ Estatic = arr->i_leakage * Vdd * Period * SCALE_S;
+
+ //static energy
+ Eavg += Estatic;
+
+ return Eavg;
+}
+
+//crossbar
+double SIM_crossbar_stat_energy(power_crossbar *crsbar, double n_data)
+{
+ double Eavg = 0, Eatomic, Estatic;
+
+ if (n_data > crsbar->n_out) {
+ n_data = crsbar->n_out;
+ }
+
+
+ switch (crsbar->model) {
+ case MATRIX_CROSSBAR:
+ case CUT_THRU_CROSSBAR:
+ case MULTREE_CROSSBAR:
+ /* assume 0.5 data switch probability */
+ //input
+ Eatomic = crsbar->e_chg_in * crsbar->data_width * SWITCHING_FACTOR * n_data;
+ Eavg += Eatomic;
+
+ //output
+ Eatomic = crsbar->e_chg_out * crsbar->data_width * SWITCHING_FACTOR * n_data;
+ Eavg += Eatomic;
+
+ //control
+ Eatomic = crsbar->e_chg_ctr * n_data;
+ Eavg += Eatomic;
+
+ if (crsbar->model == MULTREE_CROSSBAR && crsbar->depth > 1) {
+ //internal node
+ Eatomic = crsbar->e_chg_int * crsbar->data_width * (crsbar->depth - 1) * SWITCHING_FACTOR * n_data;
+ Eavg += Eatomic;
+ }
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return Eavg;
+}
+
+//arbiter
+/* stat over one cycle */
+/* info is only used by queuing arbiter */
+double SIM_arbiter_stat_energy(power_arbiter *arb, power_array_info *info, double n_req)
+{
+ double Eavg = 0, Estruct, Eatomic;
+ double total_pri, n_chg_pri, n_grant;
+
+ /* energy cycle distribution */
+ if (n_req > arb->req_width) {
+ n_req = arb->req_width;
+ }
+ if (n_req >= 1) n_grant = 1;
+ else n_grant = 1.0 / ceil(1.0 / n_req);
+
+ switch (arb->model) {
+ case RR_ARBITER:
+ /* FIXME: we may overestimate request switch */
+ //request
+ Eatomic = arb->e_chg_req * n_req;
+ Eavg += Eatomic;
+
+ //grant
+ Eatomic = arb->e_chg_grant * n_grant;
+ Eavg += Eatomic;
+
+ /* assume carry signal propagates half length in average case */
+ /* carry does not propagate in maximum case, i.e. all carrys go down */
+ //carry
+ Eatomic = arb->e_chg_carry * arb->req_width * SWITCHING_FACTOR * n_grant;
+ Eavg += Eatomic;
+
+ //internal carry
+ Eatomic = arb->e_chg_carry_in * (arb->req_width * SWITCHING_FACTOR - 1) * n_grant;
+ Eavg += Eatomic;
+
+ /* priority registers */
+ Estruct = 0;
+ //priority
+
+ //switch
+ Eatomic = arb->pri_ff.e_switch * 2 * n_grant;
+ Estruct += Eatomic;
+
+ //keep 0
+ Eatomic = arb->pri_ff.e_keep_0 * (arb->req_width - 2 * n_grant);
+ Estruct += Eatomic;
+
+ //clock
+ Eatomic = arb->pri_ff.e_clock * arb->req_width;
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+ break;
+
+ case MATRIX_ARBITER:
+ total_pri = arb->req_width * (arb->req_width - 1) * 0.5;
+ /* assume switch probability 0.5 for priorities */
+ n_chg_pri = (arb->req_width - 1) * SWITCHING_FACTOR;
+
+ /* FIXME: we may overestimate request switch */
+ //request
+ Eatomic = arb->e_chg_req * n_req;
+ Eavg += Eatomic;
+
+ //grant
+ Eatomic = arb->e_chg_grant * n_grant;
+ Eavg += Eatomic;
+
+ /* priority registers */
+ Estruct = 0;
+ //priority
+
+ //switch
+ Eatomic = arb->pri_ff.e_switch * n_chg_pri * n_grant;
+ Estruct += Eatomic;
+
+ /* assume 1 and 0 are uniformly distributed */
+ //keep 0
+ if (arb->pri_ff.e_keep_0 >= arb->pri_ff.e_keep_1) {
+ Eatomic = arb->pri_ff.e_keep_0 * (total_pri - n_chg_pri * n_grant) * SWITCHING_FACTOR;
+ Estruct += Eatomic;
+ }
+
+ //keep 1
+ if (arb->pri_ff.e_keep_0 < arb->pri_ff.e_keep_1) {
+ Eatomic = arb->pri_ff.e_keep_1 * (total_pri - n_chg_pri * n_grant) * SWITCHING_FACTOR;
+ Estruct += Eatomic;
+ }
+
+ //clock
+ Eatomic = arb->pri_ff.e_clock * total_pri;
+ Estruct += Eatomic;
+
+ Eavg += Estruct;
+
+ /* based on above assumptions */
+ //internal node
+ /* p(n-1)/2 + (n-1)/2 */
+ Eatomic = arb->e_chg_mint * (n_req + 1) * (arb->req_width - 1) * 0.5;
+ Eavg += Eatomic;
+ break;
+
+ case QUEUE_ARBITER:
+ /* FIXME: what if n_req > 1? */
+ Eavg = SIM_reg_stat_energy(info, &arb->queue, n_req, n_grant);
+ break;
+
+ default: break;/* some error handler */
+ }
+
+
+ return Eavg;
+}
+
+double SIM_bus_stat_energy(power_bus *bus, double e_link)
+{
+ double Ebus;
+ Ebus = bus->e_switch * e_link * SWITCHING_FACTOR * bus->bit_width;
+
+ return (Ebus);
+}
+
+double Router_d::calculate_offline_power(power_router *router, power_router_info *info)
+{
+ double Eavg = 0;
+ double P_in_buf, P_xbar, P_vc_in_arb, P_vc_out_arb, P_sw_in_arb, P_sw_out_arb, P_leakage, P_total;
+
+ double E_in_buf, E_xbar, E_vc_in_arb, E_vc_out_arb, E_sw_in_arb, E_sw_out_arb, E_leakage;
+ double e_in_buf_read, e_in_buf_write, e_crossbar, e_vc_local_arb, e_vc_global_arb, e_sw_local_arb, e_sw_global_arb;
+ double sim_cycles;
+
+ sim_cycles = g_eventQueue_ptr->getTime() - m_network_ptr->getRubyStartTime();
+
+ calculate_performance_numbers();
+ //counts obtained from perf. simulator
+ e_in_buf_read = (double )(buf_read_count/sim_cycles);
+ e_in_buf_write = (double )(buf_write_count/sim_cycles);
+ e_crossbar = (double )(crossbar_count/sim_cycles);
+ e_vc_local_arb = (double)(vc_local_arbit_count/sim_cycles);
+ e_vc_global_arb = (double)(vc_global_arbit_count/sim_cycles);
+ e_sw_local_arb = (double )(sw_local_arbit_count/sim_cycles);
+ e_sw_global_arb = (double )(sw_global_arbit_count/sim_cycles);
+ // e_link = (double )(link_traversal_count/sim_cycles);
+
+ /* input buffers */
+ if (info->in_buf)
+ E_in_buf = SIM_reg_stat_energy(&info->in_buf_info, &router->in_buf, e_in_buf_read, e_in_buf_write);
+ P_in_buf = E_in_buf * PARM_Freq;
+ Eavg += E_in_buf;
+
+ /* main crossbar */
+ if (info->crossbar_model)
+ E_xbar= SIM_crossbar_stat_energy(&router->crossbar, e_crossbar);
+ P_xbar = E_xbar * PARM_Freq;
+ Eavg += E_xbar;
+
+ /* vc input (local) arbiter */
+ if (info->vc_in_arb_model)
+ E_vc_in_arb = SIM_arbiter_stat_energy(&router->vc_in_arb, &info->vc_in_arb_queue_info, e_sw_local_arb);
+ P_vc_in_arb = E_vc_in_arb * PARM_Freq;
+ Eavg += E_vc_in_arb;
+
+ /* vc output (global) arbiter */
+ if (info->vc_out_arb_model)
+ E_vc_out_arb = SIM_arbiter_stat_energy(&router->vc_out_arb, &info->vc_out_arb_queue_info, e_sw_global_arb);
+ P_vc_out_arb = E_vc_out_arb * PARM_Freq;
+ Eavg += E_vc_out_arb;
+
+ /* sw input (local) arbiter */
+ if (info->sw_in_arb_model)
+ E_sw_in_arb = SIM_arbiter_stat_energy(&router->sw_in_arb, &info->sw_in_arb_queue_info, e_sw_local_arb);
+ P_sw_in_arb = E_sw_in_arb * PARM_Freq;
+ Eavg += E_sw_in_arb;
+
+ /* sw output (global) arbiter */
+ if (info->sw_out_arb_model)
+ E_sw_out_arb = SIM_arbiter_stat_energy(&router->sw_out_arb, &info->sw_out_arb_queue_info, e_sw_global_arb);
+ P_sw_out_arb = E_sw_out_arb * PARM_Freq;
+ Eavg += E_sw_out_arb;
+
+ /* static power */
+ E_leakage = router->i_leakage * Vdd * Period * SCALE_S;
+ P_leakage = E_leakage * PARM_Freq;
+ Eavg += E_leakage;
+
+ P_total = Eavg * PARM_Freq;
+
+ return Eavg;
+}
+
+double NetworkLink_d::calculate_offline_power(power_bus* bus)
+{
+ double sim_cycles = (double) (g_eventQueue_ptr->getTime() - m_net_ptr->getRubyStartTime());
+ double e_link = (double) (m_link_utilized)/ sim_cycles;
+ double E_link = SIM_bus_stat_energy(bus, e_link);
+ double P_link = E_link * PARM_Freq;
+ return P_link;
+}
+
+double NetworkLink_d::calculate_power()
+{
+ power_bus bus;
+ power_bus_init(&bus, GENERIC_BUS, IDENT_ENC, PARM_flit_width, 0, 1, 1, PARM_link_length, 0);
+ double total_power = calculate_offline_power(&bus);
+ return total_power;
+}
+
+void Router_d::power_router_initialize(power_router *router, power_router_info *info)
+{
+ info->n_in = m_input_unit.size();
+ info->n_out = m_output_unit.size();
+ info->flit_width = PARM_flit_width;
+
+ info->n_v_channel = m_num_vcs;
+ info->n_v_class = m_virtual_networks;
+
+}
+
+double Router_d::calculate_power()
+{
+ power_router router;
+ power_router_info router_info;
+ double total_energy, total_power;
+
+ power_router_initialize(&router, &router_info);
+ power_router_init(&router, &router_info);
+
+ total_energy = calculate_offline_power(&router, &router_info);
+ total_power = total_energy * PARM_Freq;
+ return total_power;
+}
diff --git a/src/mem/ruby/network/orion/NetworkPower.hh b/src/mem/ruby/network/orion/NetworkPower.hh
new file mode 100644
index 000000000..560d58376
--- /dev/null
+++ b/src/mem/ruby/network/orion/NetworkPower.hh
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _NETWORK_POWER_H
+#define _NETWORK_POWER_H
+
+#endif
diff --git a/src/mem/ruby/network/orion/SIM_port.hh b/src/mem/ruby/network/orion/SIM_port.hh
new file mode 100644
index 000000000..96d26daad
--- /dev/null
+++ b/src/mem/ruby/network/orion/SIM_port.hh
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _SIM_PORT_H
+#define _SIM_PORT_H
+
+#define PARM_POWER_STATS 1
+
+/* RF module parameters */
+#define PARM_read_port 1
+#define PARM_write_port 1
+#define PARM_n_regs 64
+#define PARM_reg_width 32
+
+#define PARM_ndwl 1
+#define PARM_ndbl 1
+#define PARM_nspd 1
+
+//Niket
+
+#define PARM_vc_in_arb_model QUEUE_ARBITER
+#define PARM_vc_out_arb_model QUEUE_ARBITER
+#define PARM_vc_in_arb_ff_model NEG_DFF
+#define PARM_vc_out_arb_ff_model NEG_DFF
+#define PARM_sw_in_arb_model QUEUE_ARBITER
+#define PARM_sw_out_arb_model QUEUE_ARBITER
+#define PARM_sw_in_arb_ff_model NEG_DFF
+#define PARM_sw_out_arb_ff_model NEG_DFF
+#define PARM_VC_per_MC 4
+
+//Niket
+
+//#define PARM_wordline_model CACHE_RW_WORDLINE
+//#define PARM_bitline_model RW_BITLINE
+//#define PARM_mem_model NORMAL_MEM
+//#define PARM_row_dec_model SIM_NO_MODEL
+//#define PARM_row_dec_pre_model SIM_NO_MODEL
+//#define PARM_col_dec_model SIM_NO_MODEL
+//#define PARM_col_dec_pre_model SIM_NO_MODEL
+//#define PARM_mux_model SIM_NO_MODEL
+//#define PARM_outdrv_model SIM_NO_MODEL
+
+/* these 3 should be changed together */
+//#define PARM_data_end 2
+//#define PARM_amp_model GENERIC_AMP
+//#define PARM_bitline_pre_model EQU_BITLINE
+//#define PARM_data_end 1
+//#define PARM_amp_model SIM_NO_MODEL
+//#define PARM_bitline_pre_model SINGLE_OTHER
+
+
+/* router module parameters */
+/* general parameters */
+#define PARM_in_port 9
+#define PARM_cache_in_port 0 /* # of cache input ports */
+#define PARM_mc_in_port 0 /* # of memory controller input ports */
+#define PARM_io_in_port 0 /* # of I/O device input ports */
+#define PARM_out_port 9
+#define PARM_cache_out_port 0 /* # of cache output ports */
+#define PARM_mc_out_port 0 /* # of memory controller output ports */
+#define PARM_io_out_port 0 /* # of I/O device output ports */
+#define PARM_flit_width 128 /* flit width in bits */
+
+/* virtual channel parameters */
+#define PARM_v_channel 1 /* # of network port virtual channels */
+#define PARM_v_class 0 /* # of total virtual classes */
+#define PARM_cache_class 0 /* # of cache port virtual classes */
+#define PARM_mc_class 0 /* # of memory controller port virtual classes */
+#define PARM_io_class 0 /* # of I/O device port virtual classes */
+/* ?? */
+#define PARM_in_share_buf 0 /* do input virtual channels physically share buffers? */
+#define PARM_out_share_buf 0 /* do output virtual channels physically share buffers? */
+/* ?? */
+#define PARM_in_share_switch 1 /* do input virtual channels share crossbar input ports? */
+#define PARM_out_share_switch 1 /* do output virtual channels share crossbar output ports? */
+
+/* crossbar parameters */
+#define PARM_crossbar_model MATRIX_CROSSBAR /* crossbar model type */
+#define PARM_crsbar_degree 4 /* crossbar mux degree */
+#define PARM_connect_type TRISTATE_GATE /* crossbar connector type */
+#define PARM_trans_type NP_GATE /* crossbar transmission gate type */
+#define PARM_crossbar_in_len 0 /* crossbar input line length, if known */
+#define PARM_crossbar_out_len 0 /* crossbar output line length, if known */
+#define PARM_xb_in_seg 0
+#define PARM_xb_out_seg 0
+/* HACK HACK HACK */
+#define PARM_exp_xb_model MATRIX_CROSSBAR
+#define PARM_exp_in_seg 2
+#define PARM_exp_out_seg 2
+
+/* input buffer parameters */
+#define PARM_in_buf 1 /* have input buffer? */
+#define PARM_in_buf_set 4
+#define PARM_in_buf_rport 1 /* # of read ports */
+
+#define PARM_cache_in_buf 0
+#define PARM_cache_in_buf_set 0
+#define PARM_cache_in_buf_rport 0
+
+#define PARM_mc_in_buf 0
+#define PARM_mc_in_buf_set 0
+#define PARM_mc_in_buf_rport 0
+
+#define PARM_io_in_buf 0
+#define PARM_io_in_buf_set 0
+#define PARM_io_in_buf_rport 0
+
+/* output buffer parameters */
+#define PARM_out_buf 0
+#define PARM_out_buf_set 4
+#define PARM_out_buf_wport 1
+
+/* central buffer parameters */
+#define PARM_central_buf 0 /* have central buffer? */
+#define PARM_cbuf_set 2560 /* # of rows */
+#define PARM_cbuf_rport 2 /* # of read ports */
+#define PARM_cbuf_wport 2 /* # of write ports */
+#define PARM_cbuf_width 4 /* # of flits in one row */
+#define PARM_pipe_depth 4 /* # of banks */
+
+/* array parameters shared by various buffers */
+#define PARM_wordline_model CACHE_RW_WORDLINE
+#define PARM_bitline_model RW_BITLINE
+#define PARM_mem_model NORMAL_MEM
+#define PARM_row_dec_model GENERIC_DEC
+#define PARM_row_dec_pre_model SINGLE_OTHER
+#define PARM_col_dec_model SIM_NO_MODEL
+#define PARM_col_dec_pre_model SIM_NO_MODEL
+#define PARM_mux_model SIM_NO_MODEL
+#define PARM_outdrv_model REG_OUTDRV
+
+/* these 3 should be changed together */
+/* use double-ended bitline because the array is too large */
+#define PARM_data_end 2
+#define PARM_amp_model GENERIC_AMP
+#define PARM_bitline_pre_model EQU_BITLINE
+//#define PARM_data_end 1
+//#define PARM_amp_model SIM_NO_MODEL
+//#define PARM_bitline_pre_model SINGLE_OTHER
+
+/* arbiter parameters */
+#define PARM_in_arb_model MATRIX_ARBITER /* input side arbiter model type */
+#define PARM_in_arb_ff_model NEG_DFF /* input side arbiter flip-flop model type */
+#define PARM_out_arb_model MATRIX_ARBITER /* output side arbiter model type */
+#define PARM_out_arb_ff_model NEG_DFF /* output side arbiter flip-flop model type */
+
+#endif /* _SIM_PORT_H */
diff --git a/src/mem/ruby/network/orion/SIM_power.hh b/src/mem/ruby/network/orion/SIM_power.hh
new file mode 100644
index 000000000..1f0ddd36c
--- /dev/null
+++ b/src/mem/ruby/network/orion/SIM_power.hh
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _SIM_POWER_H
+#define _SIM_POWER_H
+
+#include <sys/types.h>
+#include "SIM_power_test.hh"
+
+#define SIM_NO_MODEL 0
+
+#define MAX_ENERGY 1
+#define AVG_ENERGY 0
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a)>(b))?(b):(a))
+#endif
+
+#define NEXT_DEPTH(d) ((d) > 0 ? (d) - 1 : (d))
+
+#define BIGNUM 1e30
+#define BIGONE ((LIB_Type_max_uint)1)
+#define BIGNONE ((LIB_Type_max_uint)-1)
+#define HAMM_MASK(w) ((unsigned int)w < (sizeof(LIB_Type_max_uint) << 3) ? (BIGONE << w) - 1 : BIGNONE)
+
+/* Used to communicate with the horowitz model */
+#define RISE 1
+#define FALL 0
+#define NCH 1
+#define PCH 0
+
+/*
+ * Cache layout parameters and process parameters
+ * Thanks to Glenn Reinman for the technology scaling factors
+ */
+#if ( PARM(TECH_POINT) == 10 )
+#define CSCALE (84.2172) /* wire capacitance scaling factor */
+ /* linear: 51.7172, predicted: 84.2172 */
+#define RSCALE (80.0000) /* wire resistance scaling factor */
+#define LSCALE 0.1250 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.38 /* voltage scaling factor */
+#define VTSCALE 0.49 /* threshold voltage scaling factor */
+#define SSCALE 0.80 /* sense voltage scaling factor */
+/* FIXME: borrowed from 0.11u technology */
+#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (1/PARM(GEN_POWER_FACTOR))
+/* copied from TECH_POINT 10 except LSCALE */
+#elif ( PARM(TECH_POINT) == 11 )
+#define CSCALE (84.2172) /* wire capacitance scaling factor */
+#define RSCALE (80.0000) /* wire resistance scaling factor */
+#define LSCALE 0.1375 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.38 /* voltage scaling factor */
+#define VTSCALE 0.49 /* threshold voltage scaling factor */
+#define SSCALE 0.80 /* sense voltage scaling factor */
+#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (1/PARM(GEN_POWER_FACTOR))
+#elif ( PARM(TECH_POINT) == 18 )
+#define CSCALE (19.7172) /* wire capacitance scaling factor */
+#define RSCALE (20.0000) /* wire resistance scaling factor */
+#define LSCALE 0.2250 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.4 /* voltage scaling factor */
+#define VTSCALE 0.5046 /* threshold voltage scaling factor */
+#define SSCALE 0.85 /* sense voltage scaling factor */
+#define MCSCALE 4.1250 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 2.4444 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.2 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE 1
+#elif ( PARM(TECH_POINT) == 25 )
+#define CSCALE (10.2197) /* wire capacitance scaling factor */
+#define RSCALE (10.2571) /* wire resistance scaling factor */
+#define LSCALE 0.3571 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.45 /* voltage scaling factor */
+#define VTSCALE 0.5596 /* threshold voltage scaling factor */
+#define SSCALE 0.90 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE PARM(GEN_POWER_FACTOR)
+#elif ( PARM(TECH_POINT) == 35 )
+#define CSCALE (5.2197) /* wire capacitance scaling factor */
+#define RSCALE (5.2571) /* wire resistance scaling factor */
+#define LSCALE 0.4375 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.5 /* voltage scaling factor */
+#define VTSCALE 0.6147 /* threshold voltage scaling factor */
+#define SSCALE 0.95 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR))
+#elif ( PARM(TECH_POINT) == 40 )
+#define CSCALE 1.0 /* wire capacitance scaling factor */
+#define RSCALE 1.0 /* wire resistance scaling factor */
+#define LSCALE 0.5 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 1.0 /* voltage scaling factor */
+#define VTSCALE 1.0 /* threshold voltage scaling factor */
+#define SSCALE 1.0 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR))
+#else /* ( PARM(TECH_POINT) == 80 ) */
+#define CSCALE 1.0 /* wire capacitance scaling factor */
+#define RSCALE 1.0 /* wire resistance scaling factor */
+#define LSCALE 1.0 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 1.0 /* voltage scaling factor */
+#define VTSCALE 1.0 /* threshold voltage scaling factor */
+#define SSCALE 1.0 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR))
+#endif
+
+#define MSCALE (LSCALE * .624 / .2250)
+
+/*
+ * CMOS 0.8um model parameters
+ * - from Appendix II of Cacti tech report
+ */
+/* corresponds to 8um of m3 @ 225ff/um */
+#define Cwordmetal (1.8e-15 * (CSCALE * ASCALE) * SCALE_M)
+
+/* corresponds to 16um of m2 @ 275ff/um */
+#define Cbitmetal (4.4e-15 * (CSCALE * ASCALE) * SCALE_M)
+
+/* corresponds to 1um of m2 @ 275ff/um */
+#define Cmetal (Cbitmetal/16)
+#define CM2metal (Cbitmetal/16)
+#define CM3metal (Cbitmetal/16)
+
+/* minimal spacing metal cap per unit length */
+#define CCmetal (Cmetal * MCSCALE)
+#define CCM2metal (CM2metal * MCSCALE)
+#define CCM3metal (CM3metal * MCSCALE)
+/* 2x minimal spacing metal cap per unit length */
+#define CC2metal (Cmetal * MCSCALE2)
+#define CC2M2metal (CM2metal * MCSCALE2)
+#define CC2M3metal (CM3metal * MCSCALE2)
+/* 3x minimal spacing metal cap per unit length */
+#define CC3metal (Cmetal * MCSCALE3)
+#define CC3M2metal (CM2metal * MCSCALE3)
+#define CC3M3metal (CM3metal * MCSCALE3)
+
+/* um */
+#define Leff (0.8 * LSCALE)
+/* length unit in um */
+#define Lamda (Leff * 0.5)
+
+/* fF/um */
+#define Cpolywire (0.25e-15 * CSCALE * LSCALE)
+
+/* ohms*um of channel width */
+#define Rnchannelstatic (25800 * LSCALE)
+
+/* ohms*um of channel width */
+#define Rpchannelstatic (61200 * LSCALE)
+
+#define Rnchannelon (9723 * LSCALE)
+
+#define Rpchannelon (22400 * LSCALE)
+
+/* corresponds to 16um of m2 @ 48mO/sq */
+#define Rbitmetal (0.320 * (RSCALE * ASCALE))
+
+/* corresponds to 8um of m3 @ 24mO/sq */
+#define Rwordmetal (0.080 * (RSCALE * ASCALE))
+
+#ifndef Vdd
+#define Vdd (5 * VSCALE)
+#endif /* Vdd */
+
+/* other stuff (from tech report, appendix 1) */
+#define Period ((double)1/(double)PARM(Freq))
+
+#define krise (0.4e-9 * LSCALE)
+#define tsensedata (5.8e-10 * LSCALE)
+#define tsensetag (2.6e-10 * LSCALE)
+#define tfalldata (7e-10 * LSCALE)
+#define tfalltag (7e-10 * LSCALE)
+#define Vbitpre (3.3 * SSCALE)
+#define Vt (1.09 * VTSCALE)
+#define Vbitsense (0.10 * SSCALE)
+
+#define Powerfactor (PARM(Freq))*Vdd*Vdd
+#define EnergyFactor (Vdd*Vdd)
+
+#define SensePowerfactor3 (PARM(Freq))*(Vbitsense)*(Vbitsense)
+#define SensePowerfactor2 (PARM(Freq))*(Vbitpre-Vbitsense)*(Vbitpre-Vbitsense)
+#define SensePowerfactor (PARM(Freq))*Vdd*(Vdd/2)
+#define SenseEnergyFactor (Vdd*Vdd/2)
+
+/* transistor widths in um (as described in tech report, appendix 1) */
+#define Wdecdrivep (57.0 * LSCALE)
+#define Wdecdriven (40.0 * LSCALE)
+#define Wdec3to8n (14.4 * LSCALE)
+#define Wdec3to8p (14.4 * LSCALE)
+#define WdecNORn (5.4 * LSCALE)
+#define WdecNORp (30.5 * LSCALE)
+#define Wdecinvn (5.0 * LSCALE)
+#define Wdecinvp (10.0 * LSCALE)
+
+#define Wworddrivemax (100.0 * LSCALE)
+#define Wmemcella (2.4 * LSCALE)
+#define Wmemcellr (4.0 * LSCALE)
+#define Wmemcellw (2.1 * LSCALE)
+#define Wmemcellbscale 2 /* means 2x bigger than Wmemcella */
+#define Wbitpreequ (10.0 * LSCALE)
+
+#define Wbitmuxn (10.0 * LSCALE)
+#define WsenseQ1to4 (4.0 * LSCALE)
+#define Wcompinvp1 (10.0 * LSCALE)
+#define Wcompinvn1 (6.0 * LSCALE)
+#define Wcompinvp2 (20.0 * LSCALE)
+#define Wcompinvn2 (12.0 * LSCALE)
+#define Wcompinvp3 (40.0 * LSCALE)
+#define Wcompinvn3 (24.0 * LSCALE)
+#define Wevalinvp (20.0 * LSCALE)
+#define Wevalinvn (80.0 * LSCALE)
+
+#define Wcompn (20.0 * LSCALE)
+#define Wcompp (30.0 * LSCALE)
+#define Wcomppreequ (40.0 * LSCALE)
+#define Wmuxdrv12n (30.0 * LSCALE)
+#define Wmuxdrv12p (50.0 * LSCALE)
+#define WmuxdrvNANDn (20.0 * LSCALE)
+#define WmuxdrvNANDp (80.0 * LSCALE)
+#define WmuxdrvNORn (60.0 * LSCALE)
+#define WmuxdrvNORp (80.0 * LSCALE)
+#define Wmuxdrv3n (200.0 * LSCALE)
+#define Wmuxdrv3p (480.0 * LSCALE)
+#define Woutdrvseln (12.0 * LSCALE)
+#define Woutdrvselp (20.0 * LSCALE)
+#define Woutdrvnandn (24.0 * LSCALE)
+#define Woutdrvnandp (10.0 * LSCALE)
+#define Woutdrvnorn (6.0 * LSCALE)
+#define Woutdrvnorp (40.0 * LSCALE)
+#define Woutdrivern (48.0 * LSCALE)
+#define Woutdriverp (80.0 * LSCALE)
+#define Wbusdrvn (48.0 * LSCALE)
+#define Wbusdrvp (80.0 * LSCALE)
+
+#define Wcompcellpd2 (2.4 * LSCALE)
+#define Wcompdrivern (400.0 * LSCALE)
+#define Wcompdriverp (800.0 * LSCALE)
+#define Wcomparen2 (40.0 * LSCALE)
+#define Wcomparen1 (20.0 * LSCALE)
+#define Wmatchpchg (10.0 * LSCALE)
+#define Wmatchinvn (10.0 * LSCALE)
+#define Wmatchinvp (20.0 * LSCALE)
+#define Wmatchnandn (20.0 * LSCALE)
+#define Wmatchnandp (10.0 * LSCALE)
+#define Wmatchnorn (20.0 * LSCALE)
+#define Wmatchnorp (10.0 * LSCALE)
+
+#define WSelORn (10.0 * LSCALE)
+#define WSelORprequ (40.0 * LSCALE)
+#define WSelPn (10.0 * LSCALE)
+#define WSelPp (15.0 * LSCALE)
+#define WSelEnn (5.0 * LSCALE)
+#define WSelEnp (10.0 * LSCALE)
+
+#define Wsenseextdrv1p (40.0*LSCALE)
+#define Wsenseextdrv1n (24.0*LSCALE)
+#define Wsenseextdrv2p (200.0*LSCALE)
+#define Wsenseextdrv2n (120.0*LSCALE)
+
+/* bit width of RAM cell in um */
+#define BitWidth (16.0 * LSCALE)
+
+/* bit height of RAM cell in um */
+#define BitHeight (16.0 * LSCALE)
+
+#define Cout (0.5e-12 * LSCALE)
+
+/* Sizing of cells and spacings */
+#define RatCellHeight (40.0 * LSCALE)
+#define RatCellWidth (70.0 * LSCALE)
+#define RatShiftRegWidth (120.0 * LSCALE)
+#define RatNumShift 4
+#define BitlineSpacing (6.0 * LSCALE)
+#define WordlineSpacing (6.0 * LSCALE)
+
+#define RegCellHeight (16.0 * LSCALE)
+#define RegCellWidth (8.0 * LSCALE)
+
+#define CamCellHeight (40.0 * LSCALE)
+#define CamCellWidth (25.0 * LSCALE)
+#define MatchlineSpacing (6.0 * LSCALE)
+#define TaglineSpacing (6.0 * LSCALE)
+
+#define CrsbarCellHeight (6.0 * LSCALE)
+#define CrsbarCellWidth (6.0 * LSCALE)
+
+/*===================================================================*/
+
+/* ALU POWER NUMBERS for .18um 733Mhz */
+/* normalize .18um cap to other gen's cap, then xPowerfactor */
+#define POWER_SCALE (GEN_POWER_SCALE * PARM(NORMALIZE_SCALE) * Powerfactor)
+#define I_ADD ((.37 - .091)*POWER_SCALE)
+#define I_ADD32 (((.37 - .091)/2)*POWER_SCALE)
+#define I_MULT16 ((.31-.095)*POWER_SCALE)
+#define I_SHIFT ((.21-.089)*POWER_SCALE)
+#define I_LOGIC ((.04-.015)*POWER_SCALE)
+#define F_ADD ((1.307-.452)*POWER_SCALE)
+#define F_MULT ((1.307-.452)*POWER_SCALE)
+
+#define I_ADD_CLOCK (.091*POWER_SCALE)
+#define I_MULT_CLOCK (.095*POWER_SCALE)
+#define I_SHIFT_CLOCK (.089*POWER_SCALE)
+#define I_LOGIC_CLOCK (.015*POWER_SCALE)
+#define F_ADD_CLOCK (.452*POWER_SCALE)
+#define F_MULT_CLOCK (.452*POWER_SCALE)
+
+/*
+
+ transmission gate type
+typedef enum {
+ N_GATE,
+ NP_GATE
+} SIM_power_trans_t;
+
+*/
+/* some utility routines */
+extern unsigned int SIM_power_logtwo(LIB_Type_max_uint x);
+//extern int SIM_power_squarify(int rows, int cols);
+extern double SIM_power_driver_size(double driving_cap, double desiredrisetime);
+
+/* functions from cacti */
+extern double SIM_power_gatecap(double width, double wirelength);
+extern double SIM_power_gatecappass(double width, double wirelength);
+extern double SIM_power_draincap(double width, int nchannel, int stack);
+extern double SIM_power_restowidth(double res, int nchannel);
+
+extern int SIM_power_init(void);
+
+extern unsigned int SIM_power_Hamming(LIB_Type_max_uint old_val, LIB_Type_max_uint new_val, LIB_Type_max_uint mask);
+extern unsigned int SIM_power_Hamming_group(LIB_Type_max_uint d1_new, LIB_Type_max_uint d1_old, LIB_Type_max_uint d2_new, LIB_Type_max_uint d2_old, u_int width, u_int n_grp);
+
+/* statistical functions */
+//extern int SIM_print_stat_energy(char *path, double Energy, int print_flag);
+//extern u_int SIM_power_strlen(char *s);
+//extern char *SIM_power_strcat(char *dest, char *src);
+//extern int SIM_power_res_path(char *path, u_int id);
+//extern int SIM_power_dump_tech_para(void);
+
+#endif /* _SIM_POWER_H */
diff --git a/src/mem/ruby/network/orion/SIM_power_test.hh b/src/mem/ruby/network/orion/SIM_power_test.hh
new file mode 100644
index 000000000..95b304042
--- /dev/null
+++ b/src/mem/ruby/network/orion/SIM_power_test.hh
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/* all needed to perform computation out of Liberty */
+#ifndef _SIM_POWER_TEST_H
+#define _SIM_POWER_TEST_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#define LIB_Type_max_uint unsigned long int
+#define LIB_Type_max_int long int
+
+#define __INSTANCE__ mainpe__power
+#define GLOBDEF(t,n) t mainpe__power___ ## n
+#define GLOB(n) mainpe__power___ ## n
+#define FUNC(n, args...) mainpe__power___ ## n (args)
+#define FUNCPTR(n) mainpe__power___ ## n
+#define PARM(x) PARM_ ## x
+
+#undef PARM_AF
+#undef PARM_MAXN
+#undef PARM_MAXSUBARRAYS
+#undef PARM_MAXSPD
+#undef PARM_VTHSENSEEXTDRV
+#undef PARM_VTHOUTDRNOR
+#undef PARM_res_fpalu
+#undef PARM_VTHCOMPINV
+#undef PARM_MD_NUM_IREGS
+#undef PARM_die_length
+#undef PARM_BITOUT
+#undef PARM_Cndiffside
+#undef PARM_ruu_decode_width
+#undef PARM_ruu_issue_width
+#undef PARM_amp_Idsat
+#undef PARM_AF_TYPE
+#undef PARM_VSINV
+#undef PARM_Cpdiffovlp
+#undef PARM_data_width
+#undef PARM_Cgatepass
+#undef PARM_Cpdiffarea
+#undef PARM_GEN_POWER_FACTOR
+#undef PARM_res_memport
+#undef PARM_VTHNAND60x90
+#undef PARM_Cpdiffside
+#undef PARM_Cpoxideovlp
+#undef PARM_opcode_length
+#undef PARM_MD_NUM_FREGS
+#undef PARM_FUDGEFACTOR
+#undef PARM_ruu_commit_width
+#undef PARM_Cndiffovlp
+#undef PARM_VTHOUTDRIVE
+#undef PARM_Cndiffarea
+#undef PARM_VTHMUXDRV1
+#undef PARM_inst_length
+#undef PARM_VTHMUXDRV2
+#undef PARM_NORMALIZE_SCALE
+#undef PARM_ras_size
+#undef PARM_VTHMUXDRV3
+#undef PARM_ADDRESS_BITS
+#undef PARM_RUU_size
+#undef PARM_Cgate
+#undef PARM_VTHNOR12x4x1
+#undef PARM_VTHNOR12x4x2
+#undef PARM_VTHOUTDRINV
+#undef PARM_VTHNOR12x4x3
+#undef PARM_VTHEVALINV
+#undef PARM_crossover_scaling
+#undef PARM_VTHNOR12x4x4
+#undef PARM_turnoff_factor
+#undef PARM_res_ialu
+#undef PARM_Cnoxideovlp
+#undef PARM_VTHOUTDRNAND
+#undef PARM_VTHINV100x60
+#undef PARM_LSQ_size
+
+#ifndef PARM_AF
+#define PARM_AF (5.000000e-01)
+#endif /* PARM_AF */
+#ifndef PARM_MAXN
+#define PARM_MAXN (8)
+#endif /* PARM_MAXN */
+#ifndef PARM_MAXSUBARRAYS
+#define PARM_MAXSUBARRAYS (8)
+#endif /* PARM_MAXSUBARRAYS */
+#ifndef PARM_MAXSPD
+#define PARM_MAXSPD (8)
+#endif /* PARM_MAXSPD */
+#ifndef PARM_VTHSENSEEXTDRV
+#define PARM_VTHSENSEEXTDRV (4.370000e-01)
+#endif /* PARM_VTHSENSEEXTDRV */
+#ifndef PARM_VTHOUTDRNOR
+#define PARM_VTHOUTDRNOR (4.310000e-01)
+#endif /* PARM_VTHOUTDRNOR */
+#ifndef PARM_res_fpalu
+#define PARM_res_fpalu (4)
+#endif /* PARM_res_fpalu */
+#ifndef PARM_VTHCOMPINV
+#define PARM_VTHCOMPINV (4.370000e-01)
+#endif /* PARM_VTHCOMPINV */
+#ifndef PARM_MD_NUM_IREGS
+#define PARM_MD_NUM_IREGS (32)
+#endif /* PARM_MD_NUM_IREGS */
+#ifndef PARM_die_length
+#define PARM_die_length (1.800000e-02)
+#endif /* PARM_die_length */
+#ifndef PARM_BITOUT
+#define PARM_BITOUT (64)
+#endif /* PARM_BITOUT */
+#ifndef PARM_Cndiffside
+#define PARM_Cndiffside (2.750000e-16)
+#endif /* PARM_Cndiffside */
+#ifndef PARM_ruu_decode_width
+#define PARM_ruu_decode_width (4)
+#endif /* PARM_ruu_decode_width */
+#ifndef PARM_ruu_issue_width
+#define PARM_ruu_issue_width (4)
+#endif /* PARM_ruu_issue_width */
+#ifndef PARM_amp_Idsat
+#define PARM_amp_Idsat (5.000000e-04)
+#endif /* PARM_amp_Idsat */
+#ifndef PARM_AF_TYPE
+#define PARM_AF_TYPE (1)
+#endif /* PARM_AF_TYPE */
+#ifndef PARM_VSINV
+#define PARM_VSINV (4.560000e-01)
+#endif /* PARM_VSINV */
+#ifndef PARM_Cpdiffovlp
+#define PARM_Cpdiffovlp (1.380000e-16)
+#endif /* PARM_Cpdiffovlp */
+#ifndef PARM_Cgatepass
+#define PARM_Cgatepass (1.450000e-15)
+#endif /* PARM_Cgatepass */
+#ifndef PARM_Cpdiffarea
+#define PARM_Cpdiffarea (3.430000e-16)
+#endif /* PARM_Cpdiffarea */
+#ifndef PARM_GEN_POWER_FACTOR
+#define PARM_GEN_POWER_FACTOR (1.310000e+00)
+#endif /* PARM_GEN_POWER_FACTOR */
+#ifndef PARM_res_memport
+#define PARM_res_memport (2)
+#endif /* PARM_res_memport */
+#ifndef PARM_VTHNAND60x90
+#define PARM_VTHNAND60x90 (5.610000e-01)
+#endif /* PARM_VTHNAND60x90 */
+#ifndef PARM_Cpdiffside
+#define PARM_Cpdiffside (2.750000e-16)
+#endif /* PARM_Cpdiffside */
+#ifndef PARM_Cpoxideovlp
+#define PARM_Cpoxideovlp (3.380000e-16)
+#endif /* PARM_Cpoxideovlp */
+#ifndef PARM_opcode_length
+#define PARM_opcode_length (8)
+#endif /* PARM_opcode_length */
+#ifndef PARM_MD_NUM_FREGS
+#define PARM_MD_NUM_FREGS (32)
+#endif /* PARM_MD_NUM_FREGS */
+#ifndef PARM_FUDGEFACTOR
+#define PARM_FUDGEFACTOR (1.000000e+00)
+#endif /* PARM_FUDGEFACTOR */
+#ifndef PARM_ruu_commit_width
+#define PARM_ruu_commit_width (4)
+#endif /* PARM_ruu_commit_width */
+#ifndef PARM_Cndiffovlp
+#define PARM_Cndiffovlp (1.380000e-16)
+#endif /* PARM_Cndiffovlp */
+#ifndef PARM_VTHOUTDRIVE
+#define PARM_VTHOUTDRIVE (4.250000e-01)
+#endif /* PARM_VTHOUTDRIVE */
+#ifndef PARM_Cndiffarea
+#define PARM_Cndiffarea (1.370000e-16)
+#endif /* PARM_Cndiffarea */
+#ifndef PARM_VTHMUXDRV1
+#define PARM_VTHMUXDRV1 (4.370000e-01)
+#endif /* PARM_VTHMUXDRV1 */
+#ifndef PARM_inst_length
+#define PARM_inst_length (32)
+#endif /* PARM_inst_length */
+#ifndef PARM_VTHMUXDRV2
+#define PARM_VTHMUXDRV2 (4.860000e-01)
+#endif /* PARM_VTHMUXDRV2 */
+#ifndef PARM_NORMALIZE_SCALE
+#define PARM_NORMALIZE_SCALE (6.488730e-10)
+#endif /* PARM_NORMALIZE_SCALE */
+#ifndef PARM_ras_size
+#define PARM_ras_size (8)
+#endif /* PARM_ras_size */
+#ifndef PARM_VTHMUXDRV3
+#define PARM_VTHMUXDRV3 (4.370000e-01)
+#endif /* PARM_VTHMUXDRV3 */
+#ifndef PARM_ADDRESS_BITS
+#define PARM_ADDRESS_BITS (64)
+#endif /* PARM_ADDRESS_BITS */
+#ifndef PARM_RUU_size
+#define PARM_RUU_size (16)
+#endif /* PARM_RUU_size */
+#ifndef PARM_Cgate
+#define PARM_Cgate (1.950000e-15)
+#endif /* PARM_Cgate */
+#ifndef PARM_VTHNOR12x4x1
+#define PARM_VTHNOR12x4x1 (5.030000e-01)
+#endif /* PARM_VTHNOR12x4x1 */
+#ifndef PARM_VTHNOR12x4x2
+#define PARM_VTHNOR12x4x2 (4.520000e-01)
+#endif /* PARM_VTHNOR12x4x2 */
+#ifndef PARM_VTHOUTDRINV
+#define PARM_VTHOUTDRINV (4.370000e-01)
+#endif /* PARM_VTHOUTDRINV */
+#ifndef PARM_VTHNOR12x4x3
+#define PARM_VTHNOR12x4x3 (4.170000e-01)
+#endif /* PARM_VTHNOR12x4x3 */
+#ifndef PARM_VTHEVALINV
+#define PARM_VTHEVALINV (2.670000e-01)
+#endif /* PARM_VTHEVALINV */
+#ifndef PARM_crossover_scaling
+#define PARM_crossover_scaling (1.200000e+00)
+#endif /* PARM_crossover_scaling */
+#ifndef PARM_VTHNOR12x4x4
+#define PARM_VTHNOR12x4x4 (3.900000e-01)
+#endif /* PARM_VTHNOR12x4x4 */
+#ifndef PARM_turnoff_factor
+#define PARM_turnoff_factor (1.000000e-01)
+#endif /* PARM_turnoff_factor */
+#ifndef PARM_res_ialu
+#define PARM_res_ialu (4)
+#endif /* PARM_res_ialu */
+#ifndef PARM_Cnoxideovlp
+#define PARM_Cnoxideovlp (2.630000e-16)
+#endif /* PARM_Cnoxideovlp */
+#ifndef PARM_VTHOUTDRNAND
+#define PARM_VTHOUTDRNAND (4.410000e-01)
+#endif /* PARM_VTHOUTDRNAND */
+#ifndef PARM_VTHINV100x60
+#define PARM_VTHINV100x60 (4.380000e-01)
+#endif /* PARM_VTHINV100x60 */
+#ifndef PARM_LSQ_size
+#define PARM_LSQ_size (8)
+#endif /* PARM_LSQ_size */
+
+#define TEST_LENGTH (100)
+/* scaling factors from 0.1u to 0.07u, 0.05u and 0.035u */
+#if (TEST_LENGTH == 70)
+#define SCALE_T (0.5489156157)
+#define SCALE_M (0.6566502462)
+#define SCALE_S (1.4088071075)
+#elif (TEST_LENGTH == 50)
+#define SCALE_T (0.3251012552)
+#define SCALE_M (0.4426460239)
+#define SCALE_S (2.8667111607)
+#elif (TEST_LENGTH == 35)
+#define SCALE_T (0.2016627474)
+#define SCALE_M (0.2489788586)
+#define SCALE_S (8.7726826878)
+#else
+#define SCALE_T (1)
+#define SCALE_M (1)
+#define SCALE_S (1)
+#endif /* TEST_LENGTH */
+
+#endif /* _SIM_POWER_TEST_H */
diff --git a/src/mem/ruby/network/orion/parm_technology.hh b/src/mem/ruby/network/orion/parm_technology.hh
new file mode 100644
index 000000000..87049d4cd
--- /dev/null
+++ b/src/mem/ruby/network/orion/parm_technology.hh
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _PARM_TECHNOLOGY_H
+#define _PARM_TECHNOLOGY_H
+
+/******* LEAKAGE current values for different tech points are in power_static.c *******/
+/******* for LINKS: metal cap is assumed to be CC2metal and repeater size is assumed to be n_size=Lambda*10, p_size=n_size*2 *******/
+
+#define SWITCHING_FACTOR 0.5 /*used for offline calculations*/
+
+/********************* Technology point **********/
+#define PARM_TECH_POINT 10 /* 100nm */
+#define PARM_Freq 3e9
+/*************************************************/
+
+
+/*********** Transistor parasitics ******************/
+#define PARM_Cndiffside (2.750000e-16)
+#define PARM_Cpdiffovlp (1.380000e-16)
+#define PARM_Cgatepass (1.450000e-15)
+#define PARM_Cpdiffarea (3.430000e-16)
+#define PARM_Cpdiffside (2.750000e-16)
+#define PARM_Cpoxideovlp (3.380000e-16)
+#define PARM_Cndiffovlp (1.380000e-16)
+#define PARM_Cndiffarea (1.370000e-16)
+#define PARM_Cgate (1.950000e-15)
+#define PARM_Cnoxideovlp (2.630000e-16)
+/*************************************************/
+
+
+
+/************* Scaling factors for different technology points ******************/
+#if ( PARM_TECH_POINT == 10 ) /* 100nm */
+#define CSCALE (84.2172) /* wire capacitance scaling factor */
+ /* linear: 51.7172, predicted: 84.2172 */
+#define RSCALE (80.0000) /* wire resistance scaling factor */
+#define LSCALE 0.1250 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.38 /* voltage scaling factor */
+#define VTSCALE 0.49 /* threshold voltage scaling factor */
+#define SSCALE 0.80 /* sense voltage scaling factor */
+/* FIXME: borrowed from 0.11u technology */
+#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (1/PARM_GEN_POWER_FACTOR)
+/* copied from TECH_POINT 10 except LSCALE */
+#elif ( PARM_TECH_POINT == 11 ) /* 110nm */
+#define CSCALE (84.2172) /* wire capacitance scaling factor */
+#define RSCALE (80.0000) /* wire resistance scaling factor */
+#define LSCALE 0.1375 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.38 /* voltage scaling factor */
+#define VTSCALE 0.49 /* threshold voltage scaling factor */
+#define SSCALE 0.80 /* sense voltage scaling factor */
+#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (1/PARM_GEN_POWER_FACTOR)
+#elif ( PARM_TECH_POINT == 18 ) /* 180nm */
+#define CSCALE (19.7172) /* wire capacitance scaling factor */
+#define RSCALE (20.0000) /* wire resistance scaling factor */
+#define LSCALE 0.2250 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.4 /* voltage scaling factor */
+#define VTSCALE 0.5046 /* threshold voltage scaling factor */
+#define SSCALE 0.85 /* sense voltage scaling factor */
+#define MCSCALE 4.1250 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 2.4444 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.2 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE 1
+#elif ( PARM_TECH_POINT == 25 ) /* 250nm */
+#define CSCALE (10.2197) /* wire capacitance scaling factor */
+#define RSCALE (10.2571) /* wire resistance scaling factor */
+#define LSCALE 0.3571 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.45 /* voltage scaling factor */
+#define VTSCALE 0.5596 /* threshold voltage scaling factor */
+#define SSCALE 0.90 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE PARM_GEN_POWER_FACTOR
+#elif ( PARM_TECH_POINT == 35 ) /* 350nm */
+#define CSCALE (5.2197) /* wire capacitance scaling factor */
+#define RSCALE (5.2571) /* wire resistance scaling factor */
+#define LSCALE 0.4375 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 0.5 /* voltage scaling factor */
+#define VTSCALE 0.6147 /* threshold voltage scaling factor */
+#define SSCALE 0.95 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR)
+#elif ( PARM_TECH_POINT == 40 ) /* 400nm */
+#define CSCALE 1.0 /* wire capacitance scaling factor */
+#define RSCALE 1.0 /* wire resistance scaling factor */
+#define LSCALE 0.5 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 1.0 /* voltage scaling factor */
+#define VTSCALE 1.0 /* threshold voltage scaling factor */
+#define SSCALE 1.0 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR)
+#else /* ( PARM_TECH_POINT == 80 ) */ /* 800nm */
+#define CSCALE 1.0 /* wire capacitance scaling factor */
+#define RSCALE 1.0 /* wire resistance scaling factor */
+#define LSCALE 1.0 /* length (feature) scaling factor */
+#define ASCALE (LSCALE*LSCALE) /* area scaling factor */
+#define VSCALE 1.0 /* voltage scaling factor */
+#define VTSCALE 1.0 /* threshold voltage scaling factor */
+#define SSCALE 1.0 /* sense voltage scaling factor */
+#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */
+#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */
+#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */
+#define GEN_POWER_SCALE (PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR)
+#endif
+
+#define MSCALE (LSCALE * .624 / .2250)
+#define PARM_NORMALIZE_SCALE (6.488730e-10)
+
+/* scaling factors from 0.1u to 0.07u, 0.05u and 0.035u */
+/* if technology point is 0.07u, o.05u or 0.035u set PARM_TECH_POINT to 10 and
+ * set TEST_LENGTH to 70, 50 or 35 respectively(TEST_LENGTH =100 for all other technologies) */
+#define TEST_LENGTH (70)
+
+#if (TEST_LENGTH == 70)
+#define SCALE_T (0.5489156157)
+#define SCALE_M (0.6566502462)
+#define SCALE_S (1.4088071075)
+#elif (TEST_LENGTH == 50)
+#define SCALE_T (0.3251012552)
+#define SCALE_M (0.4426460239)
+#define SCALE_S (2.8667111607)
+#elif (TEST_LENGTH == 35)
+#define SCALE_T (0.2016627474)
+#define SCALE_M (0.2489788586)
+#define SCALE_S (8.7726826878)
+#else
+#define SCALE_T (1)
+#define SCALE_M (1)
+#define SCALE_S (1)
+#endif /* TEST_LENGTH */
+/*************************************************/
+
+
+
+/********************** technology point related ***************************/
+/* um */
+#define Leff (0.8 * LSCALE)
+/* length unit in um */
+#define Lamda (Leff * 0.5)
+
+#ifndef Vdd
+#define Vdd (5 * VSCALE)
+#endif /* Vdd */
+
+#define Period ((double)1/(double)PARM_Freq)
+/*************************************************/
+
+
+/**** for SRAM - decoder, mem cell, wordline, bitline, output driver ****/
+/*
+ * CMOS 0.8um model parameters
+ * - from Appendix II of Cacti tech report
+ */
+/* corresponds to 8um of m3 @ 225ff/um */
+#define Cwordmetal (1.8e-15 * (CSCALE * ASCALE) * SCALE_M)
+
+/* corresponds to 16um of m2 @ 275ff/um */
+#define Cbitmetal (4.4e-15 * (CSCALE * ASCALE) * SCALE_M)
+
+/* corresponds to 1um of m2 @ 275ff/um */
+#define Cmetal (Cbitmetal/16)
+#define CM2metal (Cbitmetal/16)
+#define CM3metal (Cbitmetal/16)
+
+/* minimal spacing metal cap per unit length */
+#define CCmetal (Cmetal * MCSCALE)
+#define CCM2metal (CM2metal * MCSCALE)
+#define CCM3metal (CM3metal * MCSCALE)
+/* 2x minimal spacing metal cap per unit length */
+#define CC2metal (Cmetal * MCSCALE2)
+#define CC2M2metal (CM2metal * MCSCALE2)
+#define CC2M3metal (CM3metal * MCSCALE2)
+/* 3x minimal spacing metal cap per unit length */
+#define CC3metal (Cmetal * MCSCALE3)
+#define CC3M2metal (CM2metal * MCSCALE3)
+#define CC3M3metal (CM3metal * MCSCALE3)
+
+/* fF/um */
+#define Cpolywire (0.25e-15 * CSCALE * LSCALE)
+
+/* ohms*um of channel width */
+#define Rnchannelstatic (25800 * LSCALE)
+
+/* ohms*um of channel width */
+#define Rpchannelstatic (61200 * LSCALE)
+
+#define Rnchannelon (9723 * LSCALE)
+
+#define Rpchannelon (22400 * LSCALE)
+
+/* corresponds to 16um of m2 @ 48mO/sq */
+#define Rbitmetal (0.320 * (RSCALE * ASCALE))
+
+/* corresponds to 8um of m3 @ 24mO/sq */
+#define Rwordmetal (0.080 * (RSCALE * ASCALE))
+
+#define Powerfactor (PARM_Freq)*Vdd*Vdd
+#define EnergyFactor (Vdd*Vdd)
+
+#define SensePowerfactor3 (PARM_Freq)*(Vbitsense)*(Vbitsense) //
+#define SensePowerfactor2 (PARM_Freq)*(Vbitpre-Vbitsense)*(Vbitpre-Vbitsense) //
+#define SensePowerfactor (PARM_Freq)*Vdd*(Vdd/2) //
+#define SenseEnergyFactor (Vdd*Vdd/2)
+
+/* transistor widths in um (as described in tech report, appendix 1) */
+#define Wdecdrivep (57.0 * LSCALE)
+#define Wdecdriven (40.0 * LSCALE)
+#define Wdec3to8n (14.4 * LSCALE)
+#define Wdec3to8p (14.4 * LSCALE)
+#define WdecNORn (5.4 * LSCALE)
+#define WdecNORp (30.5 * LSCALE)
+#define Wdecinvn (5.0 * LSCALE)
+#define Wdecinvp (10.0 * LSCALE)
+
+#define Wworddrivemax (100.0 * LSCALE)
+#define Wmemcella (2.4 * LSCALE) /* AMIT memory cell inverter PMOS transistor width */
+#define Wmemcellr (4.0 * LSCALE) /* AMIT memory cell read access transistor width */
+#define Wmemcellw (2.1 * LSCALE) /* AMIT memory cell write access transistor width */
+#define Wmemcellbscale 2 /* AMIT (mem cell inverter NMOS trans width = Wmemcella * Wmemcellbscale) means 2x bigger than Wmemcella */
+#define Wbitpreequ (10.0 * LSCALE) //
+
+#define Wbitmuxn (10.0 * LSCALE)
+#define WsenseQ1to4 (4.0 * LSCALE)
+#define Wcompinvp1 (10.0 * LSCALE)
+#define Wcompinvn1 (6.0 * LSCALE)
+#define Wcompinvp2 (20.0 * LSCALE)
+#define Wcompinvn2 (12.0 * LSCALE)
+#define Wcompinvp3 (40.0 * LSCALE)
+#define Wcompinvn3 (24.0 * LSCALE)
+#define Wevalinvp (20.0 * LSCALE)
+#define Wevalinvn (80.0 * LSCALE)
+
+#define Wcompn (20.0 * LSCALE)
+#define Wcompp (30.0 * LSCALE)
+#define Wcomppreequ (40.0 * LSCALE)
+#define Wmuxdrv12n (30.0 * LSCALE)
+#define Wmuxdrv12p (50.0 * LSCALE)
+#define WmuxdrvNANDn (20.0 * LSCALE)
+#define WmuxdrvNANDp (80.0 * LSCALE)
+#define WmuxdrvNORn (60.0 * LSCALE)
+#define WmuxdrvNORp (80.0 * LSCALE)
+#define Wmuxdrv3n (200.0 * LSCALE)
+#define Wmuxdrv3p (480.0 * LSCALE)
+#define Woutdrvseln (12.0 * LSCALE)
+#define Woutdrvselp (20.0 * LSCALE)
+#define Woutdrvnandn (24.0 * LSCALE)
+#define Woutdrvnandp (10.0 * LSCALE)
+#define Woutdrvnorn (6.0 * LSCALE)
+#define Woutdrvnorp (40.0 * LSCALE)
+#define Woutdrivern (48.0 * LSCALE)
+#define Woutdriverp (80.0 * LSCALE)
+#define Wbusdrvn (48.0 * LSCALE)
+#define Wbusdrvp (80.0 * LSCALE)
+
+#define Wcompcellpd2 (2.4 * LSCALE) //
+#define Wcompdrivern (400.0 * LSCALE)
+#define Wcompdriverp (800.0 * LSCALE)
+#define Wcomparen2 (40.0 * LSCALE)
+#define Wcomparen1 (20.0 * LSCALE)
+#define Wmatchpchg (10.0 * LSCALE)
+#define Wmatchinvn (10.0 * LSCALE)
+#define Wmatchinvp (20.0 * LSCALE)
+#define Wmatchnandn (20.0 * LSCALE)
+#define Wmatchnandp (10.0 * LSCALE)
+#define Wmatchnorn (20.0 * LSCALE)
+#define Wmatchnorp (10.0 * LSCALE)
+
+#define WSelORn (10.0 * LSCALE) //
+#define WSelORprequ (40.0 * LSCALE) //
+#define WSelPn (10.0 * LSCALE) //
+#define WSelPp (15.0 * LSCALE) //
+#define WSelEnn (5.0 * LSCALE) //
+#define WSelEnp (10.0 * LSCALE) //
+
+#define Wsenseextdrv1p (40.0*LSCALE) //
+#define Wsenseextdrv1n (24.0*LSCALE) //
+#define Wsenseextdrv2p (200.0*LSCALE) //
+#define Wsenseextdrv2n (120.0*LSCALE) //
+
+/* bit width of RAM cell in um */
+#define BitWidth (16.0 * LSCALE)
+
+/* bit height of RAM cell in um */
+#define BitHeight (16.0 * LSCALE)
+
+#define Cout (0.5e-12 * LSCALE)
+
+/* Sizing of cells and spacings */
+#define RatCellHeight (40.0 * LSCALE) //
+#define RatCellWidth (70.0 * LSCALE) //
+#define RatShiftRegWidth (120.0 * LSCALE) //
+#define RatNumShift 4 //
+#define BitlineSpacing (6.0 * LSCALE)
+#define WordlineSpacing (6.0 * LSCALE)
+
+#define RegCellHeight (16.0 * LSCALE) /* AMIT memory cell height */
+#define RegCellWidth (8.0 * LSCALE) /* AMIT memory cell width */
+
+#define CamCellHeight (40.0 * LSCALE)
+#define CamCellWidth (25.0 * LSCALE)
+#define MatchlineSpacing (6.0 * LSCALE)
+#define TaglineSpacing (6.0 * LSCALE)
+
+#define CrsbarCellHeight (6.0 * LSCALE)
+#define CrsbarCellWidth (6.0 * LSCALE)
+
+/* Link length in um */
+#define PARM_link_length 1000
+
+
+/*************************************************/
+
+/******* LEAKAGE current values for different tech points are in power_static.c *******/
+/******* for LINKS: metal cap is assumed to be CC2metal and repeater size is assumed to be n_size=Lambda*10, p_size=n_size*2 *******/
+
+/* -------------------------Miscellaneous---------------------------- */
+
+#define SIM_NO_MODEL 0
+
+#define MAX_ENERGY 1
+#define AVG_ENERGY 0
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a)>(b))?(b):(a))
+#endif
+
+#define NEXT_DEPTH(d) ((d) > 0 ? (d) - 1 : (d))
+
+#define BIGNUM 1e30
+#define BIGONE ((unsigned long int)1)
+#define BIGNONE ((unsigned long int)-1)
+#define HAMM_MASK(w) ((unsigned)w < (sizeof(unsigned long int) << 3) ? (BIGONE << w) - 1 : BIGNONE)
+
+/* Used to communicate with the horowitz model */
+#define RISE 1
+#define FALL 0
+#define NCH 1
+#define PCH 0
+/* --------------------------------------------------- */
+
+
+
+/* ---------------------- not used ------------------------------- */
+
+#define krise (0.4e-9 * LSCALE) //
+#define tsensedata (5.8e-10 * LSCALE) //
+#define tsensetag (2.6e-10 * LSCALE) //
+#define tfalldata (7e-10 * LSCALE) //
+#define tfalltag (7e-10 * LSCALE) //
+#define Vbitpre (3.3 * SSCALE) //
+#define Vt (1.09 * VTSCALE)
+#define Vbitsense (0.10 * SSCALE) //
+
+
+#define PARM_AF (5.000000e-01) //
+#define PARM_MAXN (8) //
+#define PARM_MAXSUBARRAYS (8) //
+#define PARM_MAXSPD (8) //
+#define PARM_VTHSENSEEXTDRV (4.370000e-01) //
+#define PARM_VTHOUTDRNOR (4.310000e-01) //
+#define PARM_res_fpalu (4) //
+#define PARM_VTHCOMPINV (4.370000e-01) //
+#define PARM_MD_NUM_IREGS (32) //
+#define PARM_die_length (1.800000e-02) //
+#define PARM_BITOUT (64) //
+
+#define PARM_ruu_decode_width (4) //
+#define PARM_ruu_issue_width (4) // AMIT used only for result bus
+#define PARM_amp_Idsat (5.000000e-04) //used in amp_energy
+#define PARM_AF_TYPE (1) //
+#define PARM_VSINV (4.560000e-01) //used in driver size calculations
+
+#define PARM_GEN_POWER_FACTOR (1.310000e+00) //
+#define PARM_res_memport (2) //
+#define PARM_VTHNAND60x90 (5.610000e-01) //
+
+#define PARM_opcode_length (8) //
+#define PARM_MD_NUM_FREGS (32) //
+#define PARM_FUDGEFACTOR (1.000000e+00) //
+#define PARM_ruu_commit_width (4) //
+
+#define PARM_VTHOUTDRIVE (4.250000e-01) //
+
+#define PARM_VTHMUXDRV1 (4.370000e-01) //
+#define PARM_inst_length (32) //
+#define PARM_VTHMUXDRV2 (4.860000e-01) //
+
+#define PARM_ras_size (8) //
+#define PARM_VTHMUXDRV3 (4.370000e-01) //
+#define PARM_ADDRESS_BITS (64) //
+#define PARM_RUU_size (16) //
+
+#define PARM_VTHNOR12x4x1 (5.030000e-01) //
+#define PARM_VTHNOR12x4x2 (4.520000e-01) //
+#define PARM_VTHOUTDRINV (4.370000e-01) //
+#define PARM_VTHNOR12x4x3 (4.170000e-01) //
+#define PARM_VTHEVALINV (2.670000e-01) //
+#define PARM_crossover_scaling (1.200000e+00) //
+#define PARM_VTHNOR12x4x4 (3.900000e-01) //
+#define PARM_turnoff_factor (1.000000e-01) //
+#define PARM_res_ialu (4) //
+
+#define PARM_VTHOUTDRNAND (4.410000e-01) //
+#define PARM_VTHINV100x60 (4.380000e-01) //
+#define PARM_LSQ_size (8) //
+
+/* ALU POWER NUMBERS for .18um 733Mhz */
+/* normalize .18um cap to other gen's cap, then xPowerfactor */
+#define POWER_SCALE (GEN_POWER_SCALE * PARM_NORMALIZE_SCALE * Powerfactor) //
+#define I_ADD ((.37 - .091)*POWER_SCALE) //
+#define I_ADD32 (((.37 - .091)/2)*POWER_SCALE) //
+#define I_MULT16 ((.31-.095)*POWER_SCALE) //
+#define I_SHIFT ((.21-.089)*POWER_SCALE) //
+#define I_LOGIC ((.04-.015)*POWER_SCALE) //
+#define F_ADD ((1.307-.452)*POWER_SCALE) //
+#define F_MULT ((1.307-.452)*POWER_SCALE) //
+
+#define I_ADD_CLOCK (.091*POWER_SCALE) //
+#define I_MULT_CLOCK (.095*POWER_SCALE) //
+#define I_SHIFT_CLOCK (.089*POWER_SCALE) //
+#define I_LOGIC_CLOCK (.015*POWER_SCALE) //
+#define F_ADD_CLOCK (.452*POWER_SCALE) //
+#define F_MULT_CLOCK (.452*POWER_SCALE) //
+
+
+/* ----------------------------------------------------- */
+
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_arbiter.cc b/src/mem/ruby/network/orion/power_arbiter.cc
new file mode 100644
index 000000000..ba68fbe1c
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_arbiter.cc
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "power_arbiter.hh"
+#include "power_array.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "power_utils.hh"
+
+
+
+
+
+/******************************* Power model for flip flop *****************************/
+
+/* ------- flip flop model ---------- */
+
+/* this model is based on the gate-level design given by Randy H. Katz "Contemporary Logic Design"
+ * Figure 6.24, node numbers (1-6) are assigned to all gate outputs, left to right, top to bottom
+ *
+ * We should have pure cap functions and leave the decision of whether or not to have coefficient
+ * 1/2 in init function.
+ */
+static double SIM_fpfp_node_cap(unsigned fan_in, unsigned fan_out)
+{
+ double Ctotal = 0;
+
+ /* FIXME: all need actual sizes */
+ /* part 1: drain cap of NOR gate */
+ Ctotal += fan_in * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, fan_in);
+
+ /* part 2: gate cap of NOR gates */
+ Ctotal += fan_out * SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ return Ctotal;
+}
+
+
+static double SIM_fpfp_clock_cap(void)
+{
+ /* gate cap of clock load */
+ return (2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0));
+}
+
+
+int SIM_fpfp_clear_stat(power_ff *ff)
+{
+ ff->n_switch = ff->n_keep_1 = ff->n_keep_0 = ff->n_clock = 0;
+
+ return 0;
+}
+
+
+int SIM_fpfp_init(power_ff *ff, int model, double load)
+{
+ double c1, c2, c3, c4, c5, c6;
+
+ if ((ff->model = model) && model < FF_MAX_MODEL) {
+ switch (model) {
+ case NEG_DFF:
+ SIM_fpfp_clear_stat(ff);
+
+ /* node 5 and node 6 are identical to node 1 in capacitance */
+ c1 = c5 = c6 = SIM_fpfp_node_cap(2, 1);
+ c2 = SIM_fpfp_node_cap(2, 3);
+ c3 = SIM_fpfp_node_cap(3, 2);
+ c4 = SIM_fpfp_node_cap(2, 3);
+
+ ff->e_switch = (c4 + c1 + c2 + c3 + c5 + c6 + load) / 2 * EnergyFactor;
+ /* no 1/2 for e_keep and e_clock because clock signal switches twice in one cycle */
+ ff->e_keep_1 = c3 * EnergyFactor;
+ ff->e_keep_0 = c2 * EnergyFactor;
+ ff->e_clock = SIM_fpfp_clock_cap() * EnergyFactor;
+
+ /* static power */
+ ff->i_leakage = (WdecNORp * NOR2_TAB[0] + WdecNORn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 * 6 / PARM_TECH_POINT * 100;
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+double SIM_fpfp_report(power_ff *ff)
+{
+ return (ff->e_switch * ff->n_switch + ff->e_clock * ff->n_clock +
+ ff->e_keep_0 * ff->n_keep_0 + ff->e_keep_1 * ff->n_keep_1);
+}
+
+/* ------- flip flop model ---------- */
+
+
+
+
+
+/* -------- arbiter power model ------------- */
+
+/* switch cap of request signal (round robin arbiter) */
+static double rr_arbiter_req_cap(double length)
+{
+ double Ctotal = 0;
+
+ /* part 1: gate cap of 2 NOR gates */
+ /* FIXME: need actual size */
+ Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ /* part 2: inverter */
+ /* FIXME: need actual size */
+ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) +
+ SIM_power_gatecap(Wdecinvn + Wdecinvp, 0);
+
+ /* part 3: wire cap */
+ Ctotal += length * Cmetal;
+
+ return Ctotal;
+}
+
+
+/* switch cap of priority signal (round robin arbiter) */
+static double rr_arbiter_pri_cap()
+{
+ double Ctotal = 0;
+
+ /* part 1: gate cap of NOR gate */
+ /* FIXME: need actual size */
+ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ return Ctotal;
+}
+
+
+/* switch cap of grant signal (round robin arbiter) */
+static double rr_arbiter_grant_cap()
+{
+ double Ctotal = 0;
+
+ /* part 1: drain cap of NOR gate */
+ /* FIXME: need actual size */
+ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2);
+
+ return Ctotal;
+}
+
+
+/* switch cap of carry signal (round robin arbiter) */
+static double rr_arbiter_carry_cap()
+{
+ double Ctotal = 0;
+
+ /* part 1: drain cap of NOR gate (this block) */
+ /* FIXME: need actual size */
+ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2);
+
+ /* part 2: gate cap of NOR gate (next block) */
+ /* FIXME: need actual size */
+ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ return Ctotal;
+}
+
+
+/* switch cap of internal carry node (round robin arbiter) */
+static double rr_arbiter_carry_in_cap()
+{
+ double Ctotal = 0;
+
+ /* part 1: gate cap of 2 NOR gates */
+ /* FIXME: need actual size */
+ Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ /* part 2: drain cap of NOR gate */
+ /* FIXME: need actual size */
+ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2);
+
+ return Ctotal;
+}
+
+
+/* the "huge" NOR gate in matrix arbiter model is an approximation */
+/* switch cap of request signal (matrix arbiter) */
+static double matrix_arbiter_req_cap(unsigned req_width, double length)
+{
+ double Ctotal = 0;
+
+ /* FIXME: all need actual sizes */
+ /* part 1: gate cap of NOR gates */
+ Ctotal += (req_width - 1) * SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ /* part 2: inverter */
+ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) +
+ SIM_power_gatecap(Wdecinvn + Wdecinvp, 0);
+
+ /* part 3: gate cap of the "huge" NOR gate */
+ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ /* part 4: wire cap */
+ Ctotal += length * Cmetal;
+
+ return Ctotal;
+}
+
+
+/* switch cap of priority signal (matrix arbiter) */
+static double matrix_arbiter_pri_cap(unsigned req_width)
+{
+ double Ctotal = 0;
+
+ /* part 1: gate cap of NOR gates (2 groups) */
+ Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ /* no inverter because priority signal is kept by a flip flop */
+ return Ctotal;
+}
+
+
+/* switch cap of grant signal (matrix arbiter) */
+static double matrix_arbiter_grant_cap(unsigned req_width)
+{
+ /* drain cap of the "huge" NOR gate */
+ return (req_width * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, req_width));
+}
+
+
+/* switch cap of internal node (matrix arbiter) */
+static double matrix_arbiter_int_cap()
+{
+ double Ctotal = 0;
+
+ /* part 1: drain cap of NOR gate */
+ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2);
+
+ /* part 2: gate cap of the "huge" NOR gate */
+ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0);
+
+ return Ctotal;
+}
+
+
+static int arbiter_clear_stat(power_arbiter *arb)
+{
+ arb->n_chg_req = arb->n_chg_grant = arb->n_chg_mint = 0;
+ arb->n_chg_carry = arb->n_chg_carry_in = 0;
+
+ SIM_array_clear_stat(&arb->queue);
+ SIM_fpfp_clear_stat(&arb->pri_ff);
+
+ return 0;
+}
+
+
+int power_arbiter_init(power_arbiter *arb, int arbiter_model, int ff_model, unsigned req_width, double length, power_array_info *info)
+{
+ if ((arb->model = arbiter_model) && arbiter_model < ARBITER_MAX_MODEL) {
+ arb->req_width = req_width;
+ arbiter_clear_stat(arb);
+ /* redundant field */
+ arb->mask = HAMM_MASK(req_width);
+
+ switch (arbiter_model) {
+ case RR_ARBITER:
+ arb->e_chg_req = rr_arbiter_req_cap(length) / 2 * EnergyFactor;
+ /* two grant signals switch together, so no 1/2 */
+ arb->e_chg_grant = rr_arbiter_grant_cap() * EnergyFactor;
+ arb->e_chg_carry = rr_arbiter_carry_cap() / 2 * EnergyFactor;
+ arb->e_chg_carry_in = rr_arbiter_carry_in_cap() / 2 * EnergyFactor;
+ arb->e_chg_mint = 0;
+
+ if (SIM_fpfp_init(&arb->pri_ff, ff_model, rr_arbiter_pri_cap()))
+ return -1;
+ break;
+
+ case MATRIX_ARBITER:
+ arb->e_chg_req = matrix_arbiter_req_cap(req_width, length) / 2 * EnergyFactor;
+ /* 2 grant signals switch together, so no 1/2 */
+ arb->e_chg_grant = matrix_arbiter_grant_cap(req_width) * EnergyFactor;
+ arb->e_chg_mint = matrix_arbiter_int_cap() / 2 * EnergyFactor;
+ arb->e_chg_carry = arb->e_chg_carry_in = 0;
+
+ if (SIM_fpfp_init(&arb->pri_ff, ff_model, matrix_arbiter_pri_cap(req_width)))
+ return -1;
+ break;
+
+ case QUEUE_ARBITER:
+ arb->e_chg_req = arb->e_chg_grant = arb->e_chg_mint = 0;
+ arb->e_chg_carry = arb->e_chg_carry_in = 0;
+
+ return power_array_init(info, &arb->queue);
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int arbiter_record(power_arbiter *arb, unsigned long int new_req, unsigned long int old_req, unsigned new_grant, unsigned old_grant)
+{
+ switch (arb->model) {
+ case MATRIX_ARBITER:
+ arb->n_chg_req += SIM_power_Hamming(new_req, old_req, arb->mask);
+ arb->n_chg_grant += new_grant != old_grant;
+ /* FIXME: approximation */
+ arb->n_chg_mint += (arb->req_width - 1) * arb->req_width / 2;
+ /* priority registers */
+ /* FIXME: use average instead */
+ arb->pri_ff.n_switch += (arb->req_width - 1) / 2;
+ break;
+
+ case RR_ARBITER:
+ arb->n_chg_req += SIM_power_Hamming(new_req, old_req, arb->mask);
+ arb->n_chg_grant += new_grant != old_grant;
+ /* FIXME: use average instead */
+ arb->n_chg_carry += arb->req_width / 2;
+ arb->n_chg_carry_in += arb->req_width / 2 - 1;
+ /* priority registers */
+ arb->pri_ff.n_switch += 2;
+ break;
+
+ case QUEUE_ARBITER:
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+}
+
+
+double arbiter_report(power_arbiter *arb)
+{
+ switch (arb->model) {
+ case MATRIX_ARBITER:
+ return (arb->n_chg_req * arb->e_chg_req + arb->n_chg_grant * arb->e_chg_grant +
+ arb->n_chg_mint * arb->e_chg_mint +
+ arb->pri_ff.n_switch * arb->pri_ff.e_switch +
+ arb->pri_ff.n_keep_1 * arb->pri_ff.e_keep_1 +
+ arb->pri_ff.n_keep_0 * arb->pri_ff.e_keep_0 +
+ arb->pri_ff.n_clock * arb->pri_ff.e_clock);
+
+ case RR_ARBITER:
+ return (arb->n_chg_req * arb->e_chg_req + arb->n_chg_grant * arb->e_chg_grant +
+ arb->n_chg_carry * arb->e_chg_carry + arb->n_chg_carry_in * arb->e_chg_carry_in +
+ arb->pri_ff.n_switch * arb->pri_ff.e_switch +
+ arb->pri_ff.n_keep_1 * arb->pri_ff.e_keep_1 +
+ arb->pri_ff.n_keep_0 * arb->pri_ff.e_keep_0 +
+ arb->pri_ff.n_clock * arb->pri_ff.e_clock);
+
+ default: return -1;
+ }
+}
+
+/* ---------- arbiter power model ----------- */
+
+
diff --git a/src/mem/ruby/network/orion/power_arbiter.hh b/src/mem/ruby/network/orion/power_arbiter.hh
new file mode 100644
index 000000000..671608c2f
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_arbiter.hh
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+// Arbiter
+
+
+#ifndef _POWER_ARBITER_H
+#define _POWER_ARBITER_H
+
+#include "power_array.hh"
+
+typedef enum {
+ RR_ARBITER =1,
+ MATRIX_ARBITER,
+ QUEUE_ARBITER,
+ ARBITER_MAX_MODEL
+} power_arbiter_model;
+
+typedef enum {
+ NEG_DFF = 1, /* negative egde-triggered D flip-flop */
+ FF_MAX_MODEL
+} power_ff_model;
+
+typedef struct {
+ int model;
+ unsigned long int n_switch;
+ unsigned long int n_keep_1;
+ unsigned long int n_keep_0;
+ unsigned long int n_clock;
+ double e_switch;
+ double e_keep_1;
+ double e_keep_0;
+ double e_clock;
+ double i_leakage;
+} power_ff;
+
+typedef struct{
+ int model;
+ unsigned req_width;
+ unsigned long int n_chg_req;
+ unsigned long int n_chg_grant;
+ unsigned long int n_chg_carry; //internal node of rr arbiter
+ unsigned long int n_chg_carry_in; //internal node of rr arbiter
+ unsigned long int n_chg_mint; //internal node of matrix arbiter
+ unsigned long int mask;
+ double e_chg_req;
+ double e_chg_grant;
+ double e_chg_carry;
+ double e_chg_carry_in;
+ double e_chg_mint;
+ power_ff pri_ff; //priority ff
+ power_array queue; //request queue
+ double i_leakage;
+} power_arbiter;
+
+extern int arbiter_record(power_arbiter *arb, unsigned long int new_req, unsigned long int old_req, unsigned new_grant, unsigned old_grant);
+
+extern double arbiter_report(power_arbiter *arb);
+
+extern int power_arbiter_init(power_arbiter *arb, int arbiter_model, int ff_model, unsigned req_width, double length, power_array_info *info);
+
+#endif
+
+
+
diff --git a/src/mem/ruby/network/orion/power_array.cc b/src/mem/ruby/network/orion/power_array.cc
new file mode 100644
index 000000000..225f45377
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_array.cc
@@ -0,0 +1,2158 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "power_array.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "power_utils.hh"
+
+/* local macros */
+
+#define IS_DIRECT_MAP( info ) ((info)->assoc == 1)
+#define IS_FULLY_ASSOC( info ) ((info)->n_set == 1 && (info)->assoc > 1)
+#define IS_WRITE_THROUGH( info ) (! (info)->write_policy)
+#define IS_WRITE_BACK( info ) ((info)->write_policy)
+
+/* sufficient (not necessary) condition */
+#define HAVE_TAG( info ) ((info)->tag_mem_model)
+#define HAVE_USE_BIT( info ) ((info)->use_bit_width)
+#define HAVE_COL_DEC( info ) ((info)->col_dec_model)
+#define HAVE_COL_MUX( info ) ((info)->mux_model)
+
+
+/* ----------------------------- CAM ---------------------------------- */
+/*============================== wordlines ==============================*/
+
+/* each time one wordline 1->0, another wordline 0->1, so no 1/2 */
+double SIM_cam_wordline_cap( unsigned cols, double wire_cap, double tx_width )
+{
+ double Ctotal, Cline, psize, nsize;
+
+ /* part 1: line cap, including gate cap of pass tx's and metal cap */
+ Ctotal = Cline = SIM_power_gatecappass( tx_width, 2 ) * cols + wire_cap;
+
+ /* part 2: input driver */
+ psize = SIM_power_driver_size( Cline, Period / 8 );
+ nsize = psize * Wdecinvn / Wdecinvp;
+ /* WHS: 20 should go to PARM */
+ Ctotal += SIM_power_draincap( nsize, NCH, 1 ) + SIM_power_draincap( psize, PCH, 1 ) +
+ SIM_power_gatecap( nsize + psize, 20 );
+
+ return Ctotal;
+}
+
+/*============================== wordlines ==============================*/
+
+
+
+/*============================== tag comparator ==============================*/
+
+/* tag and tagbar switch simultaneously, so no 1/2 */
+double SIM_cam_comp_tagline_cap( unsigned rows, double taglinelength )
+{
+ double Ctotal;
+
+ /* part 1: line cap, including drain cap of pass tx's and metal cap */
+ Ctotal = rows * SIM_power_gatecap( Wcomparen2, 2 ) + CC3M2metal * taglinelength;
+
+ /* part 2: input driver */
+ Ctotal += SIM_power_draincap( Wcompdrivern, NCH, 1 ) + SIM_power_draincap( Wcompdriverp, PCH, 1 ) +
+ SIM_power_gatecap( Wcompdrivern + Wcompdriverp, 1 );
+
+ return Ctotal;
+}
+
+
+/* upon mismatch, matchline 1->0, then 0->1 on next precharging, so no 1/2 */
+double SIM_cam_comp_mismatch_cap( unsigned n_bits, unsigned n_pre, double matchline_len )
+{
+ double Ctotal;
+
+ /* part 1: drain cap of precharge tx */
+ Ctotal = n_pre * SIM_power_draincap( Wmatchpchg, PCH, 1 );
+
+ /* part 2: drain cap of comparator tx */
+ Ctotal += n_bits * ( SIM_power_draincap( Wcomparen1, NCH, 1 ) + SIM_power_draincap( Wcomparen1, NCH, 2 ));
+
+ /* part 3: metal cap of matchline */
+ Ctotal += CC3M3metal * matchline_len;
+
+ /* FIXME: I don't understand the Wattch code here */
+ /* part 4: nor gate of valid output */
+ Ctotal += SIM_power_gatecap( Wmatchnorn + Wmatchnorp, 10 );
+
+ return Ctotal;
+}
+
+
+/* WHS: subtle difference of valid output between cache and inst window:
+ * fully-associative cache: nor all matchlines of the same port
+ * instruction window: nor all matchlines of the same tag line */
+/* upon miss, valid output switches twice in one cycle, so no 1/2 */
+double SIM_cam_comp_miss_cap( unsigned assoc )
+{
+ /* drain cap of valid output */
+ return ( assoc * SIM_power_draincap( Wmatchnorn, NCH, 1 ) + SIM_power_draincap( Wmatchnorp, PCH, assoc ));
+}
+
+/*============================== tag comparator ==============================*/
+
+
+
+/*============================== memory cell ==============================*/
+
+/* WHS: use Wmemcella and Wmemcellbscale to compute tx width of memory cell */
+double SIM_cam_tag_mem_cap( unsigned read_ports, unsigned write_ports, int share_rw, unsigned end, int only_write )
+{
+ double Ctotal;
+
+ /* part 1: drain capacitance of pass transistors */
+ if ( only_write )
+ Ctotal = SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports;
+ else {
+ Ctotal = SIM_power_draincap( Wmemcellr, NCH, 1 ) * read_ports * end / 2;
+ if ( ! share_rw )
+ Ctotal += SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports;
+ }
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 2: drain capacitance of memory cell */
+ Ctotal += SIM_power_draincap( Wmemcella, NCH, 1 ) + SIM_power_draincap( Wmemcella * Wmemcellbscale, PCH, 1 );
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 3: gate capacitance of memory cell */
+ Ctotal += SIM_power_gatecap( Wmemcella, 1 ) + SIM_power_gatecap( Wmemcella * Wmemcellbscale, 1 );
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 4: gate capacitance of comparator */
+ Ctotal += SIM_power_gatecap( Wcomparen1, 2 ) * read_ports;
+
+ return Ctotal;
+}
+
+
+double SIM_cam_data_mem_cap( unsigned read_ports, unsigned write_ports )
+{
+ double Ctotal;
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 1: drain capacitance of pass transistors */
+ Ctotal = SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports;
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 2: drain capacitance of memory cell */
+ Ctotal += SIM_power_draincap( Wmemcella, NCH, 1 ) + SIM_power_draincap( Wmemcella * Wmemcellbscale, PCH, 1 );
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 3: gate capacitance of memory cell */
+ Ctotal += SIM_power_gatecap( Wmemcella, 1 ) + SIM_power_gatecap( Wmemcella * Wmemcellbscale, 1 );
+
+ /* part 4: gate capacitance of output driver */
+ Ctotal += ( SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) +
+ SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 )) / 2 * read_ports;
+
+ return Ctotal;
+}
+
+/*============================== memory cell ==============================*/
+
+
+
+
+
+
+
+/* ---------- buffer model ------------ */
+
+// ------- Decoder begin
+
+/*#
+ * compute switching cap when decoder changes output (select signal)
+ *
+ * Parameters:
+ * n_input -- fanin of 1 gate of last level decoder
+ *
+ * Return value: switching cap
+ *
+ * NOTES: 2 select signals switch, so no 1/2
+ */
+static double SIM_array_dec_select_cap( unsigned n_input )
+{
+ double Ctotal = 0;
+
+ /* FIXME: why? */
+ // if ( numstack > 5 ) numstack = 5;
+
+ /* part 1: drain cap of last level decoders */
+ Ctotal = n_input * SIM_power_draincap( WdecNORn, NCH, 1 ) + SIM_power_draincap( WdecNORp, PCH, n_input );
+
+ /* part 2: output inverter */
+ /* WHS: 20 should go to PARM */
+ Ctotal += SIM_power_draincap( Wdecinvn, NCH, 1 ) + SIM_power_draincap( Wdecinvp, PCH, 1) +
+ SIM_power_gatecap( Wdecinvn + Wdecinvp, 20 );
+
+ return Ctotal;
+}
+
+
+/*#
+ * compute switching cap when 1 input bit of decoder changes
+ *
+ * Parameters:
+ * n_gates -- fanout of 1 addr signal
+ *
+ * Return value: switching cap
+ *
+ * NOTES: both addr and its complement change, so no 1/2
+ */
+static double SIM_array_dec_chgaddr_cap( unsigned n_gates )
+{
+ double Ctotal;
+
+ /* stage 1: input driver */
+ Ctotal = SIM_power_draincap( Wdecdrivep, PCH, 1 ) + SIM_power_draincap( Wdecdriven, NCH, 1 ) +
+ SIM_power_gatecap( Wdecdrivep, 1 ) + SIM_power_gatecap( Wdecdriven, 1 );
+ /* inverter to produce complement addr, this needs 1/2 */
+ /* WHS: assume Wdecinv(np) for this inverter */
+ Ctotal += ( SIM_power_draincap( Wdecinvp, PCH, 1 ) + SIM_power_draincap( Wdecinvn, NCH, 1 ) +
+ SIM_power_gatecap( Wdecinvp, 1 ) + SIM_power_gatecap( Wdecinvn, 1 )) / 2;
+
+ /* stage 2: gate cap of level-1 decoder */
+ /* WHS: 10 should go to PARM */
+ Ctotal += n_gates * SIM_power_gatecap( Wdec3to8n + Wdec3to8p, 10 );
+
+ return Ctotal;
+}
+
+
+/*#
+ * compute switching cap when 1st-level decoder changes output
+ *
+ * Parameters:
+ * n_in_1st -- fanin of 1 gate of 1st-level decoder
+ * n_in_2nd -- fanin of 1 gate of 2nd-level decoder
+ * n_gates -- # of gates of 2nd-level decoder, i.e.
+ * fanout of 1 gate of 1st-level decoder
+ *
+ * Return value: switching cap
+ *
+ * NOTES: 2 complementary signals switch, so no 1/2
+ */
+static double SIM_array_dec_chgl1_cap( unsigned n_in_1st, unsigned n_in_2nd, unsigned n_gates )
+{
+ double Ctotal;
+
+ /* part 1: drain cap of level-1 decoder */
+ Ctotal = n_in_1st * SIM_power_draincap( Wdec3to8p, PCH, 1 ) + SIM_power_draincap( Wdec3to8n, NCH, n_in_1st );
+
+ /* part 2: gate cap of level-2 decoder */
+ /* WHS: 40 and 20 should go to PARM */
+ Ctotal += n_gates * SIM_power_gatecap( WdecNORn + WdecNORp, n_in_2nd * 40 + 20 );
+
+ return Ctotal;
+}
+
+
+static int SIM_array_dec_clear_stat(power_decoder *dec)
+{
+ dec->n_chg_output = dec->n_chg_l1 = dec->n_chg_addr = 0;
+
+ return 0;
+}
+
+
+/*#
+ * initialize decoder
+ *
+ * Parameters:
+ * dec -- decoder structure
+ * model -- decoder model type
+ * n_bits -- decoder width
+ *
+ * Side effects:
+ * initialize dec structure if model type is valid
+ *
+ * Return value: -1 if model type is invalid
+ * 0 otherwise
+ */
+static int SIM_array_dec_init(power_decoder *dec, int model, unsigned n_bits )
+{
+ if ((dec->model = model) && model < DEC_MAX_MODEL) {
+ dec->n_bits = n_bits;
+ /* redundant field */
+ dec->addr_mask = HAMM_MASK(n_bits);
+
+ SIM_array_dec_clear_stat(dec);
+ dec->e_chg_output = dec->e_chg_l1 = dec->e_chg_addr = 0;
+
+ /* compute geometry parameters */
+ if ( n_bits >= 4 ) { /* 2-level decoder */
+ /* WHS: inaccurate for some n_bits */
+ dec->n_in_1st = ( n_bits == 4 ) ? 2:3;
+ dec->n_out_0th = BIGONE << ( dec->n_in_1st - 1 );
+ dec->n_in_2nd = (unsigned)ceil((double)n_bits / dec->n_in_1st );
+ dec->n_out_1st = BIGONE << ( n_bits - dec->n_in_1st );
+ }
+ else if ( n_bits >= 2 ) { /* 1-level decoder */
+ dec->n_in_1st = n_bits;
+ dec->n_out_0th = BIGONE << ( n_bits - 1 );
+ dec->n_in_2nd = dec->n_out_1st = 0;
+ }
+ else { /* no decoder basically */
+ dec->n_in_1st = dec->n_in_2nd = dec->n_out_0th = dec->n_out_1st = 0;
+ }
+
+ /* compute energy constants */
+ if ( n_bits >= 2 ) {
+ dec->e_chg_l1 = SIM_array_dec_chgl1_cap( dec->n_in_1st, dec->n_in_2nd, dec->n_out_1st ) * EnergyFactor;
+ if ( n_bits >= 4 )
+ dec->e_chg_output = SIM_array_dec_select_cap( dec->n_in_2nd ) * EnergyFactor;
+ }
+ dec->e_chg_addr = SIM_array_dec_chgaddr_cap( dec->n_out_0th ) * EnergyFactor;
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+/*#
+ * record decoder power stats
+ *
+ * Parameters:
+ * dec -- decoder structure
+ * prev_addr -- previous input
+ * curr_addr -- current input
+ *
+ * Side effects:
+ * update counters in dec structure
+ *
+ * Return value: 0
+ */
+int SIM_array_dec_record(power_decoder *dec, unsigned long int prev_addr, unsigned long int curr_addr )
+{
+ unsigned n_chg_bits, n_chg_l1 = 0, n_chg_output = 0;
+ unsigned i;
+ unsigned long int mask;
+
+ /* compute Hamming distance */
+ n_chg_bits = SIM_power_Hamming( prev_addr, curr_addr, dec->addr_mask );
+ if ( n_chg_bits ) {
+ if ( dec->n_bits >= 4 ) { /* 2-level decoder */
+ /* WHS: inaccurate for some n_bits */
+ n_chg_output ++;
+ /* count addr group changes */
+ mask = HAMM_MASK(dec->n_in_1st);
+ for ( i = 0; i < dec->n_in_2nd; i ++ ) {
+ if ( SIM_power_Hamming( prev_addr, curr_addr, mask ))
+ n_chg_l1 ++;
+ mask = mask << dec->n_in_1st;
+ }
+ }
+ else if ( dec->n_bits >= 2 ) { /* 1-level decoder */
+ n_chg_l1 ++;
+ }
+
+ dec->n_chg_addr += n_chg_bits;
+ dec->n_chg_l1 += n_chg_l1;
+ dec->n_chg_output += n_chg_output;
+ }
+
+ return 0;
+}
+
+
+/*#
+ * report decoder power stats
+ *
+ * Parameters:
+ * dec -- decoder structure
+ *
+ * Return value: total energy consumption of this decoder
+ *
+ * TODO: add more report functionality, currently only total energy is reported
+ */
+double SIM_array_dec_report(power_decoder *dec )
+{
+ double Etotal;
+
+ Etotal = dec->n_chg_output * dec->e_chg_output + dec->n_chg_l1 * dec->e_chg_l1 +
+ dec->n_chg_addr * dec->e_chg_addr;
+
+ /* bonus energy for dynamic decoder :) */
+ //if ( is_dynamic_dec( dec->model )) Etotal += Etotal;
+
+ return Etotal;
+}
+
+// ------- Decoder end
+
+
+
+// ------- Wordlines begin
+
+/*#
+ * compute wordline switching cap
+ *
+ * Parameters:
+ * cols -- # of pass transistors, i.e. # of bitlines
+ * wordlinelength -- length of wordline
+ * tx_width -- width of pass transistor
+ *
+ * Return value: switching cap
+ *
+ * NOTES: upon address change, one wordline 1->0, another 0->1, so no 1/2
+ */
+static double SIM_array_wordline_cap( unsigned cols, double wire_cap, double tx_width )
+{
+ double Ctotal, Cline, psize, nsize;
+
+ /* part 1: line cap, including gate cap of pass tx's and metal cap */
+ Ctotal = Cline = SIM_power_gatecappass( tx_width, BitWidth / 2 - tx_width ) * cols + wire_cap;
+
+ /* part 2: input driver */
+ psize = SIM_power_driver_size( Cline, Period / 16 );
+ nsize = psize * Wdecinvn / Wdecinvp;
+ /* WHS: 20 should go to PARM */
+ Ctotal += SIM_power_draincap( nsize, NCH, 1 ) + SIM_power_draincap( psize, PCH, 1 ) +
+ SIM_power_gatecap( nsize + psize, 20 );
+
+ return Ctotal;
+}
+
+
+static int SIM_array_wordline_clear_stat(power_wordline *wordline)
+{
+ wordline->n_read = wordline->n_write = 0;
+
+ return 0;
+}
+
+
+/*#
+ * initialize wordline
+ *
+ * Parameters:
+ * wordline -- wordline structure
+ * model -- wordline model type
+ * share_rw -- 1 if shared R/W wordlines, 0 if separate R/W wordlines
+ * cols -- # of array columns, NOT # of bitlines
+ * wire_cap -- wordline wire capacitance
+ * end -- end of bitlines
+ *
+ * Return value: -1 if invalid model type
+ * 0 otherwise
+ *
+ * Side effects:
+ * initialize wordline structure if model type is valid
+ *
+ * TODO: add error handler
+ */
+static int SIM_array_wordline_init(power_wordline *wordline, int model, int share_rw, unsigned cols, double wire_cap, unsigned end )
+{
+ if ((wordline->model = model) && model < WORDLINE_MAX_MODEL) {
+ SIM_array_wordline_clear_stat(wordline);
+
+ switch ( model ) {
+ case CAM_RW_WORDLINE:
+ wordline->e_read = SIM_cam_wordline_cap( cols * end, wire_cap, Wmemcellr ) * EnergyFactor;
+ if ( wordline->share_rw = share_rw )
+ wordline->e_write = wordline->e_read;
+ else
+ /* write bitlines are always double-ended */
+ wordline->e_write = SIM_cam_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor;
+ break;
+
+ case CAM_WO_WORDLINE: /* only have write wordlines */
+ wordline->share_rw = 0;
+ wordline->e_read = 0;
+ wordline->e_write = SIM_cam_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor;
+ break;
+
+ case CACHE_WO_WORDLINE: /* only have write wordlines */
+ wordline->share_rw = 0;
+ wordline->e_read = 0;
+ wordline->e_write = SIM_array_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor;
+ break;
+
+ case CACHE_RW_WORDLINE:
+ wordline->e_read = SIM_array_wordline_cap( cols * end, wire_cap, Wmemcellr ) * EnergyFactor;
+ if ( wordline->share_rw = share_rw )
+ wordline->e_write = wordline->e_read;
+ else
+ wordline->e_write = SIM_array_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor;
+
+ /* static power */
+ /* input driver */
+ wordline->i_leakage = (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) / PARM_TECH_POINT * 100;
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+/*#
+ * record wordline power stats
+ *
+ * Parameters:
+ * wordline -- wordline structure
+ * rw -- 1 if write operation, 0 if read operation
+ * n_switch -- switching times
+ *
+ * Return value: 0
+ *
+ * Side effects:
+ * update counters of wordline structure
+ */
+int SIM_array_wordline_record(power_wordline *wordline, int rw, unsigned long int n_switch )
+{
+ if ( rw ) wordline->n_write += n_switch;
+ else wordline->n_read += n_switch;
+
+ return 0;
+}
+
+
+/*#
+ * report wordline power stats
+ *
+ * Parameters:
+ * wordline -- wordline structure
+ *
+ * Return value: total energy consumption of all wordlines of this array
+ *
+ * TODO: add more report functionality, currently only total energy is reported
+ */
+double SIM_array_wordline_report(power_wordline *wordline )
+{
+ return ( wordline->n_read * wordline->e_read +
+ wordline->n_write * wordline->e_write );
+}
+
+// ------- Wordlines end
+
+
+
+// ------- Bitlines begin
+
+/*#
+ * compute switching cap of reading 1 separate bitline column
+ *
+ * Parameters:
+ * rows -- # of array rows, i.e. # of wordlines
+ * wire_cap -- bitline wire capacitance
+ * end -- end of bitlines
+ * n_share_amp -- # of columns who share one sense amp
+ * n_bitline_pre -- # of precharge transistor drains for 1 bitline column
+ * n_colsel_pre -- # of precharge transistor drains for 1 column selector, if any
+ * pre_size -- width of precharge transistors
+ * outdrv_model -- output driver model type
+ *
+ * Return value: switching cap
+ *
+ * NOTES: one bitline 1->0, then 0->1 on next precharging, so no 1/2
+ */
+static double SIM_array_column_read_cap(unsigned rows, double wire_cap, unsigned end, unsigned n_share_amp, unsigned n_bitline_pre, unsigned n_colsel_pre, double pre_size, int outdrv_model)
+{
+ double Ctotal=0, Cprecharge=0, Cpass=0, Cwire=0, Ccol_sel=0, Csense=0;
+
+ /* part 1: drain cap of precharge tx's */
+ Cprecharge = n_bitline_pre * SIM_power_draincap( pre_size, PCH, 1 );
+// printf("Precharge = %g\n", Cprecharge);
+ Ctotal = Cprecharge;
+
+ /* part 2: drain cap of pass tx's */
+ Cpass = rows * SIM_power_draincap( Wmemcellr, NCH, 1 );
+// printf("Pass = %g\n", Cpass);
+ Ctotal += Cpass;
+
+ /* part 3: metal cap */
+ Cwire = wire_cap;
+// printf("Wire = %g\n", Cwire);
+ Ctotal += Cwire;
+
+ /* part 4: column selector or bitline inverter */
+ if ( end == 1 ) { /* bitline inverter */
+ /* FIXME: magic numbers */
+ Ccol_sel = SIM_power_gatecap( MSCALE * ( 29.9 + 7.8 ), 0 ) +
+ SIM_power_gatecap( MSCALE * ( 47.0 + 12.0), 0 );
+ }
+ else if ( n_share_amp > 1 ) { /* column selector */
+ /* drain cap of pass tx's */
+ Ccol_sel = ( n_share_amp + 1 ) * SIM_power_draincap( Wbitmuxn, NCH, 1 );
+ /* drain cap of column selector precharge tx's */
+ Ccol_sel += n_colsel_pre * SIM_power_draincap( pre_size, PCH, 1 );
+ /* FIXME: no way to count activity factor on gates of column selector */
+ }
+// printf("Col selector = %g\n", Ccol_sel);
+
+ Ctotal += Ccol_sel;
+
+ /* part 5: gate cap of sense amplifier or output driver */
+ if (end == 2) /* sense amplifier */
+ Csense = 2 * SIM_power_gatecap( WsenseQ1to4, 10 );
+ else if (outdrv_model) /* end == 1, output driver */
+ Csense = SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) +
+ SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 );
+// printf("Sense = %g\n", Csense);
+ Ctotal += Csense;
+
+ return Ctotal;
+}
+
+
+/*#
+ * compute switching cap of selecting 1 column selector
+ *
+ * Parameters:
+ *
+ * Return value: switching cap
+ *
+ * NOTES: select one, deselect another, so no 1/2
+ */
+static double SIM_array_column_select_cap( void )
+{
+ return SIM_power_gatecap( Wbitmuxn, 1 );
+}
+
+
+/*#
+ * compute switching cap of writing 1 separate bitline column
+ *
+ * Parameters:
+ * rows -- # of array rows, i.e. # of wordlines
+ * wire_cap -- bitline wire capacitance
+ *
+ * Return value: switching cap
+ *
+ * NOTES: bit and bitbar switch simultaneously, so no 1/2
+ */
+static double SIM_array_column_write_cap( unsigned rows, double wire_cap )
+{
+ double Ctotal=0, Cwire=0, Cpass=0, Cdriver=0, psize, nsize;
+
+ Cwire = wire_cap;
+// printf("WRITE wire cap = %g\n", Cwire);
+ Ctotal = Cwire;
+
+ /* part 1: line cap, including drain cap of pass tx's and metal cap */
+ Cpass = rows * SIM_power_draincap( Wmemcellw, NCH, 1 );
+// printf("WRITE pass tx cap = %g\n", Cpass);
+ Ctotal += Cpass;
+
+
+ /* part 2: write driver */
+ psize = SIM_power_driver_size( Ctotal, Period / 8 );
+ nsize = psize * Wdecinvn / Wdecinvp;
+ Cdriver = SIM_power_draincap( psize, PCH, 1 ) + SIM_power_draincap( nsize, NCH, 1 ) +
+ SIM_power_gatecap( psize + nsize, 1 );
+// printf("WRITE driver cap = %g\n", Cdriver);
+ Ctotal += Cdriver;
+
+ return Ctotal;
+}
+
+
+/* one bitline switches twice in one cycle, so no 1/2 */
+static double SIM_array_share_column_write_cap( unsigned rows, double wire_cap, unsigned n_share_amp, unsigned n_bitline_pre, double pre_size )
+{
+ double Ctotal, psize, nsize;
+
+ /* part 1: drain cap of precharge tx's */
+ Ctotal = n_bitline_pre * SIM_power_draincap( pre_size, PCH, 1 );
+
+ /* part 2: drain cap of pass tx's */
+ Ctotal += rows * SIM_power_draincap( Wmemcellr, NCH, 1 );
+
+ /* part 3: metal cap */
+ Ctotal += wire_cap;
+
+ /* part 4: column selector or sense amplifier */
+ if ( n_share_amp > 1 ) Ctotal += SIM_power_draincap( Wbitmuxn, NCH, 1 );
+ else Ctotal += 2 * SIM_power_gatecap( WsenseQ1to4, 10 );
+
+ /* part 5: write driver */
+ psize = SIM_power_driver_size( Ctotal, Period / 8 );
+ nsize = psize * Wdecinvn / Wdecinvp;
+ /* WHS: omit gate cap of driver due to modeling difficulty */
+ Ctotal += SIM_power_draincap( psize, PCH, 1 ) + SIM_power_draincap( nsize, NCH, 1 );
+
+ return Ctotal;
+}
+
+
+/* one bitline switches twice in one cycle, so no 1/2 */
+static double SIM_array_share_column_read_cap( unsigned rows, double wire_cap, unsigned n_share_amp, unsigned n_bitline_pre, unsigned n_colsel_pre, double pre_size )
+{
+ double Ctotal;
+
+ /* part 1: same portion as write */
+ Ctotal = SIM_array_share_column_write_cap( rows, wire_cap, n_share_amp, n_bitline_pre, pre_size );
+
+ /* part 2: column selector and sense amplifier */
+ if ( n_share_amp > 1 ) {
+ /* bottom part of drain cap of pass tx's */
+ Ctotal += n_share_amp * SIM_power_draincap( Wbitmuxn, NCH, 1 );
+ /* drain cap of column selector precharge tx's */
+ Ctotal += n_colsel_pre * SIM_power_draincap( pre_size, PCH, 1 );
+
+ /* part 3: gate cap of sense amplifier */
+ Ctotal += 2 * SIM_power_gatecap( WsenseQ1to4, 10 );
+ }
+
+ return Ctotal;
+}
+
+
+static int SIM_array_bitline_clear_stat(power_bitline *bitline)
+{
+ bitline->n_col_write = bitline->n_col_read = bitline->n_col_sel = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_bitline_init(power_bitline *bitline, int model, int share_rw, unsigned end, unsigned rows, double wire_cap, unsigned n_share_amp, unsigned n_bitline_pre, unsigned n_colsel_pre, double pre_size, int outdrv_model)
+{
+ if ((bitline->model = model) && model < BITLINE_MAX_MODEL) {
+ bitline->end = end;
+ SIM_array_bitline_clear_stat(bitline);
+
+ switch ( model ) {
+ case RW_BITLINE:
+ if ( end == 2 )
+ bitline->e_col_sel = SIM_array_column_select_cap() * EnergyFactor;
+ else /* end == 1 implies register file */
+ bitline->e_col_sel = 0;
+// printf("BUFFER INTERNAL bitline sel energy = %g\n", bitline->e_col_sel);
+
+ if ( bitline->share_rw = share_rw ) {
+ /* shared bitlines are double-ended, so SenseEnergyFactor */
+ bitline->e_col_read = SIM_array_share_column_read_cap( rows, wire_cap, n_share_amp, n_bitline_pre, n_colsel_pre, pre_size ) * SenseEnergyFactor;
+ bitline->e_col_write = SIM_array_share_column_write_cap( rows, wire_cap, n_share_amp, n_bitline_pre, pre_size ) * EnergyFactor;
+ }
+ else {
+ bitline->e_col_read = SIM_array_column_read_cap(rows, wire_cap, end, n_share_amp, n_bitline_pre, n_colsel_pre, pre_size, outdrv_model) * (end == 2 ? SenseEnergyFactor : EnergyFactor);
+// printf("BUFFER INTERNAL bitline read energy = %g\n", bitline->e_col_read);
+ bitline->e_col_write = SIM_array_column_write_cap( rows, wire_cap ) * EnergyFactor;
+// printf("BUFFER INTERNAL bitline write energy = %g\n", bitline->e_col_write);
+
+ /* static power */
+ bitline->i_leakage = 2 * (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) / PARM_TECH_POINT * 100;
+// printf("BUFFER INTERNAL bitline leakage current = %g\n", bitline->i_leakage);
+ }
+
+ break;
+
+ case WO_BITLINE: /* only have write bitlines */
+ bitline->share_rw = 0;
+ bitline->e_col_sel = bitline->e_col_read = 0;
+ bitline->e_col_write = SIM_array_column_write_cap( rows, wire_cap ) * EnergyFactor;
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+static int is_rw_bitline( int model )
+{
+ return ( model == RW_BITLINE );
+}
+
+
+/* WHS: no way to count activity factor on column selector gates */
+int SIM_array_bitline_record(power_bitline *bitline, int rw, unsigned cols, unsigned long int old_value, unsigned long int new_value )
+{
+ /* FIXME: should use variable rather than computing each time */
+ unsigned long int mask = HAMM_MASK(cols);
+
+ if ( rw ) { /* write */
+ if ( bitline->share_rw ) /* share R/W bitlines */
+ bitline->n_col_write += cols;
+ else /* separate R/W bitlines */
+ bitline->n_col_write += SIM_power_Hamming( old_value, new_value, mask );
+ }
+ else { /* read */
+ if ( bitline->end == 2 ) /* double-ended bitline */
+ bitline->n_col_read += cols;
+ else /* single-ended bitline */
+ /* WHS: read ~new_value due to the bitline inverter */
+ bitline->n_col_read += SIM_power_Hamming( mask, ~new_value, mask );
+ }
+
+ return 0;
+}
+
+
+double SIM_array_bitline_report(power_bitline *bitline )
+{
+ return ( bitline->n_col_write * bitline->e_col_write +
+ bitline->n_col_read * bitline->e_col_read +
+ bitline->n_col_sel * bitline->e_col_sel );
+}
+
+// ------- Bitlines end
+
+
+
+// ------- Sense amplifier begin
+
+/* estimate senseamp power dissipation in cache structures (Zyuban's method) */
+static double SIM_array_amp_energy( void )
+{
+ return ( (double)Vdd / 8.0 * (double )(Period) * (double )(PARM_amp_Idsat));
+}
+
+
+static int SIM_array_amp_clear_stat(power_amp *amp)
+{
+ amp->n_access = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_amp_init(power_amp *amp, int model )
+{
+ if ((amp->model = model) && model < AMP_MAX_MODEL) {
+ SIM_array_amp_clear_stat(amp);
+ amp->e_access = SIM_array_amp_energy();
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int SIM_array_amp_record(power_amp *amp, unsigned cols )
+{
+ amp->n_access += cols;
+
+ return 0;
+}
+
+
+double SIM_array_amp_report(power_amp *amp )
+{
+ return ( amp->n_access * amp->e_access );
+}
+
+// ------- Sense amplifier end
+
+
+// ------- Tag comparator begin
+
+/* eval switches twice per cycle, so no 1/2 */
+/* WHS: assume eval = 1 when no cache operation */
+static double SIM_array_comp_base_cap( void )
+{
+ /* eval tx's: 4 inverters */
+ return ( SIM_power_draincap( Wevalinvp, PCH, 1 ) + SIM_power_draincap( Wevalinvn, NCH, 1 ) +
+ SIM_power_gatecap( Wevalinvp, 1 ) + SIM_power_gatecap( Wevalinvn, 1 ) +
+ SIM_power_draincap( Wcompinvp1, PCH, 1 ) + SIM_power_draincap( Wcompinvn1, NCH, 1 ) +
+ SIM_power_gatecap( Wcompinvp1, 1 ) + SIM_power_gatecap( Wcompinvn1, 1 ) +
+ SIM_power_draincap( Wcompinvp2, PCH, 1 ) + SIM_power_draincap( Wcompinvn2, NCH, 1 ) +
+ SIM_power_gatecap( Wcompinvp2, 1 ) + SIM_power_gatecap( Wcompinvn2, 1 ) +
+ SIM_power_draincap( Wcompinvp3, PCH, 1 ) + SIM_power_draincap( Wcompinvn3, NCH, 1 ) +
+ SIM_power_gatecap( Wcompinvp3, 1 ) + SIM_power_gatecap( Wcompinvn3, 1 ));
+}
+
+
+/* no 1/2 for the same reason with SIM_array_comp_base_cap */
+static double SIM_array_comp_match_cap( unsigned n_bits )
+{
+ return ( n_bits * ( SIM_power_draincap( Wcompn, NCH, 1 ) + SIM_power_draincap( Wcompn, NCH, 2 )));
+}
+
+
+/* upon mismatch, select signal 1->0, then 0->1 on next precharging, so no 1/2 */
+static double SIM_array_comp_mismatch_cap( unsigned n_pre )
+{
+ double Ctotal;
+
+ /* part 1: drain cap of precharge tx */
+ Ctotal = n_pre * SIM_power_draincap( Wcomppreequ, PCH, 1 );
+
+ /* part 2: nor gate of valid output */
+ Ctotal += SIM_power_gatecap( WdecNORn, 1 ) + SIM_power_gatecap( WdecNORp, 3 );
+
+ return Ctotal;
+}
+
+
+/* upon miss, valid output switches twice in one cycle, so no 1/2 */
+static double SIM_array_comp_miss_cap( unsigned assoc )
+{
+ /* drain cap of valid output */
+ return ( assoc * SIM_power_draincap( WdecNORn, NCH, 1 ) + SIM_power_draincap( WdecNORp, PCH, assoc ));
+}
+
+
+/* no 1/2 for the same reason as base_cap */
+static double SIM_array_comp_bit_match_cap( void )
+{
+ return ( 2 * ( SIM_power_draincap( Wcompn, NCH, 1 ) + SIM_power_draincap( Wcompn, NCH, 2 )));
+}
+
+
+/* no 1/2 for the same reason as base_cap */
+static double SIM_array_comp_bit_mismatch_cap( void )
+{
+ return ( 3 * SIM_power_draincap( Wcompn, NCH, 1 ) + SIM_power_draincap( Wcompn, NCH, 2 ));
+}
+
+
+/* each addr bit drives 2 nmos pass transistors, so no 1/2 */
+static double SIM_array_comp_chgaddr_cap( void )
+{
+ return ( SIM_power_gatecap( Wcompn, 1 ));
+}
+
+
+static int SIM_array_comp_clear_stat(power_comp *comp)
+{
+ comp->n_access = comp->n_miss = comp->n_chg_addr = comp->n_match = 0;
+ comp->n_mismatch = comp->n_bit_match = comp->n_bit_mismatch = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_comp_init(power_comp *comp, int model, unsigned n_bits, unsigned assoc, unsigned n_pre, double matchline_len, double tagline_len )
+{
+ if ((comp->model = model) && model < COMP_MAX_MODEL) {
+ comp->n_bits = n_bits;
+ comp->assoc = assoc;
+ /* redundant field */
+ comp->comp_mask = HAMM_MASK(n_bits);
+
+ SIM_array_comp_clear_stat(comp);
+
+ switch ( model ) {
+ case CACHE_COMPONENT:
+ comp->e_access = SIM_array_comp_base_cap() * EnergyFactor;
+ comp->e_match = SIM_array_comp_match_cap( n_bits ) * EnergyFactor;
+ comp->e_mismatch = SIM_array_comp_mismatch_cap( n_pre ) * EnergyFactor;
+ comp->e_miss = SIM_array_comp_miss_cap( assoc ) * EnergyFactor;
+ comp->e_bit_match = SIM_array_comp_bit_match_cap() * EnergyFactor;
+ comp->e_bit_mismatch = SIM_array_comp_bit_mismatch_cap() * EnergyFactor;
+ comp->e_chg_addr = SIM_array_comp_chgaddr_cap() * EnergyFactor;
+ break;
+
+ case CAM_COMP:
+ comp->e_access = comp->e_match = comp->e_chg_addr = 0;
+ comp->e_bit_match = comp->e_bit_mismatch = 0;
+ /* energy consumption of tagline */
+ comp->e_chg_addr = SIM_cam_comp_tagline_cap( assoc, tagline_len ) * EnergyFactor;
+ comp->e_mismatch = SIM_cam_comp_mismatch_cap( n_bits, n_pre, matchline_len ) * EnergyFactor;
+ comp->e_miss = SIM_cam_comp_miss_cap( assoc ) * EnergyFactor;
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int SIM_array_comp_global_record(power_comp *comp, unsigned long int prev_value, unsigned long int curr_value, int miss )
+{
+ if ( miss ) comp->n_miss ++;
+
+ switch ( comp->model ) {
+ case CACHE_COMPONENT:
+ comp->n_access ++;
+ comp->n_chg_addr += SIM_power_Hamming( prev_value, curr_value, comp->comp_mask ) * comp->assoc;
+ break;
+
+ case CAM_COMP:
+ comp->n_chg_addr += SIM_power_Hamming( prev_value, curr_value, comp->comp_mask );
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+}
+
+
+/* recover means prev_tag will recover on next cycle, e.g. driven by sense amplifier */
+/* return value: 1 if miss, 0 if hit */
+int SIM_array_comp_local_record(power_comp *comp, unsigned long int prev_tag, unsigned long int curr_tag, unsigned long int input, int recover )
+{
+ unsigned H_dist;
+ int mismatch;
+
+ if ( mismatch = ( curr_tag != input )) comp->n_mismatch ++;
+
+ /* for cam, input changes are reflected in memory cells */
+ if ( comp->model == CACHE_COMPONENT ) {
+ if ( recover )
+ comp->n_chg_addr += 2 * SIM_power_Hamming( prev_tag, curr_tag, comp->comp_mask );
+ else
+ comp->n_chg_addr += SIM_power_Hamming( prev_tag, curr_tag, comp->comp_mask );
+
+ if ( mismatch ) {
+ H_dist = SIM_power_Hamming( curr_tag, input, comp->comp_mask );
+ comp->n_bit_mismatch += H_dist;
+ comp->n_bit_match += comp->n_bits - H_dist;
+ }
+ else comp->n_match ++;
+ }
+
+ return mismatch;
+}
+
+
+double SIM_array_comp_report(power_comp *comp )
+{
+ return ( comp->n_access * comp->e_access + comp->n_match * comp->e_match +
+ comp->n_mismatch * comp->e_mismatch + comp->n_miss * comp->e_miss +
+ comp->n_bit_match * comp->e_bit_match + comp->n_chg_addr * comp->e_chg_addr +
+ comp->n_bit_mismatch * comp->e_bit_mismatch );
+}
+
+// ------- Tag comparator end
+
+
+
+// ------- Multiplexor begin
+
+/* upon mismatch, 1 output of nor gates 1->0, then 0->1 on next cycle, so no 1/2 */
+static double SIM_array_mux_mismatch_cap( unsigned n_nor_gates )
+{
+ double Cmul;
+
+ /* stage 1: inverter */
+ Cmul = SIM_power_draincap( Wmuxdrv12n, NCH, 1 ) + SIM_power_draincap( Wmuxdrv12p, PCH, 1 ) +
+ SIM_power_gatecap( Wmuxdrv12n, 1 ) + SIM_power_gatecap( Wmuxdrv12p, 1 );
+
+ /* stage 2: nor gates */
+ /* gate cap of nor gates */
+ Cmul += n_nor_gates * ( SIM_power_gatecap( WmuxdrvNORn, 1 ) + SIM_power_gatecap( WmuxdrvNORp, 1 ));
+ /* drain cap of nor gates, only count 1 */
+ Cmul += SIM_power_draincap( WmuxdrvNORp, PCH, 2 ) + 2 * SIM_power_draincap( WmuxdrvNORn, NCH, 1 );
+
+ /* stage 3: output inverter */
+ Cmul += SIM_power_gatecap( Wmuxdrv3n, 1 ) + SIM_power_gatecap( Wmuxdrv3p, 1 ) +
+ SIM_power_draincap( Wmuxdrv3n, NCH, 1 ) + SIM_power_draincap( Wmuxdrv3p, PCH, 1 );
+
+ return Cmul;
+}
+
+
+/* 2 nor gates switch gate signals, so no 1/2 */
+/* WHS: assume address changes won't propagate until matched or mismatched */
+static double SIM_array_mux_chgaddr_cap( void )
+{
+ return ( SIM_power_gatecap( WmuxdrvNORn, 1 ) + SIM_power_gatecap( WmuxdrvNORp, 1 ));
+}
+
+
+static int SIM_array_mux_clear_stat(power_mux *mux)
+{
+ mux->n_mismatch = mux->n_chg_addr = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_mux_init(power_mux *mux, int model, unsigned n_gates, unsigned assoc )
+{
+ if ((mux->model = model) && model < MUX_MAX_MODEL) {
+ mux->assoc = assoc;
+
+ SIM_array_mux_clear_stat(mux);
+
+ mux->e_mismatch = SIM_array_mux_mismatch_cap( n_gates ) * EnergyFactor;
+ mux->e_chg_addr = SIM_array_mux_chgaddr_cap() * EnergyFactor;
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int SIM_array_mux_record(power_mux *mux, unsigned long int prev_addr, unsigned long int curr_addr, int miss )
+{
+ if ( prev_addr != curr_addr )
+ mux->n_chg_addr += mux->assoc;
+
+ if ( miss )
+ mux->n_mismatch += mux->assoc;
+ else
+ mux->n_mismatch += mux->assoc - 1;
+
+ return 0;
+}
+
+
+double SIM_array_mux_report(power_mux *mux )
+{
+ return ( mux->n_mismatch * mux->e_mismatch + mux->n_chg_addr * mux->e_chg_addr );
+}
+
+// ------- Multiplexor end
+
+
+// ------- Output driver begin
+
+/* output driver should be disabled somehow when no access occurs, so no 1/2 */
+static double SIM_array_outdrv_select_cap( unsigned data_width )
+{
+ double Ctotal;
+
+ /* stage 1: inverter */
+ Ctotal = SIM_power_gatecap( Woutdrvseln, 1 ) + SIM_power_gatecap( Woutdrvselp, 1 ) +
+ SIM_power_draincap( Woutdrvseln, NCH, 1 ) + SIM_power_draincap( Woutdrvselp, PCH, 1 );
+
+ /* stage 2: gate cap of nand gate and nor gate */
+ /* only consider 1 gate cap because another and drain cap switch depends on data value */
+ Ctotal += data_width *( SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) +
+ SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 ));
+
+ return Ctotal;
+}
+
+
+/* WHS: assume data changes won't propagate until enabled */
+static double SIM_array_outdrv_chgdata_cap( void )
+{
+ return (( SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) +
+ SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 )) / 2 );
+}
+
+
+/* no 1/2 for the same reason as outdrv_select_cap */
+static double SIM_array_outdrv_outdata_cap( unsigned value )
+{
+ double Ctotal;
+
+ /* stage 1: drain cap of nand gate or nor gate */
+ if ( value )
+ /* drain cap of nand gate */
+ Ctotal = SIM_power_draincap( Woutdrvnandn, NCH, 2 ) + 2 * SIM_power_draincap( Woutdrvnandp, PCH, 1 );
+ else
+ /* drain cap of nor gate */
+ Ctotal = 2 * SIM_power_draincap( Woutdrvnorn, NCH, 1 ) + SIM_power_draincap( Woutdrvnorp, PCH, 2 );
+
+ /* stage 2: gate cap of output inverter */
+ if ( value )
+ Ctotal += SIM_power_gatecap( Woutdriverp, 1 );
+ else
+ Ctotal += SIM_power_gatecap( Woutdrivern, 1 );
+
+ /* drain cap of output inverter should be included into bus cap */
+ return Ctotal;
+}
+
+
+static int SIM_array_outdrv_clear_stat(power_out *outdrv)
+{
+ outdrv->n_select = outdrv->n_chg_data = 0;
+ outdrv->n_out_0 = outdrv->n_out_1 = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_outdrv_init(power_out *outdrv, int model, unsigned item_width )
+{
+ if ((outdrv->model = model) && model < OUTDRV_MAX_MODEL) {
+ outdrv->item_width = item_width;
+ /* redundant field */
+ outdrv->out_mask = HAMM_MASK(item_width);
+
+ SIM_array_outdrv_clear_stat(outdrv);
+
+ outdrv->e_select = SIM_array_outdrv_select_cap( item_width ) * EnergyFactor;
+ outdrv->e_out_1 = SIM_array_outdrv_outdata_cap( 1 ) * EnergyFactor;
+ outdrv->e_out_0 = SIM_array_outdrv_outdata_cap( 0 ) * EnergyFactor;
+
+ switch ( model ) {
+ case CACHE_OUTDRV:
+ outdrv->e_chg_data = SIM_array_outdrv_chgdata_cap() * EnergyFactor;
+ break;
+
+ case CAM_OUTDRV:
+ /* input changes are reflected in memory cells */
+ case REG_OUTDRV:
+ /* input changes are reflected in bitlines */
+ outdrv->e_chg_data = 0;
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int SIM_array_outdrv_global_record(power_out *outdrv, unsigned long int data )
+{
+ unsigned n_1;
+
+ outdrv->n_select ++;
+
+ n_1 = SIM_power_Hamming( data, 0, outdrv->out_mask );
+
+ outdrv->n_out_1 += n_1;
+ outdrv->n_out_0 += outdrv->item_width - n_1;
+
+ return 0;
+}
+
+
+/* recover means prev_data will recover on next cycle, e.g. driven by sense amplifier */
+/* NOTE: this function SHOULD not be called by a fully-associative cache */
+int SIM_array_outdrv_local_record(power_out *outdrv, unsigned long int prev_data, unsigned long int curr_data, int recover )
+{
+ if ( recover )
+ outdrv->n_chg_data += 2 * SIM_power_Hamming( prev_data, curr_data, outdrv->out_mask );
+ else
+ outdrv->n_chg_data += SIM_power_Hamming( prev_data, curr_data, outdrv->out_mask );
+
+ return 0;
+}
+
+
+double SIM_array_outdrv_report(power_out *outdrv )
+{
+ return ( outdrv->n_select * outdrv->e_select + outdrv->n_chg_data * outdrv->e_chg_data +
+ outdrv->n_out_1 * outdrv->e_out_1 + outdrv->n_out_0 * outdrv->e_out_0 );
+}
+
+// ------- Output driver end
+
+
+
+// ------- Memcory cell begin
+
+/* WHS: use Wmemcella and Wmemcellbscale to compute tx width of memory cell */
+static double SIM_array_mem_cap( unsigned read_ports, unsigned write_ports, int share_rw, unsigned end )
+{
+ double Ctotal;
+
+ /* part 1: drain capacitance of pass transistors */
+ Ctotal = SIM_power_draincap( Wmemcellr, NCH, 1 ) * read_ports * end / 2;
+ if ( ! share_rw )
+ Ctotal += SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports;
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 2: drain capacitance of memory cell */
+ Ctotal += SIM_power_draincap( Wmemcella, NCH, 1 ) + SIM_power_draincap( Wmemcella * Wmemcellbscale, PCH, 1 );
+
+ /* has coefficient ( 1/2 * 2 ) */
+ /* part 3: gate capacitance of memory cell */
+ Ctotal += SIM_power_gatecap( Wmemcella, 1 ) + SIM_power_gatecap( Wmemcella * Wmemcellbscale, 1 );
+
+ return Ctotal;
+}
+
+
+static int SIM_array_mem_clear_stat(power_mem *mem)
+{
+ mem->n_switch = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_mem_init(power_mem *mem, int model, unsigned read_ports, unsigned write_ports, int share_rw, unsigned end )
+{
+ double i_leakage;
+
+ if ((mem->model = model) && model < MEM_MAX_MODEL) {
+ mem->end = end;
+ SIM_array_mem_clear_stat(mem);
+
+ switch ( model ) {
+ case CAM_TAG_RW_MEM:
+ mem->e_switch = SIM_cam_tag_mem_cap( read_ports, write_ports, share_rw, end, SIM_ARRAY_RW ) * EnergyFactor;
+ break;
+
+ /* FIXME: it's only an approximation using CAM_TAG_WO_MEM to emulate CAM_ATTACH_MEM */
+ case CAM_ATTACH_MEM:
+ case CAM_TAG_WO_MEM:
+ mem->e_switch = SIM_cam_tag_mem_cap( read_ports, write_ports, share_rw, end, SIM_ARRAY_WO ) * EnergyFactor;
+ break;
+
+ case CAM_DATA_MEM:
+ mem->e_switch = SIM_cam_data_mem_cap( read_ports, write_ports ) * EnergyFactor;
+ break;
+
+ default: /* NORMAL_MEM */
+ mem->e_switch = SIM_array_mem_cap( read_ports, write_ports, share_rw, end ) * EnergyFactor;
+
+ /* static power */
+ i_leakage = 0;
+ /* memory cell */
+ i_leakage += (Wmemcella * NMOS_TAB[0] + Wmemcella * Wmemcellbscale * PMOS_TAB[0]) * 2;
+ /* read port pass tx */
+ i_leakage += Wmemcellr * NMOS_TAB[0] * end * read_ports;
+ /* write port pass tx */
+ if (! share_rw)
+ i_leakage += Wmemcellw * NMOS_TAB[0] * 2 * write_ports;
+
+ mem->i_leakage = i_leakage / PARM_TECH_POINT * 100;
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int SIM_array_mem_record(power_mem *mem, unsigned long int prev_value, unsigned long int curr_value, unsigned width )
+{
+ mem->n_switch += SIM_power_Hamming( prev_value, curr_value, HAMM_MASK(width));
+
+ return 0;
+}
+
+
+double SIM_array_mem_report(power_mem *mem )
+{
+ return ( mem->n_switch * mem->e_switch );
+}
+
+// ------- Memcory cell end
+
+
+
+// ------- Precharge begin
+
+/* consider charge then discharge, so no 1/2 */
+static double SIM_array_pre_cap( double width, double length )
+{
+ return SIM_power_gatecap( width, length );
+}
+
+
+/* return # of precharging gates per column */
+static unsigned n_pre_gate( int model )
+{
+ switch ( model ) {
+ case SINGLE_BITLINE: return 2;
+ case EQU_BITLINE: return 3;
+ case SINGLE_OTHER: return 1;
+ default: break;/* some error handler */
+ }
+
+ return 0;
+}
+
+
+/* return # of precharging drains per line */
+static unsigned n_pre_drain( int model )
+{
+ switch ( model ) {
+ case SINGLE_BITLINE: return 1;
+ case EQU_BITLINE: return 2;
+ case SINGLE_OTHER: return 1;
+ default: break;/* some error handler */
+ }
+
+ return 0;
+}
+
+
+static int SIM_array_pre_clear_stat(power_arr_pre *pre)
+{
+ pre->n_charge = 0;
+
+ return 0;
+}
+
+
+static int SIM_array_pre_init(power_arr_pre *pre, int model, double pre_size )
+{
+ unsigned n_gate;
+
+ n_gate = n_pre_gate(model);
+
+ if ((pre->model = model) && model < PRE_MAX_MODEL) {
+ SIM_array_pre_clear_stat(pre);
+
+ /* WHS: 10 should go to PARM */
+ pre->e_charge = SIM_array_pre_cap( pre_size, 10 ) * n_gate * EnergyFactor;
+
+ /* static power */
+ pre->i_leakage = n_gate * pre_size * PMOS_TAB[0] / PARM_TECH_POINT * 100;
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int SIM_array_pre_record(power_arr_pre *pre, unsigned long int n_charge )
+{
+ pre->n_charge += n_charge;
+
+ return 0;
+}
+
+
+double SIM_array_pre_report(power_arr_pre *pre )
+{
+ return ( pre->n_charge * pre->e_charge );
+}
+
+// ------- Precharge end
+
+/* ---------- buffer model end ------------ */
+
+
+
+
+
+
+
+
+/***** from SIM_array_internal_m.c *********/
+
+
+/* for now we simply initialize all fields to 0, which should not
+ * add too much error if the program runtime is long enough :) */
+int SIM_array_port_state_init(power_array_info *info, SIM_array_port_state_t *port )
+{
+ //if ( IS_FULLY_ASSOC( info ) || !(info->share_rw))
+ //bzero( port->data_line, port->data_line_size );
+
+ port->tag_line = 0;
+ port->row_addr = 0;
+ port->col_addr = 0;
+ port->tag_addr = 0;
+
+ return 0;
+}
+
+
+int SIM_array_set_state_init( power_array_info *info, SIM_array_set_state_t *set )
+{
+ set->entry = NULL;
+ set->entry_set = NULL;
+
+ if ( IS_FULLY_ASSOC( info )) {
+ set->write_flag = 0;
+ set->write_back_flag = 0;
+ }
+
+ /* no default value for other fields */
+ return 0;
+}
+
+
+/* record row decoder and wordline activity */
+/* only used by non-fully-associative array, but we check it anyway */
+int SIM_power_array_dec( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int row_addr, int rw )
+{
+ if ( ! IS_FULLY_ASSOC( info )) {
+ /* record row decoder stats */
+ if (info->row_dec_model) {
+ SIM_array_dec_record( &arr->row_dec, port->row_addr, row_addr );
+
+ /* update state */
+ port->row_addr = row_addr;
+ }
+
+ /* record wordline stats */
+ SIM_array_wordline_record( &arr->data_wordline, rw, info->data_ndwl );
+ if ( HAVE_TAG( info ))
+ SIM_array_wordline_record( &arr->tag_wordline, rw, info->tag_ndwl );
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+/* record read data activity (including bitline and sense amplifier) */
+/* only used by non-fully-associative array, but we check it anyway */
+/* data only used by RF array */
+int SIM_power_array_data_read( power_array_info *info, power_array *arr, unsigned long int data )
+{
+ if (info->data_end == 1) {
+ SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_READ, info->eff_data_cols, 0, data );
+
+ return 0;
+ }
+ else if ( ! IS_FULLY_ASSOC( info )) {
+ SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_READ, info->eff_data_cols, 0, 0 );
+ SIM_array_amp_record( &arr->data_amp, info->eff_data_cols );
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+/* record write data bitline and memory cell activity */
+/* assume no alignment restriction on write, so (char *) */
+/* set only used by fully-associative array */
+/* data_line only used by fully-associative or RF array */
+int SIM_power_array_data_write( power_array_info *info, power_array *arr, SIM_array_set_state_t *set, unsigned n_item, char *data_line, char *old_data, char *new_data )
+{
+ unsigned i;
+
+ /* record bitline stats */
+ if ( IS_FULLY_ASSOC( info )) {
+ /* wordline should be driven only once */
+ if ( ! set->write_flag ) {
+ SIM_array_wordline_record( &arr->data_wordline, SIM_ARRAY_WRITE, 1 );
+ set->write_flag = 1;
+ }
+
+ /* for fully-associative array, data bank has no read
+ * bitlines, so bitlines not written have no activity */
+ for ( i = 0; i < n_item; i ++ ) {
+ SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, 8, data_line[i], new_data[i] );
+ /* update state */
+ data_line[i] = new_data[i];
+ }
+ }
+ else if (info->share_rw) {
+ /* there is some subtlety here: write width may not be as wide as block size,
+ * bitlines not written are actually read, but column selector should be off,
+ * so read energy per bitline is the same as write energy per bitline */
+ SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, info->eff_data_cols, 0, 0 );
+
+ /* write in all sub-arrays if direct-mapped, which implies 1 cycle write latency,
+ * in those sub-arrays wordlines are not driven, so only n items columns switch */
+ if ( IS_DIRECT_MAP( info ) && info->data_ndbl > 1 )
+ SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, n_item * 8 * ( info->data_ndbl - 1 ), 0, 0 );
+ }
+ else { /* separate R/W bitlines */
+ /* same arguments as in the previous case apply here, except that when we say
+ * read_energy = write_energy, we omit the energy of write driver gate cap */
+ for ( i = 0; i < n_item; i ++ ) {
+ SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, 8, data_line[i], new_data[i] );
+ /* update state */
+ data_line[i] = new_data[i];
+ }
+ }
+
+ /* record memory cell stats */
+ for ( i = 0; i < n_item; i ++ )
+ SIM_array_mem_record( &arr->data_mem, old_data[i], new_data[i], 8 );
+
+ return 0;
+}
+
+
+/* record read tag activity (including bitline and sense amplifier) */
+/* only used by non-RF array */
+/* set only used by fully-associative array */
+int SIM_power_array_tag_read( power_array_info *info, power_array *arr, SIM_array_set_state_t *set )
+{
+ if ( IS_FULLY_ASSOC( info )) {
+ /* the only reason to read a fully-associative array tag is writing back */
+ SIM_array_wordline_record( &arr->tag_wordline, SIM_ARRAY_READ, 1 );
+ set->write_back_flag = 1;
+ }
+
+ SIM_array_bitline_record( &arr->tag_bitline, SIM_ARRAY_READ, info->eff_tag_cols, 0, 0 );
+ SIM_array_amp_record( &arr->tag_amp, info->eff_tag_cols );
+
+ return 0;
+}
+
+
+/* record write tag bitline and memory cell activity */
+/* WHS: assume update of use bit, valid bit, dirty bit and tag will be coalesced */
+/* only used by non-RF array */
+/* port only used by fully-associative array */
+//int SIM_power_array_tag_update( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, SIM_array_set_state_t *set )
+//{
+ //unsigned i;
+ //unsigned long int curr_tag;
+ //power_mem *tag_attach_mem;
+
+ /* get current tag */
+ //if ( set->entry )
+ //curr_tag = (*info->get_entry_tag)( set->entry );
+
+ // if ( IS_FULLY_ASSOC( info ))
+ // tag_attach_mem = &arr->tag_attach_mem;
+ //else
+ //tag_attach_mem = &arr->tag_mem;
+
+ /* record tag bitline stats */
+ //if ( IS_FULLY_ASSOC( info )) {
+ // if ( set->entry && curr_tag != set->tag_bak ) {
+ // /* shared wordline should be driven only once */
+ // if ( ! set->write_back_flag )
+ // SIM_array_wordline_record( &arr->tag_wordline, SIM_ARRAY_WRITE, 1 );
+
+ /* WHS: value of tag_line doesn't matter if not write_through */
+ //SIM_array_bitline_record( &arr->tag_bitline, SIM_ARRAY_WRITE, info->eff_tag_cols, port->tag_line, curr_tag );
+ /* update state */
+ //if ( IS_WRITE_THROUGH( info ))
+ // port->tag_line = curr_tag;
+ //}
+ //}
+ //else {
+ /* tag update cannot occur at the 1st cycle, so no other sub-arrays */
+ // SIM_array_bitline_record( &arr->tag_bitline, SIM_ARRAY_WRITE, info->eff_tag_cols, 0, 0 );
+ //}
+
+ /* record tag memory cell stats */
+ //if ( HAVE_USE_BIT( info ))
+ // for ( i = 0; i < info->assoc; i ++ )
+ // SIM_array_mem_record( tag_attach_mem, set->use_bak[i], (*info->get_set_use_bit)( set->entry_set, i ), info->use_bit_width );
+
+ //if ( set->entry ) {
+ // SIM_array_mem_record( tag_attach_mem, set->valid_bak, (*info->get_entry_valid_bit)( set->entry ), info->valid_bit_width );
+ //SIM_array_mem_record( &arr->tag_mem, set->tag_bak, curr_tag, info->tag_addr_width );
+
+ //if ( IS_WRITE_BACK( info ))
+ // SIM_array_mem_record( tag_attach_mem, set->dirty_bak, (*info->get_entry_dirty_bit)( set->entry ), 1 );
+ //}
+
+ //return 0;
+//}
+
+
+/* record tag compare activity (including tag comparator, column decoder and multiplexor) */
+/* NOTE: this function may be called twice during ONE array operation, remember to update
+ * states at the end so that call to *_record won't add erroneous extra energy */
+/* only used by non-RF array */
+//int SIM_power_array_tag_compare( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int tag_input, unsigned long int col_addr, SIM_array_set_state_t *set )
+//{
+ //int miss = 0;
+ //unsigned i;
+
+ /* record tag comparator stats */
+ //for ( i = 0; i < info->assoc; i ++ ) {
+ /* WHS: sense amplifiers output 0 when idle */
+ //if ( SIM_array_comp_local_record( &arr->comp, 0, (*info->get_set_tag)( set->entry_set, i ), tag_input, SIM_ARRAY_RECOVER ))
+ // miss = 1;
+ //}
+
+ //SIM_array_comp_global_record( &arr->comp, port->tag_addr, tag_input, miss );
+
+ /* record column decoder stats */
+ //if ( HAVE_COL_DEC( info ))
+ //SIM_array_dec_record( &arr->col_dec, port->col_addr, col_addr );
+
+ /* record multiplexor stats */
+ //if ( HAVE_COL_MUX( info ))
+ //SIM_array_mux_record( &arr->mux, port->col_addr, col_addr, miss );
+
+ /* update state */
+ //port->tag_addr = tag_input;
+ //if ( HAVE_COL_DEC( info ))
+ //port->col_addr = col_addr;
+
+ //return 0;
+//}
+
+
+/* record output driver activity */
+/* assume alignment restriction on read, so specify data_size */
+/* WHS: it's really a mess to use data_size to specify data type */
+/* data_all only used by non-RF and non-fully-associative array */
+/* WHS: don't support 128-bit or wider integer */
+//int SIM_power_array_output( power_array_info *info, power_array *arr, unsigned data_size, unsigned length, void *data_out, void *data_all )
+//{
+ // unsigned i, j;
+
+ /* record output driver stats */
+ //for ( i = 0; i < length; i ++ ) {
+ // switch ( data_size ) {
+ // case 1: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned8_t *)data_out)[i] );
+ // break;
+ //case 2: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned16_t *)data_out)[i] );
+ // break;
+ //case 4: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned32_t *)data_out)[i] );
+ // break;
+ //case 8: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned64_t *)data_out)[i] );
+ // break;
+ //default: /* some error handler */
+ //}
+ //}
+
+ //if ( ! IS_FULLY_ASSOC( info )) {
+ //for ( i = 0; i < info->assoc; i ++ )
+ //for ( j = 0; j < info->n_item; j ++ )
+ /* sense amplifiers output 0 when idle */
+ //switch ( data_size ) {
+ //case 1: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned8_t **)data_all)[i][j], SIM_ARRAY_RECOVER );
+ //break;
+ //case 2: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned16_t **)data_all)[i][j], SIM_ARRAY_RECOVER );
+ //break;
+ //case 4: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned32_t **)data_all)[i][j], SIM_ARRAY_RECOVER );
+ //break;
+ //case 8: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned64_t **)data_all)[i][j], SIM_ARRAY_RECOVER );
+ //break;
+ //default: /* some error handler */
+ //}
+ //}
+
+ //return 0;
+//}
+
+
+/********* end from SIM_array_internal_m.c **********/
+
+
+// ------- Array init
+
+
+int power_array_init(power_array_info *info, power_array *arr )
+{
+ unsigned rows, cols, ports, dec_width, n_bitline_pre, n_colsel_pre;
+ double wordline_len, bitline_len, tagline_len, matchline_len;
+ double wordline_cmetal, bitline_cmetal;
+ double Cline, pre_size, comp_pre_size;
+
+ arr->i_leakage = 0;
+
+ /* sanity check */
+ if ( info->read_ports == 0 ) info->share_rw = 0;
+ if ( info->share_rw ) { //AMIT are read and write ports shared?
+ info->data_end = 2;
+ info->tag_end = 2;
+ }
+
+ if ( info->share_rw ) ports = info->read_ports;
+ else ports = info->read_ports + info->write_ports;
+
+ /* data array unit length wire cap */
+ if (ports > 1) {
+ /* 3x minimal spacing */
+ wordline_cmetal = CC3M3metal;
+ bitline_cmetal = CC3M2metal;
+ }
+ else if (info->data_end == 2) {
+ /* wordline infinite spacing, bitline 3x minimal spacing */
+ wordline_cmetal = CM3metal;
+ bitline_cmetal = CC3M2metal;
+ }
+ else {
+ /* both infinite spacing */
+ wordline_cmetal = CM3metal;
+ bitline_cmetal = CM2metal;
+ }
+
+ info->data_arr_width = 0;
+ info->tag_arr_width = 0;
+ info->data_arr_height = 0;
+ info->tag_arr_height = 0;
+
+ /* BEGIN: data array power initialization */
+ if (dec_width = SIM_power_logtwo(info->n_set)) { //AMIT: not fully associative, n->sets!=1
+ /* row decoder power initialization */
+ SIM_array_dec_init( &arr->row_dec, info->row_dec_model, dec_width );
+
+ /* row decoder precharging power initialization */
+ //if ( is_dynamic_dec( info->row_dec_model ))
+ /* FIXME: need real pre_size */
+ //SIM_array_pre_init( &arr->row_dec_pre, info->row_dec_pre_model, 0 );
+
+ rows = info->n_set / info->data_ndbl / info->data_nspd; //AMIT: n_set is the number of sets(fully associative n_sets=1)
+ cols = info->blk_bits * info->assoc * info->data_nspd / info->data_ndwl; //AMIT: blk_bits is the line size
+
+ bitline_len = rows * ( RegCellHeight + ports * WordlineSpacing );
+ if ( info->data_end == 2 )
+ wordline_len = cols * ( RegCellWidth + 2 * ports * BitlineSpacing );
+ else /* info->data_end == 1 */
+ wordline_len = cols * ( RegCellWidth + ( 2 * ports - info->read_ports ) * BitlineSpacing );
+ info->data_arr_width = wordline_len;
+ info->data_arr_height = bitline_len;
+
+ /* compute precharging size */
+ /* FIXME: should consider n_pre and pre_size simultaneously */
+ Cline = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ) + bitline_cmetal * bitline_len;
+ pre_size = SIM_power_driver_size( Cline, Period / 8 );
+ /* WHS: ?? compensate for not having an nmos pre-charging */
+ pre_size += pre_size * Wdecinvn / Wdecinvp;
+
+ /* bitline power initialization */
+ n_bitline_pre = n_pre_drain( info->data_bitline_pre_model );
+ n_colsel_pre = ( info->data_n_share_amp > 1 ) ? n_pre_drain( info->data_colsel_pre_model ) : 0;
+ SIM_array_bitline_init(&arr->data_bitline, info->data_bitline_model, info->share_rw, info->data_end, rows, bitline_len * bitline_cmetal, info->data_n_share_amp, n_bitline_pre, n_colsel_pre, pre_size, info->outdrv_model);
+ /* static power */
+ arr->i_leakage += arr->data_bitline.i_leakage * cols * info->write_ports;
+
+ /* bitline precharging power initialization */
+ SIM_array_pre_init( &arr->data_bitline_pre, info->data_bitline_pre_model, pre_size );
+ /* static power */
+ arr->i_leakage += arr->data_bitline_pre.i_leakage * cols * info->read_ports;
+ /* bitline column selector precharging power initialization */
+ if ( info->data_n_share_amp > 1 )
+ SIM_array_pre_init( &arr->data_colsel_pre, info->data_colsel_pre_model, pre_size );
+
+ /* sense amplifier power initialization */
+ SIM_array_amp_init( &arr->data_amp, info->data_amp_model );
+ }
+ else {
+ /* info->n_set == 1 means this array is fully-associative */
+ rows = info->assoc;
+ cols = info->blk_bits;
+
+ /* WHS: no read wordlines or bitlines */
+ bitline_len = rows * ( RegCellHeight + info->write_ports * WordlineSpacing );
+ wordline_len = cols * ( RegCellWidth + 2 * info->write_ports * BitlineSpacing );
+ info->data_arr_width = wordline_len;
+ info->data_arr_height = bitline_len;
+
+ /* bitline power initialization */
+ SIM_array_bitline_init(&arr->data_bitline, info->data_bitline_model, 0, info->data_end, rows, bitline_len * bitline_cmetal, 1, 0, 0, 0, info->outdrv_model);
+ }
+
+ /* wordline power initialization */
+ SIM_array_wordline_init( &arr->data_wordline, info->data_wordline_model, info->share_rw, cols, wordline_len * wordline_cmetal, info->data_end );
+ /* static power */
+ arr->i_leakage += arr->data_wordline.i_leakage * rows * ports;
+
+ if (dec_width = SIM_power_logtwo(info->n_item)) {
+ /* multiplexor power initialization */
+ SIM_array_mux_init( &arr->mux, info->mux_model, info->n_item, info->assoc );
+
+ /* column decoder power initialization */
+ SIM_array_dec_init( &arr->col_dec, info->col_dec_model, dec_width );
+
+ /* column decoder precharging power initialization */
+ //if ( is_dynamic_dec( info->col_dec_model ))
+ /* FIXME: need real pre_size */
+ //SIM_array_pre_init( &arr->col_dec_pre, info->col_dec_pre_model, 0 );
+ }
+
+ /* memory cell power initialization */
+ SIM_array_mem_init( &arr->data_mem, info->data_mem_model, info->read_ports, info->write_ports, info->share_rw, info->data_end );
+ /* static power */
+ arr->i_leakage += arr->data_mem.i_leakage * rows * cols;
+
+ /* output driver power initialization */
+ SIM_array_outdrv_init( &arr->outdrv, info->outdrv_model, info->data_width );
+ /* END: data array power initialization */
+
+
+ /* BEGIN: tag array power initialization */
+ /* assume a tag array must have memory cells */
+ if ( info->tag_mem_model ) {
+ if ( info->n_set > 1 ) {
+ /* tag array unit length wire cap */
+ if (ports > 1) {
+ /* 3x minimal spacing */
+ wordline_cmetal = CC3M3metal;
+ bitline_cmetal = CC3M2metal;
+ }
+ else if (info->data_end == 2) {
+ /* wordline infinite spacing, bitline 3x minimal spacing */
+ wordline_cmetal = CM3metal;
+ bitline_cmetal = CC3M2metal;
+ }
+ else {
+ /* both infinite spacing */
+ wordline_cmetal = CM3metal;
+ bitline_cmetal = CM2metal;
+ }
+
+ rows = info->n_set / info->tag_ndbl / info->tag_nspd;
+ cols = info->tag_line_width * info->assoc * info->tag_nspd / info->tag_ndwl;
+
+ bitline_len = rows * ( RegCellHeight + ports * WordlineSpacing );
+ if ( info->tag_end == 2 )
+ wordline_len = cols * ( RegCellWidth + 2 * ports * BitlineSpacing );
+ else /* info->tag_end == 1 */
+ wordline_len = cols * ( RegCellWidth + ( 2 * ports - info->read_ports ) * BitlineSpacing );
+ info->tag_arr_width = wordline_len;
+ info->tag_arr_height = bitline_len;
+
+ /* compute precharging size */
+ /* FIXME: should consider n_pre and pre_size simultaneously */
+ Cline = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ) + bitline_cmetal * bitline_len;
+ pre_size = SIM_power_driver_size( Cline, Period / 8 );
+ /* WHS: ?? compensate for not having an nmos pre-charging */
+ pre_size += pre_size * Wdecinvn / Wdecinvp;
+
+ /* bitline power initialization */
+ n_bitline_pre = n_pre_drain( info->tag_bitline_pre_model );
+ n_colsel_pre = ( info->tag_n_share_amp > 1 ) ? n_pre_drain( info->tag_colsel_pre_model ) : 0;
+ SIM_array_bitline_init(&arr->tag_bitline, info->tag_bitline_model, info->share_rw, info->tag_end, rows, bitline_len * bitline_cmetal, info->tag_n_share_amp, n_bitline_pre, n_colsel_pre, pre_size, SIM_NO_MODEL);
+
+ /* bitline precharging power initialization */
+ SIM_array_pre_init( &arr->tag_bitline_pre, info->tag_bitline_pre_model, pre_size );
+ /* bitline column selector precharging power initialization */
+ if ( info->tag_n_share_amp > 1 )
+ SIM_array_pre_init( &arr->tag_colsel_pre, info->tag_colsel_pre_model, pre_size );
+
+ /* sense amplifier power initialization */
+ SIM_array_amp_init( &arr->tag_amp, info->tag_amp_model );
+
+ /* prepare for comparator initialization */
+ tagline_len = matchline_len = 0;
+ comp_pre_size = Wcomppreequ;
+ }
+ else { /* info->n_set == 1 */
+ /* cam cells are big enough, so infinite spacing */
+ wordline_cmetal = CM3metal;
+ bitline_cmetal = CM2metal;
+
+ rows = info->assoc;
+ /* FIXME: operations of valid bit, use bit and dirty bit are not modeled */
+ cols = info->tag_addr_width;
+
+ bitline_len = rows * ( CamCellHeight + ports * WordlineSpacing + info->read_ports * MatchlineSpacing );
+ if ( info->tag_end == 2 )
+ wordline_len = cols * ( CamCellWidth + 2 * ports * BitlineSpacing + 2 * info->read_ports * TaglineSpacing );
+ else /* info->tag_end == 1 */
+ wordline_len = cols * ( CamCellWidth + ( 2 * ports - info->read_ports ) * BitlineSpacing + 2 * info->read_ports * TaglineSpacing );
+ info->tag_arr_width = wordline_len;
+ info->tag_arr_height = bitline_len;
+
+ if ( is_rw_bitline ( info->tag_bitline_model )) {
+ /* compute precharging size */
+ /* FIXME: should consider n_pre and pre_size simultaneously */
+ Cline = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ) + bitline_cmetal * bitline_len;
+ pre_size = SIM_power_driver_size( Cline, Period / 8 );
+ /* WHS: ?? compensate for not having an nmos pre-charging */
+ pre_size += pre_size * Wdecinvn / Wdecinvp;
+
+ /* bitline power initialization */
+ n_bitline_pre = n_pre_drain( info->tag_bitline_pre_model );
+ SIM_array_bitline_init(&arr->tag_bitline, info->tag_bitline_model, info->share_rw, info->tag_end, rows, bitline_len * bitline_cmetal, 1, n_bitline_pre, 0, pre_size, SIM_NO_MODEL);
+
+ /* bitline precharging power initialization */
+ SIM_array_pre_init( &arr->tag_bitline_pre, info->tag_bitline_pre_model, pre_size );
+
+ /* sense amplifier power initialization */
+ SIM_array_amp_init( &arr->tag_amp, info->tag_amp_model );
+ }
+ else {
+ /* bitline power initialization */
+ SIM_array_bitline_init(&arr->tag_bitline, info->tag_bitline_model, 0, info->tag_end, rows, bitline_len * bitline_cmetal, 1, 0, 0, 0, SIM_NO_MODEL);
+ }
+
+ /* memory cell power initialization */
+ SIM_array_mem_init( &arr->tag_attach_mem, info->tag_attach_mem_model, info->read_ports, info->write_ports, info->share_rw, info->tag_end );
+
+ /* prepare for comparator initialization */
+ tagline_len = bitline_len;
+ matchline_len = wordline_len;
+ comp_pre_size = Wmatchpchg;
+ }
+
+ /* wordline power initialization */
+ SIM_array_wordline_init( &arr->tag_wordline, info->tag_wordline_model, info->share_rw, cols, wordline_len * wordline_cmetal, info->tag_end );
+
+ /* comparator power initialization */
+ SIM_array_comp_init( &arr->comp, info->comp_model, info->tag_addr_width, info->assoc, n_pre_drain( info->comp_pre_model ), matchline_len, tagline_len );
+
+ /* comparator precharging power initialization */
+ SIM_array_pre_init( &arr->comp_pre, info->comp_pre_model, comp_pre_size );
+
+ /* memory cell power initialization */
+ SIM_array_mem_init( &arr->tag_mem, info->tag_mem_model, info->read_ports, info->write_ports, info->share_rw, info->tag_end );
+ }
+ /* END: tag array power initialization */
+
+ return 0;
+}
+
+double array_report(power_array_info *info, power_array *arr)
+{
+ double epart, etotal = 0;
+
+ if (info->row_dec_model) {
+ epart = SIM_array_dec_report(&arr->row_dec);
+ //fprintf(stderr, "row decoder: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->col_dec_model) {
+ epart = SIM_array_dec_report(&arr->col_dec);
+ //fprintf(stderr, "col decoder: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->data_wordline_model) {
+ epart = SIM_array_wordline_report(&arr->data_wordline);
+ //fprintf(stderr, "data wordline: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->tag_wordline_model) {
+ epart = SIM_array_wordline_report(&arr->tag_wordline);
+ //fprintf(stderr, "tag wordline: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->data_bitline_model) {
+ epart = SIM_array_bitline_report(&arr->data_bitline);
+ //fprintf(stderr, "data bitline: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->data_bitline_pre_model) {
+ epart = SIM_array_pre_report(&arr->data_bitline_pre);
+ //fprintf(stderr, "data bitline precharge: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->tag_bitline_model) {
+ epart = SIM_array_bitline_report(&arr->tag_bitline);
+ //fprintf(stderr, "tag bitline: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->data_mem_model) {
+ epart = SIM_array_mem_report(&arr->data_mem);
+ //fprintf(stderr, "data memory: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->tag_mem_model) {
+ epart = SIM_array_mem_report(&arr->tag_mem);
+ //fprintf(stderr, "tag memory: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->data_amp_model) {
+ epart = SIM_array_amp_report(&arr->data_amp);
+ //fprintf(stderr, "data amp: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->tag_amp_model) {
+ epart = SIM_array_amp_report(&arr->tag_amp);
+ //fprintf(stderr, "tag amp: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->comp_model) {
+ epart = SIM_array_comp_report(&arr->comp);
+ //fprintf(stderr, "comparator: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->mux_model) {
+ epart = SIM_array_mux_report(&arr->mux);
+ //fprintf(stderr, "multiplexor: %g\n", epart);
+ etotal += epart;
+ }
+ if (info->outdrv_model) {
+ epart = SIM_array_outdrv_report(&arr->outdrv);
+ //fprintf(stderr, "output driver: %g\n", epart);
+ etotal += epart;
+ }
+ /* ignore other precharging for now */
+
+ //fprintf(stderr, "total energy: %g\n", etotal);
+
+ return etotal;
+}
+
+/* ==================== buffer (wrapper/record functions) ==================== */
+
+/* record read data activity */
+int SIM_buf_power_data_read(power_array_info *info, power_array *arr, unsigned long int data)
+{
+ /* precharge */
+ SIM_array_pre_record(&arr->data_bitline_pre, info->blk_bits);
+ /* drive the wordline */
+ SIM_power_array_dec(info, arr, NULL, 0, SIM_ARRAY_READ);
+ /* read data */
+ SIM_power_array_data_read(info, arr, data);
+
+ return 0;
+}
+
+
+/* record write data bitline and memory cell activity */
+int SIM_buf_power_data_write(power_array_info *info, power_array *arr, char *data_line, char *old_data, char *new_data)
+{
+#define N_ITEM (PARM_flit_width / 8 + (PARM_flit_width % 8 ? 1:0))
+ /* drive the wordline */
+ SIM_power_array_dec(info, arr, NULL, 0, SIM_ARRAY_WRITE);
+ /* write data */
+ SIM_power_array_data_write(info, arr, NULL, N_ITEM, data_line, old_data, new_data);
+
+ return 0;
+}
+
+/* WHS: missing data output wrapper function */
+
+/* ==================== buffer (wrapper/record functions) end ==================== */
+
+
+
+
+
+int SIM_array_clear_stat(power_array *arr)
+{
+ SIM_array_dec_clear_stat(&arr->row_dec);
+ SIM_array_dec_clear_stat(&arr->col_dec);
+ SIM_array_wordline_clear_stat(&arr->data_wordline);
+ SIM_array_wordline_clear_stat(&arr->tag_wordline);
+ SIM_array_bitline_clear_stat(&arr->data_bitline);
+ SIM_array_bitline_clear_stat(&arr->tag_bitline);
+ SIM_array_mem_clear_stat(&arr->data_mem);
+ SIM_array_mem_clear_stat(&arr->tag_mem);
+ SIM_array_mem_clear_stat(&arr->tag_attach_mem);
+ SIM_array_amp_clear_stat(&arr->data_amp);
+ SIM_array_amp_clear_stat(&arr->tag_amp);
+ SIM_array_comp_clear_stat(&arr->comp);
+ SIM_array_mux_clear_stat(&arr->mux);
+ SIM_array_outdrv_clear_stat(&arr->outdrv);
+ SIM_array_pre_clear_stat(&arr->row_dec_pre);
+ SIM_array_pre_clear_stat(&arr->col_dec_pre);
+ SIM_array_pre_clear_stat(&arr->data_bitline_pre);
+ SIM_array_pre_clear_stat(&arr->tag_bitline_pre);
+ SIM_array_pre_clear_stat(&arr->data_colsel_pre);
+ SIM_array_pre_clear_stat(&arr->tag_colsel_pre);
+ SIM_array_pre_clear_stat(&arr->comp_pre);
+
+ return 0;
+}
+
+
+
+
+
diff --git a/src/mem/ruby/network/orion/power_array.hh b/src/mem/ruby/network/orion/power_array.hh
new file mode 100644
index 000000000..dbd2733c9
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_array.hh
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _POWER_ARRAY_H
+#define _POWER_ARRAY_H
+
+
+#define SIM_ARRAY_NO_MODEL 0
+#define SIM_ARRAY_READ 0
+#define SIM_ARRAY_WRITE 1
+
+#define SIM_ARRAY_RECOVER 1
+
+/* read/write */
+#define SIM_ARRAY_RW 0
+/* only write */
+#define SIM_ARRAY_WO 1
+
+typedef enum {
+ GENERIC_DEC =1,
+ DEC_MAX_MODEL
+} power_dec_model;
+
+typedef enum {
+ GENERIC_MUX =1,
+ MUX_MAX_MODEL
+} power_mux_model;
+
+typedef enum {
+ GENERIC_AMP =1,
+ AMP_MAX_MODEL
+} power_amp_model;
+
+typedef enum {
+ CACHE_RW_WORDLINE =1,
+ CACHE_WO_WORDLINE,
+ CAM_RW_WORDLINE,
+ CAM_WO_WORDLINE,
+ WORDLINE_MAX_MODEL
+} power_wordline_model;
+
+typedef enum {
+ RW_BITLINE =1,
+ WO_BITLINE,
+ BITLINE_MAX_MODEL
+} power_bitline_model;
+
+typedef enum {
+ SINGLE_BITLINE =1,
+ EQU_BITLINE,
+ SINGLE_OTHER,
+ PRE_MAX_MODEL
+} power_pre_model;
+
+typedef enum {
+ NORMAL_MEM =1,
+ CAM_TAG_RW_MEM,
+ CAM_TAG_WO_MEM,
+ CAM_DATA_MEM,
+ CAM_ATTACH_MEM,
+ MEM_MAX_MODEL
+} power_mem_model;
+
+typedef enum {
+ CACHE_COMPONENT =1,
+ CAM_COMP,
+ COMP_MAX_MODEL
+} power_comp_model;
+
+typedef enum {
+ CACHE_OUTDRV =1,
+ CAM_OUTDRV,
+ REG_OUTDRV,
+ OUTDRV_MAX_MODEL
+} power_outdrv_model;
+
+
+
+typedef struct {
+ int model;
+ unsigned n_bits;
+ unsigned long int n_chg_output;
+ unsigned long int n_chg_addr;
+ unsigned long int n_chg_l1;
+ double e_chg_output;
+ double e_chg_addr;
+ double e_chg_l1;
+ unsigned n_in_1st;
+ unsigned n_in_2nd;
+ unsigned n_out_0th;
+ unsigned n_out_1st;
+ unsigned long int addr_mask;
+} power_decoder;
+
+typedef struct {
+ int model;
+ int share_rw;
+ unsigned long int n_read;
+ unsigned long int n_write;
+ double e_read;
+ double e_write;
+ double i_leakage;
+} power_wordline;
+
+typedef struct {
+ int model;
+ int share_rw;
+ unsigned end;
+ unsigned long int n_col_write;
+ unsigned long int n_col_read;
+ unsigned long int n_col_sel;
+ double e_col_write;
+ double e_col_read;
+ double e_col_sel;
+ double i_leakage;
+} power_bitline;
+
+typedef struct {
+ int model;
+ unsigned long int n_access;
+ double e_access;
+} power_amp;
+
+typedef struct {
+ int model;
+ unsigned n_bits;
+ unsigned assoc;
+ unsigned long int n_access;
+ unsigned long int n_match;
+ unsigned long int n_mismatch;
+ unsigned long int n_miss;
+ unsigned long int n_bit_match;
+ unsigned long int n_bit_mismatch;
+ unsigned long int n_chg_addr;
+ double e_access;
+ double e_match;
+ double e_mismatch;
+ double e_miss;
+ double e_bit_match;
+ double e_bit_mismatch;
+ double e_chg_addr;
+ unsigned long int comp_mask;
+} power_comp;
+
+typedef struct {
+ int model;
+ unsigned end;
+ unsigned long int n_switch;
+ double e_switch;
+ double i_leakage;
+} power_mem;
+
+typedef struct {
+ int model;
+ unsigned assoc;
+ unsigned long int n_mismatch;
+ unsigned long int n_chg_addr;
+ double e_mismatch;
+ double e_chg_addr;
+} power_mux;
+
+typedef struct {
+ int model;
+ unsigned item_width;
+ unsigned long int n_select;
+ unsigned long int n_chg_data;
+ unsigned long int n_out_1;
+ unsigned long int n_out_0;
+ double e_select;
+ double e_chg_data;
+ double e_out_1;
+ double e_out_0;
+ unsigned long int out_mask;
+} power_out;
+
+typedef struct {
+ int model;
+ unsigned long int n_charge;
+ double e_charge;
+ double i_leakage;
+} power_arr_pre;
+
+
+/*@
+ * data type: array port state
+ *
+ * - row_addr -- input to row decoder
+ * col_addr -- input to column decoder, if any
+ * tag_addr -- input to tag comparator
+ * $+ tag_line -- value of tag bitline
+ * # data_line_size -- size of data_line in char
+ * # data_line -- value of data bitline
+ *
+ * legend:
+ * -: only used by non-fully-associative array
+ * +: only used by fully-associative array
+ * #: only used by fully-associative array or RF array
+ * $: only used by write-through array
+ *
+ * NOTE:
+ * (1) *_addr may not necessarily be an address
+ * (2) data_line_size is the allocated size of data_line in simulator,
+ * which must be no less than the physical size of data line
+ * (3) each instance of module should define an instance-specific data
+ * type with non-zero-length data_line and cast it to this type
+ */
+typedef struct {
+ unsigned long int row_addr;
+ unsigned long int col_addr;
+ unsigned long int tag_addr;
+ unsigned long int tag_line;
+ unsigned data_line_size;
+ char data_line[0];
+} SIM_array_port_state_t;
+
+/*@
+ * data type: array set state
+ *
+ * entry -- pointer to some entry structure if an entry is selected for
+ * r/w, NULL otherwise
+ * entry_set -- pointer to corresponding set structure
+ * + write_flag -- 1 if entry is already written once, 0 otherwise
+ * + write_back_flag -- 1 if entry is already written back, 0 otherwise
+ * valid_bak -- valid bit of selected entry before operation
+ * dirty_bak -- dirty bit of selected entry, if any, before operation
+ * tag_bak -- tag of selected entry before operation
+ * use_bak -- use bits of all entries before operation
+ *
+ * legend:
+ * +: only used by fully-associative array
+ *
+ * NOTE:
+ * (1) entry is interpreted by modules, if some module has no "entry structure",
+ * then make sure this field is non-zero if some entry is selected
+ * (2) tag_addr may not necessarily be an address
+ * (3) each instance of module should define an instance-specific data
+ * type with non-zero-length use_bit and cast it to this type
+ */
+typedef struct {
+ void *entry;
+ void *entry_set;
+ int write_flag;
+ int write_back_flag;
+ unsigned valid_bak;
+ unsigned dirty_bak;
+ unsigned long int tag_bak;
+ unsigned use_bak[0];
+} SIM_array_set_state_t;
+
+
+
+
+
+// Array
+
+typedef struct {
+ power_decoder row_dec;
+ power_decoder col_dec;
+ power_wordline data_wordline;
+ power_wordline tag_wordline;
+ power_bitline data_bitline;
+ power_bitline tag_bitline;
+ power_mem data_mem;
+ power_mem tag_mem;
+ power_mem tag_attach_mem;
+ power_amp data_amp;
+ power_amp tag_amp;
+ power_comp comp;
+ power_mux mux;
+ power_out outdrv;
+ power_arr_pre row_dec_pre;
+ power_arr_pre col_dec_pre;
+ power_arr_pre data_bitline_pre;
+ power_arr_pre tag_bitline_pre;
+ power_arr_pre data_colsel_pre;
+ power_arr_pre tag_colsel_pre;
+ power_arr_pre comp_pre;
+ double i_leakage;
+} power_array;
+
+typedef struct {
+ //common for data and tag array
+ int share_rw;
+ unsigned read_ports;
+ unsigned write_ports;
+ unsigned n_set;
+ unsigned blk_bits;
+ unsigned assoc;
+ int row_dec_model;
+ //for data array
+ unsigned data_width;
+ int col_dec_model;
+ int mux_model;
+ int outdrv_model;
+ //for tag array
+ unsigned tag_addr_width;
+ unsigned tag_line_width;
+ int comp_model;
+ //data common
+ unsigned data_ndwl;
+ unsigned data_ndbl;
+ unsigned data_nspd;
+ unsigned data_n_share_amp;
+ unsigned data_end;
+ int data_wordline_model;
+ int data_bitline_model;
+ int data_amp_model;
+ int data_mem_model;
+ //tag common
+ unsigned tag_ndwl;
+ unsigned tag_ndbl;
+ unsigned tag_nspd;
+ unsigned tag_n_share_amp;
+ unsigned tag_end;
+ unsigned tag_wordline_model;
+ unsigned tag_bitline_model;
+ unsigned tag_amp_model;
+ unsigned tag_mem_model;
+ unsigned tag_attach_mem_model;
+ //precharging parameters
+ int row_dec_pre_model;
+ int col_dec_pre_model;
+ int data_bitline_pre_model;
+ int tag_bitline_pre_model;
+ int data_colsel_pre_model;
+ int tag_colsel_pre_model;
+ int comp_pre_model;
+ //derived
+ unsigned n_item;
+ unsigned eff_data_cols;
+ unsigned eff_tag_cols;
+ //flags used by prototype array model
+ unsigned use_bit_width;
+ unsigned valid_bit_width;
+ int write_policy;
+ //fields filled up during initialization
+ double data_arr_width;
+ double tag_arr_width;
+ double data_arr_height;
+ double tag_arr_height;
+} power_array_info;
+
+
+extern int power_array_init(power_array_info *info, power_array *arr );
+
+extern double array_report(power_array_info *info, power_array *arr);
+
+extern int SIM_buf_power_data_read(power_array_info *info, power_array *arr, unsigned long int data);
+
+extern int SIM_buf_power_data_write(power_array_info *info, power_array *arr, char *data_line, char *old_data, char *new_data);
+
+extern int SIM_array_clear_stat(power_array *arr);
+
+extern int SIM_power_array_dec( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int row_addr, int rw );
+extern int SIM_power_array_data_read( power_array_info *info, power_array *arr, unsigned long int data );
+extern int SIM_power_array_data_write( power_array_info *info, power_array *arr, SIM_array_set_state_t *set, unsigned n_item, char *data_line, char *old_data, char *new_data );
+extern int power_array_tag_read( power_array_info *info, power_array *arr, SIM_array_set_state_t *set );
+extern int power_array_tag_update( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, SIM_array_set_state_t *set );
+extern int power_array_tag_compare( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int tag_input, unsigned long int col_addr, SIM_array_set_state_t *set );
+extern int SIM_power_array_output( power_array_info *info, power_array *arr, unsigned data_size, unsigned length, void *data_out, void *data_all );
+
+extern int SIM_array_port_state_init( power_array_info *info, SIM_array_port_state_t *port );
+extern int SIM_array_set_state_init( power_array_info *info, SIM_array_set_state_t *set );
+
+#endif
+
+
+
+
diff --git a/src/mem/ruby/network/orion/power_bus.cc b/src/mem/ruby/network/orion/power_bus.cc
new file mode 100644
index 000000000..032c3c519
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_bus.cc
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "power_bus.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "power_utils.hh"
+
+/* ------- bus(link) model ---------- */
+
+static int SIM_bus_bitwidth(int encoding, unsigned data_width, unsigned grp_width)
+{
+ if (encoding && encoding < BUS_MAX_ENC)
+ switch (encoding) {
+ case IDENT_ENC:
+ case TRANS_ENC: return data_width;
+ case BUSINV_ENC: return data_width + data_width / grp_width + (data_width % grp_width ? 1:0);
+ default: return 0;/* some error handler */
+ }
+ else
+ return -1;
+}
+
+
+/*
+ * this function is provided to upper layers to compute the exact binary bus representation
+ * only correct when grp_width divides data_width
+ */
+unsigned long int SIM_bus_state(power_bus *bus, unsigned long int old_data, unsigned long int old_state, unsigned long int new_data)
+{
+ unsigned long int mask_bus, mask_data;
+ unsigned long int new_state = 0;
+ unsigned done_width = 0;
+
+ switch (bus->encoding) {
+ case IDENT_ENC: return new_data;
+ case TRANS_ENC: return new_data ^ old_data;
+
+ case BUSINV_ENC:
+ /* FIXME: this function should be re-written for boundary checking */
+ mask_data = (BIGONE << bus->grp_width) - 1;
+ mask_bus = (mask_data << 1) + 1;
+
+ while (bus->data_width > done_width) {
+ if (SIM_power_Hamming(old_state & mask_bus, new_data & mask_data, mask_bus) > bus->grp_width / 2)
+ new_state += (~(new_data & mask_data) & mask_bus) << done_width + done_width / bus->grp_width;
+ else
+ new_state += (new_data & mask_data) << done_width + done_width / bus->grp_width;
+
+ done_width += bus->grp_width;
+ old_state >>= bus->grp_width + 1;
+ new_data >>= bus->grp_width;
+ }
+
+ return new_state;
+
+ default: return 0;/* some error handler */
+ }
+}
+
+
+static double SIM_resultbus_cap(void)
+{
+ double Cline, reg_height;
+
+ /* compute size of result bus tags */
+ reg_height = PARM_RUU_size * (RegCellHeight + WordlineSpacing * 3 * PARM_ruu_issue_width);
+
+ /* assume num alu's = ialu */
+ /* FIXME: generate a more detailed result bus network model */
+ /* WHS: 3200 should go to PARM */
+ /* WHS: use minimal pitch for buses */
+ Cline = CCmetal * (reg_height + 0.5 * PARM_res_ialu * 3200 * LSCALE);
+
+ /* or use result bus length measured from 21264 die photo */
+ // Cline = CCmetal * 3.3 * 1000;
+
+ return Cline;
+}
+
+
+static double SIM_generic_bus_cap(unsigned n_snd, unsigned n_rcv, double length, double time)
+{
+ double Ctotal = 0;
+ double n_size, p_size;
+
+ /* part 1: wire cap */
+ /* WHS: use minimal pitch for buses */
+ Ctotal += CC2metal * length;
+
+ if ((n_snd == 1) && (n_rcv == 1)) {
+ /* directed bus if only one sender and one receiver */
+
+ /* part 2: repeater cap */
+ /* FIXME: ratio taken from Raw, does not scale now */
+ n_size = Lamda * 10;
+ p_size = n_size * 2;
+
+ Ctotal += SIM_power_gatecap(n_size + p_size, 0) + SIM_power_draincap(n_size, NCH, 1) + SIM_power_draincap(p_size, PCH, 1);
+
+ n_size *= 2.5;
+ p_size *= 2.5;
+
+ Ctotal += SIM_power_gatecap(n_size + p_size, 0) + SIM_power_draincap(n_size, NCH, 1) + SIM_power_draincap(p_size, PCH, 1);
+ }
+ else {
+ /* otherwise, broadcasting bus */
+
+ /* part 2: input cap */
+ /* WHS: no idea how input interface is, use an inverter for now */
+ Ctotal += n_rcv * SIM_power_gatecap(Wdecinvn + Wdecinvp, 0);
+
+ /* part 3: output driver cap */
+ if (time) {
+ p_size = SIM_power_driver_size(Ctotal, time);
+ n_size = p_size / 2;
+ }
+ else {
+ p_size = Wbusdrvp;
+ n_size = Wbusdrvn;
+ }
+
+ Ctotal += n_snd * (SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1));
+ }
+
+ return Ctotal;
+}
+
+
+/*
+ * n_snd -> # of senders
+ * n_rcv -> # of receivers
+ * time -> rise and fall time, 0 means using default transistor sizes
+ * grp_width only matters for BUSINV_ENC
+ */
+int power_bus_init(power_bus *bus, int model, int encoding, unsigned width, unsigned grp_width, unsigned n_snd, unsigned n_rcv, double length, double time)
+{
+ if ((bus->model = model) && model < BUS_MAX_MODEL) {
+ bus->data_width = width;
+ bus->grp_width = grp_width;
+ bus->n_switch = 0;
+
+ switch (model) {
+ case RESULT_BUS:
+ /* assume result bus uses identity encoding */
+ bus->encoding = IDENT_ENC;
+ bus->e_switch = SIM_resultbus_cap() / 2 * EnergyFactor;
+ break;
+
+ case GENERIC_BUS:
+ if ((bus->encoding = encoding) && encoding < BUS_MAX_ENC) {
+ bus->e_switch = SIM_generic_bus_cap(n_snd, n_rcv, length, time) / 2 * EnergyFactor;
+ /* sanity check */
+ if (!grp_width || grp_width > width)
+ bus->grp_width = width;
+ }
+ else return -1;
+
+ default: break;/* some error handler */
+ }
+
+ bus->bit_width = SIM_bus_bitwidth(bus->encoding, width, bus->grp_width);
+ bus->bus_mask = HAMM_MASK(bus->bit_width);
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+int bus_record(power_bus *bus, unsigned long int old_state, unsigned long int new_state)
+{
+ bus->n_switch += SIM_power_Hamming(new_state, old_state, bus->bus_mask);
+ return 0;
+}
+
+
+double bus_report(power_bus *bus)
+{
+ return (bus->n_switch * bus->e_switch);
+}
+
+/* ------- bus(link) model ---------- */
+
+
diff --git a/src/mem/ruby/network/orion/power_bus.hh b/src/mem/ruby/network/orion/power_bus.hh
new file mode 100644
index 000000000..e1c3ef565
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_bus.hh
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _POWER_BUS_H
+#define _POWER_BUS_H
+
+typedef enum {
+ RESULT_BUS = 1,
+ GENERIC_BUS,
+ BUS_MAX_MODEL
+} power_bus_model;
+
+typedef enum {
+ IDENT_ENC = 1, /* identity encoding */
+ TRANS_ENC, /* transition encoding */
+ BUSINV_ENC, /* bus inversion encoding */
+ BUS_MAX_ENC
+} power_bus_enc;
+
+
+typedef struct {
+ int model;
+ int encoding;
+ unsigned data_width;
+ unsigned grp_width;
+ unsigned long int n_switch;
+ double e_switch;
+ /* redundant field */
+ unsigned bit_width;
+ unsigned long int bus_mask;
+} power_bus;
+
+extern int power_bus_init(power_bus *bus, int model, int encoding, unsigned width, unsigned grp_width, unsigned n_snd, unsigned n_rcv, double length, double time);
+
+extern int bus_record(power_bus *bus, unsigned long int old_state, unsigned long int new_state);
+
+extern double bus_report(power_bus *bus);
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_crossbar.cc b/src/mem/ruby/network/orion/power_crossbar.cc
new file mode 100644
index 000000000..d3e2232ae
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_crossbar.cc
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "power_ll.hh"
+#include "power_crossbar.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "power_utils.hh"
+
+/*-------------------- CROSSBAR power model -------------------*/
+
+static double crossbar_in_cap(double wire_cap, unsigned n_out, int connect_type, int trans_type, double *Nsize)
+{
+ double Ctotal = 0, Ctrans = 0, psize, nsize, Cdriver = 0;
+
+ /* part 1: wire cap */
+ Ctotal += wire_cap;
+ //printf("CROSSBAR_INTERNAL: input wire cap = %g\n", wire_cap);
+
+ /* part 2: drain cap of transmission gate or gate cap of tri-state gate */
+ if (connect_type == TRANS_GATE) {
+ /* FIXME: resizing strategy */
+ nsize = Nsize ? *Nsize : Wmemcellr;
+ psize = nsize * Wdecinvp / Wdecinvn;
+ Ctrans = SIM_power_draincap(nsize, NCH, 1);
+ if (trans_type == NP_GATE)
+ Ctrans += SIM_power_draincap(psize, PCH, 1);
+ }
+ else if (connect_type == TRISTATE_GATE) {
+ Ctrans = SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) +
+ SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0);
+ }
+ else {/* some error handler */}
+
+ //printf("CROSSBAR_INTERNAL: input connector cap = %g\n", (n_out * Ctrans));
+ Ctotal += n_out * Ctrans;
+
+ /* part 3: input driver */
+ /* FIXME: how to specify timing? */
+ psize = SIM_power_driver_size(Ctotal, Period / 3);
+ nsize = psize * Wdecinvn / Wdecinvp;
+ Cdriver = SIM_power_draincap(nsize, NCH, 1) + SIM_power_draincap(psize, PCH, 1) +
+ SIM_power_gatecap(nsize + psize, 0);
+
+ //printf("CROSSBAR_INTERNAL: input driver cap = %g\n", Cdriver);
+
+ Ctotal += Cdriver;
+
+ return Ctotal / 2;
+}
+
+
+static double crossbar_out_cap(double length, unsigned n_in, int connect_type, int trans_type, double *Nsize)
+{
+ double Ctotal = 0, Cwire = 0, Ctrans = 0, Cdriver = 0, psize, nsize;
+
+ /* part 1: wire cap */
+ Cwire += CC3metal * length;
+ //printf("CROSSBAR_INTERNAL: output wire cap = %g\n", Cwire);
+
+ Ctotal += Cwire;
+
+ /* part 2: drain cap of transmission gate or tri-state gate */
+ if (connect_type == TRANS_GATE) {
+ /* FIXME: resizing strategy */
+ if (Nsize) {
+ /* FIXME: how to specify timing? */
+ psize = SIM_power_driver_size(Ctotal, Period / 3);
+ *Nsize = nsize = psize * Wdecinvn / Wdecinvp;
+ }
+ else {
+ nsize = Wmemcellr;
+ psize = nsize * Wdecinvp / Wdecinvn;
+ }
+ Ctrans = SIM_power_draincap(nsize, NCH, 1);
+ if (trans_type == NP_GATE)
+ Ctrans += SIM_power_draincap(psize, PCH, 1);
+ }
+ else if (connect_type == TRISTATE_GATE) {
+ Ctrans = SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1);
+ }
+ else {/* some error handler */}
+
+ //printf("CROSSBAR_INTERNAL: output connector cap = %g\n", (n_in * Ctrans));
+ Ctotal += n_in * Ctrans;
+
+ /* part 3: output driver */
+ Cdriver += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) +
+ SIM_power_gatecap(Woutdrivern + Woutdriverp, 0);
+
+ //printf("CROSSBAR_INTERNAL: output driver cap = %g\n", Cdriver);
+
+ Ctotal += Cdriver;
+
+ return Ctotal / 2;
+}
+
+
+/* cut-through crossbar only supports 4x4 now */
+static double crossbar_io_cap(double length)
+{
+ double Ctotal = 0, psize, nsize;
+
+ /* part 1: wire cap */
+ Ctotal += CC3metal * length;
+
+ /* part 2: gate cap of tri-state gate */
+ Ctotal += 2 * (SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) +
+ SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0));
+
+ /* part 3: drain cap of tri-state gate */
+ Ctotal += 2 * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1));
+
+ /* part 4: input driver */
+ /* FIXME: how to specify timing? */
+ psize = SIM_power_driver_size(Ctotal, Period * 0.8);
+ nsize = psize * Wdecinvn / Wdecinvp;
+ Ctotal += SIM_power_draincap(nsize, NCH, 1) + SIM_power_draincap(psize, PCH, 1) +
+ SIM_power_gatecap(nsize + psize, 0);
+
+ /* part 5: output driver */
+ Ctotal += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) +
+ SIM_power_gatecap(Woutdrivern + Woutdriverp, 0);
+
+ /* HACK HACK HACK */
+ /* this HACK is to count a 1:4 mux and a 4:1 mux, so we have a 5x5 crossbar */
+ return Ctotal / 2 * 1.32;
+}
+
+
+static double crossbar_int_cap(unsigned degree, int connect_type, int trans_type)
+{
+ double Ctotal = 0, Ctrans;
+
+ if (connect_type == TRANS_GATE) {
+ /* part 1: drain cap of transmission gate */
+ /* FIXME: Wmemcellr and resize */
+ Ctrans = SIM_power_draincap(Wmemcellr, NCH, 1);
+ if (trans_type == NP_GATE)
+ Ctrans += SIM_power_draincap(Wmemcellr * Wdecinvp / Wdecinvn, PCH, 1);
+ Ctotal += (degree + 1) * Ctrans;
+ }
+ else if (connect_type == TRISTATE_GATE) {
+ /* part 1: drain cap of tri-state gate */
+ Ctotal += degree * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1));
+
+ /* part 2: gate cap of tri-state gate */
+ Ctotal += SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) +
+ SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0);
+ }
+ else {/* some error handler */}
+
+ return Ctotal / 2;
+}
+
+
+/* FIXME: segment control signals are not handled yet */
+static double crossbar_ctr_cap(double length, unsigned data_width, int prev_ctr, int next_ctr, unsigned degree, int connect_type, int trans_type)
+{
+ double Ctotal = 0, Cgate;
+
+ /* part 1: wire cap */
+ Ctotal = Cmetal * length;
+
+ /* part 2: gate cap of transmission gate or tri-state gate */
+ if (connect_type == TRANS_GATE) {
+ /* FIXME: Wmemcellr and resize */
+ Cgate = SIM_power_gatecap(Wmemcellr, 0);
+ if (trans_type == NP_GATE)
+ Cgate += SIM_power_gatecap(Wmemcellr * Wdecinvp / Wdecinvn, 0);
+ }
+ else if (connect_type == TRISTATE_GATE) {
+ Cgate = SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) +
+ SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0);
+ }
+ else {/* some error handler */}
+
+ Ctotal += data_width * Cgate;
+
+ /* part 3: inverter */
+ if (!(connect_type == TRANS_GATE && trans_type == N_GATE && !prev_ctr))
+ /* FIXME: need accurate size, use minimal size for now */
+ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) +
+ SIM_power_gatecap(Wdecinvn + Wdecinvp, 0);
+
+ /* part 4: drain cap of previous level control signal */
+ if (prev_ctr)
+ /* FIXME: need actual size, use decoder data for now */
+ Ctotal += degree * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, degree);
+
+ /* part 5: gate cap of next level control signal */
+ if (next_ctr)
+ /* FIXME: need actual size, use decoder data for now */
+ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, degree * 40 + 20);
+
+ return Ctotal;
+}
+
+
+int power_crossbar_init(power_crossbar *crsbar, int model, unsigned n_in, unsigned n_out, unsigned data_width, unsigned degree, int connect_type, int trans_type, double in_len, double out_len, double *req_len)
+{
+ double in_length, out_length, ctr_length, Nsize, in_wire_cap, i_leakage;
+
+ if ((crsbar->model = model) && model < CROSSBAR_MAX_MODEL) {
+ crsbar->n_in = n_in;
+ crsbar->n_out = n_out;
+ crsbar->data_width = data_width;
+ crsbar->degree = degree;
+ crsbar->connect_type = connect_type;
+ crsbar->trans_type = trans_type;
+ /* redundant field */
+ crsbar->mask = HAMM_MASK(data_width);
+
+ crsbar->n_chg_in = crsbar->n_chg_int = crsbar->n_chg_out = crsbar->n_chg_ctr = 0;
+
+ switch (model) {
+ case MATRIX_CROSSBAR:
+
+ /* FIXME: need accurate spacing */
+ in_length = n_out * data_width * CrsbarCellWidth;
+ out_length = n_in * data_width * CrsbarCellHeight;
+ if (in_length < in_len) in_length = in_len;
+ if (out_length < out_len) out_length = out_len;
+ ctr_length = in_length / 2;
+ if (req_len) *req_len = in_length;
+
+ in_wire_cap = in_length * CC3metal;
+
+ crsbar->e_chg_out = crossbar_out_cap(out_length, n_in, connect_type, trans_type, &Nsize) * EnergyFactor;
+ crsbar->e_chg_in = crossbar_in_cap(in_wire_cap, n_out, connect_type, trans_type, &Nsize) * EnergyFactor;
+ /* FIXME: wire length estimation, really reset? */
+ /* control signal should reset after transmission is done, so no 1/2 */
+ crsbar->e_chg_ctr = crossbar_ctr_cap(ctr_length, data_width, 0, 0, 0, connect_type, trans_type) * EnergyFactor;
+ crsbar->e_chg_int = 0;
+
+ /* static power */
+ i_leakage = 0;
+ /* tri-state buffers */
+ i_leakage += ((Woutdrvnandp * (NAND2_TAB[0] + NAND2_TAB[1] + NAND2_TAB[2]) + Woutdrvnandn * NAND2_TAB[3]) / 4 +
+ (Woutdrvnorp * NOR2_TAB[0] + Woutdrvnorn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 +
+ Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_in * n_out * data_width;
+ /* input driver */
+ i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * data_width;
+ /* output driver */
+ i_leakage += (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_out * data_width;
+ /* control signal inverter */
+ i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * n_out;
+ crsbar->i_leakage = i_leakage / PARM_TECH_POINT * 100;
+ break;
+
+ case MULTREE_CROSSBAR:
+ /* input wire horizontal segment length */
+ in_length = n_in * data_width * CrsbarCellWidth * (n_out / 2);
+ in_wire_cap = in_length * CCmetal;
+ /* input wire vertical segment length */
+ in_length = n_in * data_width * (5 * Lamda) * (n_out / 2);
+ in_wire_cap += in_length * CC3metal;
+
+ ctr_length = n_in * data_width * CrsbarCellWidth * (n_out / 2) / 2;
+
+ crsbar->e_chg_out = crossbar_out_cap(0, degree, connect_type, trans_type, NULL) * EnergyFactor;
+ crsbar->e_chg_in = crossbar_in_cap(in_wire_cap, n_out, connect_type, trans_type, NULL) * EnergyFactor;
+ crsbar->e_chg_int = crossbar_int_cap(degree, connect_type, trans_type) * EnergyFactor;
+
+ /* redundant field */
+ crsbar->depth = (unsigned)ceil(log(n_in) / log(degree));
+
+ /* control signal should reset after transmission is done, so no 1/2 */
+ if (crsbar->depth == 1)
+ /* only one level of control signal */
+ crsbar->e_chg_ctr = crossbar_ctr_cap(ctr_length, data_width, 0, 0, degree, connect_type, trans_type) * EnergyFactor;
+ else {
+ /* first level and last level control signals */
+ crsbar->e_chg_ctr = crossbar_ctr_cap(ctr_length, data_width, 0, 1, degree, connect_type, trans_type) * EnergyFactor +
+ crossbar_ctr_cap(0, data_width, 1, 0, degree, connect_type, trans_type) * EnergyFactor;
+ /* intermediate control signals */
+ if (crsbar->depth > 2)
+ crsbar->e_chg_ctr += (crsbar->depth - 2) * crossbar_ctr_cap(0, data_width, 1, 1, degree, connect_type, trans_type) * EnergyFactor;
+ }
+
+ /* static power */
+ i_leakage = 0;
+ /* input driver */
+ i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * data_width;
+ /* output driver */
+ i_leakage += (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_out * data_width;
+ /* mux */
+ i_leakage += (WdecNORp * NOR2_TAB[0] + WdecNORn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 * (2 * n_in - 1) * n_out * data_width;
+ /* control signal inverter */
+ i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * n_out;
+ crsbar->i_leakage = i_leakage / PARM_TECH_POINT * 100;
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
+
+/* FIXME: MULTREE_CROSSBAR record missing */
+int crossbar_record(power_crossbar *xb, int io, unsigned long int new_data, unsigned long int old_data, unsigned new_port, unsigned old_port)
+{
+ switch (xb->model) {
+ case MATRIX_CROSSBAR:
+ if (io) /* input port */
+ xb->n_chg_in += SIM_power_Hamming(new_data, old_data, xb->mask);
+ else { /* output port */
+ xb->n_chg_out += SIM_power_Hamming(new_data, old_data, xb->mask);
+ xb->n_chg_ctr += new_port != old_port;
+ }
+ break;
+
+ case MULTREE_CROSSBAR:
+ break;
+
+ default: break;/* some error handler */
+ }
+
+ return 0;
+}
+
+
+double crossbar_report(power_crossbar *crsbar)
+{
+ return (crsbar->n_chg_in * crsbar->e_chg_in + crsbar->n_chg_out * crsbar->e_chg_out +
+ crsbar->n_chg_int * crsbar->e_chg_int + crsbar->n_chg_ctr * crsbar->e_chg_ctr);
+}
+
+/* ---------- crossbar model ---------- */
+
+
+
diff --git a/src/mem/ruby/network/orion/power_crossbar.hh b/src/mem/ruby/network/orion/power_crossbar.hh
new file mode 100644
index 000000000..1dc0220e7
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_crossbar.hh
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+// Crossbar
+
+#ifndef _POWER_CROSSBAR_H
+#define _POWER_CROSSBAR_H
+
+typedef enum {
+ TRANS_GATE,
+ TRISTATE_GATE
+} power_connect_model;
+
+/* transmission gate type */
+typedef enum {
+ N_GATE,
+ NP_GATE
+} power_trans;
+
+typedef enum {
+ MATRIX_CROSSBAR =1,
+ MULTREE_CROSSBAR,
+ CUT_THRU_CROSSBAR,
+ CROSSBAR_MAX_MODEL
+} power_crossbar_model;
+
+
+typedef struct {
+ int model;
+ unsigned n_in;
+ unsigned n_out;
+ unsigned data_width;
+ unsigned degree; //used only for multree xbar
+ unsigned connect_type;
+ unsigned trans_type;
+ unsigned long int n_chg_in;
+ unsigned long int n_chg_int;
+ unsigned long int n_chg_out;
+ unsigned long int n_chg_ctr;
+ unsigned long int mask;
+ double e_chg_in;
+ double e_chg_int;
+ double e_chg_out;
+ double e_chg_ctr;
+ unsigned depth; //used only for multree xbar
+ double i_leakage;
+} power_crossbar;
+
+
+extern int crossbar_record(power_crossbar *xb, int io, unsigned long int new_data, unsigned long int old_data, unsigned new_port, unsigned old_port);
+
+extern int power_crossbar_init(power_crossbar *crsbar, int model, unsigned n_in, unsigned n_out, unsigned data_width, unsigned degree, int connect_type, int trans_type, double in_len, double out_len, double *req_len);
+
+extern double crossbar_report(power_crossbar *crsbar);
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_ll.cc b/src/mem/ruby/network/orion/power_ll.cc
new file mode 100644
index 000000000..3628989d0
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_ll.cc
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*------------------------------------------------------------
+ * Copyright 1994 Digital Equipment Corporation and Steve Wilton
+ * All Rights Reserved
+ *
+ * Permission to use, copy, and modify this software and its documentation is
+ * hereby granted only under the following terms and conditions. Both the
+ * above copyright notice and this permission notice must appear in all copies
+ * of the software, derivative works or modified versions, and any portions
+ * thereof, and both notices must appear in supporting documentation.
+ *
+ * Users of this software agree to the terms and conditions set forth herein,
+ * and hereby grant back to Digital a non-exclusive, unrestricted, royalty-
+ * free right and license under any changes, enhancements or extensions
+ * made to the core functions of the software, including but not limited to
+ * those affording compatibility with other hardware or software
+ * environments, but excluding applications which incorporate this software.
+ * Users further agree to use their best efforts to return to Digital any
+ * such changes, enhancements or extensions that they make and inform Digital
+ * of noteworthy uses of this software. Correspondence should be provided
+ * to Digital at:
+ *
+ * Director of Licensing
+ * Western Research Laboratory
+ * Digital Equipment Corporation
+ * 100 Hamilton Avenue
+ * Palo Alto, California 94301
+ *
+ * This software may be distributed (but not offered for sale or transferred
+ * for compensation) to third parties, provided such third parties agree to
+ * abide by the terms and conditions of this notice.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *------------------------------------------------------------*/
+
+#include <math.h>
+#include <assert.h>
+
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "power_ll.hh"
+
+/*----------------------------------------------------------------------*/
+
+double SIM_power_gatecap(double width,double wirelength) /* returns gate capacitance in Farads */
+//double width; /* gate width in um (length is Leff) */
+//double wirelength; /* poly wire length going to gate in lambda */
+{
+
+ double overlapCap;
+ double gateCap;
+ double l = 0.1525;
+
+#if defined(Pdelta_w)
+ overlapCap = (width - 2*Pdelta_w) * PCov;
+ gateCap = ((width - 2*Pdelta_w) * (l * LSCALE - 2*Pdelta_l) *
+ PCg) + 2.0 * overlapCap;
+
+ return gateCap;
+#endif
+ return(width*Leff*PARM_Cgate+wirelength*Cpolywire*Leff * SCALE_T);
+ /* return(width*Leff*PARM_Cgate); */
+ /* return(width*CgateLeff+wirelength*Cpolywire*Leff);*/
+}
+
+
+double SIM_power_gatecappass(double width,double wirelength) /* returns gate capacitance in Farads */
+//double width; /* gate width in um (length is Leff) */
+//double wirelength; /* poly wire length going to gate in lambda */
+{
+ return(SIM_power_gatecap(width,wirelength));
+ /* return(width*Leff*PARM_Cgatepass+wirelength*Cpolywire*Leff); */
+}
+
+
+/*----------------------------------------------------------------------*/
+
+/* Routine for calculating drain capacitances. The draincap routine
+ * folds transistors larger than 10um */
+double SIM_power_draincap(double width,int nchannel,int stack) /* returns drain cap in Farads */
+//double width; /* um */
+//int nchannel; /* whether n or p-channel (boolean) */
+//int stack; /* number of transistors in series that are on */
+{
+ double Cdiffside,Cdiffarea,Coverlap,cap;
+
+ double overlapCap;
+ double swAreaUnderGate;
+ double area_peri;
+ double diffArea;
+ double diffPeri;
+ double l = 0.4 * LSCALE;
+
+
+ diffArea = l * width;
+ diffPeri = 2 * l + 2 * width;
+
+#if defined(Pdelta_w)
+ if(nchannel == 0) {
+ overlapCap = (width - 2 * Pdelta_w) * PCov;
+ swAreaUnderGate = (width - 2 * Pdelta_w) * PCjswA;
+ area_peri = ((diffArea * PCja)
+ + (diffPeri * PCjsw));
+
+ return(stack*(area_peri + overlapCap + swAreaUnderGate));
+ }
+ else {
+ overlapCap = (width - 2 * Ndelta_w) * NCov;
+ swAreaUnderGate = (width - 2 * Ndelta_w) * NCjswA;
+ area_peri = ((diffArea * NCja * LSCALE)
+ + (diffPeri * NCjsw * LSCALE));
+
+ return(stack*(area_peri + overlapCap + swAreaUnderGate));
+ }
+#endif
+
+ Cdiffside = (nchannel) ? PARM_Cndiffside : PARM_Cpdiffside;
+ Cdiffarea = (nchannel) ? PARM_Cndiffarea : PARM_Cpdiffarea;
+ Coverlap = (nchannel) ? (PARM_Cndiffovlp+PARM_Cnoxideovlp) :
+ (PARM_Cpdiffovlp+PARM_Cpoxideovlp);
+ /* calculate directly-connected (non-stacked) capacitance */
+ /* then add in capacitance due to stacking */
+ if (width >= 10) {
+ cap = 3.0*Leff*width/2.0*Cdiffarea + 6.0*Leff*Cdiffside +
+ width*Coverlap;
+ cap += (double)(stack-1)*(Leff*width*Cdiffarea +
+ 4.0*Leff*Cdiffside + 2.0*width*Coverlap);
+ } else {
+ cap = 3.0*Leff*width*Cdiffarea + (6.0*Leff+width)*Cdiffside +
+ width*Coverlap;
+ cap += (double)(stack-1)*(Leff*width*Cdiffarea +
+ 2.0*Leff*Cdiffside + 2.0*width*Coverlap);
+ }
+ return(cap * SCALE_T);
+}
+
+
+/*----------------------------------------------------------------------*/
+
+/* The following routines estimate the effective resistance of an
+ on transistor as described in the tech report. The first routine
+ gives the "switching" resistance, and the second gives the
+ "full-on" resistance */
+double SIM_power_transresswitch(double width,int nchannel,int stack) /* returns resistance in ohms */
+//double width; /* um */
+//int nchannel; /* whether n or p-channel (boolean) */
+//int stack; /* number of transistors in series */
+{
+ double restrans;
+ restrans = (nchannel) ? (Rnchannelstatic):
+ (Rpchannelstatic);
+ /* calculate resistance of stack - assume all but switching trans
+ have 0.8X the resistance since they are on throughout switching */
+ return((1.0+((stack-1.0)*0.8))*restrans/width);
+}
+
+
+/*----------------------------------------------------------------------*/
+
+double SIM_power_transreson(double width,int nchannel,int stack) /* returns resistance in ohms */
+//double width; /* um */
+//int nchannel; /* whether n or p-channel (boolean) */
+//int stack; /* number of transistors in series */
+{
+ double restrans;
+ restrans = (nchannel) ? Rnchannelon : Rpchannelon;
+
+ /* calculate resistance of stack. Unlike transres, we don't
+ multiply the stacked transistors by 0.8 */
+ return(stack*restrans/width);
+}
+
+
+/*----------------------------------------------------------------------*/
+
+/* This routine operates in reverse: given a resistance, it finds
+ * the transistor width that would have this R. It is used in the
+ * data wordline to estimate the wordline driver size. */
+double SIM_power_restowidth(double res,int nchannel) /* returns width in um */
+//double res; /* resistance in ohms */
+//int nchannel; /* whether N-channel or P-channel */
+{
+ double restrans;
+
+ restrans = (nchannel) ? Rnchannelon : Rpchannelon;
+
+ return(restrans/res);
+}
+
+
+/*----------------------------------------------------------------------*/
+
+double SIM_power_horowitz(double inputramptime,double tf,double vs1,double vs2,int rise)
+//double inputramptime, /* input rise time */
+ // tf, /* time constant of gate */
+ // vs1,vs2; /* threshold voltages */
+//int rise; /* whether INPUT rise or fall (boolean) */
+{
+ double a,b,td;
+
+ a = inputramptime/tf;
+ if (rise==RISE) {
+ b = 0.5;
+ td = tf*sqrt(fabs( log(vs1)*log(vs1)+2*a*b*(1.0-vs1))) +
+ tf*(log(vs1)-log(vs2));
+ } else {
+ b = 0.4;
+ td = tf*sqrt(fabs( log(1.0-vs1)*log(1.0-vs1)+2*a*b*(vs1))) +
+ tf*(log(1.0-vs1)-log(1.0-vs2));
+ }
+
+ return(td);
+}
+
+
+
+
+double SIM_power_driver_size(double driving_cap, double desiredrisetime)
+{
+ double nsize, psize;
+ double Rpdrive;
+
+ Rpdrive = desiredrisetime/(driving_cap*log(PARM_VSINV)*-1.0);
+ psize = SIM_power_restowidth(Rpdrive,PCH);
+ nsize = SIM_power_restowidth(Rpdrive,NCH);
+ if (psize > Wworddrivemax) {
+ psize = Wworddrivemax;
+ }
+ if (psize < 4.0 * LSCALE)
+ psize = 4.0 * LSCALE;
+
+ return (psize);
+}
+
+
diff --git a/src/mem/ruby/network/orion/power_ll.hh b/src/mem/ruby/network/orion/power_ll.hh
new file mode 100644
index 000000000..4cae89dcc
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_ll.hh
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef POWER_LL_H_
+#define POWER_LL_H_
+
+extern double SIM_power_driver_size(double driving_cap, double desiredrisetime);
+extern int SIM_power_init(void);
+extern double SIM_power_gatecap(double width, double wirelength) ;
+extern double SIM_power_gatecappass(double width, double wirelength);
+extern double SIM_power_draincap(double width, int nchannel, int stack);
+extern double SIM_power_transresswitch(double width, int nchannel, int stack);
+extern double SIM_power_transreson(double width,int nchannel,int stack);
+extern double SIM_power_restowidth(double res,int nchannel);
+extern double SIM_power_horowitz(double inputramptime,double tf,double vs1,double vs2,int rise);
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_router_init.cc b/src/mem/ruby/network/orion/power_router_init.cc
new file mode 100644
index 000000000..be58fbdbf
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_router_init.cc
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "power_router_init.hh"
+#include "power_array.hh"
+#include "power_arbiter.hh"
+#include "power_crossbar.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "power_utils.hh"
+
+/* -------------------------------------------------------------------------------------------- */
+// Set buffer parameters
+int buf_set_para(power_array_info *info, int is_fifo, unsigned n_read_port, unsigned n_write_port, unsigned n_entry, unsigned line_width, int outdrv)
+{
+ //general parameters
+ info->share_rw = 0;
+ info->read_ports = n_read_port;
+ info->write_ports = n_write_port;
+ info->n_set = n_entry;
+ info->blk_bits = line_width;
+ info->assoc = 1;
+ info->data_width = line_width;
+ info->data_end = PARM_data_end;
+
+ //no array subpartition
+ info->data_ndwl = 1;
+ info->data_ndbl = 1;
+ info->data_nspd = 1;
+
+ info->data_n_share_amp =1;
+
+ //MODEL parameters
+ if(is_fifo) {
+ info->row_dec_model = SIM_NO_MODEL;
+ info->row_dec_pre_model = SIM_NO_MODEL;
+ }
+ else {
+ info->row_dec_model = PARM_row_dec_model;
+ info->row_dec_pre_model = PARM_row_dec_pre_model;
+ }
+
+ info->data_wordline_model = PARM_wordline_model;
+ info->data_bitline_model = PARM_bitline_model;
+ info->data_bitline_pre_model = PARM_bitline_pre_model;
+ info->data_mem_model = PARM_mem_model;
+
+ if(PARM_data_end == 2)
+ info->data_amp_model = PARM_amp_model;
+ else
+ info->data_amp_model = SIM_NO_MODEL;
+ if(outdrv)
+ info->outdrv_model = PARM_outdrv_model;
+ else
+ info->outdrv_model = SIM_NO_MODEL;
+
+ info->data_colsel_pre_model = SIM_NO_MODEL;
+ info->col_dec_model = SIM_NO_MODEL;
+ info->col_dec_pre_model = SIM_NO_MODEL;
+ info->mux_model = SIM_NO_MODEL;
+
+ //no tag array
+
+ info->tag_wordline_model = SIM_NO_MODEL;
+ info->tag_bitline_model = SIM_NO_MODEL;
+ info->tag_bitline_pre_model = SIM_NO_MODEL;
+ info->tag_mem_model = SIM_NO_MODEL;
+ info->tag_attach_mem_model = SIM_NO_MODEL;
+ info->tag_amp_model = SIM_NO_MODEL;
+ info->tag_colsel_pre_model = SIM_NO_MODEL;
+ info->comp_model = SIM_NO_MODEL;
+ info->comp_pre_model = SIM_NO_MODEL;
+
+ info->write_policy = 0; //no dirty bit
+
+ //derived
+ if(info->data_width != 0){
+ info->n_item = info->blk_bits / info->data_width;
+ }
+ else{
+ info->eff_data_cols = info->blk_bits * info->assoc * info->data_nspd;
+ }
+
+ return 0;
+}
+/* -------------------------------------------------------------------------------------------- */
+
+
+/* --------------- Router init --------------------------------------*/
+
+
+int power_router_init(power_router *router, power_router_info *info)
+{
+ int outdrv;
+ double req_len = 0;
+
+ //general
+// info->n_in = PARM_in_port;
+ info->n_total_in = info->n_in;
+// info->n_out = PARM_out_port;
+ info->n_total_out = info->n_out;
+// info->flit_width = PARM_flit_width;
+
+ //vc
+// info->n_v_channel = MAX(PARM_v_channel, 1);
+// info->n_v_class = MAX(info->n_v_channel, PARM_v_class);
+
+ if(info->n_v_class > 1) {
+ info->in_share_buf = PARM_in_share_buf;
+ info->out_share_buf = PARM_out_share_buf;
+ info->in_share_switch = PARM_in_share_switch;
+ info->out_share_switch = PARM_out_share_switch;
+ }
+ else {
+ info->in_share_buf = 0;
+ info->out_share_buf = 0;
+ info->in_share_switch = 0;
+ info->out_share_switch = 0;
+ }
+
+ //xbar
+ info->crossbar_model = PARM_crossbar_model;
+ info->degree = PARM_crsbar_degree;
+ info->connect_type = PARM_connect_type;
+ info->trans_type = PARM_trans_type;
+ info->crossbar_in_len = PARM_crossbar_in_len;
+ info->crossbar_out_len = PARM_crossbar_out_len;
+
+ //input buffer
+ info->in_buf = PARM_in_buf;
+ outdrv = !info->in_share_buf && info->in_share_switch;
+ buf_set_para(&info->in_buf_info, 0, PARM_in_buf_rport, 1, PARM_in_buf_set, info->flit_width, outdrv);
+
+ //vc arbiter
+ if(info->n_v_class > 1) {
+ info->vc_in_arb_model = PARM_vc_in_arb_model;
+ info->vc_out_arb_model = PARM_vc_out_arb_model;
+ if(info->vc_in_arb_model == QUEUE_ARBITER) {
+ buf_set_para(&info->vc_in_arb_queue_info, 1, 1, 1, info->n_v_class, SIM_power_logtwo(info->n_v_class), 0);
+ info->vc_in_arb_ff_model = SIM_NO_MODEL;
+ }
+ else
+ info->vc_in_arb_ff_model = PARM_vc_in_arb_ff_model;
+
+ if(info->vc_out_arb_model == QUEUE_ARBITER) {
+ buf_set_para(&info->vc_out_arb_queue_info, 1, 1, 1, info->n_total_in - 1, SIM_power_logtwo(info->n_total_in - 1), 0);
+ info->vc_out_arb_ff_model = SIM_NO_MODEL;
+ }
+ else
+ info->vc_out_arb_ff_model = PARM_vc_out_arb_ff_model;
+ }
+ else {
+ info->vc_in_arb_model = SIM_NO_MODEL;
+ info->vc_in_arb_ff_model = SIM_NO_MODEL;
+ info->vc_out_arb_model = SIM_NO_MODEL;
+ info->vc_out_arb_ff_model = SIM_NO_MODEL;
+ }
+
+ //switch arbiter
+ if (info->n_in > 2) {
+ info->sw_in_arb_model = PARM_sw_in_arb_model;
+ info->sw_out_arb_model = PARM_sw_out_arb_model;
+ if(info->sw_in_arb_model == QUEUE_ARBITER) {
+ buf_set_para(&info->sw_in_arb_queue_info, 1, 1, 1, info->n_v_class, SIM_power_logtwo(info->n_v_class), 0);
+ info->sw_in_arb_ff_model = SIM_NO_MODEL;
+ }
+ else
+ info->sw_in_arb_ff_model = PARM_sw_in_arb_ff_model;
+
+ if(info->sw_out_arb_model == QUEUE_ARBITER) {
+ buf_set_para(&info->sw_out_arb_queue_info, 1, 1, 1, info->n_total_in - 1, SIM_power_logtwo(info->n_total_in - 1), 0);
+ info->sw_out_arb_ff_model = SIM_NO_MODEL;
+ }
+ else
+ info->sw_out_arb_ff_model = PARM_sw_out_arb_ff_model;
+ }
+ else {
+ info->sw_in_arb_model = SIM_NO_MODEL;
+ info->sw_in_arb_ff_model = SIM_NO_MODEL;
+ info->sw_out_arb_model = SIM_NO_MODEL;
+ info->sw_out_arb_ff_model = SIM_NO_MODEL;
+ }
+
+ if(info->in_buf) {
+ if(info->in_share_buf)
+ info->in_n_switch = info->in_buf_info.read_ports;
+ else if(info->in_share_switch)
+ info->in_n_switch = 1;
+ else
+ info->in_n_switch = info->n_v_class;
+ }
+ else
+ info->in_n_switch = 1;
+
+ info->n_switch_in = info->n_in * info->in_n_switch;
+
+ info->n_switch_out = info->n_out;
+
+ //-------- call initialize functions -----------
+
+ router->i_leakage = 0;
+
+ //initialize crossbar
+ power_crossbar_init(&router->crossbar, info->crossbar_model, info->n_switch_in, info->n_switch_out, info->flit_width, info->degree, info->connect_type, info->trans_type, info->crossbar_in_len, info->crossbar_out_len, &req_len);
+ router->i_leakage += router->crossbar.i_leakage;
+// printf("xbar_leak %g", router->crossbar.i_leakage);
+
+ //initialize input buffer
+ if(info->in_buf) {
+ power_array_init(&info->in_buf_info, &router->in_buf);
+ router->i_leakage += router->in_buf.i_leakage * info->n_in;
+// printf("buffer_leak %g", router->in_buf.i_leakage);
+ }
+// printf("initialize in buffer over\n");
+
+ //initialize vc arbiter
+ if(info->vc_in_arb_model)
+ power_arbiter_init(&router->vc_in_arb, info->vc_in_arb_model, info->vc_in_arb_ff_model, PARM_VC_per_MC, 0, &info->vc_in_arb_queue_info);
+
+ if(info->vc_out_arb_model)
+ power_arbiter_init(&router->vc_out_arb, info->vc_out_arb_model, info->vc_out_arb_ff_model, info->n_total_in - 1, req_len, &info->vc_out_arb_queue_info);
+
+ //initialize switch arbiter
+ if(info->sw_in_arb_model)
+ power_arbiter_init(&router->sw_in_arb, info->sw_in_arb_model, info->sw_in_arb_ff_model, info->n_v_class, 0, &info->sw_in_arb_queue_info);
+
+ if(info->sw_out_arb_model)
+ power_arbiter_init(&router->sw_out_arb, info->sw_out_arb_model, info->sw_out_arb_ff_model, info->n_total_in - 1, req_len, &info->sw_out_arb_queue_info);
+
+ return 0;
+}
diff --git a/src/mem/ruby/network/orion/power_router_init.hh b/src/mem/ruby/network/orion/power_router_init.hh
new file mode 100644
index 000000000..2d95cea0b
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_router_init.hh
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _POWER_ROUTER_INIT_H
+#define _POWER_ROUTER_INIT_H
+
+#include "power_array.hh"
+#include "power_arbiter.hh"
+#include "power_crossbar.hh"
+
+/* ------------ Models ------------------------ */
+/*typedef enum {
+ GENERIC_SEL = 1,
+ SEL_MAX_MODEL
+} power_sel_model;
+*/
+
+/* ------------ Misc --------------------------- */
+
+/*typedef struct {
+ int model;
+ unsigned width;
+ unsigned long long n_anyreq;
+ unsigned long long n_chgreq;
+ unsigned long long n_grant;
+ unsigned long long n_enc[MAX_SEL_LEVEL];
+ double e_anyreq;
+ double e_chgreq;
+ double e_grant;
+ double e_enc[MAX_SEL_LEVEL];
+} power_sel;
+*/
+
+/* --------------- Loading --------------- */
+typedef enum {
+ ACTUAL_LOADING =1,
+ HALF_LOADING,
+ MAX_LOADING
+}loading;
+
+/* ----------------- Router --------------- */
+
+typedef struct {
+ power_crossbar crossbar;
+ power_array in_buf;
+ power_arbiter vc_in_arb;
+ power_arbiter vc_out_arb;
+ power_arbiter sw_in_arb;
+ power_arbiter sw_out_arb;
+ double i_leakage;
+} power_router;
+
+typedef struct {
+ //general
+ unsigned n_in;
+ unsigned n_out;
+ unsigned flit_width;
+ //vc
+ unsigned n_v_channel;
+ unsigned n_v_class;
+ int in_share_buf;
+ int out_share_buf;
+ int in_share_switch;
+ int out_share_switch;
+ //xbar
+ int crossbar_model;
+ int degree;
+ int connect_type;
+ int trans_type;
+ double crossbar_in_len;
+ double crossbar_out_len;
+
+ int in_buf;
+
+ //buffer
+ power_array_info in_buf_info;
+ unsigned pipe_depth;
+ //arbiter
+ int vc_in_arb_model;
+ int vc_out_arb_model;
+ int vc_in_arb_ff_model;
+ int vc_out_arb_ff_model;
+ int sw_in_arb_model;
+ int sw_out_arb_model;
+ int sw_in_arb_ff_model;
+ int sw_out_arb_ff_model;
+
+ power_array_info vc_in_arb_queue_info;
+ power_array_info vc_out_arb_queue_info;
+ power_array_info sw_in_arb_queue_info;
+ power_array_info sw_out_arb_queue_info;
+ //derived
+ unsigned n_total_in;
+ unsigned n_total_out;
+ unsigned in_n_switch;
+ unsigned n_switch_in;
+ unsigned n_switch_out;
+} power_router_info;
+
+extern int power_router_init(power_router *router, power_router_info *info);
+#endif
diff --git a/src/mem/ruby/network/orion/power_static.cc b/src/mem/ruby/network/orion/power_static.cc
new file mode 100644
index 000000000..c0ae394a6
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_static.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include "power_static.hh"
+
+#if (PARM_TECH_POINT == 18)
+double NMOS_TAB[1] = {20.5e-9};
+double PMOS_TAB[1] = {9.2e-9};
+double NAND2_TAB[4] = {6.4e-10, 20.4e-9, 12.6e-9, 18.4e-9};
+double NOR2_TAB[4] ={40.9e-9, 8.32e-9, 9.2e-9, 2.3e-10};
+#elif (PARM_TECH_POINT == 10)
+double NMOS_TAB[1] = {22.7e-9};
+double PMOS_TAB[1] = {18.0e-9};
+double NAND2_TAB[4] = {1.2e-9, 22.6e-9, 11.4e-9, 35.9e-9};
+double NOR2_TAB[4] ={45.1e-9, 11.5e-9, 17.9e-9, 1.8e-9};
+#elif (PARM_TECH_POINT == 7)
+double NMOS_TAB[1] = {118.1e-9};
+double PMOS_TAB[1] = {135.2e-9};
+double NAND2_TAB[4] = {19.7e-9, 115.3e-9, 83.0e-9, 267.6e-9};
+double NOR2_TAB[4] ={232.4e-9, 79.6e-9, 127.9e-9, 12.3e-9};
+#endif
diff --git a/src/mem/ruby/network/orion/power_static.hh b/src/mem/ruby/network/orion/power_static.hh
new file mode 100644
index 000000000..6bc58ca01
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_static.hh
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _POWER_STATIC_H
+#define _POWER_STATIC_H
+
+#include "parm_technology.hh"
+
+extern double NMOS_TAB[1];
+extern double PMOS_TAB[1];
+extern double NAND2_TAB[4];
+extern double NOR2_TAB[4];
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_utils.cc b/src/mem/ruby/network/orion/power_utils.cc
new file mode 100644
index 000000000..1f592fff0
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_utils.cc
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#include <stdio.h>
+#include "parm_technology.hh"
+#include "power_utils.hh"
+#include <assert.h>
+#include <math.h>
+
+/* ----------- from SIM_power_util.c ------------ */
+
+/* Hamming distance table */
+static char h_tab[256] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
+
+
+static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int new_val, unsigned long int mask )
+{
+ /* old slow code, I don't understand the new fast code though */
+ /* unsigned long int dist;
+ unsigned Hamming = 0;
+
+ dist = ( old_val ^ new_val ) & mask;
+ mask = (mask >> 1) + 1;
+
+ while ( mask ) {
+ if ( mask & dist ) Hamming ++;
+ mask = mask >> 1;
+ }
+
+ return Hamming; */
+
+#define TWO(k) (BIGONE << (k))
+#define CYCL(k) (BIGNONE/(1 + (TWO(TWO(k)))))
+#define BSUM(x,k) ((x)+=(x) >> TWO(k), (x) &= CYCL(k))
+ unsigned long int x;
+
+ x = (old_val ^ new_val) & mask;
+ x = (x & CYCL(0)) + ((x>>TWO(0)) & CYCL(0));
+ x = (x & CYCL(1)) + ((x>>TWO(1)) & CYCL(1));
+ BSUM(x,2);
+ BSUM(x,3);
+ BSUM(x,4);
+ BSUM(x,5);
+
+ return x;
+}
+
+
+int SIM_power_init(void)
+{
+ unsigned i;
+
+ /* initialize Hamming distance table */
+ for (i = 0; i < 256; i++)
+ h_tab[i] = SIM_power_Hamming_slow(i, 0, 0xFF);
+
+ return 0;
+}
+
+
+/* assume unsigned long int is unsigned64_t */
+unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask)
+{
+ union {
+ unsigned long int x;
+ char id[8];
+ } u;
+ unsigned rval;
+
+ u.x = (old_val ^ new_val) & mask;
+
+ rval = h_tab[u.id[0]];
+ rval += h_tab[u.id[1]];
+ rval += h_tab[u.id[2]];
+ rval += h_tab[u.id[3]];
+ rval += h_tab[u.id[4]];
+ rval += h_tab[u.id[5]];
+ rval += h_tab[u.id[6]];
+ rval += h_tab[u.id[7]];
+
+ return rval;
+}
+
+
+unsigned SIM_power_Hamming_group(unsigned long int d1_new, unsigned long int d1_old, unsigned long int d2_new, unsigned long int d2_old, unsigned width, unsigned n_grp)
+{
+ unsigned rval = 0;
+ unsigned long int g1_new, g1_old, g2_new, g2_old, mask;
+
+ mask = HAMM_MASK(width);
+
+ while (n_grp--) {
+ g1_new = d1_new & mask;
+ g1_old = d1_old & mask;
+ g2_new = d2_new & mask;
+ g2_old = d2_old & mask;
+
+ if (g1_new != g1_old || g2_new != g2_old)
+ rval ++;
+
+ d1_new >>= width;
+ d1_old >>= width;
+ d2_new >>= width;
+ d2_old >>= width;
+ }
+
+ return rval;
+}
+
+/* ---------------------------------------------- */
+
+/* ----------------------------------------------- */
+
+
+
+
+double logtwo(double x)
+{
+ assert(x > 0);
+ return log10(x)/log10(2);
+}
+
+unsigned SIM_power_logtwo(unsigned long int x)
+{
+ unsigned rval = 0;
+
+ while (x >> rval && rval < sizeof(unsigned long int) << 3) rval++;
+ if (x == (BIGONE << rval - 1)) rval--;
+
+ return rval;
+}
+
diff --git a/src/mem/ruby/network/orion/power_utils.hh b/src/mem/ruby/network/orion/power_utils.hh
new file mode 100644
index 000000000..59123c1f7
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_utils.hh
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef _POWER_UTILS_H
+#define _POWER_UTILS_H
+extern unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask);
+extern double logtwo(double x);
+extern unsigned SIM_power_logtwo(unsigned long int x);
+
+#endif
diff --git a/src/mem/ruby/network/simple/Network_Files/GarnetFileMaker.py b/src/mem/ruby/network/simple/Network_Files/GarnetFileMaker.py
new file mode 100644
index 000000000..b47bb0161
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/GarnetFileMaker.py
@@ -0,0 +1,45 @@
+#!/s/std/bin/python
+import sys, os, string, re, math
+
+rows = 0
+cols =0
+
+if len(sys.argv) == 3:
+ rows = int(sys.argv[1])
+ cols = int(sys.argv[2])
+else:
+ sys.stderr.write("usage : GarnetFileMaker.py <rows> <cols> \n\n")
+
+banks = rows*cols
+bank = 0
+while bank < banks:
+ sys.stdout.write("ext_node:L1Cache:%d int_node:%d link_latency:1 \n" % (bank, bank))
+ sys.stdout.write("ext_node:L2Cache:%d int_node:%d link_latency:1 \n" % (bank, bank))
+ bank += 1
+
+sys.stdout.write("\n")
+
+col = 0
+while col < cols:
+ row = 1
+ bank = col*rows
+ while row < rows:
+ sys.stdout.write("int_node:%d int_node:%d link_latency:1 link_weight:1\n" % (bank, bank+1))
+ bank += 1
+ row += 1
+ sys.stdout.write("\n")
+ col += 1
+
+sys.stdout.write("\n")
+
+row = 0
+while row < rows:
+ col = 1
+ bank = row
+ while col < cols:
+ sys.stdout.write("int_node:%d int_node:%d link_latency:1 link_weight:2\n" % (bank, rows+bank))
+ bank += rows
+ col += 1
+ sys.stdout.write("\n")
+ row += 1
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt
new file mode 100644
index 000000000..1304a5e0a
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt
@@ -0,0 +1,78 @@
+
+processors:16
+procs_per_chip:16
+L2banks:16
+memories:16
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:8 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:9 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:10 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:11 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:12 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:13 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:14 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:15 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:8 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:9 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:10 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:11 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:12 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:13 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:14 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:15 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:Directory:0 int_node:0 link_latency:20 bw_multiplier:80
+ext_node:Directory:1 int_node:1 link_latency:20 bw_multiplier:80
+ext_node:Directory:2 int_node:2 link_latency:20 bw_multiplier:80
+ext_node:Directory:3 int_node:3 link_latency:20 bw_multiplier:80
+ext_node:Directory:4 int_node:4 link_latency:20 bw_multiplier:80
+ext_node:Directory:5 int_node:5 link_latency:20 bw_multiplier:80
+ext_node:Directory:6 int_node:6 link_latency:20 bw_multiplier:80
+ext_node:Directory:7 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:8 int_node:8 link_latency:20 bw_multiplier:80
+ext_node:Directory:9 int_node:9 link_latency:20 bw_multiplier:80
+ext_node:Directory:10 int_node:10 link_latency:20 bw_multiplier:80
+ext_node:Directory:11 int_node:11 link_latency:20 bw_multiplier:80
+ext_node:Directory:12 int_node:12 link_latency:20 bw_multiplier:80
+ext_node:Directory:13 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:14 int_node:14 link_latency:20 bw_multiplier:80
+ext_node:Directory:15 int_node:15 link_latency:20 bw_multiplier:80
+int_node:0 int_node:1 link_latency:1 bw_multiplier:72
+int_node:1 int_node:2 link_latency:1 bw_multiplier:72
+int_node:2 int_node:3 link_latency:1 bw_multiplier:72
+int_node:0 int_node:4 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:1 int_node:5 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:2 int_node:6 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:3 int_node:7 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:4 int_node:5 link_latency:1 bw_multiplier:72
+int_node:5 int_node:6 link_latency:1 bw_multiplier:72
+int_node:6 int_node:7 link_latency:1 bw_multiplier:72
+int_node:4 int_node:8 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:5 int_node:9 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:6 int_node:10 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:7 int_node:11 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:8 int_node:9 link_latency:1 bw_multiplier:72
+int_node:9 int_node:10 link_latency:1 bw_multiplier:72
+int_node:10 int_node:11 link_latency:1 bw_multiplier:72
+int_node:8 int_node:12 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:9 int_node:13 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:10 int_node:14 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:11 int_node:15 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:12 int_node:13 link_latency:1 bw_multiplier:72
+int_node:13 int_node:14 link_latency:1 bw_multiplier:72
+int_node:14 int_node:15 link_latency:1 bw_multiplier:72
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-4.txt
new file mode 100644
index 000000000..329156a33
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-4.txt
@@ -0,0 +1,56 @@
+
+processors:16
+procs_per_chip:16
+L2banks:16
+memories:4
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:8 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:9 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:10 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:11 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:12 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:13 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:14 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:15 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:8 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:9 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:10 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:11 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:12 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:13 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:14 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:15 int_node:7 link_latency:1 bw_multiplier:72
+int_node:11 int_node:12 link_latency:1 bw_multiplier:72
+int_node:8 int_node:13 link_latency:1 bw_multiplier:72
+int_node:0 int_node:8 link_latency:1 bw_multiplier:72
+int_node:4 int_node:8 link_latency:1 bw_multiplier:72
+int_node:1 int_node:9 link_latency:1 bw_multiplier:72
+int_node:5 int_node:9 link_latency:1 bw_multiplier:72
+int_node:2 int_node:10 link_latency:1 bw_multiplier:72
+int_node:6 int_node:10 link_latency:1 bw_multiplier:72
+int_node:3 int_node:11 link_latency:1 bw_multiplier:72
+int_node:7 int_node:11 link_latency:1 bw_multiplier:72
+int_node:8 int_node:9 link_latency:1 bw_multiplier:72
+int_node:9 int_node:10 link_latency:1 bw_multiplier:72
+int_node:10 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:Directory:0 int_node:12 link_latency:20 bw_multiplier:80
+ext_node:Directory:1 int_node:12 link_latency:20 bw_multiplier:80
+ext_node:Directory:2 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:3 int_node:13 link_latency:20 bw_multiplier:80
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-8.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-8.txt
new file mode 100644
index 000000000..7b714cdc1
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-8.txt
@@ -0,0 +1,61 @@
+
+processors:16
+procs_per_chip:16
+L2banks:16
+memories:8
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:8 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:9 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:10 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:11 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:12 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:13 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:14 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:15 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:8 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:9 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:10 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:11 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:12 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:13 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:14 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:15 int_node:7 link_latency:1 bw_multiplier:72
+int_node:12 int_node:13 link_latency:20 bw_multiplier:10
+int_node:9 int_node:12 link_latency:1 bw_multiplier:72
+int_node:10 int_node:12 link_latency:1 bw_multiplier:72
+int_node:0 int_node:8 link_latency:1 bw_multiplier:72
+int_node:4 int_node:8 link_latency:1 bw_multiplier:72
+int_node:1 int_node:9 link_latency:1 bw_multiplier:72
+int_node:5 int_node:9 link_latency:1 bw_multiplier:72
+int_node:2 int_node:10 link_latency:1 bw_multiplier:72
+int_node:6 int_node:10 link_latency:1 bw_multiplier:72
+int_node:3 int_node:11 link_latency:1 bw_multiplier:72
+int_node:7 int_node:11 link_latency:1 bw_multiplier:72
+int_node:8 int_node:9 link_latency:1 bw_multiplier:72
+int_node:9 int_node:10 link_latency:1 bw_multiplier:72
+int_node:10 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:Directory:0 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:1 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:2 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:3 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:4 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:5 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:6 int_node:13 link_latency:20 bw_multiplier:80
+ext_node:Directory:7 int_node:13 link_latency:20 bw_multiplier:80
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-1_L2Banks-16_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-1_L2Banks-16_Memories-16.txt
new file mode 100644
index 000000000..b1a262d42
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-1_L2Banks-16_Memories-16.txt
@@ -0,0 +1,190 @@
+
+processors:16
+procs_per_chip:1
+L2banks:16
+memories:16
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:0 link_latency:40 bw_multiplier:10
+int_node:0 int_node:1 link_latency:40 bw_multiplier:16
+int_node:0 int_node:2 link_latency:40 bw_multiplier:16
+int_node:0 int_node:3 link_latency:40 bw_multiplier:16
+int_node:0 int_node:4 link_latency:40 bw_multiplier:16
+int_node:0 int_node:5 link_latency:40 bw_multiplier:16
+int_node:0 int_node:6 link_latency:40 bw_multiplier:16
+int_node:0 int_node:7 link_latency:40 bw_multiplier:16
+int_node:0 int_node:8 link_latency:40 bw_multiplier:16
+int_node:0 int_node:9 link_latency:40 bw_multiplier:16
+int_node:0 int_node:10 link_latency:40 bw_multiplier:16
+int_node:0 int_node:11 link_latency:40 bw_multiplier:16
+int_node:0 int_node:12 link_latency:40 bw_multiplier:16
+int_node:0 int_node:13 link_latency:40 bw_multiplier:16
+int_node:0 int_node:14 link_latency:40 bw_multiplier:16
+int_node:0 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:1 link_latency:40 bw_multiplier:10
+int_node:1 int_node:2 link_latency:40 bw_multiplier:16
+int_node:1 int_node:3 link_latency:40 bw_multiplier:16
+int_node:1 int_node:4 link_latency:40 bw_multiplier:16
+int_node:1 int_node:5 link_latency:40 bw_multiplier:16
+int_node:1 int_node:6 link_latency:40 bw_multiplier:16
+int_node:1 int_node:7 link_latency:40 bw_multiplier:16
+int_node:1 int_node:8 link_latency:40 bw_multiplier:16
+int_node:1 int_node:9 link_latency:40 bw_multiplier:16
+int_node:1 int_node:10 link_latency:40 bw_multiplier:16
+int_node:1 int_node:11 link_latency:40 bw_multiplier:16
+int_node:1 int_node:12 link_latency:40 bw_multiplier:16
+int_node:1 int_node:13 link_latency:40 bw_multiplier:16
+int_node:1 int_node:14 link_latency:40 bw_multiplier:16
+int_node:1 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:Directory:2 int_node:2 link_latency:40 bw_multiplier:10
+int_node:2 int_node:3 link_latency:40 bw_multiplier:16
+int_node:2 int_node:4 link_latency:40 bw_multiplier:16
+int_node:2 int_node:5 link_latency:40 bw_multiplier:16
+int_node:2 int_node:6 link_latency:40 bw_multiplier:16
+int_node:2 int_node:7 link_latency:40 bw_multiplier:16
+int_node:2 int_node:8 link_latency:40 bw_multiplier:16
+int_node:2 int_node:9 link_latency:40 bw_multiplier:16
+int_node:2 int_node:10 link_latency:40 bw_multiplier:16
+int_node:2 int_node:11 link_latency:40 bw_multiplier:16
+int_node:2 int_node:12 link_latency:40 bw_multiplier:16
+int_node:2 int_node:13 link_latency:40 bw_multiplier:16
+int_node:2 int_node:14 link_latency:40 bw_multiplier:16
+int_node:2 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:3 int_node:3 link_latency:40 bw_multiplier:10
+int_node:3 int_node:4 link_latency:40 bw_multiplier:16
+int_node:3 int_node:5 link_latency:40 bw_multiplier:16
+int_node:3 int_node:6 link_latency:40 bw_multiplier:16
+int_node:3 int_node:7 link_latency:40 bw_multiplier:16
+int_node:3 int_node:8 link_latency:40 bw_multiplier:16
+int_node:3 int_node:9 link_latency:40 bw_multiplier:16
+int_node:3 int_node:10 link_latency:40 bw_multiplier:16
+int_node:3 int_node:11 link_latency:40 bw_multiplier:16
+int_node:3 int_node:12 link_latency:40 bw_multiplier:16
+int_node:3 int_node:13 link_latency:40 bw_multiplier:16
+int_node:3 int_node:14 link_latency:40 bw_multiplier:16
+int_node:3 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:4 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:Directory:4 int_node:4 link_latency:40 bw_multiplier:10
+int_node:4 int_node:5 link_latency:40 bw_multiplier:16
+int_node:4 int_node:6 link_latency:40 bw_multiplier:16
+int_node:4 int_node:7 link_latency:40 bw_multiplier:16
+int_node:4 int_node:8 link_latency:40 bw_multiplier:16
+int_node:4 int_node:9 link_latency:40 bw_multiplier:16
+int_node:4 int_node:10 link_latency:40 bw_multiplier:16
+int_node:4 int_node:11 link_latency:40 bw_multiplier:16
+int_node:4 int_node:12 link_latency:40 bw_multiplier:16
+int_node:4 int_node:13 link_latency:40 bw_multiplier:16
+int_node:4 int_node:14 link_latency:40 bw_multiplier:16
+int_node:4 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:5 int_node:5 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:5 link_latency:1 bw_multiplier:64
+ext_node:Directory:5 int_node:5 link_latency:40 bw_multiplier:10
+int_node:5 int_node:6 link_latency:40 bw_multiplier:16
+int_node:5 int_node:7 link_latency:40 bw_multiplier:16
+int_node:5 int_node:8 link_latency:40 bw_multiplier:16
+int_node:5 int_node:9 link_latency:40 bw_multiplier:16
+int_node:5 int_node:10 link_latency:40 bw_multiplier:16
+int_node:5 int_node:11 link_latency:40 bw_multiplier:16
+int_node:5 int_node:12 link_latency:40 bw_multiplier:16
+int_node:5 int_node:13 link_latency:40 bw_multiplier:16
+int_node:5 int_node:14 link_latency:40 bw_multiplier:16
+int_node:5 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:6 int_node:6 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:6 link_latency:1 bw_multiplier:64
+ext_node:Directory:6 int_node:6 link_latency:40 bw_multiplier:10
+int_node:6 int_node:7 link_latency:40 bw_multiplier:16
+int_node:6 int_node:8 link_latency:40 bw_multiplier:16
+int_node:6 int_node:9 link_latency:40 bw_multiplier:16
+int_node:6 int_node:10 link_latency:40 bw_multiplier:16
+int_node:6 int_node:11 link_latency:40 bw_multiplier:16
+int_node:6 int_node:12 link_latency:40 bw_multiplier:16
+int_node:6 int_node:13 link_latency:40 bw_multiplier:16
+int_node:6 int_node:14 link_latency:40 bw_multiplier:16
+int_node:6 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:7 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:Directory:7 int_node:7 link_latency:40 bw_multiplier:10
+int_node:7 int_node:8 link_latency:40 bw_multiplier:16
+int_node:7 int_node:9 link_latency:40 bw_multiplier:16
+int_node:7 int_node:10 link_latency:40 bw_multiplier:16
+int_node:7 int_node:11 link_latency:40 bw_multiplier:16
+int_node:7 int_node:12 link_latency:40 bw_multiplier:16
+int_node:7 int_node:13 link_latency:40 bw_multiplier:16
+int_node:7 int_node:14 link_latency:40 bw_multiplier:16
+int_node:7 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:8 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:Directory:8 int_node:8 link_latency:40 bw_multiplier:10
+int_node:8 int_node:9 link_latency:40 bw_multiplier:16
+int_node:8 int_node:10 link_latency:40 bw_multiplier:16
+int_node:8 int_node:11 link_latency:40 bw_multiplier:16
+int_node:8 int_node:12 link_latency:40 bw_multiplier:16
+int_node:8 int_node:13 link_latency:40 bw_multiplier:16
+int_node:8 int_node:14 link_latency:40 bw_multiplier:16
+int_node:8 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:9 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:Directory:9 int_node:9 link_latency:40 bw_multiplier:10
+int_node:9 int_node:10 link_latency:40 bw_multiplier:16
+int_node:9 int_node:11 link_latency:40 bw_multiplier:16
+int_node:9 int_node:12 link_latency:40 bw_multiplier:16
+int_node:9 int_node:13 link_latency:40 bw_multiplier:16
+int_node:9 int_node:14 link_latency:40 bw_multiplier:16
+int_node:9 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:10 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:Directory:10 int_node:10 link_latency:40 bw_multiplier:10
+int_node:10 int_node:11 link_latency:40 bw_multiplier:16
+int_node:10 int_node:12 link_latency:40 bw_multiplier:16
+int_node:10 int_node:13 link_latency:40 bw_multiplier:16
+int_node:10 int_node:14 link_latency:40 bw_multiplier:16
+int_node:10 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:11 int_node:11 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11 int_node:11 link_latency:1 bw_multiplier:64
+ext_node:Directory:11 int_node:11 link_latency:40 bw_multiplier:10
+int_node:11 int_node:12 link_latency:40 bw_multiplier:16
+int_node:11 int_node:13 link_latency:40 bw_multiplier:16
+int_node:11 int_node:14 link_latency:40 bw_multiplier:16
+int_node:11 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:12 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:Directory:12 int_node:12 link_latency:40 bw_multiplier:10
+int_node:12 int_node:13 link_latency:40 bw_multiplier:16
+int_node:12 int_node:14 link_latency:40 bw_multiplier:16
+int_node:12 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:13 int_node:13 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13 int_node:13 link_latency:1 bw_multiplier:64
+ext_node:Directory:13 int_node:13 link_latency:40 bw_multiplier:10
+int_node:13 int_node:14 link_latency:40 bw_multiplier:16
+int_node:13 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:14 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:Directory:14 int_node:14 link_latency:40 bw_multiplier:10
+int_node:14 int_node:15 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:15 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:Directory:15 int_node:15 link_latency:40 bw_multiplier:10
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt
new file mode 100644
index 000000000..3e0030c43
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt
@@ -0,0 +1,90 @@
+
+processors:16
+procs_per_chip:4
+L2banks:16
+memories:16
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:1 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:2 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:3 int_node:6 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:2 link_latency:1 bw_multiplier:16
+int_node:5 int_node:4 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:20 bw_multiplier:10
+
+int_node:5 int_node:12 link_latency:20 bw_multiplier:10
+int_node:5 int_node:19 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:Directory:4 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:5 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:6 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:7 int_node:13 link_latency:20 bw_multiplier:10
+int_node:7 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:9 link_latency:1 bw_multiplier:16
+int_node:12 int_node:11 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:20 bw_multiplier:10
+
+int_node:12 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:8 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:Directory:8 int_node:20 link_latency:20 bw_multiplier:10
+ext_node:Directory:9 int_node:20 link_latency:20 bw_multiplier:10
+ext_node:Directory:10 int_node:20 link_latency:20 bw_multiplier:10
+ext_node:Directory:11 int_node:20 link_latency:20 bw_multiplier:10
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:16 link_latency:1 bw_multiplier:16
+int_node:19 int_node:18 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:20 bw_multiplier:10
+
+int_node:19 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:12 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:24 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15 int_node:24 link_latency:1 bw_multiplier:64
+ext_node:Directory:12 int_node:27 link_latency:20 bw_multiplier:10
+ext_node:Directory:13 int_node:27 link_latency:20 bw_multiplier:10
+ext_node:Directory:14 int_node:27 link_latency:20 bw_multiplier:10
+ext_node:Directory:15 int_node:27 link_latency:20 bw_multiplier:10
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:23 link_latency:1 bw_multiplier:16
+int_node:26 int_node:25 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:20 bw_multiplier:10
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-4.txt
new file mode 100644
index 000000000..b7ef403ff
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-4.txt
@@ -0,0 +1,78 @@
+
+processors:16
+procs_per_chip:4
+L2banks:16
+memories:4
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:6 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:2 link_latency:1 bw_multiplier:16
+int_node:5 int_node:4 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:20 bw_multiplier:10
+
+int_node:5 int_node:12 link_latency:20 bw_multiplier:10
+int_node:5 int_node:19 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:13 link_latency:20 bw_multiplier:10
+int_node:7 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:9 link_latency:1 bw_multiplier:16
+int_node:12 int_node:11 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:20 bw_multiplier:10
+
+int_node:12 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:8 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:Directory:2 int_node:20 link_latency:20 bw_multiplier:10
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:16 link_latency:1 bw_multiplier:16
+int_node:19 int_node:18 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:20 bw_multiplier:10
+
+int_node:19 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:12 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:24 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15 int_node:24 link_latency:1 bw_multiplier:64
+ext_node:Directory:3 int_node:27 link_latency:20 bw_multiplier:10
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:23 link_latency:1 bw_multiplier:16
+int_node:26 int_node:25 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:20 bw_multiplier:10
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-32_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-32_Memories-4.txt
new file mode 100644
index 000000000..4fbcfb467
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-32_Memories-4.txt
@@ -0,0 +1,123 @@
+
+processors:16
+procs_per_chip:4
+L2banks:32
+memories:4
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0:bank:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0:bank:1 int_node:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:1:bank:0 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1:bank:1 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2:bank:0 int_node:6 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2:bank:1 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3:bank:0 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3:bank:1 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:5 link_latency:40 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:0 int_node:2 link_latency:1 bw_multiplier:16
+int_node:1 int_node:3 link_latency:1 bw_multiplier:16
+int_node:2 int_node:4 link_latency:1 bw_multiplier:16
+int_node:2 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:5 link_latency:1 bw_multiplier:16
+int_node:4 int_node:6 link_latency:1 bw_multiplier:16
+int_node:4 int_node:5 link_latency:1 bw_multiplier:16
+int_node:5 int_node:7 link_latency:1 bw_multiplier:16
+int_node:6 int_node:8 link_latency:1 bw_multiplier:16
+int_node:6 int_node:7 link_latency:1 bw_multiplier:16
+int_node:7 int_node:9 link_latency:1 bw_multiplier:16
+int_node:8 int_node:9 link_latency:1 bw_multiplier:16
+
+int_node:5 int_node:15 link_latency:40 bw_multiplier:10
+int_node:5 int_node:25 link_latency:40 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:11 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:18 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:19 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4:bank:0 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4:bank:1 int_node:11 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5:bank:0 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5:bank:1 int_node:13 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6:bank:0 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6:bank:1 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7:bank:0 int_node:18 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7:bank:1 int_node:19 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:15 link_latency:40 bw_multiplier:10
+int_node:10 int_node:11 link_latency:1 bw_multiplier:16
+int_node:10 int_node:12 link_latency:1 bw_multiplier:16
+int_node:11 int_node:13 link_latency:1 bw_multiplier:16
+int_node:12 int_node:14 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:15 link_latency:1 bw_multiplier:16
+int_node:14 int_node:16 link_latency:1 bw_multiplier:16
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:17 link_latency:1 bw_multiplier:16
+int_node:16 int_node:18 link_latency:1 bw_multiplier:16
+int_node:16 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:19 link_latency:1 bw_multiplier:16
+int_node:18 int_node:19 link_latency:1 bw_multiplier:16
+
+int_node:15 int_node:35 link_latency:40 bw_multiplier:10
+
+ext_node:L1Cache:8 int_node:20 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:28 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:29 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8:bank:0 int_node:20 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8:bank:1 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9:bank:0 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9:bank:1 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10:bank:0 int_node:26 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10:bank:1 int_node:27 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11:bank:0 int_node:28 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11:bank:1 int_node:29 link_latency:1 bw_multiplier:64
+ext_node:Directory:2 int_node:25 link_latency:40 bw_multiplier:10
+int_node:20 int_node:21 link_latency:1 bw_multiplier:16
+int_node:20 int_node:22 link_latency:1 bw_multiplier:16
+int_node:21 int_node:23 link_latency:1 bw_multiplier:16
+int_node:22 int_node:24 link_latency:1 bw_multiplier:16
+int_node:22 int_node:23 link_latency:1 bw_multiplier:16
+int_node:23 int_node:25 link_latency:1 bw_multiplier:16
+int_node:24 int_node:26 link_latency:1 bw_multiplier:16
+int_node:24 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:27 link_latency:1 bw_multiplier:16
+int_node:26 int_node:28 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:1 bw_multiplier:16
+int_node:27 int_node:29 link_latency:1 bw_multiplier:16
+int_node:28 int_node:29 link_latency:1 bw_multiplier:16
+
+int_node:25 int_node:35 link_latency:40 bw_multiplier:10
+
+ext_node:L1Cache:12 int_node:30 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:31 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:38 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:39 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12:bank:0 int_node:30 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12:bank:1 int_node:31 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13:bank:0 int_node:32 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13:bank:1 int_node:33 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14:bank:0 int_node:36 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14:bank:1 int_node:37 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15:bank:0 int_node:38 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15:bank:1 int_node:39 link_latency:1 bw_multiplier:64
+ext_node:Directory:3 int_node:35 link_latency:40 bw_multiplier:10
+int_node:30 int_node:31 link_latency:1 bw_multiplier:16
+int_node:30 int_node:32 link_latency:1 bw_multiplier:16
+int_node:31 int_node:33 link_latency:1 bw_multiplier:16
+int_node:32 int_node:34 link_latency:1 bw_multiplier:16
+int_node:32 int_node:33 link_latency:1 bw_multiplier:16
+int_node:33 int_node:35 link_latency:1 bw_multiplier:16
+int_node:34 int_node:36 link_latency:1 bw_multiplier:16
+int_node:34 int_node:35 link_latency:1 bw_multiplier:16
+int_node:35 int_node:37 link_latency:1 bw_multiplier:16
+int_node:36 int_node:38 link_latency:1 bw_multiplier:16
+int_node:36 int_node:37 link_latency:1 bw_multiplier:16
+int_node:37 int_node:39 link_latency:1 bw_multiplier:16
+int_node:38 int_node:39 link_latency:1 bw_multiplier:16
+
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-16.txt
new file mode 100644
index 000000000..fc1cef27a
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-16.txt
@@ -0,0 +1,78 @@
+
+processors:16
+procs_per_chip:4
+L2banks:4
+memories:16
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:5 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:1 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:2 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:3 int_node:6 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:2 link_latency:1 bw_multiplier:16
+int_node:5 int_node:4 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:20 bw_multiplier:10
+
+int_node:5 int_node:12 link_latency:20 bw_multiplier:10
+int_node:5 int_node:19 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:Directory:4 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:5 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:6 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:7 int_node:13 link_latency:20 bw_multiplier:10
+int_node:7 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:9 link_latency:1 bw_multiplier:16
+int_node:12 int_node:11 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:20 bw_multiplier:10
+
+int_node:12 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:8 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:19 link_latency:1 bw_multiplier:64
+ext_node:Directory:8 int_node:20 link_latency:20 bw_multiplier:10
+ext_node:Directory:9 int_node:20 link_latency:20 bw_multiplier:10
+ext_node:Directory:10 int_node:20 link_latency:20 bw_multiplier:10
+ext_node:Directory:11 int_node:20 link_latency:20 bw_multiplier:10
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:16 link_latency:1 bw_multiplier:16
+int_node:19 int_node:18 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:20 bw_multiplier:10
+
+int_node:19 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:12 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:24 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:26 link_latency:1 bw_multiplier:64
+ext_node:Directory:12 int_node:27 link_latency:20 bw_multiplier:10
+ext_node:Directory:13 int_node:27 link_latency:20 bw_multiplier:10
+ext_node:Directory:14 int_node:27 link_latency:20 bw_multiplier:10
+ext_node:Directory:15 int_node:27 link_latency:20 bw_multiplier:10
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:23 link_latency:1 bw_multiplier:16
+int_node:26 int_node:25 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:20 bw_multiplier:10
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-4.txt
new file mode 100644
index 000000000..3b71e62a5
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-16_ProcsPerChip-4_L2Banks-4_Memories-4.txt
@@ -0,0 +1,66 @@
+
+processors:16
+procs_per_chip:4
+L2banks:4
+memories:4
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:5 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:6 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:2 link_latency:1 bw_multiplier:16
+int_node:5 int_node:4 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:20 bw_multiplier:10
+
+int_node:5 int_node:12 link_latency:20 bw_multiplier:10
+int_node:5 int_node:19 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:13 link_latency:20 bw_multiplier:10
+int_node:7 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:9 link_latency:1 bw_multiplier:16
+int_node:12 int_node:11 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:20 bw_multiplier:10
+
+int_node:12 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:8 int_node:14 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:15 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:16 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:17 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:19 link_latency:1 bw_multiplier:64
+ext_node:Directory:2 int_node:20 link_latency:20 bw_multiplier:10
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:16 link_latency:1 bw_multiplier:16
+int_node:19 int_node:18 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:20 bw_multiplier:10
+
+int_node:19 int_node:26 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:12 int_node:21 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:22 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:23 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:24 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:26 link_latency:1 bw_multiplier:64
+ext_node:Directory:3 int_node:27 link_latency:20 bw_multiplier:10
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:23 link_latency:1 bw_multiplier:16
+int_node:26 int_node:25 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:20 bw_multiplier:10
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-1_Memories-1.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-1_Memories-1.txt
new file mode 100644
index 000000000..a4462c3df
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-1_Memories-1.txt
@@ -0,0 +1,10 @@
+
+processors:1
+procs_per_chip:1
+L2banks:1
+memories:1
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:0 link_latency:40 bw_multiplier:10
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-256_Memories-1.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-256_Memories-1.txt
new file mode 100644
index 000000000..b1c9de652
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-256_Memories-1.txt
@@ -0,0 +1,780 @@
+
+processors:1
+procs_per_chip:1
+L2banks:256
+memories:1
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:248 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:248 link_latency:80 bw_multiplier:10
+
+ext_node:L2Cache:0:bank:0 int_node:0 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:1 int_node:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:2 int_node:2 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:3 int_node:3 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:4 int_node:4 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:5 int_node:5 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:6 int_node:6 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:7 int_node:7 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:8 int_node:8 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:9 int_node:9 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:10 int_node:10 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:11 int_node:11 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:12 int_node:12 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:13 int_node:13 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:14 int_node:14 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:15 int_node:15 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:16 int_node:16 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:17 int_node:17 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:18 int_node:18 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:19 int_node:19 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:20 int_node:20 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:21 int_node:21 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:22 int_node:22 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:23 int_node:23 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:24 int_node:24 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:25 int_node:25 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:26 int_node:26 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:27 int_node:27 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:28 int_node:28 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:29 int_node:29 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:30 int_node:30 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:31 int_node:31 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:32 int_node:32 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:33 int_node:33 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:34 int_node:34 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:35 int_node:35 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:36 int_node:36 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:37 int_node:37 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:38 int_node:38 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:39 int_node:39 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:40 int_node:40 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:41 int_node:41 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:42 int_node:42 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:43 int_node:43 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:44 int_node:44 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:45 int_node:45 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:46 int_node:46 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:47 int_node:47 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:48 int_node:48 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:49 int_node:49 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:50 int_node:50 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:51 int_node:51 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:52 int_node:52 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:53 int_node:53 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:54 int_node:54 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:55 int_node:55 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:56 int_node:56 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:57 int_node:57 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:58 int_node:58 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:59 int_node:59 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:60 int_node:60 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:61 int_node:61 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:62 int_node:62 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:63 int_node:63 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:64 int_node:64 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:65 int_node:65 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:66 int_node:66 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:67 int_node:67 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:68 int_node:68 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:69 int_node:69 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:70 int_node:70 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:71 int_node:71 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:72 int_node:72 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:73 int_node:73 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:74 int_node:74 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:75 int_node:75 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:76 int_node:76 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:77 int_node:77 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:78 int_node:78 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:79 int_node:79 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:80 int_node:80 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:81 int_node:81 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:82 int_node:82 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:83 int_node:83 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:84 int_node:84 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:85 int_node:85 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:86 int_node:86 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:87 int_node:87 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:88 int_node:88 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:89 int_node:89 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:90 int_node:90 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:91 int_node:91 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:92 int_node:92 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:93 int_node:93 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:94 int_node:94 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:95 int_node:95 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:96 int_node:96 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:97 int_node:97 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:98 int_node:98 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:99 int_node:99 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:100 int_node:100 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:101 int_node:101 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:102 int_node:102 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:103 int_node:103 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:104 int_node:104 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:105 int_node:105 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:106 int_node:106 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:107 int_node:107 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:108 int_node:108 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:109 int_node:109 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:110 int_node:110 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:111 int_node:111 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:112 int_node:112 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:113 int_node:113 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:114 int_node:114 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:115 int_node:115 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:116 int_node:116 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:117 int_node:117 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:118 int_node:118 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:119 int_node:119 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:120 int_node:120 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:121 int_node:121 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:122 int_node:122 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:123 int_node:123 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:124 int_node:124 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:125 int_node:125 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:126 int_node:126 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:127 int_node:127 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:128 int_node:128 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:129 int_node:129 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:130 int_node:130 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:131 int_node:131 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:132 int_node:132 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:133 int_node:133 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:134 int_node:134 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:135 int_node:135 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:136 int_node:136 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:137 int_node:137 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:138 int_node:138 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:139 int_node:139 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:140 int_node:140 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:141 int_node:141 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:142 int_node:142 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:143 int_node:143 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:144 int_node:144 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:145 int_node:145 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:146 int_node:146 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:147 int_node:147 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:148 int_node:148 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:149 int_node:149 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:150 int_node:150 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:151 int_node:151 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:152 int_node:152 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:153 int_node:153 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:154 int_node:154 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:155 int_node:155 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:156 int_node:156 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:157 int_node:157 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:158 int_node:158 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:159 int_node:159 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:160 int_node:160 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:161 int_node:161 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:162 int_node:162 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:163 int_node:163 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:164 int_node:164 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:165 int_node:165 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:166 int_node:166 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:167 int_node:167 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:168 int_node:168 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:169 int_node:169 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:170 int_node:170 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:171 int_node:171 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:172 int_node:172 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:173 int_node:173 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:174 int_node:174 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:175 int_node:175 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:176 int_node:176 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:177 int_node:177 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:178 int_node:178 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:179 int_node:179 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:180 int_node:180 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:181 int_node:181 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:182 int_node:182 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:183 int_node:183 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:184 int_node:184 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:185 int_node:185 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:186 int_node:186 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:187 int_node:187 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:188 int_node:188 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:189 int_node:189 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:190 int_node:190 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:191 int_node:191 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:192 int_node:192 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:193 int_node:193 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:194 int_node:194 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:195 int_node:195 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:196 int_node:196 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:197 int_node:197 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:198 int_node:198 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:199 int_node:199 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:200 int_node:200 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:201 int_node:201 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:202 int_node:202 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:203 int_node:203 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:204 int_node:204 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:205 int_node:205 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:206 int_node:206 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:207 int_node:207 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:208 int_node:208 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:209 int_node:209 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:210 int_node:210 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:211 int_node:211 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:212 int_node:212 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:213 int_node:213 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:214 int_node:214 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:215 int_node:215 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:216 int_node:216 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:217 int_node:217 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:218 int_node:218 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:219 int_node:219 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:220 int_node:220 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:221 int_node:221 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:222 int_node:222 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:223 int_node:223 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:224 int_node:224 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:225 int_node:225 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:226 int_node:226 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:227 int_node:227 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:228 int_node:228 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:229 int_node:229 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:230 int_node:230 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:231 int_node:231 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:232 int_node:232 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:233 int_node:233 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:234 int_node:234 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:235 int_node:235 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:236 int_node:236 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:237 int_node:237 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:238 int_node:238 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:239 int_node:239 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:240 int_node:240 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:241 int_node:241 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:242 int_node:242 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:243 int_node:243 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:244 int_node:244 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:245 int_node:245 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:246 int_node:246 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:247 int_node:247 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:248 int_node:248 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:249 int_node:249 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:250 int_node:250 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:251 int_node:251 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:252 int_node:252 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:253 int_node:253 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:254 int_node:254 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:255 int_node:255 link_latency:1 bw_multiplier:16
+
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:2 link_latency:1 bw_multiplier:16
+int_node:2 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:5 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:1 bw_multiplier:16
+int_node:6 int_node:7 link_latency:1 bw_multiplier:16
+int_node:7 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:9 link_latency:1 bw_multiplier:16
+int_node:9 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:12 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:14 link_latency:1 bw_multiplier:16
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+
+int_node:16 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:1 bw_multiplier:16
+int_node:20 int_node:21 link_latency:1 bw_multiplier:16
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:23 link_latency:1 bw_multiplier:16
+int_node:23 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:26 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:1 bw_multiplier:16
+int_node:27 int_node:28 link_latency:1 bw_multiplier:16
+int_node:28 int_node:29 link_latency:1 bw_multiplier:16
+int_node:29 int_node:30 link_latency:1 bw_multiplier:16
+int_node:30 int_node:31 link_latency:1 bw_multiplier:16
+
+int_node:32 int_node:33 link_latency:1 bw_multiplier:16
+int_node:33 int_node:34 link_latency:1 bw_multiplier:16
+int_node:34 int_node:35 link_latency:1 bw_multiplier:16
+int_node:35 int_node:36 link_latency:1 bw_multiplier:16
+int_node:36 int_node:37 link_latency:1 bw_multiplier:16
+int_node:37 int_node:38 link_latency:1 bw_multiplier:16
+int_node:38 int_node:39 link_latency:1 bw_multiplier:16
+int_node:39 int_node:40 link_latency:1 bw_multiplier:16
+int_node:40 int_node:41 link_latency:1 bw_multiplier:16
+int_node:41 int_node:42 link_latency:1 bw_multiplier:16
+int_node:42 int_node:43 link_latency:1 bw_multiplier:16
+int_node:43 int_node:44 link_latency:1 bw_multiplier:16
+int_node:44 int_node:45 link_latency:1 bw_multiplier:16
+int_node:45 int_node:46 link_latency:1 bw_multiplier:16
+int_node:46 int_node:47 link_latency:1 bw_multiplier:16
+
+int_node:48 int_node:49 link_latency:1 bw_multiplier:16
+int_node:49 int_node:50 link_latency:1 bw_multiplier:16
+int_node:50 int_node:51 link_latency:1 bw_multiplier:16
+int_node:51 int_node:52 link_latency:1 bw_multiplier:16
+int_node:52 int_node:53 link_latency:1 bw_multiplier:16
+int_node:53 int_node:54 link_latency:1 bw_multiplier:16
+int_node:54 int_node:55 link_latency:1 bw_multiplier:16
+int_node:55 int_node:56 link_latency:1 bw_multiplier:16
+int_node:56 int_node:57 link_latency:1 bw_multiplier:16
+int_node:57 int_node:58 link_latency:1 bw_multiplier:16
+int_node:58 int_node:59 link_latency:1 bw_multiplier:16
+int_node:59 int_node:60 link_latency:1 bw_multiplier:16
+int_node:60 int_node:61 link_latency:1 bw_multiplier:16
+int_node:61 int_node:62 link_latency:1 bw_multiplier:16
+int_node:62 int_node:63 link_latency:1 bw_multiplier:16
+
+int_node:64 int_node:65 link_latency:1 bw_multiplier:16
+int_node:65 int_node:66 link_latency:1 bw_multiplier:16
+int_node:66 int_node:67 link_latency:1 bw_multiplier:16
+int_node:67 int_node:68 link_latency:1 bw_multiplier:16
+int_node:68 int_node:69 link_latency:1 bw_multiplier:16
+int_node:69 int_node:70 link_latency:1 bw_multiplier:16
+int_node:70 int_node:71 link_latency:1 bw_multiplier:16
+int_node:71 int_node:72 link_latency:1 bw_multiplier:16
+int_node:72 int_node:73 link_latency:1 bw_multiplier:16
+int_node:73 int_node:74 link_latency:1 bw_multiplier:16
+int_node:74 int_node:75 link_latency:1 bw_multiplier:16
+int_node:75 int_node:76 link_latency:1 bw_multiplier:16
+int_node:76 int_node:77 link_latency:1 bw_multiplier:16
+int_node:77 int_node:78 link_latency:1 bw_multiplier:16
+int_node:78 int_node:79 link_latency:1 bw_multiplier:16
+
+int_node:80 int_node:81 link_latency:1 bw_multiplier:16
+int_node:81 int_node:82 link_latency:1 bw_multiplier:16
+int_node:82 int_node:83 link_latency:1 bw_multiplier:16
+int_node:83 int_node:84 link_latency:1 bw_multiplier:16
+int_node:84 int_node:85 link_latency:1 bw_multiplier:16
+int_node:85 int_node:86 link_latency:1 bw_multiplier:16
+int_node:86 int_node:87 link_latency:1 bw_multiplier:16
+int_node:87 int_node:88 link_latency:1 bw_multiplier:16
+int_node:88 int_node:89 link_latency:1 bw_multiplier:16
+int_node:89 int_node:90 link_latency:1 bw_multiplier:16
+int_node:90 int_node:91 link_latency:1 bw_multiplier:16
+int_node:91 int_node:92 link_latency:1 bw_multiplier:16
+int_node:92 int_node:93 link_latency:1 bw_multiplier:16
+int_node:93 int_node:94 link_latency:1 bw_multiplier:16
+int_node:94 int_node:95 link_latency:1 bw_multiplier:16
+
+int_node:96 int_node:97 link_latency:1 bw_multiplier:16
+int_node:97 int_node:98 link_latency:1 bw_multiplier:16
+int_node:98 int_node:99 link_latency:1 bw_multiplier:16
+int_node:99 int_node:100 link_latency:1 bw_multiplier:16
+int_node:100 int_node:101 link_latency:1 bw_multiplier:16
+int_node:101 int_node:102 link_latency:1 bw_multiplier:16
+int_node:102 int_node:103 link_latency:1 bw_multiplier:16
+int_node:103 int_node:104 link_latency:1 bw_multiplier:16
+int_node:104 int_node:105 link_latency:1 bw_multiplier:16
+int_node:105 int_node:106 link_latency:1 bw_multiplier:16
+int_node:106 int_node:107 link_latency:1 bw_multiplier:16
+int_node:107 int_node:108 link_latency:1 bw_multiplier:16
+int_node:108 int_node:109 link_latency:1 bw_multiplier:16
+int_node:109 int_node:110 link_latency:1 bw_multiplier:16
+int_node:110 int_node:111 link_latency:1 bw_multiplier:16
+
+int_node:112 int_node:113 link_latency:1 bw_multiplier:16
+int_node:113 int_node:114 link_latency:1 bw_multiplier:16
+int_node:114 int_node:115 link_latency:1 bw_multiplier:16
+int_node:115 int_node:116 link_latency:1 bw_multiplier:16
+int_node:116 int_node:117 link_latency:1 bw_multiplier:16
+int_node:117 int_node:118 link_latency:1 bw_multiplier:16
+int_node:118 int_node:119 link_latency:1 bw_multiplier:16
+int_node:119 int_node:120 link_latency:1 bw_multiplier:16
+int_node:120 int_node:121 link_latency:1 bw_multiplier:16
+int_node:121 int_node:122 link_latency:1 bw_multiplier:16
+int_node:122 int_node:123 link_latency:1 bw_multiplier:16
+int_node:123 int_node:124 link_latency:1 bw_multiplier:16
+int_node:124 int_node:125 link_latency:1 bw_multiplier:16
+int_node:125 int_node:126 link_latency:1 bw_multiplier:16
+int_node:126 int_node:127 link_latency:1 bw_multiplier:16
+
+int_node:128 int_node:129 link_latency:1 bw_multiplier:16
+int_node:129 int_node:130 link_latency:1 bw_multiplier:16
+int_node:130 int_node:131 link_latency:1 bw_multiplier:16
+int_node:131 int_node:132 link_latency:1 bw_multiplier:16
+int_node:132 int_node:133 link_latency:1 bw_multiplier:16
+int_node:133 int_node:134 link_latency:1 bw_multiplier:16
+int_node:134 int_node:135 link_latency:1 bw_multiplier:16
+int_node:135 int_node:136 link_latency:1 bw_multiplier:16
+int_node:136 int_node:137 link_latency:1 bw_multiplier:16
+int_node:137 int_node:138 link_latency:1 bw_multiplier:16
+int_node:138 int_node:139 link_latency:1 bw_multiplier:16
+int_node:139 int_node:140 link_latency:1 bw_multiplier:16
+int_node:140 int_node:141 link_latency:1 bw_multiplier:16
+int_node:141 int_node:142 link_latency:1 bw_multiplier:16
+int_node:142 int_node:143 link_latency:1 bw_multiplier:16
+
+int_node:144 int_node:145 link_latency:1 bw_multiplier:16
+int_node:145 int_node:146 link_latency:1 bw_multiplier:16
+int_node:146 int_node:147 link_latency:1 bw_multiplier:16
+int_node:147 int_node:148 link_latency:1 bw_multiplier:16
+int_node:148 int_node:149 link_latency:1 bw_multiplier:16
+int_node:149 int_node:150 link_latency:1 bw_multiplier:16
+int_node:150 int_node:151 link_latency:1 bw_multiplier:16
+int_node:151 int_node:152 link_latency:1 bw_multiplier:16
+int_node:152 int_node:153 link_latency:1 bw_multiplier:16
+int_node:153 int_node:154 link_latency:1 bw_multiplier:16
+int_node:154 int_node:155 link_latency:1 bw_multiplier:16
+int_node:155 int_node:156 link_latency:1 bw_multiplier:16
+int_node:156 int_node:157 link_latency:1 bw_multiplier:16
+int_node:157 int_node:158 link_latency:1 bw_multiplier:16
+int_node:158 int_node:159 link_latency:1 bw_multiplier:16
+
+int_node:160 int_node:161 link_latency:1 bw_multiplier:16
+int_node:161 int_node:162 link_latency:1 bw_multiplier:16
+int_node:162 int_node:163 link_latency:1 bw_multiplier:16
+int_node:163 int_node:164 link_latency:1 bw_multiplier:16
+int_node:164 int_node:165 link_latency:1 bw_multiplier:16
+int_node:165 int_node:166 link_latency:1 bw_multiplier:16
+int_node:166 int_node:167 link_latency:1 bw_multiplier:16
+int_node:167 int_node:168 link_latency:1 bw_multiplier:16
+int_node:168 int_node:169 link_latency:1 bw_multiplier:16
+int_node:169 int_node:170 link_latency:1 bw_multiplier:16
+int_node:170 int_node:171 link_latency:1 bw_multiplier:16
+int_node:171 int_node:172 link_latency:1 bw_multiplier:16
+int_node:172 int_node:173 link_latency:1 bw_multiplier:16
+int_node:173 int_node:174 link_latency:1 bw_multiplier:16
+int_node:174 int_node:175 link_latency:1 bw_multiplier:16
+
+int_node:176 int_node:177 link_latency:1 bw_multiplier:16
+int_node:177 int_node:178 link_latency:1 bw_multiplier:16
+int_node:178 int_node:179 link_latency:1 bw_multiplier:16
+int_node:179 int_node:180 link_latency:1 bw_multiplier:16
+int_node:180 int_node:181 link_latency:1 bw_multiplier:16
+int_node:181 int_node:182 link_latency:1 bw_multiplier:16
+int_node:182 int_node:183 link_latency:1 bw_multiplier:16
+int_node:183 int_node:184 link_latency:1 bw_multiplier:16
+int_node:184 int_node:185 link_latency:1 bw_multiplier:16
+int_node:185 int_node:186 link_latency:1 bw_multiplier:16
+int_node:186 int_node:187 link_latency:1 bw_multiplier:16
+int_node:187 int_node:188 link_latency:1 bw_multiplier:16
+int_node:188 int_node:189 link_latency:1 bw_multiplier:16
+int_node:189 int_node:190 link_latency:1 bw_multiplier:16
+int_node:190 int_node:191 link_latency:1 bw_multiplier:16
+
+int_node:192 int_node:193 link_latency:1 bw_multiplier:16
+int_node:193 int_node:194 link_latency:1 bw_multiplier:16
+int_node:194 int_node:195 link_latency:1 bw_multiplier:16
+int_node:195 int_node:196 link_latency:1 bw_multiplier:16
+int_node:196 int_node:197 link_latency:1 bw_multiplier:16
+int_node:197 int_node:198 link_latency:1 bw_multiplier:16
+int_node:198 int_node:199 link_latency:1 bw_multiplier:16
+int_node:199 int_node:200 link_latency:1 bw_multiplier:16
+int_node:200 int_node:201 link_latency:1 bw_multiplier:16
+int_node:201 int_node:202 link_latency:1 bw_multiplier:16
+int_node:202 int_node:203 link_latency:1 bw_multiplier:16
+int_node:203 int_node:204 link_latency:1 bw_multiplier:16
+int_node:204 int_node:205 link_latency:1 bw_multiplier:16
+int_node:205 int_node:206 link_latency:1 bw_multiplier:16
+int_node:206 int_node:207 link_latency:1 bw_multiplier:16
+
+int_node:208 int_node:209 link_latency:1 bw_multiplier:16
+int_node:209 int_node:210 link_latency:1 bw_multiplier:16
+int_node:210 int_node:211 link_latency:1 bw_multiplier:16
+int_node:211 int_node:212 link_latency:1 bw_multiplier:16
+int_node:212 int_node:213 link_latency:1 bw_multiplier:16
+int_node:213 int_node:214 link_latency:1 bw_multiplier:16
+int_node:214 int_node:215 link_latency:1 bw_multiplier:16
+int_node:215 int_node:216 link_latency:1 bw_multiplier:16
+int_node:216 int_node:217 link_latency:1 bw_multiplier:16
+int_node:217 int_node:218 link_latency:1 bw_multiplier:16
+int_node:218 int_node:219 link_latency:1 bw_multiplier:16
+int_node:219 int_node:220 link_latency:1 bw_multiplier:16
+int_node:220 int_node:221 link_latency:1 bw_multiplier:16
+int_node:221 int_node:222 link_latency:1 bw_multiplier:16
+int_node:222 int_node:223 link_latency:1 bw_multiplier:16
+
+int_node:224 int_node:225 link_latency:1 bw_multiplier:16
+int_node:225 int_node:226 link_latency:1 bw_multiplier:16
+int_node:226 int_node:227 link_latency:1 bw_multiplier:16
+int_node:227 int_node:228 link_latency:1 bw_multiplier:16
+int_node:228 int_node:229 link_latency:1 bw_multiplier:16
+int_node:229 int_node:230 link_latency:1 bw_multiplier:16
+int_node:230 int_node:231 link_latency:1 bw_multiplier:16
+int_node:231 int_node:232 link_latency:1 bw_multiplier:16
+int_node:232 int_node:233 link_latency:1 bw_multiplier:16
+int_node:233 int_node:234 link_latency:1 bw_multiplier:16
+int_node:234 int_node:235 link_latency:1 bw_multiplier:16
+int_node:235 int_node:236 link_latency:1 bw_multiplier:16
+int_node:236 int_node:237 link_latency:1 bw_multiplier:16
+int_node:237 int_node:238 link_latency:1 bw_multiplier:16
+int_node:238 int_node:239 link_latency:1 bw_multiplier:16
+
+int_node:240 int_node:241 link_latency:1 bw_multiplier:16
+int_node:241 int_node:242 link_latency:1 bw_multiplier:16
+int_node:242 int_node:243 link_latency:1 bw_multiplier:16
+int_node:243 int_node:244 link_latency:1 bw_multiplier:16
+int_node:244 int_node:245 link_latency:1 bw_multiplier:16
+int_node:245 int_node:246 link_latency:1 bw_multiplier:16
+int_node:246 int_node:247 link_latency:1 bw_multiplier:16
+int_node:247 int_node:248 link_latency:1 bw_multiplier:16
+int_node:248 int_node:249 link_latency:1 bw_multiplier:16
+int_node:249 int_node:250 link_latency:1 bw_multiplier:16
+int_node:250 int_node:251 link_latency:1 bw_multiplier:16
+int_node:251 int_node:252 link_latency:1 bw_multiplier:16
+int_node:252 int_node:253 link_latency:1 bw_multiplier:16
+int_node:253 int_node:254 link_latency:1 bw_multiplier:16
+int_node:254 int_node:255 link_latency:1 bw_multiplier:16
+
+
+int_node:0 int_node:16 link_latency:1 bw_multiplier:16
+int_node:16 int_node:32 link_latency:1 bw_multiplier:16
+int_node:32 int_node:48 link_latency:1 bw_multiplier:16
+int_node:48 int_node:64 link_latency:1 bw_multiplier:16
+int_node:64 int_node:80 link_latency:1 bw_multiplier:16
+int_node:80 int_node:96 link_latency:1 bw_multiplier:16
+int_node:96 int_node:112 link_latency:1 bw_multiplier:16
+int_node:112 int_node:128 link_latency:1 bw_multiplier:16
+int_node:128 int_node:144 link_latency:1 bw_multiplier:16
+int_node:144 int_node:160 link_latency:1 bw_multiplier:16
+int_node:160 int_node:176 link_latency:1 bw_multiplier:16
+int_node:176 int_node:192 link_latency:1 bw_multiplier:16
+int_node:192 int_node:208 link_latency:1 bw_multiplier:16
+int_node:208 int_node:224 link_latency:1 bw_multiplier:16
+int_node:224 int_node:240 link_latency:1 bw_multiplier:16
+
+int_node:1 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:33 link_latency:1 bw_multiplier:16
+int_node:33 int_node:49 link_latency:1 bw_multiplier:16
+int_node:49 int_node:65 link_latency:1 bw_multiplier:16
+int_node:65 int_node:81 link_latency:1 bw_multiplier:16
+int_node:81 int_node:97 link_latency:1 bw_multiplier:16
+int_node:97 int_node:113 link_latency:1 bw_multiplier:16
+int_node:113 int_node:129 link_latency:1 bw_multiplier:16
+int_node:129 int_node:145 link_latency:1 bw_multiplier:16
+int_node:145 int_node:161 link_latency:1 bw_multiplier:16
+int_node:161 int_node:177 link_latency:1 bw_multiplier:16
+int_node:177 int_node:193 link_latency:1 bw_multiplier:16
+int_node:193 int_node:209 link_latency:1 bw_multiplier:16
+int_node:209 int_node:225 link_latency:1 bw_multiplier:16
+int_node:225 int_node:241 link_latency:1 bw_multiplier:16
+
+int_node:2 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:34 link_latency:1 bw_multiplier:16
+int_node:34 int_node:50 link_latency:1 bw_multiplier:16
+int_node:50 int_node:66 link_latency:1 bw_multiplier:16
+int_node:66 int_node:82 link_latency:1 bw_multiplier:16
+int_node:82 int_node:98 link_latency:1 bw_multiplier:16
+int_node:98 int_node:114 link_latency:1 bw_multiplier:16
+int_node:114 int_node:130 link_latency:1 bw_multiplier:16
+int_node:130 int_node:146 link_latency:1 bw_multiplier:16
+int_node:146 int_node:162 link_latency:1 bw_multiplier:16
+int_node:162 int_node:178 link_latency:1 bw_multiplier:16
+int_node:178 int_node:194 link_latency:1 bw_multiplier:16
+int_node:194 int_node:210 link_latency:1 bw_multiplier:16
+int_node:210 int_node:226 link_latency:1 bw_multiplier:16
+int_node:226 int_node:242 link_latency:1 bw_multiplier:16
+
+int_node:3 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:35 link_latency:1 bw_multiplier:16
+int_node:35 int_node:51 link_latency:1 bw_multiplier:16
+int_node:51 int_node:67 link_latency:1 bw_multiplier:16
+int_node:67 int_node:83 link_latency:1 bw_multiplier:16
+int_node:83 int_node:99 link_latency:1 bw_multiplier:16
+int_node:99 int_node:115 link_latency:1 bw_multiplier:16
+int_node:115 int_node:131 link_latency:1 bw_multiplier:16
+int_node:131 int_node:147 link_latency:1 bw_multiplier:16
+int_node:147 int_node:163 link_latency:1 bw_multiplier:16
+int_node:163 int_node:179 link_latency:1 bw_multiplier:16
+int_node:179 int_node:195 link_latency:1 bw_multiplier:16
+int_node:195 int_node:211 link_latency:1 bw_multiplier:16
+int_node:211 int_node:227 link_latency:1 bw_multiplier:16
+int_node:227 int_node:243 link_latency:1 bw_multiplier:16
+
+int_node:4 int_node:20 link_latency:1 bw_multiplier:16
+int_node:20 int_node:36 link_latency:1 bw_multiplier:16
+int_node:36 int_node:52 link_latency:1 bw_multiplier:16
+int_node:52 int_node:68 link_latency:1 bw_multiplier:16
+int_node:68 int_node:84 link_latency:1 bw_multiplier:16
+int_node:84 int_node:100 link_latency:1 bw_multiplier:16
+int_node:100 int_node:116 link_latency:1 bw_multiplier:16
+int_node:116 int_node:132 link_latency:1 bw_multiplier:16
+int_node:132 int_node:148 link_latency:1 bw_multiplier:16
+int_node:148 int_node:164 link_latency:1 bw_multiplier:16
+int_node:164 int_node:180 link_latency:1 bw_multiplier:16
+int_node:180 int_node:196 link_latency:1 bw_multiplier:16
+int_node:196 int_node:212 link_latency:1 bw_multiplier:16
+int_node:212 int_node:228 link_latency:1 bw_multiplier:16
+int_node:228 int_node:244 link_latency:1 bw_multiplier:16
+
+int_node:5 int_node:21 link_latency:1 bw_multiplier:16
+int_node:21 int_node:37 link_latency:1 bw_multiplier:16
+int_node:37 int_node:53 link_latency:1 bw_multiplier:16
+int_node:53 int_node:69 link_latency:1 bw_multiplier:16
+int_node:69 int_node:85 link_latency:1 bw_multiplier:16
+int_node:85 int_node:101 link_latency:1 bw_multiplier:16
+int_node:101 int_node:117 link_latency:1 bw_multiplier:16
+int_node:117 int_node:133 link_latency:1 bw_multiplier:16
+int_node:133 int_node:149 link_latency:1 bw_multiplier:16
+int_node:149 int_node:165 link_latency:1 bw_multiplier:16
+int_node:165 int_node:181 link_latency:1 bw_multiplier:16
+int_node:181 int_node:197 link_latency:1 bw_multiplier:16
+int_node:197 int_node:213 link_latency:1 bw_multiplier:16
+int_node:213 int_node:229 link_latency:1 bw_multiplier:16
+int_node:229 int_node:245 link_latency:1 bw_multiplier:16
+
+int_node:6 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:38 link_latency:1 bw_multiplier:16
+int_node:38 int_node:54 link_latency:1 bw_multiplier:16
+int_node:54 int_node:70 link_latency:1 bw_multiplier:16
+int_node:70 int_node:86 link_latency:1 bw_multiplier:16
+int_node:86 int_node:102 link_latency:1 bw_multiplier:16
+int_node:102 int_node:118 link_latency:1 bw_multiplier:16
+int_node:118 int_node:134 link_latency:1 bw_multiplier:16
+int_node:134 int_node:150 link_latency:1 bw_multiplier:16
+int_node:150 int_node:166 link_latency:1 bw_multiplier:16
+int_node:166 int_node:182 link_latency:1 bw_multiplier:16
+int_node:182 int_node:198 link_latency:1 bw_multiplier:16
+int_node:198 int_node:214 link_latency:1 bw_multiplier:16
+int_node:214 int_node:230 link_latency:1 bw_multiplier:16
+int_node:230 int_node:246 link_latency:1 bw_multiplier:16
+
+int_node:7 int_node:23 link_latency:1 bw_multiplier:16
+int_node:23 int_node:39 link_latency:1 bw_multiplier:16
+int_node:39 int_node:55 link_latency:1 bw_multiplier:16
+int_node:55 int_node:71 link_latency:1 bw_multiplier:16
+int_node:71 int_node:87 link_latency:1 bw_multiplier:16
+int_node:87 int_node:103 link_latency:1 bw_multiplier:16
+int_node:103 int_node:119 link_latency:1 bw_multiplier:16
+int_node:119 int_node:135 link_latency:1 bw_multiplier:16
+int_node:135 int_node:151 link_latency:1 bw_multiplier:16
+int_node:151 int_node:167 link_latency:1 bw_multiplier:16
+int_node:167 int_node:183 link_latency:1 bw_multiplier:16
+int_node:183 int_node:199 link_latency:1 bw_multiplier:16
+int_node:199 int_node:215 link_latency:1 bw_multiplier:16
+int_node:215 int_node:231 link_latency:1 bw_multiplier:16
+int_node:231 int_node:247 link_latency:1 bw_multiplier:16
+
+int_node:8 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:40 link_latency:1 bw_multiplier:16
+int_node:40 int_node:56 link_latency:1 bw_multiplier:16
+int_node:56 int_node:72 link_latency:1 bw_multiplier:16
+int_node:72 int_node:88 link_latency:1 bw_multiplier:16
+int_node:88 int_node:104 link_latency:1 bw_multiplier:16
+int_node:104 int_node:120 link_latency:1 bw_multiplier:16
+int_node:120 int_node:136 link_latency:1 bw_multiplier:16
+int_node:136 int_node:152 link_latency:1 bw_multiplier:16
+int_node:152 int_node:168 link_latency:1 bw_multiplier:16
+int_node:168 int_node:184 link_latency:1 bw_multiplier:16
+int_node:184 int_node:200 link_latency:1 bw_multiplier:16
+int_node:200 int_node:216 link_latency:1 bw_multiplier:16
+int_node:216 int_node:232 link_latency:1 bw_multiplier:16
+int_node:232 int_node:248 link_latency:1 bw_multiplier:16
+
+int_node:9 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:41 link_latency:1 bw_multiplier:16
+int_node:41 int_node:57 link_latency:1 bw_multiplier:16
+int_node:57 int_node:73 link_latency:1 bw_multiplier:16
+int_node:73 int_node:89 link_latency:1 bw_multiplier:16
+int_node:89 int_node:105 link_latency:1 bw_multiplier:16
+int_node:105 int_node:121 link_latency:1 bw_multiplier:16
+int_node:121 int_node:137 link_latency:1 bw_multiplier:16
+int_node:137 int_node:153 link_latency:1 bw_multiplier:16
+int_node:153 int_node:169 link_latency:1 bw_multiplier:16
+int_node:169 int_node:185 link_latency:1 bw_multiplier:16
+int_node:185 int_node:201 link_latency:1 bw_multiplier:16
+int_node:201 int_node:217 link_latency:1 bw_multiplier:16
+int_node:217 int_node:233 link_latency:1 bw_multiplier:16
+int_node:233 int_node:249 link_latency:1 bw_multiplier:16
+
+int_node:10 int_node:26 link_latency:1 bw_multiplier:16
+int_node:26 int_node:42 link_latency:1 bw_multiplier:16
+int_node:42 int_node:58 link_latency:1 bw_multiplier:16
+int_node:58 int_node:74 link_latency:1 bw_multiplier:16
+int_node:74 int_node:90 link_latency:1 bw_multiplier:16
+int_node:90 int_node:106 link_latency:1 bw_multiplier:16
+int_node:106 int_node:122 link_latency:1 bw_multiplier:16
+int_node:122 int_node:138 link_latency:1 bw_multiplier:16
+int_node:138 int_node:154 link_latency:1 bw_multiplier:16
+int_node:154 int_node:170 link_latency:1 bw_multiplier:16
+int_node:170 int_node:186 link_latency:1 bw_multiplier:16
+int_node:186 int_node:202 link_latency:1 bw_multiplier:16
+int_node:202 int_node:218 link_latency:1 bw_multiplier:16
+int_node:218 int_node:234 link_latency:1 bw_multiplier:16
+int_node:234 int_node:250 link_latency:1 bw_multiplier:16
+
+int_node:11 int_node:27 link_latency:1 bw_multiplier:16
+int_node:27 int_node:43 link_latency:1 bw_multiplier:16
+int_node:43 int_node:59 link_latency:1 bw_multiplier:16
+int_node:59 int_node:75 link_latency:1 bw_multiplier:16
+int_node:75 int_node:91 link_latency:1 bw_multiplier:16
+int_node:91 int_node:107 link_latency:1 bw_multiplier:16
+int_node:107 int_node:123 link_latency:1 bw_multiplier:16
+int_node:123 int_node:139 link_latency:1 bw_multiplier:16
+int_node:139 int_node:155 link_latency:1 bw_multiplier:16
+int_node:155 int_node:171 link_latency:1 bw_multiplier:16
+int_node:171 int_node:187 link_latency:1 bw_multiplier:16
+int_node:187 int_node:203 link_latency:1 bw_multiplier:16
+int_node:203 int_node:219 link_latency:1 bw_multiplier:16
+int_node:219 int_node:235 link_latency:1 bw_multiplier:16
+int_node:235 int_node:251 link_latency:1 bw_multiplier:16
+
+int_node:12 int_node:28 link_latency:1 bw_multiplier:16
+int_node:28 int_node:44 link_latency:1 bw_multiplier:16
+int_node:44 int_node:60 link_latency:1 bw_multiplier:16
+int_node:60 int_node:76 link_latency:1 bw_multiplier:16
+int_node:76 int_node:92 link_latency:1 bw_multiplier:16
+int_node:92 int_node:108 link_latency:1 bw_multiplier:16
+int_node:108 int_node:124 link_latency:1 bw_multiplier:16
+int_node:124 int_node:140 link_latency:1 bw_multiplier:16
+int_node:140 int_node:156 link_latency:1 bw_multiplier:16
+int_node:156 int_node:172 link_latency:1 bw_multiplier:16
+int_node:172 int_node:188 link_latency:1 bw_multiplier:16
+int_node:188 int_node:204 link_latency:1 bw_multiplier:16
+int_node:204 int_node:220 link_latency:1 bw_multiplier:16
+int_node:220 int_node:236 link_latency:1 bw_multiplier:16
+int_node:236 int_node:252 link_latency:1 bw_multiplier:16
+
+int_node:13 int_node:29 link_latency:1 bw_multiplier:16
+int_node:29 int_node:45 link_latency:1 bw_multiplier:16
+int_node:45 int_node:61 link_latency:1 bw_multiplier:16
+int_node:61 int_node:77 link_latency:1 bw_multiplier:16
+int_node:77 int_node:93 link_latency:1 bw_multiplier:16
+int_node:93 int_node:109 link_latency:1 bw_multiplier:16
+int_node:109 int_node:125 link_latency:1 bw_multiplier:16
+int_node:125 int_node:141 link_latency:1 bw_multiplier:16
+int_node:141 int_node:157 link_latency:1 bw_multiplier:16
+int_node:157 int_node:173 link_latency:1 bw_multiplier:16
+int_node:173 int_node:189 link_latency:1 bw_multiplier:16
+int_node:189 int_node:205 link_latency:1 bw_multiplier:16
+int_node:205 int_node:221 link_latency:1 bw_multiplier:16
+int_node:221 int_node:237 link_latency:1 bw_multiplier:16
+int_node:237 int_node:253 link_latency:1 bw_multiplier:16
+
+int_node:14 int_node:30 link_latency:1 bw_multiplier:16
+int_node:30 int_node:46 link_latency:1 bw_multiplier:16
+int_node:46 int_node:62 link_latency:1 bw_multiplier:16
+int_node:62 int_node:78 link_latency:1 bw_multiplier:16
+int_node:78 int_node:94 link_latency:1 bw_multiplier:16
+int_node:94 int_node:110 link_latency:1 bw_multiplier:16
+int_node:110 int_node:126 link_latency:1 bw_multiplier:16
+int_node:126 int_node:142 link_latency:1 bw_multiplier:16
+int_node:142 int_node:158 link_latency:1 bw_multiplier:16
+int_node:158 int_node:174 link_latency:1 bw_multiplier:16
+int_node:174 int_node:190 link_latency:1 bw_multiplier:16
+int_node:190 int_node:206 link_latency:1 bw_multiplier:16
+int_node:206 int_node:222 link_latency:1 bw_multiplier:16
+int_node:222 int_node:238 link_latency:1 bw_multiplier:16
+int_node:238 int_node:254 link_latency:1 bw_multiplier:16
+
+int_node:15 int_node:31 link_latency:1 bw_multiplier:16
+int_node:31 int_node:47 link_latency:1 bw_multiplier:16
+int_node:47 int_node:63 link_latency:1 bw_multiplier:16
+int_node:63 int_node:79 link_latency:1 bw_multiplier:16
+int_node:79 int_node:95 link_latency:1 bw_multiplier:16
+int_node:95 int_node:111 link_latency:1 bw_multiplier:16
+int_node:111 int_node:127 link_latency:1 bw_multiplier:16
+int_node:127 int_node:143 link_latency:1 bw_multiplier:16
+int_node:143 int_node:159 link_latency:1 bw_multiplier:16
+int_node:159 int_node:175 link_latency:1 bw_multiplier:16
+int_node:175 int_node:191 link_latency:1 bw_multiplier:16
+int_node:191 int_node:207 link_latency:1 bw_multiplier:16
+int_node:207 int_node:223 link_latency:1 bw_multiplier:16
+int_node:223 int_node:239 link_latency:1 bw_multiplier:16
+int_node:239 int_node:255 link_latency:1 bw_multiplier:16
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-32_Memories-1.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-32_Memories-1.txt
new file mode 100644
index 000000000..5aba03c94
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-32_Memories-1.txt
@@ -0,0 +1,107 @@
+
+processors:1
+procs_per_chip:1
+L2banks:32
+memories:1
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:28 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:28 link_latency:80 bw_multiplier:10
+
+ext_node:L2Cache:0:bank:0 int_node:0 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:1 int_node:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:2 int_node:2 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:3 int_node:3 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:4 int_node:4 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:5 int_node:5 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:6 int_node:6 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:7 int_node:7 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:8 int_node:8 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:9 int_node:9 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:10 int_node:10 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:11 int_node:11 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:12 int_node:12 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:13 int_node:13 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:14 int_node:14 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:15 int_node:15 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:16 int_node:16 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:17 int_node:17 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:18 int_node:18 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:19 int_node:19 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:20 int_node:20 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:21 int_node:21 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:22 int_node:22 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:23 int_node:23 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:24 int_node:24 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:25 int_node:25 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:26 int_node:26 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:27 int_node:27 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:28 int_node:28 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:29 int_node:29 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:30 int_node:30 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:31 int_node:31 link_latency:1 bw_multiplier:16
+
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:2 link_latency:1 bw_multiplier:16
+int_node:2 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:5 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:1 bw_multiplier:16
+int_node:6 int_node:7 link_latency:1 bw_multiplier:16
+
+int_node:8 int_node:9 link_latency:1 bw_multiplier:16
+int_node:9 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:12 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:14 link_latency:1 bw_multiplier:16
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+
+int_node:16 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:1 bw_multiplier:16
+int_node:20 int_node:21 link_latency:1 bw_multiplier:16
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:23 link_latency:1 bw_multiplier:16
+
+int_node:24 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:26 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:1 bw_multiplier:16
+int_node:27 int_node:28 link_latency:1 bw_multiplier:16
+int_node:28 int_node:29 link_latency:1 bw_multiplier:16
+int_node:29 int_node:30 link_latency:1 bw_multiplier:16
+int_node:30 int_node:31 link_latency:1 bw_multiplier:16
+
+int_node:0 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:16 link_latency:1 bw_multiplier:16
+int_node:16 int_node:24 link_latency:1 bw_multiplier:16
+
+int_node:1 int_node:9 link_latency:1 bw_multiplier:16
+int_node:9 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:25 link_latency:1 bw_multiplier:16
+
+int_node:2 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:26 link_latency:1 bw_multiplier:16
+
+int_node:3 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:27 link_latency:1 bw_multiplier:16
+
+int_node:4 int_node:12 link_latency:1 bw_multiplier:16
+int_node:12 int_node:20 link_latency:1 bw_multiplier:16
+int_node:20 int_node:28 link_latency:1 bw_multiplier:16
+
+int_node:5 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:21 link_latency:1 bw_multiplier:16
+int_node:21 int_node:29 link_latency:1 bw_multiplier:16
+
+int_node:6 int_node:14 link_latency:1 bw_multiplier:16
+int_node:14 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:30 link_latency:1 bw_multiplier:16
+
+int_node:7 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:23 link_latency:1 bw_multiplier:16
+int_node:23 int_node:31 link_latency:1 bw_multiplier:16
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-64_Memories-1.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-64_Memories-1.txt
new file mode 100644
index 000000000..faf61c76d
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-1_ProcsPerChip-1_L2Banks-64_Memories-1.txt
@@ -0,0 +1,204 @@
+
+processors:1
+procs_per_chip:1
+L2banks:64
+memories:1
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:60 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:60 link_latency:80 bw_multiplier:10
+
+ext_node:L2Cache:0:bank:0 int_node:0 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:1 int_node:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:2 int_node:2 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:3 int_node:3 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:4 int_node:4 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:5 int_node:5 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:6 int_node:6 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:7 int_node:7 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:8 int_node:8 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:9 int_node:9 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:10 int_node:10 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:11 int_node:11 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:12 int_node:12 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:13 int_node:13 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:14 int_node:14 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:15 int_node:15 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:16 int_node:16 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:17 int_node:17 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:18 int_node:18 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:19 int_node:19 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:20 int_node:20 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:21 int_node:21 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:22 int_node:22 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:23 int_node:23 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:24 int_node:24 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:25 int_node:25 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:26 int_node:26 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:27 int_node:27 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:28 int_node:28 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:29 int_node:29 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:30 int_node:30 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:31 int_node:31 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:32 int_node:32 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:33 int_node:33 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:34 int_node:34 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:35 int_node:35 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:36 int_node:36 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:37 int_node:37 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:38 int_node:38 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:39 int_node:39 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:40 int_node:40 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:41 int_node:41 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:42 int_node:42 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:43 int_node:43 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:44 int_node:44 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:45 int_node:45 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:46 int_node:46 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:47 int_node:47 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:48 int_node:48 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:49 int_node:49 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:50 int_node:50 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:51 int_node:51 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:52 int_node:52 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:53 int_node:53 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:54 int_node:54 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:55 int_node:55 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:56 int_node:56 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:57 int_node:57 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:58 int_node:58 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:59 int_node:59 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:60 int_node:60 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:61 int_node:61 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:62 int_node:62 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:0:bank:63 int_node:63 link_latency:1 bw_multiplier:16
+
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:2 link_latency:1 bw_multiplier:16
+int_node:2 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:5 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:1 bw_multiplier:16
+int_node:6 int_node:7 link_latency:1 bw_multiplier:16
+
+int_node:8 int_node:9 link_latency:1 bw_multiplier:16
+int_node:9 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:12 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:14 link_latency:1 bw_multiplier:16
+int_node:14 int_node:15 link_latency:1 bw_multiplier:16
+
+int_node:16 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:20 link_latency:1 bw_multiplier:16
+int_node:20 int_node:21 link_latency:1 bw_multiplier:16
+int_node:21 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:23 link_latency:1 bw_multiplier:16
+
+int_node:24 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:26 link_latency:1 bw_multiplier:16
+int_node:26 int_node:27 link_latency:1 bw_multiplier:16
+int_node:27 int_node:28 link_latency:1 bw_multiplier:16
+int_node:28 int_node:29 link_latency:1 bw_multiplier:16
+int_node:29 int_node:30 link_latency:1 bw_multiplier:16
+int_node:30 int_node:31 link_latency:1 bw_multiplier:16
+
+int_node:32 int_node:33 link_latency:1 bw_multiplier:16
+int_node:33 int_node:34 link_latency:1 bw_multiplier:16
+int_node:34 int_node:35 link_latency:1 bw_multiplier:16
+int_node:35 int_node:36 link_latency:1 bw_multiplier:16
+int_node:36 int_node:37 link_latency:1 bw_multiplier:16
+int_node:37 int_node:38 link_latency:1 bw_multiplier:16
+int_node:38 int_node:39 link_latency:1 bw_multiplier:16
+
+int_node:40 int_node:41 link_latency:1 bw_multiplier:16
+int_node:41 int_node:42 link_latency:1 bw_multiplier:16
+int_node:42 int_node:43 link_latency:1 bw_multiplier:16
+int_node:43 int_node:44 link_latency:1 bw_multiplier:16
+int_node:44 int_node:45 link_latency:1 bw_multiplier:16
+int_node:45 int_node:46 link_latency:1 bw_multiplier:16
+int_node:46 int_node:47 link_latency:1 bw_multiplier:16
+
+int_node:48 int_node:49 link_latency:1 bw_multiplier:16
+int_node:49 int_node:50 link_latency:1 bw_multiplier:16
+int_node:50 int_node:51 link_latency:1 bw_multiplier:16
+int_node:51 int_node:52 link_latency:1 bw_multiplier:16
+int_node:52 int_node:53 link_latency:1 bw_multiplier:16
+int_node:53 int_node:54 link_latency:1 bw_multiplier:16
+int_node:54 int_node:55 link_latency:1 bw_multiplier:16
+
+int_node:56 int_node:57 link_latency:1 bw_multiplier:16
+int_node:57 int_node:58 link_latency:1 bw_multiplier:16
+int_node:58 int_node:59 link_latency:1 bw_multiplier:16
+int_node:59 int_node:60 link_latency:1 bw_multiplier:16
+int_node:60 int_node:61 link_latency:1 bw_multiplier:16
+int_node:61 int_node:62 link_latency:1 bw_multiplier:16
+int_node:62 int_node:63 link_latency:1 bw_multiplier:16
+
+
+int_node:0 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:16 link_latency:1 bw_multiplier:16
+int_node:16 int_node:24 link_latency:1 bw_multiplier:16
+int_node:24 int_node:32 link_latency:1 bw_multiplier:16
+int_node:32 int_node:40 link_latency:1 bw_multiplier:16
+int_node:40 int_node:48 link_latency:1 bw_multiplier:16
+int_node:48 int_node:56 link_latency:1 bw_multiplier:16
+
+int_node:1 int_node:9 link_latency:1 bw_multiplier:16
+int_node:9 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:25 link_latency:1 bw_multiplier:16
+int_node:25 int_node:33 link_latency:1 bw_multiplier:16
+int_node:33 int_node:41 link_latency:1 bw_multiplier:16
+int_node:41 int_node:49 link_latency:1 bw_multiplier:16
+int_node:49 int_node:57 link_latency:1 bw_multiplier:16
+
+int_node:2 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:26 link_latency:1 bw_multiplier:16
+int_node:26 int_node:34 link_latency:1 bw_multiplier:16
+int_node:34 int_node:42 link_latency:1 bw_multiplier:16
+int_node:42 int_node:50 link_latency:1 bw_multiplier:16
+int_node:50 int_node:58 link_latency:1 bw_multiplier:16
+
+int_node:3 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:27 link_latency:1 bw_multiplier:16
+int_node:27 int_node:35 link_latency:1 bw_multiplier:16
+int_node:35 int_node:43 link_latency:1 bw_multiplier:16
+int_node:43 int_node:51 link_latency:1 bw_multiplier:16
+int_node:51 int_node:59 link_latency:1 bw_multiplier:16
+
+int_node:4 int_node:12 link_latency:1 bw_multiplier:16
+int_node:12 int_node:20 link_latency:1 bw_multiplier:16
+int_node:20 int_node:28 link_latency:1 bw_multiplier:16
+int_node:28 int_node:36 link_latency:1 bw_multiplier:16
+int_node:36 int_node:44 link_latency:1 bw_multiplier:16
+int_node:44 int_node:52 link_latency:1 bw_multiplier:16
+int_node:52 int_node:60 link_latency:1 bw_multiplier:16
+
+int_node:5 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:21 link_latency:1 bw_multiplier:16
+int_node:21 int_node:29 link_latency:1 bw_multiplier:16
+int_node:29 int_node:37 link_latency:1 bw_multiplier:16
+int_node:37 int_node:45 link_latency:1 bw_multiplier:16
+int_node:45 int_node:53 link_latency:1 bw_multiplier:16
+int_node:53 int_node:61 link_latency:1 bw_multiplier:16
+
+int_node:6 int_node:14 link_latency:1 bw_multiplier:16
+int_node:14 int_node:22 link_latency:1 bw_multiplier:16
+int_node:22 int_node:30 link_latency:1 bw_multiplier:16
+int_node:30 int_node:38 link_latency:1 bw_multiplier:16
+int_node:38 int_node:46 link_latency:1 bw_multiplier:16
+int_node:46 int_node:54 link_latency:1 bw_multiplier:16
+int_node:54 int_node:62 link_latency:1 bw_multiplier:16
+
+int_node:7 int_node:15 link_latency:1 bw_multiplier:16
+int_node:15 int_node:23 link_latency:1 bw_multiplier:16
+int_node:23 int_node:31 link_latency:1 bw_multiplier:16
+int_node:31 int_node:39 link_latency:1 bw_multiplier:16
+int_node:39 int_node:47 link_latency:1 bw_multiplier:16
+int_node:47 int_node:55 link_latency:1 bw_multiplier:16
+int_node:55 int_node:63 link_latency:1 bw_multiplier:16
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-1_L2Banks-2_Memories-2.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-1_L2Banks-2_Memories-2.txt
new file mode 100644
index 000000000..5f3825b1d
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-1_L2Banks-2_Memories-2.txt
@@ -0,0 +1,15 @@
+
+processors:2
+procs_per_chip:1
+L2banks:2
+memories:2
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:0 link_latency:40 bw_multiplier:10
+int_node:0 int_node:1 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:1 link_latency:40 bw_multiplier:10
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-2_L2Banks-2_Memories-2.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-2_L2Banks-2_Memories-2.txt
new file mode 100644
index 000000000..f776eab73
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-2_ProcsPerChip-2_L2Banks-2_Memories-2.txt
@@ -0,0 +1,15 @@
+
+processors:2
+procs_per_chip:2
+L2banks:2
+memories:2
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:2 link_latency:40 bw_multiplier:10
+int_node:0 int_node:2 link_latency:40 bw_multiplier:16
+int_node:1 int_node:2 link_latency:40 bw_multiplier:16
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-16.txt
new file mode 100644
index 000000000..6c29eaa43
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-16.txt
@@ -0,0 +1,148 @@
+
+processors:32
+procs_per_chip:32
+L2banks:32
+memories:16
+
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:8 int_node:16 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:8 int_node:16 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:9 int_node:17 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:9 int_node:17 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:10 int_node:24 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:10 int_node:24 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:11 int_node:25 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:11 int_node:25 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:12 int_node:18 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:12 int_node:18 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:13 int_node:19 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:13 int_node:19 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:14 int_node:26 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:14 int_node:26 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:15 int_node:27 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:15 int_node:27 link_latency:1 bw_multiplier:72
+
+ext_node:L1Cache:16 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:16 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:17 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:17 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:18 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:18 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:19 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:19 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:20 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:20 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:21 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:21 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:22 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:22 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:23 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:23 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:24 int_node:20 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:24 int_node:20 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:25 int_node:21 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:25 int_node:21 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:26 int_node:28 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:26 int_node:28 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:27 int_node:29 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:27 int_node:29 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:28 int_node:22 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:28 int_node:22 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:29 int_node:23 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:29 int_node:23 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:30 int_node:30 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:30 int_node:30 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:31 int_node:31 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:31 int_node:31 link_latency:1 bw_multiplier:72
+
+
+int_node:0 int_node:1 link_latency:2 bw_multiplier:16
+int_node:1 int_node:2 link_latency:2 bw_multiplier:16
+int_node:2 int_node:3 link_latency:2 bw_multiplier:16
+int_node:8 int_node:9 link_latency:2 bw_multiplier:16
+int_node:9 int_node:10 link_latency:2 bw_multiplier:16
+int_node:10 int_node:11 link_latency:2 bw_multiplier:16
+int_node:16 int_node:17 link_latency:2 bw_multiplier:16
+int_node:17 int_node:18 link_latency:2 bw_multiplier:16
+int_node:18 int_node:19 link_latency:2 bw_multiplier:16
+int_node:24 int_node:25 link_latency:2 bw_multiplier:16
+int_node:25 int_node:26 link_latency:2 bw_multiplier:16
+int_node:26 int_node:27 link_latency:2 bw_multiplier:16
+int_node:0 int_node:8 link_latency:2 bw_multiplier:16
+int_node:8 int_node:16 link_latency:2 bw_multiplier:16
+int_node:16 int_node:24 link_latency:2 bw_multiplier:16
+int_node:1 int_node:9 link_latency:2 bw_multiplier:16
+int_node:9 int_node:17 link_latency:2 bw_multiplier:16
+int_node:17 int_node:25 link_latency:2 bw_multiplier:16
+int_node:2 int_node:10 link_latency:2 bw_multiplier:16
+int_node:10 int_node:18 link_latency:2 bw_multiplier:16
+int_node:18 int_node:26 link_latency:2 bw_multiplier:16
+int_node:3 int_node:11 link_latency:2 bw_multiplier:16
+int_node:11 int_node:19 link_latency:2 bw_multiplier:16
+int_node:19 int_node:27 link_latency:2 bw_multiplier:16
+
+int_node:4 int_node:5 link_latency:2 bw_multiplier:16
+int_node:5 int_node:6 link_latency:2 bw_multiplier:16
+int_node:6 int_node:7 link_latency:2 bw_multiplier:16
+int_node:12 int_node:13 link_latency:2 bw_multiplier:16
+int_node:13 int_node:14 link_latency:2 bw_multiplier:16
+int_node:14 int_node:15 link_latency:2 bw_multiplier:16
+int_node:20 int_node:21 link_latency:2 bw_multiplier:16
+int_node:21 int_node:22 link_latency:2 bw_multiplier:16
+int_node:22 int_node:23 link_latency:2 bw_multiplier:16
+int_node:28 int_node:29 link_latency:2 bw_multiplier:16
+int_node:29 int_node:30 link_latency:2 bw_multiplier:16
+int_node:30 int_node:31 link_latency:2 bw_multiplier:16
+int_node:4 int_node:12 link_latency:2 bw_multiplier:16
+int_node:12 int_node:20 link_latency:2 bw_multiplier:16
+int_node:20 int_node:28 link_latency:2 bw_multiplier:16
+int_node:5 int_node:13 link_latency:2 bw_multiplier:16
+int_node:13 int_node:21 link_latency:2 bw_multiplier:16
+int_node:21 int_node:29 link_latency:2 bw_multiplier:16
+int_node:6 int_node:14 link_latency:2 bw_multiplier:16
+int_node:14 int_node:22 link_latency:2 bw_multiplier:16
+int_node:22 int_node:30 link_latency:2 bw_multiplier:16
+int_node:7 int_node:15 link_latency:2 bw_multiplier:16
+int_node:15 int_node:23 link_latency:2 bw_multiplier:16
+int_node:23 int_node:31 link_latency:2 bw_multiplier:16
+
+int_node:3 int_node:4 link_latency:2 bw_multiplier:16
+int_node:11 int_node:12 link_latency:2 bw_multiplier:16
+int_node:19 int_node:20 link_latency:2 bw_multiplier:16
+int_node:27 int_node:28 link_latency:2 bw_multiplier:16
+
+
+ext_node:Directory:0 int_node:0 link_latency:20 bw_multiplier:80
+ext_node:Directory:4 int_node:1 link_latency:20 bw_multiplier:80
+ext_node:Directory:8 int_node:2 link_latency:20 bw_multiplier:80
+ext_node:Directory:12 int_node:3 link_latency:20 bw_multiplier:80
+ext_node:Directory:1 int_node:4 link_latency:20 bw_multiplier:80
+ext_node:Directory:5 int_node:5 link_latency:20 bw_multiplier:80
+ext_node:Directory:9 int_node:6 link_latency:20 bw_multiplier:80
+ext_node:Directory:13 int_node:7 link_latency:20 bw_multiplier:80
+
+ext_node:Directory:2 int_node:24 link_latency:20 bw_multiplier:80
+ext_node:Directory:6 int_node:25 link_latency:20 bw_multiplier:80
+ext_node:Directory:10 int_node:26 link_latency:20 bw_multiplier:80
+ext_node:Directory:14 int_node:27 link_latency:20 bw_multiplier:80
+ext_node:Directory:3 int_node:28 link_latency:20 bw_multiplier:80
+ext_node:Directory:7 int_node:29 link_latency:20 bw_multiplier:80
+ext_node:Directory:11 int_node:30 link_latency:20 bw_multiplier:80
+ext_node:Directory:15 int_node:31 link_latency:20 bw_multiplier:80
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-4.txt
new file mode 100644
index 000000000..f9eb088b7
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-32_ProcsPerChip-32_L2Banks-32_Memories-4.txt
@@ -0,0 +1,126 @@
+
+processors:32
+procs_per_chip:32
+L2banks:32
+memories:4
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:8 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:9 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:10 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:11 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:12 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:13 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:14 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:15 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:16 int_node:16 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:17 int_node:17 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:18 int_node:18 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:19 int_node:19 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:20 int_node:20 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:21 int_node:21 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:22 int_node:22 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:23 int_node:23 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:24 int_node:24 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:25 int_node:25 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:26 int_node:26 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:27 int_node:27 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:28 int_node:28 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:29 int_node:29 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:30 int_node:30 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:31 int_node:31 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:8 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:9 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:10 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:11 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:12 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:13 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:14 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:15 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:16 int_node:16 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:17 int_node:17 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:18 int_node:18 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:19 int_node:19 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:20 int_node:20 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:21 int_node:21 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:22 int_node:22 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:23 int_node:23 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:24 int_node:24 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:25 int_node:25 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:26 int_node:26 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:27 int_node:27 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:28 int_node:28 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:29 int_node:29 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:30 int_node:30 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:31 int_node:31 link_latency:1 bw_multiplier:72
+ext_node:Directory:0 int_node:0 link_latency:1 bw_multiplier:80
+ext_node:Directory:1 int_node:7 link_latency:1 bw_multiplier:80
+ext_node:Directory:2 int_node:24 link_latency:1 bw_multiplier:80
+ext_node:Directory:3 int_node:31 link_latency:1 bw_multiplier:80
+int_node:0 int_node:1 link_latency:1 bw_multiplier:72
+int_node:1 int_node:2 link_latency:1 bw_multiplier:72
+int_node:2 int_node:3 link_latency:1 bw_multiplier:72
+int_node:3 int_node:4 link_latency:1 bw_multiplier:72
+int_node:4 int_node:5 link_latency:1 bw_multiplier:72
+int_node:5 int_node:6 link_latency:1 bw_multiplier:72
+int_node:6 int_node:7 link_latency:1 bw_multiplier:72
+int_node:8 int_node:9 link_latency:1 bw_multiplier:72
+int_node:9 int_node:10 link_latency:1 bw_multiplier:72
+int_node:10 int_node:11 link_latency:1 bw_multiplier:72
+int_node:11 int_node:12 link_latency:1 bw_multiplier:72
+int_node:12 int_node:13 link_latency:1 bw_multiplier:72
+int_node:13 int_node:14 link_latency:1 bw_multiplier:72
+int_node:14 int_node:15 link_latency:1 bw_multiplier:72
+int_node:16 int_node:17 link_latency:1 bw_multiplier:72
+int_node:17 int_node:18 link_latency:1 bw_multiplier:72
+int_node:18 int_node:19 link_latency:1 bw_multiplier:72
+int_node:19 int_node:20 link_latency:1 bw_multiplier:72
+int_node:20 int_node:21 link_latency:1 bw_multiplier:72
+int_node:21 int_node:22 link_latency:1 bw_multiplier:72
+int_node:22 int_node:23 link_latency:1 bw_multiplier:72
+int_node:24 int_node:25 link_latency:1 bw_multiplier:72
+int_node:25 int_node:26 link_latency:1 bw_multiplier:72
+int_node:26 int_node:27 link_latency:1 bw_multiplier:72
+int_node:27 int_node:28 link_latency:1 bw_multiplier:72
+int_node:28 int_node:29 link_latency:1 bw_multiplier:72
+int_node:29 int_node:30 link_latency:1 bw_multiplier:72
+int_node:30 int_node:31 link_latency:1 bw_multiplier:72
+int_node:0 int_node:8 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:1 int_node:9 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:2 int_node:10 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:3 int_node:11 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:4 int_node:12 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:5 int_node:13 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:6 int_node:14 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:7 int_node:15 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:8 int_node:16 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:9 int_node:17 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:10 int_node:18 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:11 int_node:19 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:12 int_node:20 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:13 int_node:21 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:14 int_node:22 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:15 int_node:23 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:16 int_node:24 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:17 int_node:25 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:18 int_node:26 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:19 int_node:27 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:20 int_node:28 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:21 int_node:29 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:22 int_node:30 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:23 int_node:31 link_latency:1 bw_multiplier:72 link_weight:2
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-1_L2Banks-4_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-1_L2Banks-4_Memories-4.txt
new file mode 100644
index 000000000..ffbe7a7ff
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-1_L2Banks-4_Memories-4.txt
@@ -0,0 +1,28 @@
+
+processors:4
+procs_per_chip:1
+L2banks:4
+memories:4
+bw_unit:10000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:0 link_latency:40 bw_multiplier:10
+int_node:0 int_node:1 link_latency:40 bw_multiplier:16
+int_node:0 int_node:2 link_latency:40 bw_multiplier:16
+int_node:0 int_node:3 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:1 link_latency:40 bw_multiplier:10
+int_node:1 int_node:2 link_latency:40 bw_multiplier:16
+int_node:1 int_node:3 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:Directory:2 int_node:2 link_latency:40 bw_multiplier:10
+int_node:2 int_node:3 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:3 int_node:3 link_latency:40 bw_multiplier:10
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-4_L2Banks-4_Memories-4.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-4_L2Banks-4_Memories-4.txt
new file mode 100644
index 000000000..2cce39750
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-4_ProcsPerChip-4_L2Banks-4_Memories-4.txt
@@ -0,0 +1,24 @@
+
+processors:4
+procs_per_chip:4
+L2banks:4
+memories:4
+bw_unit:10000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:0 link_latency:1 bw_multiplier:10
+ext_node:Directory:1 int_node:1 link_latency:1 bw_multiplier:10
+ext_node:Directory:2 int_node:2 link_latency:1 bw_multiplier:10
+ext_node:Directory:3 int_node:3 link_latency:1 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16 link_weight:1
+int_node:0 int_node:2 link_latency:1 bw_multiplier:16 link_weight:2
+int_node:2 int_node:3 link_latency:1 bw_multiplier:16 link_weight:1
+int_node:1 int_node:3 link_latency:1 bw_multiplier:16 link_weight:2
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-7_ProcsPerChip-7_L2Banks-7_Memories-7.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-7_ProcsPerChip-7_L2Banks-7_Memories-7.txt
new file mode 100644
index 000000000..e3d6b0fc3
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-7_ProcsPerChip-7_L2Banks-7_Memories-7.txt
@@ -0,0 +1,139 @@
+
+processors:7
+procs_per_chip:7
+L2banks:7
+memories:7
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:4 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:5 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:6 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:7 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:8 int_node:8 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:9 int_node:9 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:10 int_node:10 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:11 int_node:11 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:12 int_node:12 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:13 int_node:13 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:14 int_node:14 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:15 int_node:15 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:16 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:17 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:18 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:19 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:20 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:21 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:22 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:23 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:8 int_node:24 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:9 int_node:25 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:10 int_node:26 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:11 int_node:27 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:12 int_node:28 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:13 int_node:29 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:14 int_node:30 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:15 int_node:31 link_latency:1 bw_multiplier:72
+ext_node:Directory:0 int_node:32 link_latency:1 bw_multiplier:80
+ext_node:Directory:1 int_node:33 link_latency:1 bw_multiplier:80
+ext_node:Directory:2 int_node:34 link_latency:1 bw_multiplier:80
+ext_node:Directory:3 int_node:35 link_latency:1 bw_multiplier:80
+ext_node:Directory:4 int_node:36 link_latency:1 bw_multiplier:80
+ext_node:Directory:5 int_node:37 link_latency:1 bw_multiplier:80
+ext_node:Directory:6 int_node:38 link_latency:1 bw_multiplier:80
+ext_node:Directory:7 int_node:39 link_latency:1 bw_multiplier:80
+ext_node:Directory:8 int_node:40 link_latency:1 bw_multiplier:80
+ext_node:Directory:9 int_node:41 link_latency:1 bw_multiplier:80
+ext_node:Directory:10 int_node:42 link_latency:1 bw_multiplier:80
+ext_node:Directory:11 int_node:43 link_latency:1 bw_multiplier:80
+ext_node:Directory:12 int_node:44 link_latency:1 bw_multiplier:80
+ext_node:Directory:13 int_node:45 link_latency:1 bw_multiplier:80
+ext_node:Directory:14 int_node:46 link_latency:1 bw_multiplier:80
+ext_node:Directory:15 int_node:47 link_latency:1 bw_multiplier:80
+ext_node:Directory:16 int_node:48 link_latency:1 bw_multiplier:80
+int_node:0 int_node:1 link_latency:1 bw_multiplier:72
+int_node:1 int_node:2 link_latency:1 bw_multiplier:72
+int_node:2 int_node:3 link_latency:1 bw_multiplier:72
+int_node:3 int_node:4 link_latency:1 bw_multiplier:72
+int_node:4 int_node:5 link_latency:1 bw_multiplier:72
+int_node:5 int_node:6 link_latency:1 bw_multiplier:72
+int_node:7 int_node:8 link_latency:1 bw_multiplier:72
+int_node:8 int_node:9 link_latency:1 bw_multiplier:72
+int_node:9 int_node:10 link_latency:1 bw_multiplier:72
+int_node:10 int_node:11 link_latency:1 bw_multiplier:72
+int_node:11 int_node:12 link_latency:1 bw_multiplier:72
+int_node:12 int_node:13 link_latency:1 bw_multiplier:72
+int_node:14 int_node:15 link_latency:1 bw_multiplier:72
+int_node:15 int_node:16 link_latency:1 bw_multiplier:72
+int_node:16 int_node:17 link_latency:1 bw_multiplier:72
+int_node:17 int_node:18 link_latency:1 bw_multiplier:72
+int_node:18 int_node:19 link_latency:1 bw_multiplier:72
+int_node:19 int_node:20 link_latency:1 bw_multiplier:72
+int_node:21 int_node:22 link_latency:1 bw_multiplier:72
+int_node:22 int_node:23 link_latency:1 bw_multiplier:72
+int_node:23 int_node:24 link_latency:1 bw_multiplier:72
+int_node:24 int_node:25 link_latency:1 bw_multiplier:72
+int_node:25 int_node:26 link_latency:1 bw_multiplier:72
+int_node:26 int_node:27 link_latency:1 bw_multiplier:72
+int_node:28 int_node:29 link_latency:1 bw_multiplier:72
+int_node:29 int_node:30 link_latency:1 bw_multiplier:72
+int_node:30 int_node:31 link_latency:1 bw_multiplier:72
+int_node:31 int_node:32 link_latency:1 bw_multiplier:72
+int_node:32 int_node:33 link_latency:1 bw_multiplier:72
+int_node:33 int_node:34 link_latency:1 bw_multiplier:72
+int_node:35 int_node:36 link_latency:1 bw_multiplier:72
+int_node:36 int_node:37 link_latency:1 bw_multiplier:72
+int_node:37 int_node:38 link_latency:1 bw_multiplier:72
+int_node:38 int_node:39 link_latency:1 bw_multiplier:72
+int_node:39 int_node:40 link_latency:1 bw_multiplier:72
+int_node:40 int_node:41 link_latency:1 bw_multiplier:72
+int_node:42 int_node:43 link_latency:1 bw_multiplier:72
+int_node:43 int_node:44 link_latency:1 bw_multiplier:72
+int_node:44 int_node:45 link_latency:1 bw_multiplier:72
+int_node:45 int_node:46 link_latency:1 bw_multiplier:72
+int_node:46 int_node:47 link_latency:1 bw_multiplier:72
+int_node:47 int_node:48 link_latency:1 bw_multiplier:72
+int_node:0 int_node:7 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:1 int_node:8 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:2 int_node:9 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:3 int_node:10 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:4 int_node:11 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:5 int_node:12 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:6 int_node:13 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:7 int_node:14 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:8 int_node:15 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:9 int_node:16 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:10 int_node:17 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:11 int_node:18 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:12 int_node:19 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:13 int_node:20 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:14 int_node:21 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:15 int_node:22 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:16 int_node:23 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:17 int_node:24 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:18 int_node:25 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:19 int_node:26 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:20 int_node:27 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:21 int_node:28 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:22 int_node:29 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:23 int_node:30 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:24 int_node:31 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:25 int_node:32 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:26 int_node:33 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:27 int_node:34 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:28 int_node:35 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:29 int_node:36 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:30 int_node:37 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:31 int_node:38 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:32 int_node:39 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:33 int_node:40 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:34 int_node:41 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:35 int_node:42 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:36 int_node:43 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:37 int_node:44 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:38 int_node:45 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:39 int_node:46 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:40 int_node:47 link_latency:1 bw_multiplier:72 link_weight:2
+int_node:41 int_node:48 link_latency:1 bw_multiplier:72 link_weight:2
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-1_L2Banks-8_Memories-8.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-1_L2Banks-8_Memories-8.txt
new file mode 100644
index 000000000..3603077c0
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-1_L2Banks-8_Memories-8.txt
@@ -0,0 +1,66 @@
+
+processors:8
+procs_per_chip:1
+L2banks:8
+memories:8
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:0 link_latency:40 bw_multiplier:10
+int_node:0 int_node:1 link_latency:40 bw_multiplier:16
+int_node:0 int_node:2 link_latency:40 bw_multiplier:16
+int_node:0 int_node:3 link_latency:40 bw_multiplier:16
+int_node:0 int_node:4 link_latency:40 bw_multiplier:16
+int_node:0 int_node:5 link_latency:40 bw_multiplier:16
+int_node:0 int_node:6 link_latency:40 bw_multiplier:16
+int_node:0 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:Directory:1 int_node:1 link_latency:40 bw_multiplier:10
+int_node:1 int_node:2 link_latency:40 bw_multiplier:16
+int_node:1 int_node:3 link_latency:40 bw_multiplier:16
+int_node:1 int_node:4 link_latency:40 bw_multiplier:16
+int_node:1 int_node:5 link_latency:40 bw_multiplier:16
+int_node:1 int_node:6 link_latency:40 bw_multiplier:16
+int_node:1 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:Directory:2 int_node:2 link_latency:40 bw_multiplier:10
+int_node:2 int_node:3 link_latency:40 bw_multiplier:16
+int_node:2 int_node:4 link_latency:40 bw_multiplier:16
+int_node:2 int_node:5 link_latency:40 bw_multiplier:16
+int_node:2 int_node:6 link_latency:40 bw_multiplier:16
+int_node:2 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:3 int_node:3 link_latency:40 bw_multiplier:10
+int_node:3 int_node:4 link_latency:40 bw_multiplier:16
+int_node:3 int_node:5 link_latency:40 bw_multiplier:16
+int_node:3 int_node:6 link_latency:40 bw_multiplier:16
+int_node:3 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:4 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:Directory:4 int_node:4 link_latency:40 bw_multiplier:10
+int_node:4 int_node:5 link_latency:40 bw_multiplier:16
+int_node:4 int_node:6 link_latency:40 bw_multiplier:16
+int_node:4 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:5 int_node:5 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:5 link_latency:1 bw_multiplier:64
+ext_node:Directory:5 int_node:5 link_latency:40 bw_multiplier:10
+int_node:5 int_node:6 link_latency:40 bw_multiplier:16
+int_node:5 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:6 int_node:6 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:6 link_latency:1 bw_multiplier:64
+ext_node:Directory:6 int_node:6 link_latency:40 bw_multiplier:10
+int_node:6 int_node:7 link_latency:40 bw_multiplier:16
+
+ext_node:L1Cache:7 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:Directory:7 int_node:7 link_latency:40 bw_multiplier:10
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-4_L2Banks-8_Memories-8.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-4_L2Banks-8_Memories-8.txt
new file mode 100644
index 000000000..bdcb02297
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-4_L2Banks-8_Memories-8.txt
@@ -0,0 +1,46 @@
+
+processors:8
+procs_per_chip:4
+L2banks:8
+memories:8
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:1 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:2 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:3 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:1 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:2 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:3 int_node:6 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:4 link_latency:1 bw_multiplier:16
+int_node:4 int_node:3 link_latency:1 bw_multiplier:16
+int_node:3 int_node:2 link_latency:1 bw_multiplier:16
+int_node:5 int_node:4 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:20 bw_multiplier:10
+
+int_node:5 int_node:12 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:7 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:9 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:10 link_latency:1 bw_multiplier:64
+ext_node:Directory:4 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:5 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:6 int_node:13 link_latency:20 bw_multiplier:10
+ext_node:Directory:7 int_node:13 link_latency:20 bw_multiplier:10
+int_node:7 int_node:8 link_latency:1 bw_multiplier:16
+int_node:8 int_node:11 link_latency:1 bw_multiplier:16
+int_node:11 int_node:10 link_latency:1 bw_multiplier:16
+int_node:10 int_node:9 link_latency:1 bw_multiplier:16
+int_node:12 int_node:11 link_latency:1 bw_multiplier:16
+int_node:12 int_node:13 link_latency:20 bw_multiplier:10
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt
new file mode 100644
index 000000000..ecf52ab8f
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt
@@ -0,0 +1,412 @@
+
+processors:8
+procs_per_chip:8
+L2banks:256
+memories:8
+
+ext_node:L1Cache:0 int_node:1 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:5 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:15 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:47 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:62 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:58 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:48 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:16 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:0 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:1 int_node:0 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:2 int_node:1 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:3 int_node:1 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:4 int_node:2 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:5 int_node:2 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:128 int_node:3 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:144 int_node:3 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:16 int_node:4 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:17 int_node:4 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:18 int_node:5 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:19 int_node:5 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:20 int_node:6 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:21 int_node:6 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:32 int_node:7 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:33 int_node:7 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:6 int_node:0 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:7 int_node:0 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:8 int_node:1 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:9 int_node:1 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:10 int_node:2 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:11 int_node:2 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:129 int_node:3 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:145 int_node:3 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:22 int_node:4 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:23 int_node:4 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:24 int_node:5 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:25 int_node:5 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:26 int_node:6 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:27 int_node:6 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:34 int_node:7 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:35 int_node:7 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:112 int_node:8 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:113 int_node:8 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:12 int_node:9 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:13 int_node:9 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:130 int_node:10 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:131 int_node:10 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:132 int_node:11 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:146 int_node:11 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:147 int_node:12 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:148 int_node:12 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:28 int_node:13 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:29 int_node:13 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:36 int_node:14 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:37 int_node:14 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:38 int_node:15 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:39 int_node:15 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:114 int_node:8 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:115 int_node:8 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:14 int_node:9 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:15 int_node:9 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:133 int_node:10 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:134 int_node:10 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:135 int_node:11 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:149 int_node:11 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:150 int_node:12 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:151 int_node:12 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:30 int_node:13 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:31 int_node:13 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:40 int_node:14 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:41 int_node:14 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:42 int_node:15 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:43 int_node:15 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:116 int_node:16 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:117 int_node:16 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:118 int_node:17 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:119 int_node:17 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:136 int_node:18 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:137 int_node:18 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:138 int_node:19 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:152 int_node:19 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:153 int_node:20 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:154 int_node:20 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:160 int_node:21 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:161 int_node:21 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:162 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:163 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:44 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:45 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:120 int_node:16 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:121 int_node:16 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:122 int_node:17 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:123 int_node:17 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:139 int_node:18 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:140 int_node:18 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:141 int_node:19 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:155 int_node:19 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:156 int_node:20 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:157 int_node:20 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:164 int_node:21 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:165 int_node:21 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:166 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:167 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:46 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:47 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:124 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:125 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:240 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:241 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:242 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:243 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:142 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:158 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:168 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:169 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:170 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:171 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:172 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:173 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:174 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:175 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:126 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:127 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:244 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:245 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:246 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:247 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:143 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:159 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:176 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:177 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:178 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:179 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:180 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:181 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:182 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:183 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:248 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:249 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:250 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:251 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:252 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:253 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:254 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:255 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:208 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:192 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:184 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:185 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:186 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:187 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:48 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:49 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:224 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:225 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:226 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:227 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:228 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:229 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:230 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:231 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:209 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:193 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:188 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:189 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:190 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:191 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:50 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:51 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:96 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:97 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:232 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:233 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:234 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:235 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:210 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:211 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:212 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:194 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:195 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:196 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:52 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:53 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:54 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:55 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:98 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:99 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:236 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:237 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:238 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:239 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:213 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:214 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:215 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:197 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:198 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:199 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:56 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:57 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:58 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:59 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:100 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:101 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:102 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:103 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:80 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:81 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:216 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:217 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:218 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:200 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:201 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:202 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:64 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:65 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:60 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:61 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:104 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:105 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:106 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:107 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:82 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:83 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:219 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:220 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:221 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:203 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:204 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:205 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:66 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:67 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:62 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:63 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:108 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:109 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:84 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:85 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:86 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:87 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:88 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:89 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:222 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:206 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:68 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:69 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:70 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:71 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:72 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:73 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:110 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:111 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:90 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:91 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:92 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:93 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:94 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:95 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:223 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:207 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:74 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:75 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:76 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:77 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:78 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:79 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+int_node:65 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:0 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:1 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:2 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:3 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:4 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:5 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:6 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:7 int_node:64 link_weight:1000 link_latency:20 bw_multiplier:32
+int_node:27 int_node:65 link_weight:1000 link_latency:1 bw_multiplier:64
+int_node:28 int_node:65 link_weight:1000 link_latency:1 bw_multiplier:64
+int_node:35 int_node:65 link_weight:1000 link_latency:1 bw_multiplier:64
+int_node:36 int_node:65 link_weight:1000 link_latency:1 bw_multiplier:64
+
+int_node:0 int_node:1 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:1 int_node:2 link_weight:2 link_latency:1 bw_multiplier:32
+int_node:2 int_node:3 link_weight:3 link_latency:1 bw_multiplier:32
+int_node:3 int_node:4 link_weight:4 link_latency:1 bw_multiplier:32
+int_node:4 int_node:5 link_weight:5 link_latency:1 bw_multiplier:32
+int_node:5 int_node:6 link_weight:6 link_latency:1 bw_multiplier:32
+int_node:6 int_node:7 link_weight:7 link_latency:1 bw_multiplier:32
+
+int_node:8 int_node:9 link_weight:8 link_latency:1 bw_multiplier:32
+int_node:9 int_node:10 link_weight:9 link_latency:1 bw_multiplier:32
+int_node:10 int_node:11 link_weight:10 link_latency:1 bw_multiplier:32
+int_node:11 int_node:12 link_weight:11 link_latency:1 bw_multiplier:32
+int_node:12 int_node:13 link_weight:12 link_latency:1 bw_multiplier:32
+int_node:13 int_node:14 link_weight:13 link_latency:1 bw_multiplier:32
+int_node:14 int_node:15 link_weight:14 link_latency:1 bw_multiplier:32
+
+int_node:16 int_node:17 link_weight:15 link_latency:1 bw_multiplier:32
+int_node:17 int_node:18 link_weight:16 link_latency:1 bw_multiplier:32
+int_node:18 int_node:19 link_weight:17 link_latency:1 bw_multiplier:32
+int_node:19 int_node:20 link_weight:18 link_latency:1 bw_multiplier:32
+int_node:20 int_node:21 link_weight:19 link_latency:1 bw_multiplier:32
+int_node:21 int_node:22 link_weight:20 link_latency:1 bw_multiplier:32
+int_node:22 int_node:23 link_weight:21 link_latency:1 bw_multiplier:32
+
+int_node:24 int_node:25 link_weight:22 link_latency:1 bw_multiplier:32
+int_node:25 int_node:26 link_weight:23 link_latency:1 bw_multiplier:32
+int_node:26 int_node:27 link_weight:24 link_latency:1 bw_multiplier:32
+int_node:27 int_node:28 link_weight:25 link_latency:1 bw_multiplier:32
+int_node:28 int_node:29 link_weight:26 link_latency:1 bw_multiplier:32
+int_node:29 int_node:30 link_weight:27 link_latency:1 bw_multiplier:32
+int_node:30 int_node:31 link_weight:28 link_latency:1 bw_multiplier:32
+
+int_node:32 int_node:33 link_weight:29 link_latency:1 bw_multiplier:32
+int_node:33 int_node:34 link_weight:30 link_latency:1 bw_multiplier:32
+int_node:34 int_node:35 link_weight:31 link_latency:1 bw_multiplier:32
+int_node:35 int_node:36 link_weight:32 link_latency:1 bw_multiplier:32
+int_node:36 int_node:37 link_weight:33 link_latency:1 bw_multiplier:32
+int_node:37 int_node:38 link_weight:34 link_latency:1 bw_multiplier:32
+int_node:38 int_node:39 link_weight:35 link_latency:1 bw_multiplier:32
+
+int_node:40 int_node:41 link_weight:36 link_latency:1 bw_multiplier:32
+int_node:41 int_node:42 link_weight:37 link_latency:1 bw_multiplier:32
+int_node:42 int_node:43 link_weight:38 link_latency:1 bw_multiplier:32
+int_node:43 int_node:44 link_weight:39 link_latency:1 bw_multiplier:32
+int_node:44 int_node:45 link_weight:40 link_latency:1 bw_multiplier:32
+int_node:45 int_node:46 link_weight:41 link_latency:1 bw_multiplier:32
+int_node:46 int_node:47 link_weight:42 link_latency:1 bw_multiplier:32
+
+int_node:48 int_node:49 link_weight:43 link_latency:1 bw_multiplier:32
+int_node:49 int_node:50 link_weight:44 link_latency:1 bw_multiplier:32
+int_node:50 int_node:51 link_weight:45 link_latency:1 bw_multiplier:32
+int_node:51 int_node:52 link_weight:46 link_latency:1 bw_multiplier:32
+int_node:52 int_node:53 link_weight:47 link_latency:1 bw_multiplier:32
+int_node:53 int_node:54 link_weight:48 link_latency:1 bw_multiplier:32
+int_node:54 int_node:55 link_weight:49 link_latency:1 bw_multiplier:32
+
+int_node:56 int_node:57 link_weight:50 link_latency:1 bw_multiplier:32
+int_node:57 int_node:58 link_weight:51 link_latency:1 bw_multiplier:32
+int_node:58 int_node:59 link_weight:52 link_latency:1 bw_multiplier:32
+int_node:59 int_node:60 link_weight:53 link_latency:1 bw_multiplier:32
+int_node:60 int_node:61 link_weight:54 link_latency:1 bw_multiplier:32
+int_node:61 int_node:62 link_weight:55 link_latency:1 bw_multiplier:32
+int_node:62 int_node:63 link_weight:56 link_latency:1 bw_multiplier:32
+
+
+int_node:0 int_node:8 link_weight:57 link_latency:1 bw_multiplier:32
+int_node:1 int_node:9 link_weight:58 link_latency:1 bw_multiplier:32
+int_node:2 int_node:10 link_weight:59 link_latency:1 bw_multiplier:32
+int_node:3 int_node:11 link_weight:60 link_latency:1 bw_multiplier:32
+int_node:4 int_node:12 link_weight:61 link_latency:1 bw_multiplier:32
+int_node:5 int_node:13 link_weight:62 link_latency:1 bw_multiplier:32
+int_node:6 int_node:14 link_weight:63 link_latency:1 bw_multiplier:32
+int_node:7 int_node:15 link_weight:64 link_latency:1 bw_multiplier:32
+
+int_node:8 int_node:16 link_weight:65 link_latency:1 bw_multiplier:32
+int_node:9 int_node:17 link_weight:66 link_latency:1 bw_multiplier:32
+int_node:10 int_node:18 link_weight:67 link_latency:1 bw_multiplier:32
+int_node:11 int_node:19 link_weight:68 link_latency:1 bw_multiplier:32
+int_node:12 int_node:20 link_weight:69 link_latency:1 bw_multiplier:32
+int_node:13 int_node:21 link_weight:70 link_latency:1 bw_multiplier:32
+int_node:14 int_node:22 link_weight:71 link_latency:1 bw_multiplier:32
+int_node:15 int_node:23 link_weight:72 link_latency:1 bw_multiplier:32
+
+int_node:16 int_node:24 link_weight:73 link_latency:1 bw_multiplier:32
+int_node:17 int_node:25 link_weight:74 link_latency:1 bw_multiplier:32
+int_node:18 int_node:26 link_weight:75 link_latency:1 bw_multiplier:32
+int_node:19 int_node:27 link_weight:76 link_latency:1 bw_multiplier:32
+int_node:20 int_node:28 link_weight:77 link_latency:1 bw_multiplier:32
+int_node:21 int_node:29 link_weight:78 link_latency:1 bw_multiplier:32
+int_node:22 int_node:30 link_weight:79 link_latency:1 bw_multiplier:32
+int_node:23 int_node:31 link_weight:80 link_latency:1 bw_multiplier:32
+
+int_node:24 int_node:32 link_weight:81 link_latency:1 bw_multiplier:32
+int_node:25 int_node:33 link_weight:82 link_latency:1 bw_multiplier:32
+int_node:26 int_node:34 link_weight:83 link_latency:1 bw_multiplier:32
+int_node:27 int_node:35 link_weight:84 link_latency:1 bw_multiplier:32
+int_node:28 int_node:36 link_weight:85 link_latency:1 bw_multiplier:32
+int_node:29 int_node:37 link_weight:86 link_latency:1 bw_multiplier:32
+int_node:30 int_node:38 link_weight:87 link_latency:1 bw_multiplier:32
+int_node:31 int_node:39 link_weight:88 link_latency:1 bw_multiplier:32
+
+int_node:32 int_node:40 link_weight:89 link_latency:1 bw_multiplier:32
+int_node:33 int_node:41 link_weight:90 link_latency:1 bw_multiplier:32
+int_node:34 int_node:42 link_weight:91 link_latency:1 bw_multiplier:32
+int_node:35 int_node:43 link_weight:92 link_latency:1 bw_multiplier:32
+int_node:36 int_node:44 link_weight:93 link_latency:1 bw_multiplier:32
+int_node:37 int_node:45 link_weight:94 link_latency:1 bw_multiplier:32
+int_node:38 int_node:46 link_weight:95 link_latency:1 bw_multiplier:32
+int_node:39 int_node:47 link_weight:96 link_latency:1 bw_multiplier:32
+
+int_node:40 int_node:48 link_weight:97 link_latency:1 bw_multiplier:32
+int_node:41 int_node:49 link_weight:98 link_latency:1 bw_multiplier:32
+int_node:42 int_node:50 link_weight:99 link_latency:1 bw_multiplier:32
+int_node:43 int_node:51 link_weight:100 link_latency:1 bw_multiplier:32
+int_node:44 int_node:52 link_weight:101 link_latency:1 bw_multiplier:32
+int_node:45 int_node:53 link_weight:102 link_latency:1 bw_multiplier:32
+int_node:46 int_node:54 link_weight:103 link_latency:1 bw_multiplier:32
+int_node:47 int_node:55 link_weight:104 link_latency:1 bw_multiplier:32
+
+int_node:48 int_node:56 link_weight:105 link_latency:1 bw_multiplier:32
+int_node:49 int_node:57 link_weight:106 link_latency:1 bw_multiplier:32
+int_node:50 int_node:58 link_weight:107 link_latency:1 bw_multiplier:32
+int_node:51 int_node:59 link_weight:108 link_latency:1 bw_multiplier:32
+int_node:52 int_node:60 link_weight:109 link_latency:1 bw_multiplier:32
+int_node:53 int_node:61 link_weight:110 link_latency:1 bw_multiplier:32
+int_node:54 int_node:62 link_weight:111 link_latency:1 bw_multiplier:32
+int_node:55 int_node:63 link_weight:112 link_latency:1 bw_multiplier:32
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-8_Memories-8.txt b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-8_Memories-8.txt
new file mode 100644
index 000000000..acfc124a4
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NUCA_Procs-8_ProcsPerChip-8_L2Banks-8_Memories-8.txt
@@ -0,0 +1,44 @@
+
+processors:8
+procs_per_chip:8
+L2banks:8
+memories:8
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:3 link_latency:1 bw_multiplier:72
+
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:1 int_node:0 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:2 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:3 int_node:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:4 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:5 int_node:2 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:6 int_node:3 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:7 int_node:3 link_latency:1 bw_multiplier:72
+
+int_node:0 int_node:4 link_latency:1 bw_multiplier:72
+int_node:1 int_node:4 link_latency:1 bw_multiplier:72
+int_node:2 int_node:5 link_latency:1 bw_multiplier:72
+int_node:3 int_node:5 link_latency:1 bw_multiplier:72
+
+int_node:4 int_node:5 link_latency:1 bw_multiplier:72
+int_node:4 int_node:6 link_latency:1 bw_multiplier:72
+int_node:5 int_node:6 link_latency:1 bw_multiplier:72
+
+int_node:6 int_node:7 link_latency:20 bw_multiplier:10
+
+ext_node:Directory:0 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:1 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:2 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:3 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:4 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:5 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:6 int_node:7 link_latency:20 bw_multiplier:80
+ext_node:Directory:7 int_node:7 link_latency:20 bw_multiplier:80
+
diff --git a/src/mem/ruby/network/simple/Network_Files/NetworkFileMaker.py b/src/mem/ruby/network/simple/Network_Files/NetworkFileMaker.py
new file mode 100644
index 000000000..7d07588a1
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/NetworkFileMaker.py
@@ -0,0 +1,44 @@
+#!/s/std/bin/python
+import sys, os, string, re, math
+
+rows = 0
+cols =0
+
+if len(sys.argv) == 3:
+ rows = int(sys.argv[1])
+ cols = int(sys.argv[2])
+else:
+ sys.stderr.write("usage : NetworkFileMaker.py <rows> <cols> \n\n")
+
+banks = rows*cols
+bank = 0
+while bank < banks:
+ sys.stdout.write("ext_node:L2Cache:0:bank:%d int_node:%d link_latency:1 bw_multiplier:16\n" % (bank, bank))
+ bank += 1
+
+sys.stdout.write("\n")
+
+col = 0
+while col < cols:
+ row = 1
+ bank = col*rows
+ while row < rows:
+ sys.stdout.write("int_node:%d int_node:%d link_latency:1 bw_multiplier:16\n" % (bank, bank+1))
+ bank += 1
+ row += 1
+ sys.stdout.write("\n")
+ col += 1
+
+sys.stdout.write("\n")
+
+row = 0
+while row < rows:
+ col = 1
+ bank = row
+ while col < cols:
+ sys.stdout.write("int_node:%d int_node:%d link_latency:1 bw_multiplier:16\n" % (bank, rows+bank))
+ bank += rows
+ col += 1
+ sys.stdout.write("\n")
+ row += 1
+
diff --git a/src/mem/ruby/network/simple/Network_Files/TLC_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt b/src/mem/ruby/network/simple/Network_Files/TLC_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt
new file mode 100644
index 000000000..d43386237
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/TLC_Procs-8_ProcsPerChip-8_L2Banks-256_Memories-8.txt
@@ -0,0 +1,367 @@
+
+processors:8
+procs_per_chip:8
+L2banks:256
+memories:8
+
+ext_node:L1Cache:0 int_node:0 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:1 int_node:2 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:2 int_node:2 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:3 int_node:4 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:4 int_node:0 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:5 int_node:2 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:6 int_node:2 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L1Cache:7 int_node:4 link_weight:1 link_latency:1 bw_multiplier:72
+ext_node:L2Cache:0 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:1 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:2 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:3 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:4 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:5 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:6 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:7 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:8 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:9 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:10 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:11 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:12 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:13 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:14 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:15 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:16 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:17 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:18 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:19 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:20 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:21 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:22 int_node:66 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:23 int_node:66 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:24 int_node:70 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:25 int_node:70 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:26 int_node:74 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:27 int_node:74 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:28 int_node:78 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:29 int_node:78 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:30 int_node:82 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:31 int_node:82 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:32 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:33 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:34 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:35 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:36 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:37 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:38 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:39 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:40 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:41 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:42 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:43 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:44 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:45 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:46 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:47 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:48 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:49 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:50 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:51 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:52 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:53 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:54 int_node:67 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:55 int_node:67 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:56 int_node:71 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:57 int_node:71 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:58 int_node:75 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:59 int_node:75 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:60 int_node:79 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:61 int_node:79 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:62 int_node:83 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:63 int_node:83 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:64 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:65 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:66 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:67 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:68 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:69 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:70 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:71 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:72 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:73 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:74 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:75 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:76 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:77 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:78 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:79 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:80 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:81 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:82 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:83 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:84 int_node:64 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:85 int_node:64 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:86 int_node:68 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:87 int_node:68 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:88 int_node:72 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:89 int_node:72 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:90 int_node:76 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:91 int_node:76 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:92 int_node:80 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:93 int_node:80 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:94 int_node:84 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:95 int_node:84 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:96 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:97 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:98 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:99 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:100 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:101 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:102 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:103 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:104 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:105 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:106 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:107 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:108 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:109 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:110 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:111 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:112 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:113 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:114 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:115 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:116 int_node:65 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:117 int_node:65 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:118 int_node:69 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:119 int_node:69 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:120 int_node:73 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:121 int_node:73 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:122 int_node:77 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:123 int_node:77 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:124 int_node:81 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:125 int_node:81 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:126 int_node:85 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:127 int_node:85 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:128 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:129 int_node:22 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:130 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:131 int_node:26 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:132 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:133 int_node:30 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:134 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:135 int_node:34 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:136 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:137 int_node:38 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:138 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:139 int_node:42 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:140 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:141 int_node:46 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:142 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:143 int_node:50 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:144 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:145 int_node:54 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:146 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:147 int_node:58 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:148 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:149 int_node:62 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:150 int_node:66 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:151 int_node:66 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:152 int_node:70 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:153 int_node:70 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:154 int_node:74 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:155 int_node:74 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:156 int_node:78 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:157 int_node:78 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:158 int_node:82 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:159 int_node:82 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:160 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:161 int_node:23 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:162 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:163 int_node:27 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:164 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:165 int_node:31 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:166 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:167 int_node:35 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:168 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:169 int_node:39 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:170 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:171 int_node:43 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:172 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:173 int_node:47 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:174 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:175 int_node:51 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:176 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:177 int_node:55 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:178 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:179 int_node:59 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:180 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:181 int_node:63 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:182 int_node:67 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:183 int_node:67 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:184 int_node:71 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:185 int_node:71 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:186 int_node:75 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:187 int_node:75 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:188 int_node:79 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:189 int_node:79 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:190 int_node:83 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:191 int_node:83 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:192 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:193 int_node:24 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:194 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:195 int_node:28 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:196 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:197 int_node:32 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:198 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:199 int_node:36 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:200 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:201 int_node:40 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:202 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:203 int_node:44 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:204 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:205 int_node:48 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:206 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:207 int_node:52 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:208 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:209 int_node:56 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:210 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:211 int_node:60 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:212 int_node:64 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:213 int_node:64 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:214 int_node:68 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:215 int_node:68 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:216 int_node:72 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:217 int_node:72 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:218 int_node:76 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:219 int_node:76 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:220 int_node:80 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:221 int_node:80 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:222 int_node:84 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:223 int_node:84 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:224 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:225 int_node:25 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:226 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:227 int_node:29 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:228 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:229 int_node:33 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:230 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:231 int_node:37 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:232 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:233 int_node:41 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:234 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:235 int_node:45 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:236 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:237 int_node:49 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:238 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:239 int_node:53 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:240 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:241 int_node:57 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:242 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:243 int_node:61 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:244 int_node:65 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:245 int_node:65 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:246 int_node:69 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:247 int_node:69 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:248 int_node:73 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:249 int_node:73 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:250 int_node:77 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:251 int_node:77 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:252 int_node:81 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:253 int_node:81 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:254 int_node:85 link_weight:1 link_latency:1 bw_multiplier:16
+ext_node:L2Cache:255 int_node:85 link_weight:1 link_latency:1 bw_multiplier:16
+
+int_node:22 int_node:5 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:23 int_node:5 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:24 int_node:5 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:25 int_node:5 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:26 int_node:6 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:27 int_node:6 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:28 int_node:6 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:29 int_node:6 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:30 int_node:7 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:31 int_node:7 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:32 int_node:7 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:33 int_node:7 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:34 int_node:8 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:35 int_node:8 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:36 int_node:8 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:37 int_node:8 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:38 int_node:9 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:39 int_node:9 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:40 int_node:9 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:41 int_node:9 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:42 int_node:10 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:43 int_node:10 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:44 int_node:10 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:45 int_node:10 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:46 int_node:11 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:47 int_node:11 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:48 int_node:11 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:49 int_node:11 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:50 int_node:12 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:51 int_node:12 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:52 int_node:12 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:53 int_node:12 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:54 int_node:13 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:55 int_node:13 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:56 int_node:13 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:57 int_node:13 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:58 int_node:14 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:59 int_node:14 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:60 int_node:14 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:61 int_node:14 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:62 int_node:15 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:63 int_node:15 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:64 int_node:15 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:65 int_node:15 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:66 int_node:16 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:67 int_node:16 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:68 int_node:16 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:69 int_node:16 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:70 int_node:17 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:71 int_node:17 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:72 int_node:17 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:73 int_node:17 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:74 int_node:18 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:75 int_node:18 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:76 int_node:18 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:77 int_node:18 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:78 int_node:19 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:79 int_node:19 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:80 int_node:19 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:81 int_node:19 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:82 int_node:20 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:83 int_node:20 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:84 int_node:20 link_weight:1 link_latency:1 bw_multiplier:32
+int_node:85 int_node:20 link_weight:1 link_latency:1 bw_multiplier:32
+
+int_node:2 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:0 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:1 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:2 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:3 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:4 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:5 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:6 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+ext_node:Directory:7 int_node:21 link_weight:1000 link_latency:20 bw_multiplier:32
+
+int_node:0 int_node:1 link_weight:1 link_latency:1 bw_multiplier:80
+int_node:1 int_node:2 link_weight:1 link_latency:1 bw_multiplier:80
+int_node:2 int_node:3 link_weight:1 link_latency:1 bw_multiplier:80
+int_node:3 int_node:4 link_weight:1 link_latency:1 bw_multiplier:80
+int_node:0 int_node:5 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:1 int_node:6 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:7 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:8 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:9 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:10 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:3 int_node:11 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:4 int_node:12 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:0 int_node:13 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:1 int_node:14 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:15 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:16 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:17 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:2 int_node:18 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:3 int_node:19 link_weight:1 link_latency:1 bw_multiplier:8
+int_node:4 int_node:20 link_weight:1 link_latency:1 bw_multiplier:8
+
diff --git a/src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt
new file mode 100644
index 000000000..b6b1dbd98
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-16_L2Banks-16_Memories-16.txt
@@ -0,0 +1,74 @@
+
+processors:16
+procs_per_chip:16
+L2banks:16
+memories:16
+bw_unit:10000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:4 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:8 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:12 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:1 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:2 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:3 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:4 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:5 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:6 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:7 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:8 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:9 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:10 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:11 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:12 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:13 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:14 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:15 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:0 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:1 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:2 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:3 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:4 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:5 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:6 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:7 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:8 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:9 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:10 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:11 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:12 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:13 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:14 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:15 int_node:2 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:20 bw_multiplier:16
+int_node:1 int_node:2 link_latency:20 bw_multiplier:10
+
diff --git a/src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt b/src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt
new file mode 100644
index 000000000..28a9be8f5
--- /dev/null
+++ b/src/mem/ruby/network/simple/Network_Files/TOKEN_CMP_Procs-16_ProcsPerChip-4_L2Banks-16_Memories-16.txt
@@ -0,0 +1,101 @@
+
+processors:16
+procs_per_chip:4
+L2banks:16
+memories:16
+bw_unit:1000
+
+ext_node:L1Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:1 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:2 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:3 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:0 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:1 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:2 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:3 int_node:0 link_latency:1 bw_multiplier:64
+ext_node:Directory:0 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:1 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:2 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:Directory:3 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:0 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:1 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:2 int_node:2 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:3 int_node:2 link_latency:20 bw_multiplier:10
+int_node:0 int_node:1 link_latency:1 bw_multiplier:16
+int_node:1 int_node:2 link_latency:20 bw_multiplier:10
+int_node:0 int_node:16 link_latency:1 bw_multiplier:16
+int_node:16 int_node:3 link_latency:1 bw_multiplier:16
+
+int_node:3 int_node:7 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:4 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:5 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:6 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:7 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:4 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:5 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:6 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:7 int_node:4 link_latency:1 bw_multiplier:64
+ext_node:Directory:4 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:5 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:6 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:Directory:7 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:4 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:5 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:6 int_node:6 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:7 int_node:6 link_latency:20 bw_multiplier:10
+int_node:4 int_node:5 link_latency:1 bw_multiplier:16
+int_node:5 int_node:6 link_latency:20 bw_multiplier:16
+int_node:4 int_node:17 link_latency:1 bw_multiplier:16
+int_node:17 int_node:7 link_latency:1 bw_multiplier:16
+
+int_node:7 int_node:11 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:8 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:9 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:10 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:11 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:8 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:9 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:10 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:11 int_node:8 link_latency:1 bw_multiplier:64
+ext_node:Directory:8 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:Directory:9 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:Directory:10 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:Directory:11 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:8 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:9 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:10 int_node:10 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:11 int_node:10 link_latency:20 bw_multiplier:10
+int_node:8 int_node:9 link_latency:1 bw_multiplier:16
+int_node:9 int_node:10 link_latency:20 bw_multiplier:10
+int_node:8 int_node:18 link_latency:1 bw_multiplier:16
+int_node:18 int_node:11 link_latency:1 bw_multiplier:16
+
+int_node:11 int_node:15 link_latency:20 bw_multiplier:10
+
+ext_node:L1Cache:12 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:13 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:14 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L1Cache:15 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:12 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:13 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:14 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:L2Cache:15 int_node:12 link_latency:1 bw_multiplier:64
+ext_node:Directory:12 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:Directory:13 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:Directory:14 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:Directory:15 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:12 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:13 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:14 int_node:14 link_latency:20 bw_multiplier:10
+ext_node:PersistentArbiter:15 int_node:14 link_latency:20 bw_multiplier:10
+int_node:12 int_node:13 link_latency:1 bw_multiplier:16
+int_node:13 int_node:14 link_latency:20 bw_multiplier:10
+int_node:12 int_node:19 link_latency:1 bw_multiplier:16
+int_node:19 int_node:15 link_latency:1 bw_multiplier:16
+
+int_node:15 int_node:3 link_latency:20 bw_multiplier:10
+int_node:15 int_node:7 link_latency:20 bw_multiplier:10
+int_node:11 int_node:3 link_latency:20 bw_multiplier:10
+
diff --git a/src/mem/ruby/network/simple/PerfectSwitch.cc b/src/mem/ruby/network/simple/PerfectSwitch.cc
new file mode 100644
index 000000000..a88a29e83
--- /dev/null
+++ b/src/mem/ruby/network/simple/PerfectSwitch.cc
@@ -0,0 +1,319 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * PerfectSwitch.C
+ *
+ * Description: See PerfectSwitch.h
+ *
+ * $Id$
+ *
+ */
+
+
+#include "PerfectSwitch.hh"
+#include "NetworkMessage.hh"
+#include "Profiler.hh"
+#include "System.hh"
+#include "SimpleNetwork.hh"
+#include "util.hh"
+#include "MessageBuffer.hh"
+#include "Protocol.hh"
+
+const int PRIORITY_SWITCH_LIMIT = 128;
+
+// Operator for helper class
+bool operator<(const LinkOrder& l1, const LinkOrder& l2) {
+ return (l1.m_value < l2.m_value);
+}
+
+PerfectSwitch::PerfectSwitch(SwitchID sid, SimpleNetwork* network_ptr)
+{
+ m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS; // FIXME - pass me as a parameter?
+ m_switch_id = sid;
+ m_round_robin_start = 0;
+ m_network_ptr = network_ptr;
+ m_wakeups_wo_switch = 0;
+}
+
+void PerfectSwitch::addInPort(const Vector<MessageBuffer*>& in)
+{
+ assert(in.size() == m_virtual_networks);
+ NodeID port = m_in.size();
+ m_in.insertAtBottom(in);
+ for (int j = 0; j < m_virtual_networks; j++) {
+ m_in[port][j]->setConsumer(this);
+ string desc = "[Queue from port " + NodeIDToString(m_switch_id) + " " + NodeIDToString(port) + " " + NodeIDToString(j) + " to PerfectSwitch]";
+ m_in[port][j]->setDescription(desc);
+ }
+}
+
+void PerfectSwitch::addOutPort(const Vector<MessageBuffer*>& out, const NetDest& routing_table_entry)
+{
+ assert(out.size() == m_virtual_networks);
+
+ // Setup link order
+ LinkOrder l;
+ l.m_value = 0;
+ l.m_link = m_out.size();
+ m_link_order.insertAtBottom(l);
+
+ // Add to routing table
+ m_out.insertAtBottom(out);
+ m_routing_table.insertAtBottom(routing_table_entry);
+
+ if (g_PRINT_TOPOLOGY) {
+ m_out_link_vec.insertAtBottom(out);
+ }
+}
+
+void PerfectSwitch::clearRoutingTables()
+{
+ m_routing_table.clear();
+}
+
+void PerfectSwitch::clearBuffers()
+{
+ for(int i=0; i<m_in.size(); i++){
+ for(int vnet=0; vnet < m_virtual_networks; vnet++) {
+ m_in[i][vnet]->clear();
+ }
+ }
+
+ for(int i=0; i<m_out.size(); i++){
+ for(int vnet=0; vnet < m_virtual_networks; vnet++) {
+ m_out[i][vnet]->clear();
+ }
+ }
+}
+
+void PerfectSwitch::reconfigureOutPort(const NetDest& routing_table_entry)
+{
+ m_routing_table.insertAtBottom(routing_table_entry);
+}
+
+PerfectSwitch::~PerfectSwitch()
+{
+}
+
+void PerfectSwitch::wakeup()
+{
+
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, m_switch_id);
+
+ MsgPtr msg_ptr;
+
+ // Give the highest numbered link priority most of the time
+ m_wakeups_wo_switch++;
+ int highest_prio_vnet = m_virtual_networks-1;
+ int lowest_prio_vnet = 0;
+ int decrementer = 1;
+ bool schedule_wakeup = false;
+ NetworkMessage* net_msg_ptr = NULL;
+
+ // invert priorities to avoid starvation seen in the component network
+ if (m_wakeups_wo_switch > PRIORITY_SWITCH_LIMIT) {
+ m_wakeups_wo_switch = 0;
+ highest_prio_vnet = 0;
+ lowest_prio_vnet = m_virtual_networks-1;
+ decrementer = -1;
+ }
+
+ for (int vnet = highest_prio_vnet; (vnet*decrementer) >= (decrementer*lowest_prio_vnet); vnet -= decrementer) {
+
+ // For all components incoming queues
+ int incoming = m_round_robin_start; // This is for round-robin scheduling
+ m_round_robin_start++;
+ if (m_round_robin_start >= m_in.size()) {
+ m_round_robin_start = 0;
+ }
+
+ // for all input ports, use round robin scheduling
+ for (int counter = 0; counter < m_in.size(); counter++) {
+
+ // Round robin scheduling
+ incoming++;
+ if (incoming >= m_in.size()) {
+ incoming = 0;
+ }
+
+ // temporary vectors to store the routing results
+ Vector<LinkID> output_links;
+ Vector<NetDest> output_link_destinations;
+
+ // Is there a message waiting?
+ while (m_in[incoming][vnet]->isReady()) {
+
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, incoming);
+
+ // Peek at message
+ msg_ptr = m_in[incoming][vnet]->peekMsgPtr();
+ net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, *net_msg_ptr);
+
+ output_links.clear();
+ output_link_destinations.clear();
+ NetDest msg_destinations = net_msg_ptr->getInternalDestination();
+
+ // Unfortunately, the token-protocol sends some
+ // zero-destination messages, so this assert isn't valid
+ // assert(msg_destinations.count() > 0);
+
+ assert(m_link_order.size() == m_routing_table.size());
+ assert(m_link_order.size() == m_out.size());
+
+ if (g_adaptive_routing) {
+ if (m_network_ptr->isVNetOrdered(vnet)) {
+ // Don't adaptively route
+ for (int outlink=0; outlink<m_out.size(); outlink++) {
+ m_link_order[outlink].m_link = outlink;
+ m_link_order[outlink].m_value = 0;
+ }
+ } else {
+ // Find how clogged each link is
+ for (int outlink=0; outlink<m_out.size(); outlink++) {
+ int out_queue_length = 0;
+ for (int v=0; v<m_virtual_networks; v++) {
+ out_queue_length += m_out[outlink][v]->getSize();
+ }
+ m_link_order[outlink].m_link = outlink;
+ m_link_order[outlink].m_value = 0;
+ m_link_order[outlink].m_value |= (out_queue_length << 8);
+ m_link_order[outlink].m_value |= (random() & 0xff);
+ }
+ m_link_order.sortVector(); // Look at the most empty link first
+ }
+ }
+
+ for (int i=0; i<m_routing_table.size(); i++) {
+ // pick the next link to look at
+ int link = m_link_order[i].m_link;
+
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, m_routing_table[link]);
+
+ if (msg_destinations.intersectionIsNotEmpty(m_routing_table[link])) {
+
+ // Remember what link we're using
+ output_links.insertAtBottom(link);
+
+ // Need to remember which destinations need this message
+ // in another vector. This Set is the intersection of the
+ // routing_table entry and the current destination set.
+ // The intersection must not be empty, since we are inside "if"
+ output_link_destinations.insertAtBottom(msg_destinations.AND(m_routing_table[link]));
+
+ // Next, we update the msg_destination not to include
+ // those nodes that were already handled by this link
+ msg_destinations.removeNetDest(m_routing_table[link]);
+ }
+ }
+
+ assert(msg_destinations.count() == 0);
+ //assert(output_links.size() > 0);
+
+ // Check for resources - for all outgoing queues
+ bool enough = true;
+ for (int i=0; i<output_links.size(); i++) {
+ int outgoing = output_links[i];
+ enough = enough && m_out[outgoing][vnet]->areNSlotsAvailable(1);
+ DEBUG_MSG(NETWORK_COMP, HighPrio, "checking if node is blocked");
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, outgoing);
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, vnet);
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, enough);
+ }
+
+ // There were not enough resources
+ if(!enough) {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ DEBUG_MSG(NETWORK_COMP, HighPrio, "Can't deliver message to anyone since a node is blocked");
+ DEBUG_EXPR(NETWORK_COMP, HighPrio, *net_msg_ptr);
+ break; // go to next incoming port
+ }
+
+ MsgPtr unmodified_msg_ptr;
+
+ if (output_links.size() > 1) {
+ // If we are sending this message down more than one link
+ // (size>1), we need to make a copy of the message so each
+ // branch can have a different internal destination
+ // we need to create an unmodified MsgPtr because the MessageBuffer enqueue func
+ // will modify the message
+ unmodified_msg_ptr = *(msg_ptr.ref()); // This magic line creates a private copy of the message
+ }
+
+ // Enqueue it - for all outgoing queues
+ for (int i=0; i<output_links.size(); i++) {
+ int outgoing = output_links[i];
+
+ if (i > 0) {
+ msg_ptr = *(unmodified_msg_ptr.ref()); // create a private copy of the unmodified message
+ }
+
+ // Change the internal destination set of the message so it
+ // knows which destinations this link is responsible for.
+ net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
+ net_msg_ptr->getInternalDestination() = output_link_destinations[i];
+
+ // Enqeue msg
+ DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
+ DEBUG_MSG(NETWORK_COMP,HighPrio,"switch: " + int_to_string(m_switch_id)
+ + " enqueuing net msg from inport[" + int_to_string(incoming) + "]["
+ + int_to_string(vnet) +"] to outport [" + int_to_string(outgoing)
+ + "][" + int_to_string(vnet) +"]"
+ + " time: " + int_to_string(g_eventQueue_ptr->getTime()) + ".");
+ DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
+
+ m_out[outgoing][vnet]->enqueue(msg_ptr);
+ }
+
+ // Dequeue msg
+ m_in[incoming][vnet]->pop();
+ }
+ }
+ }
+}
+
+void PerfectSwitch::printStats(ostream& out) const
+{
+ out << "PerfectSwitch printStats" << endl;
+}
+
+void PerfectSwitch::clearStats()
+{
+}
+
+void PerfectSwitch::printConfig(ostream& out) const
+{
+}
+
+void PerfectSwitch::print(ostream& out) const
+{
+ out << "[PerfectSwitch " << m_switch_id << "]";
+}
+
diff --git a/src/mem/ruby/network/simple/PerfectSwitch.hh b/src/mem/ruby/network/simple/PerfectSwitch.hh
new file mode 100644
index 000000000..4d381ccc9
--- /dev/null
+++ b/src/mem/ruby/network/simple/PerfectSwitch.hh
@@ -0,0 +1,118 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: Perfect switch, of course it is perfect and no latency or what
+ * so ever. Every cycle it is woke up and perform all the
+ * necessary routings that must be done. Note, this switch also
+ * has number of input ports/output ports and has a routing table
+ * as well.
+ *
+ */
+
+#ifndef PerfectSwitch_H
+#define PerfectSwitch_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "Consumer.hh"
+#include "NodeID.hh"
+
+class MessageBuffer;
+class NetDest;
+class SimpleNetwork;
+
+class LinkOrder {
+public:
+ int m_link;
+ int m_value;
+};
+
+class PerfectSwitch : public Consumer {
+public:
+ // Constructors
+
+ // constructor specifying the number of ports
+ PerfectSwitch(SwitchID sid, SimpleNetwork* network_ptr);
+ void addInPort(const Vector<MessageBuffer*>& in);
+ void addOutPort(const Vector<MessageBuffer*>& out, const NetDest& routing_table_entry);
+ void clearRoutingTables();
+ void clearBuffers();
+ void reconfigureOutPort(const NetDest& routing_table_entry);
+ int getInLinks() const { return m_in.size(); }
+ int getOutLinks() const { return m_out.size(); }
+
+ // Destructor
+ ~PerfectSwitch();
+
+ // Public Methods
+ void wakeup();
+
+ void printStats(ostream& out) const;
+ void clearStats();
+ void printConfig(ostream& out) const;
+
+ void print(ostream& out) const;
+private:
+
+ // Private copy constructor and assignment operator
+ PerfectSwitch(const PerfectSwitch& obj);
+ PerfectSwitch& operator=(const PerfectSwitch& obj);
+
+ // Data Members (m_ prefix)
+ SwitchID m_switch_id;
+
+ // vector of queues from the components
+ Vector<Vector<MessageBuffer*> > m_in;
+ Vector<Vector<MessageBuffer*> > m_out;
+ Vector<NetDest> m_routing_table;
+ Vector<LinkOrder> m_link_order;
+ int m_virtual_networks;
+ int m_round_robin_start;
+ int m_wakeups_wo_switch;
+ SimpleNetwork* m_network_ptr;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const PerfectSwitch& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const PerfectSwitch& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //PerfectSwitch_H
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc
new file mode 100644
index 000000000..549503e47
--- /dev/null
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc
@@ -0,0 +1,257 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * SimpleNetwork.C
+ *
+ * Description: See SimpleNetwork.h
+ *
+ * $Id$
+ *
+ */
+
+#include "SimpleNetwork.hh"
+#include "Profiler.hh"
+#include "System.hh"
+#include "Switch.hh"
+#include "NetDest.hh"
+#include "Topology.hh"
+#include "TopologyType.hh"
+#include "MachineType.hh"
+#include "MessageBuffer.hh"
+#include "Protocol.hh"
+#include "Map.hh"
+
+// ***BIG HACK*** - This is actually code that _should_ be in Network.C
+
+// Note: Moved to Princeton Network
+// calls new to abstract away from the network
+/*
+Network* Network::createNetwork(int nodes)
+{
+ return new SimpleNetwork(nodes);
+}
+*/
+
+SimpleNetwork::SimpleNetwork(int nodes)
+{
+ m_nodes = MachineType_base_number(MachineType_NUM);
+
+ m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS;
+ m_endpoint_switches.setSize(m_nodes);
+
+ m_in_use.setSize(m_virtual_networks);
+ m_ordered.setSize(m_virtual_networks);
+ for (int i = 0; i < m_virtual_networks; i++) {
+ m_in_use[i] = false;
+ m_ordered[i] = false;
+ }
+
+ // Allocate to and from queues
+ m_toNetQueues.setSize(m_nodes);
+ m_fromNetQueues.setSize(m_nodes);
+ for (int node = 0; node < m_nodes; node++) {
+ m_toNetQueues[node].setSize(m_virtual_networks);
+ m_fromNetQueues[node].setSize(m_virtual_networks);
+ for (int j = 0; j < m_virtual_networks; j++) {
+ m_toNetQueues[node][j] = new MessageBuffer;
+ m_fromNetQueues[node][j] = new MessageBuffer;
+ }
+ }
+
+ // Setup the network switches
+ m_topology_ptr = new Topology(this, m_nodes);
+ int number_of_switches = m_topology_ptr->numSwitches();
+ for (int i=0; i<number_of_switches; i++) {
+ m_switch_ptr_vector.insertAtBottom(new Switch(i, this));
+ }
+ m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
+}
+
+void SimpleNetwork::reset()
+{
+ for (int node = 0; node < m_nodes; node++) {
+ for (int j = 0; j < m_virtual_networks; j++) {
+ m_toNetQueues[node][j]->clear();
+ m_fromNetQueues[node][j]->clear();
+ }
+ }
+
+ for(int i=0; i<m_switch_ptr_vector.size(); i++){
+ m_switch_ptr_vector[i]->clearBuffers();
+ }
+}
+
+SimpleNetwork::~SimpleNetwork()
+{
+ for (int i = 0; i < m_nodes; i++) {
+ m_toNetQueues[i].deletePointers();
+ m_fromNetQueues[i].deletePointers();
+ }
+ m_switch_ptr_vector.deletePointers();
+ m_buffers_to_free.deletePointers();
+ delete m_topology_ptr;
+}
+
+// From a switch to an endpoint node
+void SimpleNetwork::makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ assert(dest < m_nodes);
+ assert(src < m_switch_ptr_vector.size());
+ assert(m_switch_ptr_vector[src] != NULL);
+ if(!isReconfiguration){
+ m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest], routing_table_entry, link_latency, bw_multiplier);
+ m_endpoint_switches[dest] = m_switch_ptr_vector[src];
+ } else {
+ m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry);
+ }
+}
+
+// From an endpoint node to a switch
+void SimpleNetwork::makeInLink(NodeID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration)
+{
+ assert(src < m_nodes);
+ if(!isReconfiguration){
+ m_switch_ptr_vector[dest]->addInPort(m_toNetQueues[src]);
+ } else {
+ // do nothing
+ }
+}
+
+// From a switch to a switch
+void SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ if(!isReconfiguration){
+ // Create a set of new MessageBuffers
+ Vector<MessageBuffer*> queues;
+ for (int i = 0; i < m_virtual_networks; i++) {
+ // allocate a buffer
+ MessageBuffer* buffer_ptr = new MessageBuffer;
+ buffer_ptr->setOrdering(true);
+ if(FINITE_BUFFERING) {
+ buffer_ptr->setSize(FINITE_BUFFER_SIZE);
+ }
+ queues.insertAtBottom(buffer_ptr);
+ // remember to deallocate it
+ m_buffers_to_free.insertAtBottom(buffer_ptr);
+ }
+
+ // Connect it to the two switches
+ m_switch_ptr_vector[dest]->addInPort(queues);
+ m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry, link_latency, bw_multiplier);
+ } else {
+ m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry);
+ }
+}
+
+void SimpleNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num)
+{
+ ASSERT(id < m_nodes);
+ ASSERT(network_num < m_virtual_networks);
+
+ if (ordered) {
+ m_ordered[network_num] = true;
+ }
+ m_in_use[network_num] = true;
+}
+
+MessageBuffer* SimpleNetwork::getToNetQueue(NodeID id, bool ordered, int network_num)
+{
+ checkNetworkAllocation(id, ordered, network_num);
+ return m_toNetQueues[id][network_num];
+}
+
+MessageBuffer* SimpleNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num)
+{
+ checkNetworkAllocation(id, ordered, network_num);
+ return m_fromNetQueues[id][network_num];
+}
+
+const Vector<Throttle*>* SimpleNetwork::getThrottles(NodeID id) const
+{
+ assert(id >= 0);
+ assert(id < m_nodes);
+ assert(m_endpoint_switches[id] != NULL);
+ return m_endpoint_switches[id]->getThrottles();
+}
+
+void SimpleNetwork::printStats(ostream& out) const
+{
+ out << endl;
+ out << "Network Stats" << endl;
+ out << "-------------" << endl;
+ out << endl;
+ for(int i=0; i<m_switch_ptr_vector.size(); i++) {
+ m_switch_ptr_vector[i]->printStats(out);
+ }
+}
+
+void SimpleNetwork::clearStats()
+{
+ for(int i=0; i<m_switch_ptr_vector.size(); i++) {
+ m_switch_ptr_vector[i]->clearStats();
+ }
+}
+
+void SimpleNetwork::printConfig(ostream& out) const
+{
+ out << endl;
+ out << "Network Configuration" << endl;
+ out << "---------------------" << endl;
+ out << "network: SIMPLE_NETWORK" << endl;
+ out << "topology: " << g_NETWORK_TOPOLOGY << endl;
+ out << endl;
+
+ for (int i = 0; i < m_virtual_networks; i++) {
+ out << "virtual_net_" << i << ": ";
+ if (m_in_use[i]) {
+ out << "active, ";
+ if (m_ordered[i]) {
+ out << "ordered" << endl;
+ } else {
+ out << "unordered" << endl;
+ }
+ } else {
+ out << "inactive" << endl;
+ }
+ }
+ out << endl;
+ for(int i=0; i<m_switch_ptr_vector.size(); i++) {
+ m_switch_ptr_vector[i]->printConfig(out);
+ }
+
+ if (g_PRINT_TOPOLOGY) {
+ m_topology_ptr->printConfig(out);
+ }
+}
+
+void SimpleNetwork::print(ostream& out) const
+{
+ out << "[SimpleNetwork]";
+}
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.hh b/src/mem/ruby/network/simple/SimpleNetwork.hh
new file mode 100644
index 000000000..a28904227
--- /dev/null
+++ b/src/mem/ruby/network/simple/SimpleNetwork.hh
@@ -0,0 +1,157 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * SimpleNetwork.h
+ *
+ * Description: The SimpleNetwork class implements the interconnection
+ * SimpleNetwork between components (processor/cache components and
+ * memory/directory components). The interconnection network as
+ * described here is not a physical network, but a programming concept
+ * used to implement all communication between components. Thus parts
+ * of this 'network' may model the on-chip connections between cache
+ * controllers and directory controllers as well as the links between
+ * chip and network switches.
+ *
+ * Two conceptual networks, an address and data network, are modeled.
+ * The data network is unordered, where the address network provides
+ * and conforms to a global ordering of all transactions.
+ *
+ * Currently the data network is point-to-point and the address
+ * network is a broadcast network. These two distinct conceptual
+ * network can be modeled as physically separate networks or
+ * multiplexed over a single physical network.
+ *
+ * The network encapsulates all notion of virtual global time and is
+ * responsible for ordering the network transactions received. This
+ * hides all of these ordering details from the processor/cache and
+ * directory/memory modules.
+ *
+ * FIXME: Various flavor of networks are provided as a compiler time
+ * configurable. We currently include this SimpleNetwork in the
+ * makefile's vpath, so that SimpleNetwork.C can provide an alternative
+ * version constructor for the abstract Network class. It is easy to
+ * modify this to make network a runtime configuable. Just make the
+ * abstract Network class take a enumeration parameter, and based on
+ * that to initial proper network. Or even better, just make the ruby
+ * system initializer choose the proper network to initiate.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef SIMPLENETWORK_H
+#define SIMPLENETWORK_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "Network.hh"
+#include "NodeID.hh"
+
+class NetDest;
+class MessageBuffer;
+class Throttle;
+class Switch;
+class Topology;
+
+class SimpleNetwork : public Network {
+public:
+ // Constructors
+ SimpleNetwork(int nodes);
+
+ // Destructor
+ ~SimpleNetwork();
+
+ // Public Methods
+ void printStats(ostream& out) const;
+ void clearStats();
+ void printConfig(ostream& out) const;
+
+ void reset();
+
+ // returns the queue requested for the given component
+ MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num);
+ MessageBuffer* getFromNetQueue(NodeID id, bool ordered, int network_num);
+ virtual const Vector<Throttle*>* getThrottles(NodeID id) const;
+
+ bool isVNetOrdered(int vnet) { return m_ordered[vnet]; }
+ bool validVirtualNetwork(int vnet) { return m_in_use[vnet]; }
+
+ int getNumNodes() {return m_nodes; }
+
+ // Methods used by Topology to setup the network
+ void makeOutLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
+ void makeInLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int bw_multiplier, bool isReconfiguration);
+ void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
+
+ void print(ostream& out) const;
+private:
+ void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
+ void addLink(SwitchID src, SwitchID dest, int link_latency);
+ void makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency);
+ SwitchID createSwitch();
+ void makeTopology();
+ void linkTopology();
+
+
+ // Private copy constructor and assignment operator
+ SimpleNetwork(const SimpleNetwork& obj);
+ SimpleNetwork& operator=(const SimpleNetwork& obj);
+
+ // Data Members (m_ prefix)
+
+ // vector of queues from the components
+ Vector<Vector<MessageBuffer*> > m_toNetQueues;
+ Vector<Vector<MessageBuffer*> > m_fromNetQueues;
+
+ int m_nodes;
+ int m_virtual_networks;
+ Vector<bool> m_in_use;
+ Vector<bool> m_ordered;
+ Vector<Switch*> m_switch_ptr_vector;
+ Vector<MessageBuffer*> m_buffers_to_free;
+ Vector<Switch*> m_endpoint_switches;
+ Topology* m_topology_ptr;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const SimpleNetwork& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const SimpleNetwork& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SIMPLENETWORK_H
diff --git a/src/mem/ruby/network/simple/Switch.cc b/src/mem/ruby/network/simple/Switch.cc
new file mode 100644
index 000000000..3b55d156f
--- /dev/null
+++ b/src/mem/ruby/network/simple/Switch.cc
@@ -0,0 +1,205 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Switch.C
+ *
+ * Description: See Switch.h
+ *
+ * $Id$
+ *
+ */
+
+
+#include "Switch.hh"
+#include "PerfectSwitch.hh"
+#include "MessageBuffer.hh"
+#include "Throttle.hh"
+#include "MessageSizeType.hh"
+#include "Network.hh"
+#include "Protocol.hh"
+
+Switch::Switch(SwitchID sid, SimpleNetwork* network_ptr)
+{
+ m_perfect_switch_ptr = new PerfectSwitch(sid, network_ptr);
+ m_switch_id = sid;
+ m_throttles.setSize(0);
+}
+
+Switch::~Switch()
+{
+ delete m_perfect_switch_ptr;
+
+ // Delete throttles (one per output port)
+ m_throttles.deletePointers();
+
+ // Delete MessageBuffers
+ m_buffers_to_free.deletePointers();
+}
+
+void Switch::addInPort(const Vector<MessageBuffer*>& in)
+{
+ m_perfect_switch_ptr->addInPort(in);
+}
+
+void Switch::addOutPort(const Vector<MessageBuffer*>& out, const NetDest& routing_table_entry, int link_latency, int bw_multiplier)
+{
+ Throttle* throttle_ptr = NULL;
+
+ // Create a throttle
+ throttle_ptr = new Throttle(m_switch_id, m_throttles.size(), link_latency, bw_multiplier);
+ m_throttles.insertAtBottom(throttle_ptr);
+
+ // Create one buffer per vnet (these are intermediaryQueues)
+ Vector<MessageBuffer*> intermediateBuffers;
+ for (int i=0; i<out.size(); i++) {
+ MessageBuffer* buffer_ptr = new MessageBuffer;
+ // Make these queues ordered
+ buffer_ptr->setOrdering(true);
+ if(FINITE_BUFFERING) {
+ buffer_ptr->setSize(FINITE_BUFFER_SIZE);
+ }
+ intermediateBuffers.insertAtBottom(buffer_ptr);
+ m_buffers_to_free.insertAtBottom(buffer_ptr);
+ }
+
+ // Hook the queues to the PerfectSwitch
+ m_perfect_switch_ptr->addOutPort(intermediateBuffers, routing_table_entry);
+
+ // Hook the queues to the Throttle
+ throttle_ptr->addLinks(intermediateBuffers, out);
+
+}
+
+void Switch::clearRoutingTables()
+{
+ m_perfect_switch_ptr->clearRoutingTables();
+}
+
+void Switch::clearBuffers()
+{
+ m_perfect_switch_ptr->clearBuffers();
+ for (int i=0; i<m_throttles.size(); i++) {
+ if (m_throttles[i] != NULL) {
+ m_throttles[i]->clear();
+ }
+ }
+}
+
+void Switch::reconfigureOutPort(const NetDest& routing_table_entry)
+{
+ m_perfect_switch_ptr->reconfigureOutPort(routing_table_entry);
+}
+
+const Throttle* Switch::getThrottle(LinkID link_number) const
+{
+ assert(m_throttles[link_number] != NULL);
+ return m_throttles[link_number];
+}
+
+const Vector<Throttle*>* Switch::getThrottles() const
+{
+ return &m_throttles;
+}
+
+void Switch::printStats(ostream& out) const
+{
+ out << "switch_" << m_switch_id << "_inlinks: " << m_perfect_switch_ptr->getInLinks() << endl;
+ out << "switch_" << m_switch_id << "_outlinks: " << m_perfect_switch_ptr->getOutLinks() << endl;
+
+ // Average link utilizations
+ double average_utilization = 0.0;
+ int throttle_count = 0;
+
+ for (int i=0; i<m_throttles.size(); i++) {
+ Throttle* throttle_ptr = m_throttles[i];
+ if (throttle_ptr != NULL) {
+ average_utilization += throttle_ptr->getUtilization();
+ throttle_count++;
+ }
+ }
+ average_utilization = (throttle_count == 0) ? 0 : average_utilization / float(throttle_count);
+
+ // Individual link utilizations
+ out << "links_utilized_percent_switch_" << m_switch_id << ": " << average_utilization << endl;
+ for (int link=0; link<m_throttles.size(); link++) {
+ Throttle* throttle_ptr = m_throttles[link];
+ if (throttle_ptr != NULL) {
+ out << " links_utilized_percent_switch_" << m_switch_id << "_link_" << link << ": "
+ << throttle_ptr->getUtilization() << " bw: " << throttle_ptr->getLinkBandwidth()
+ << " base_latency: " << throttle_ptr->getLatency() << endl;
+ }
+ }
+ out << endl;
+
+ // Traffic breakdown
+ for (int link=0; link<m_throttles.size(); link++) {
+ Throttle* throttle_ptr = m_throttles[link];
+ if (throttle_ptr != NULL) {
+ const Vector<Vector<int> >& message_counts = throttle_ptr->getCounters();
+ for (int int_type=0; int_type<MessageSizeType_NUM; int_type++) {
+ MessageSizeType type = MessageSizeType(int_type);
+ int sum = message_counts[type].sum();
+ if (sum != 0) {
+ out << " outgoing_messages_switch_" << m_switch_id << "_link_" << link << "_" << type
+ << ": " << sum << " " << sum * MessageSizeType_to_int(type)
+ << " " << message_counts[type] << " base_latency: " << throttle_ptr->getLatency() << endl;
+ }
+ }
+ }
+ }
+ out << endl;
+}
+
+void Switch::clearStats()
+{
+ m_perfect_switch_ptr->clearStats();
+ for (int i=0; i<m_throttles.size(); i++) {
+ if (m_throttles[i] != NULL) {
+ m_throttles[i]->clearStats();
+ }
+ }
+}
+
+void Switch::printConfig(ostream& out) const
+{
+ m_perfect_switch_ptr->printConfig(out);
+ for (int i=0; i<m_throttles.size(); i++) {
+ if (m_throttles[i] != NULL) {
+ m_throttles[i]->printConfig(out);
+ }
+ }
+}
+
+void Switch::print(ostream& out) const
+{
+ // FIXME printing
+ out << "[Switch]";
+}
+
diff --git a/src/mem/ruby/network/simple/Switch.hh b/src/mem/ruby/network/simple/Switch.hh
new file mode 100644
index 000000000..a408155c0
--- /dev/null
+++ b/src/mem/ruby/network/simple/Switch.hh
@@ -0,0 +1,105 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: The actual modelled switch. It use the perfect switch and a
+ * Throttle object to control and bandwidth and timing *only for
+ * the output port*. So here we have un-realistic modelling,
+ * since the order of PerfectSwitch and Throttle objects get
+ * woke up affect the message timing. A more accurate model would
+ * be having two set of system states, one for this cycle, one for
+ * next cycle. And on the cycle boundary swap the two set of
+ * states.
+ *
+ */
+
+#ifndef Switch_H
+#define Switch_H
+
+#include "Global.hh"
+#include "Vector.hh"
+
+class MessageBuffer;
+class PerfectSwitch;
+class NetDest;
+class SimpleNetwork;
+class Throttle;
+
+class Switch {
+public:
+ // Constructors
+
+ // constructor specifying the number of ports
+ Switch(SwitchID sid, SimpleNetwork* network_ptr);
+ void addInPort(const Vector<MessageBuffer*>& in);
+ void addOutPort(const Vector<MessageBuffer*>& out, const NetDest& routing_table_entry, int link_latency, int bw_multiplier);
+ const Throttle* getThrottle(LinkID link_number) const;
+ const Vector<Throttle*>* getThrottles() const;
+ void clearRoutingTables();
+ void clearBuffers();
+ void reconfigureOutPort(const NetDest& routing_table_entry);
+
+ void printStats(ostream& out) const;
+ void clearStats();
+ void printConfig(ostream& out) const;
+
+ // Destructor
+ ~Switch();
+
+ void print(ostream& out) const;
+private:
+
+ // Private copy constructor and assignment operator
+ Switch(const Switch& obj);
+ Switch& operator=(const Switch& obj);
+
+ // Data Members (m_ prefix)
+ PerfectSwitch* m_perfect_switch_ptr;
+ Vector<Throttle*> m_throttles;
+ Vector<MessageBuffer*> m_buffers_to_free;
+ SwitchID m_switch_id;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Switch& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Switch& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //Switch_H
diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc
new file mode 100644
index 000000000..2f6e68afd
--- /dev/null
+++ b/src/mem/ruby/network/simple/Throttle.cc
@@ -0,0 +1,291 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: see Throttle.h
+ *
+ */
+
+#include "Throttle.hh"
+#include "MessageBuffer.hh"
+#include "Network.hh"
+#include "System.hh"
+#include "NetworkMessage.hh"
+#include "Protocol.hh"
+
+const int HIGH_RANGE = 256;
+const int ADJUST_INTERVAL = 50000;
+const int MESSAGE_SIZE_MULTIPLIER = 1000;
+//const int BROADCAST_SCALING = 4; // Have a 16p system act like a 64p systems
+const int BROADCAST_SCALING = 1;
+const int PRIORITY_SWITCH_LIMIT = 128;
+
+static int network_message_to_size(NetworkMessage* net_msg_ptr);
+
+extern std::ostream * debug_cout_ptr;
+
+Throttle::Throttle(int sID, NodeID node, int link_latency, int link_bandwidth_multiplier)
+{
+ init(node, link_latency, link_bandwidth_multiplier);
+ m_sID = sID;
+}
+
+Throttle::Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier)
+{
+ init(node, link_latency, link_bandwidth_multiplier);
+ m_sID = 0;
+}
+
+void Throttle::init(NodeID node, int link_latency, int link_bandwidth_multiplier)
+{
+ m_node = node;
+ m_vnets = 0;
+
+ ASSERT(link_bandwidth_multiplier > 0);
+ m_link_bandwidth_multiplier = link_bandwidth_multiplier;
+ m_link_latency = link_latency;
+
+ m_bash_counter = HIGH_RANGE;
+ m_bandwidth_since_sample = 0;
+ m_last_bandwidth_sample = 0;
+ m_wakeups_wo_switch = 0;
+ clearStats();
+}
+
+void Throttle::clear()
+{
+ for (int counter = 0; counter < m_vnets; counter++) {
+ m_in[counter]->clear();
+ m_out[counter]->clear();
+ }
+}
+
+void Throttle::addLinks(const Vector<MessageBuffer*>& in_vec, const Vector<MessageBuffer*>& out_vec)
+{
+ assert(in_vec.size() == out_vec.size());
+ for (int i=0; i<in_vec.size(); i++) {
+ addVirtualNetwork(in_vec[i], out_vec[i]);
+ }
+
+ m_message_counters.setSize(MessageSizeType_NUM);
+ for (int i=0; i<MessageSizeType_NUM; i++) {
+ m_message_counters[i].setSize(in_vec.size());
+ for (int j=0; j<m_message_counters[i].size(); j++) {
+ m_message_counters[i][j] = 0;
+ }
+ }
+
+ if (g_PRINT_TOPOLOGY) {
+ m_out_link_vec.insertAtBottom(out_vec);
+ }
+}
+
+void Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
+{
+ m_units_remaining.insertAtBottom(0);
+ m_in.insertAtBottom(in_ptr);
+ m_out.insertAtBottom(out_ptr);
+
+ // Set consumer and description
+ m_in[m_vnets]->setConsumer(this);
+ string desc = "[Queue to Throttle " + NodeIDToString(m_sID) + " " + NodeIDToString(m_node) + "]";
+ m_in[m_vnets]->setDescription(desc);
+ m_vnets++;
+}
+
+void Throttle::wakeup()
+{
+ // Limits the number of message sent to a limited number of bytes/cycle.
+ assert(getLinkBandwidth() > 0);
+ int bw_remaining = getLinkBandwidth();
+
+ // Give the highest numbered link priority most of the time
+ m_wakeups_wo_switch++;
+ int highest_prio_vnet = m_vnets-1;
+ int lowest_prio_vnet = 0;
+ int counter = 1;
+ bool schedule_wakeup = false;
+
+ // invert priorities to avoid starvation seen in the component network
+ if (m_wakeups_wo_switch > PRIORITY_SWITCH_LIMIT) {
+ m_wakeups_wo_switch = 0;
+ highest_prio_vnet = 0;
+ lowest_prio_vnet = m_vnets-1;
+ counter = -1;
+ }
+
+ for (int vnet = highest_prio_vnet; (vnet*counter) >= (counter*lowest_prio_vnet); vnet -= counter) {
+
+ assert(m_out[vnet] != NULL);
+ assert(m_in[vnet] != NULL);
+ assert(m_units_remaining[vnet] >= 0);
+
+ while ((bw_remaining > 0) && ((m_in[vnet]->isReady()) || (m_units_remaining[vnet] > 0)) && m_out[vnet]->areNSlotsAvailable(1)) {
+
+ // See if we are done transferring the previous message on this virtual network
+ if (m_units_remaining[vnet] == 0 && m_in[vnet]->isReady()) {
+
+ // Find the size of the message we are moving
+ MsgPtr msg_ptr = m_in[vnet]->peekMsgPtr();
+ NetworkMessage* net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
+ m_units_remaining[vnet] += network_message_to_size(net_msg_ptr);
+
+ DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
+ DEBUG_MSG(NETWORK_COMP,HighPrio,"throttle: " + int_to_string(m_node)
+ + " my bw " + int_to_string(getLinkBandwidth())
+ + " bw spent enqueueing net msg " + int_to_string(m_units_remaining[vnet])
+ + " time: " + int_to_string(g_eventQueue_ptr->getTime()) + ".");
+
+ // Move the message
+ m_out[vnet]->enqueue(m_in[vnet]->peekMsgPtr(), m_link_latency);
+ m_in[vnet]->pop();
+
+ // Count the message
+ m_message_counters[net_msg_ptr->getMessageSize()][vnet]++;
+
+ DEBUG_MSG(NETWORK_COMP,LowPrio,*m_out[vnet]);
+ DEBUG_NEWLINE(NETWORK_COMP,HighPrio);
+ }
+
+ // Calculate the amount of bandwidth we spent on this message
+ int diff = m_units_remaining[vnet] - bw_remaining;
+ m_units_remaining[vnet] = max(0, diff);
+ bw_remaining = max(0, -diff);
+ }
+
+ if ((bw_remaining > 0) && ((m_in[vnet]->isReady()) || (m_units_remaining[vnet] > 0)) && !m_out[vnet]->areNSlotsAvailable(1)) {
+ DEBUG_MSG(NETWORK_COMP,LowPrio,vnet);
+ schedule_wakeup = true; // schedule me to wakeup again because I'm waiting for my output queue to become available
+ }
+ }
+
+ // We should only wake up when we use the bandwidth
+ // assert(bw_remaining != getLinkBandwidth()); // This is only mostly true
+
+ // Record that we used some or all of the link bandwidth this cycle
+ double ratio = 1.0-(double(bw_remaining)/double(getLinkBandwidth()));
+ // If ratio = 0, we used no bandwidth, if ratio = 1, we used all
+ linkUtilized(ratio);
+
+ // Sample the link bandwidth utilization over a number of cycles
+ int bw_used = getLinkBandwidth()-bw_remaining;
+ m_bandwidth_since_sample += bw_used;
+
+ // FIXME - comment out the bash specific code for faster performance
+ // Start Bash code
+ // Update the predictor
+ Time current_time = g_eventQueue_ptr->getTime();
+ while ((current_time - m_last_bandwidth_sample) > ADJUST_INTERVAL) {
+ double utilization = m_bandwidth_since_sample/double(ADJUST_INTERVAL * getLinkBandwidth());
+
+ if (utilization > g_bash_bandwidth_adaptive_threshold) {
+ // Used more bandwidth
+ m_bash_counter++;
+ } else {
+ // Used less bandwidth
+ m_bash_counter--;
+ }
+
+ // Make sure we don't overflow
+ m_bash_counter = min(HIGH_RANGE, m_bash_counter);
+ m_bash_counter = max(0, m_bash_counter);
+
+ // Reset samples
+ m_last_bandwidth_sample += ADJUST_INTERVAL;
+ m_bandwidth_since_sample = 0;
+ }
+ // End Bash code
+
+ if ((bw_remaining > 0) && !schedule_wakeup) {
+ // We have extra bandwidth and our output buffer was available, so we must not have anything else to do until another message arrives.
+ DEBUG_MSG(NETWORK_COMP,LowPrio,*this);
+ DEBUG_MSG(NETWORK_COMP,LowPrio,"not scheduled again");
+ } else {
+ DEBUG_MSG(NETWORK_COMP,LowPrio,*this);
+ DEBUG_MSG(NETWORK_COMP,LowPrio,"scheduled again");
+ // We are out of bandwidth for this cycle, so wakeup next cycle and continue
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ }
+}
+
+bool Throttle::broadcastBandwidthAvailable(int rand) const
+{
+ bool result = !(m_bash_counter > ((HIGH_RANGE/4) + (rand % (HIGH_RANGE/2))));
+ return result;
+}
+
+void Throttle::printStats(ostream& out) const
+{
+ out << "utilized_percent: " << getUtilization() << endl;
+}
+
+void Throttle::clearStats()
+{
+ m_ruby_start = g_eventQueue_ptr->getTime();
+ m_links_utilized = 0.0;
+
+ for (int i=0; i<m_message_counters.size(); i++) {
+ for (int j=0; j<m_message_counters[i].size(); j++) {
+ m_message_counters[i][j] = 0;
+ }
+ }
+}
+
+void Throttle::printConfig(ostream& out) const
+{
+
+}
+
+double Throttle::getUtilization() const
+{
+ return (100.0 * double(m_links_utilized)) / (double(g_eventQueue_ptr->getTime()-m_ruby_start));
+}
+
+void Throttle::print(ostream& out) const
+{
+ out << "[Throttle: " << m_sID << " " << m_node << " bw: " << getLinkBandwidth() << "]";
+}
+
+// Helper function
+
+static
+int network_message_to_size(NetworkMessage* net_msg_ptr)
+{
+ assert(net_msg_ptr != NULL);
+
+ // Artificially increase the size of broadcast messages
+ if (BROADCAST_SCALING > 1) {
+ if (net_msg_ptr->getDestination().isBroadcast()) {
+ return (MessageSizeType_to_int(net_msg_ptr->getMessageSize()) * MESSAGE_SIZE_MULTIPLIER * BROADCAST_SCALING);
+ }
+ }
+ return (MessageSizeType_to_int(net_msg_ptr->getMessageSize()) * MESSAGE_SIZE_MULTIPLIER);
+}
diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh
new file mode 100644
index 000000000..67cfabcdc
--- /dev/null
+++ b/src/mem/ruby/network/simple/Throttle.hh
@@ -0,0 +1,124 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: The class to implement bandwidth and latency throttle. An
+ * instance of consumer class that can be woke up. It is only used
+ * to control bandwidth at output port of a switch. And the
+ * throttle is added *after* the output port, means the message is
+ * put in the output port of the PerfectSwitch (a
+ * intermediateBuffers) first, then go through the Throttle.
+ *
+ */
+
+#ifndef THROTTLE_H
+#define THROTTLE_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "Consumer.hh"
+#include "NodeID.hh"
+#include "RubyConfig.hh"
+
+class MessageBuffer;
+
+class Throttle : public Consumer {
+public:
+ // Constructors
+ Throttle(int sID, NodeID node, int link_latency, int link_bandwidth_multiplier);
+ Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier);
+
+ // Destructor
+ ~Throttle() {}
+
+ // Public Methods
+ void addLinks(const Vector<MessageBuffer*>& in_vec, const Vector<MessageBuffer*>& out_vec);
+ void wakeup();
+ bool broadcastBandwidthAvailable(int rand) const;
+
+ void printStats(ostream& out) const;
+ void clearStats();
+ void printConfig(ostream& out) const;
+ double getUtilization() const; // The average utilization (a percent) since last clearStats()
+ int getLinkBandwidth() const { return g_endpoint_bandwidth * m_link_bandwidth_multiplier; }
+ int getLatency() const { return m_link_latency; }
+
+ const Vector<Vector<int> >& getCounters() const { return m_message_counters; }
+
+ void clear();
+
+ void print(ostream& out) const;
+
+private:
+ // Private Methods
+ void init(NodeID node, int link_latency, int link_bandwidth_multiplier);
+ void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr);
+ void linkUtilized(double ratio) { m_links_utilized += ratio; }
+
+ // Private copy constructor and assignment operator
+ Throttle(const Throttle& obj);
+ Throttle& operator=(const Throttle& obj);
+
+ // Data Members (m_ prefix)
+ Vector<MessageBuffer*> m_in;
+ Vector<MessageBuffer*> m_out;
+ Vector<Vector<int> > m_message_counters;
+ int m_vnets;
+ Vector<int> m_units_remaining;
+ int m_sID;
+ NodeID m_node;
+ int m_bash_counter;
+ int m_bandwidth_since_sample;
+ Time m_last_bandwidth_sample;
+ int m_link_bandwidth_multiplier;
+ int m_link_latency;
+ int m_wakeups_wo_switch;
+
+ // For tracking utilization
+ Time m_ruby_start;
+ double m_links_utilized;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Throttle& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Throttle& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //THROTTLE_H
diff --git a/src/mem/ruby/network/simple/Topology.cc b/src/mem/ruby/network/simple/Topology.cc
new file mode 100644
index 000000000..db886052f
--- /dev/null
+++ b/src/mem/ruby/network/simple/Topology.cc
@@ -0,0 +1,801 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Topology.C
+ *
+ * Description: See Topology.h
+ *
+ * $Id$
+ *
+ * */
+
+#include "Topology.hh"
+#include "NetDest.hh"
+#include "Network.hh"
+#include "TopologyType.hh"
+#include "RubyConfig.hh"
+#include "util.hh"
+#include "MachineType.hh"
+#include "Protocol.hh"
+#include <string>
+
+static const int INFINITE_LATENCY = 10000; // Yes, this is a big hack
+static const int DEFAULT_BW_MULTIPLIER = 1; // Just to be consistent with above :)
+
+// Note: In this file, we use the first 2*m_nodes SwitchIDs to
+// represent the input and output endpoint links. These really are
+// not 'switches', as they will not have a Switch object allocated for
+// them. The first m_nodes SwitchIDs are the links into the network,
+// the second m_nodes set of SwitchIDs represent the the output queues
+// of the network.
+
+// Helper functions based on chapter 29 of Cormen et al.
+static Matrix extend_shortest_path(const Matrix& current_dist, Matrix& latencies, Matrix& inter_switches);
+static Matrix shortest_path(const Matrix& weights, Matrix& latencies, Matrix& inter_switches);
+static bool link_is_shortest_path_to_node(SwitchID src, SwitchID next, SwitchID final, const Matrix& weights, const Matrix& dist);
+static NetDest shortest_path_to_node(SwitchID src, SwitchID next, const Matrix& weights, const Matrix& dist);
+
+
+Topology::Topology(Network* network_ptr, int number_of_nodes)
+{
+ m_network_ptr = network_ptr;
+ m_nodes = number_of_nodes;
+ m_number_of_switches = 0;
+ init();
+}
+
+void Topology::init()
+{
+ if (m_nodes == 1) {
+ SwitchID id = newSwitchID();
+ addLink(0, id, NETWORK_LINK_LATENCY);
+ addLink(id, 1, NETWORK_LINK_LATENCY);
+ return;
+ }
+
+ // topology-specific set-up
+ TopologyType topology = string_to_TopologyType(g_NETWORK_TOPOLOGY);
+ switch (topology) {
+ case TopologyType_TORUS_2D:
+ make2DTorus();
+ break;
+ case TopologyType_HIERARCHICAL_SWITCH:
+ makeHierarchicalSwitch(FAN_OUT_DEGREE);
+ break;
+ case TopologyType_CROSSBAR:
+ makeHierarchicalSwitch(1024);
+ break;
+ case TopologyType_PT_TO_PT:
+ makePtToPt();
+ break;
+ case TopologyType_FILE_SPECIFIED:
+ makeFileSpecified();
+ break;
+ default:
+ ERROR_MSG("Unexpected typology type")
+ }
+
+ // initialize component latencies record
+ m_component_latencies.setSize(0);
+ m_component_inter_switches.setSize(0);
+}
+
+void Topology::makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChipSwitches)
+{
+
+ Vector < SwitchID > nodes; // temporary buffer
+ nodes.setSize(2);
+
+ Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network
+ endpointConnectionExist.setSize(m_nodes);
+ // initialize endpoint check vector
+ for (int k = 0; k < endpointConnectionExist.size(); k++) {
+ endpointConnectionExist[k] = false;
+ }
+
+ Vector<int> componentCount;
+ componentCount.setSize(MachineType_NUM);
+ for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
+ componentCount[mType] = 0;
+ }
+
+ // components to/from network links
+ for (int chip = 0; chip < RubyConfig::numberOfChips(); chip++) {
+ for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
+ for (int component = 0; component < MachineType_chip_count(mType, chip); component++) {
+
+ int latency = -1;
+ int bw_multiplier = -1; // internal link bw multiplier of the global bandwidth
+ if (mType != MachineType_Directory) {
+ latency = ON_CHIP_LINK_LATENCY; // internal link latency
+ bw_multiplier = 10; // internal link bw multiplier of the global bandwidth
+ } else {
+ latency = NETWORK_LINK_LATENCY; // local memory latency
+ bw_multiplier = 1; // local memory link bw multiplier of the global bandwidth
+ }
+ nodes[0] = MachineType_base_number(mType)+componentCount[mType];
+ nodes[1] = chip+m_nodes*2; // this is the chip's internal switch id #
+
+ // insert link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ //bw_multis.insertAtBottom(bw_multiplier);
+ bw_multis.insertAtBottom(componentCount[mType]+MachineType_base_number((MachineType)mType));
+
+ // opposite direction link
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ otherDirectionNodes[1] = nodes[0]+m_nodes;
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ assert(!endpointConnectionExist[nodes[0]]);
+ endpointConnectionExist[nodes[0]] = true;
+ componentCount[mType]++;
+ }
+ }
+ }
+
+ // make sure all enpoints are connected in the soon to be created network
+ for (int k = 0; k < endpointConnectionExist.size(); k++) {
+ if (endpointConnectionExist[k] == false) {
+ cerr << "Error: Unconnected Endpoint: " << k << endl;
+ exit(1);
+ }
+ }
+
+ // secondary check to ensure we saw the correct machine counts
+ for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
+ assert(componentCount[mType] == MachineType_base_count((MachineType)mType));
+ }
+
+}
+
+// 2D torus topology
+
+void Topology::make2DTorus()
+{
+ Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+ Vector<int> latencies; // link latencies for each link extracted
+ Vector<int> bw_multis; // bw multipliers for each link extracted
+
+ Vector < SwitchID > nodes; // temporary buffer
+ nodes.setSize(2);
+
+ // number of inter-chip switches
+ int numberOfTorusSwitches = m_nodes/MachineType_base_level(MachineType_NUM);
+ // one switch per machine node grouping
+ Vector<SwitchID> torusSwitches;
+ for(int i=0; i<numberOfTorusSwitches; i++){
+ SwitchID new_switch = newSwitchID();
+ torusSwitches.insertAtBottom(new_switch);
+ }
+
+ makeSwitchesPerChip(nodePairs, latencies, bw_multis, numberOfTorusSwitches);
+
+ int lengthOfSide = (int)sqrt((double)numberOfTorusSwitches);
+
+ // Now connect the inter-chip torus links
+
+ int latency = NETWORK_LINK_LATENCY; // external link latency
+ int bw_multiplier = 1; // external link bw multiplier of the global bandwidth
+
+ for(int i=0; i<numberOfTorusSwitches; i++){
+ nodes[0] = torusSwitches[i]; // current switch
+
+ // left
+ if(nodes[0]%lengthOfSide == 0){ // determine left neighbor
+ nodes[1] = nodes[0] - 1 + lengthOfSide;
+ } else {
+ nodes[1] = nodes[0] - 1;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // right
+ if((nodes[0] + 1)%lengthOfSide == 0){ // determine right neighbor
+ nodes[1] = nodes[0] + 1 - lengthOfSide;
+ } else {
+ nodes[1] = nodes[0] + 1;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // top
+ if(nodes[0] - lengthOfSide < 2*m_nodes){ // determine if node is on the top
+ nodes[1] = nodes[0] - lengthOfSide + (lengthOfSide*lengthOfSide);
+ } else {
+ nodes[1] = nodes[0] - lengthOfSide;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // bottom
+ if(nodes[0] + lengthOfSide >= 2*m_nodes+numberOfTorusSwitches){ // determine if node is on the bottom
+ // sorin: bad bug if this is a > instead of a >=
+ nodes[1] = nodes[0] + lengthOfSide - (lengthOfSide*lengthOfSide);
+ } else {
+ nodes[1] = nodes[0] + lengthOfSide;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ }
+
+ // add links
+ ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.size())
+ for (int k = 0; k < nodePairs.size(); k++) {
+ ASSERT(nodePairs[k].size() == 2);
+ addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k]);
+ }
+
+}
+
+// hierarchical switch topology
+void Topology::makeHierarchicalSwitch(int fan_out_degree)
+{
+ // Make a row of switches with only one input. This extra row makes
+ // sure the links out of the nodes have latency and limited
+ // bandwidth.
+
+ // number of inter-chip switches, i.e. the last row of switches
+ Vector<SwitchID> last_level;
+ for (int i=0; i<m_nodes; i++) {
+ SwitchID new_switch = newSwitchID(); // internal switch id #
+ addLink(i, new_switch, NETWORK_LINK_LATENCY);
+ last_level.insertAtBottom(new_switch);
+ }
+
+ // Create Hierarchical Switches
+
+ // start from the bottom level and work up to root
+ Vector<SwitchID> next_level;
+ while(last_level.size() > 1) {
+ for (int i=0; i<last_level.size(); i++) {
+ if ((i % fan_out_degree) == 0) {
+ next_level.insertAtBottom(newSwitchID());
+ }
+ // Add this link to the last switch we created
+ addLink(last_level[i], next_level[next_level.size()-1], NETWORK_LINK_LATENCY);
+ }
+
+ // Make the current level the last level to get ready for next
+ // iteration
+ last_level = next_level;
+ next_level.clear();
+ }
+
+ SwitchID root_switch = last_level[0];
+
+ Vector<SwitchID> out_level;
+ for (int i=0; i<m_nodes; i++) {
+ out_level.insertAtBottom(m_nodes+i);
+ }
+
+ // Build the down network from the endpoints to the root
+ while(out_level.size() != 1) {
+
+ // A level of switches
+ for (int i=0; i<out_level.size(); i++) {
+ if ((i % fan_out_degree) == 0) {
+ if (out_level.size() > fan_out_degree) {
+ next_level.insertAtBottom(newSwitchID());
+ } else {
+ next_level.insertAtBottom(root_switch);
+ }
+ }
+ // Add this link to the last switch we created
+ addLink(next_level[next_level.size()-1], out_level[i], NETWORK_LINK_LATENCY);
+ }
+
+ // Make the current level the last level to get ready for next
+ // iteration
+ out_level = next_level;
+ next_level.clear();
+ }
+}
+
+// one internal node per chip, point to point links between chips
+void Topology::makePtToPt()
+{
+ Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+ Vector<int> latencies; // link latencies for each link extracted
+ Vector<int> bw_multis; // bw multipliers for each link extracted
+
+ Vector < SwitchID > nodes;
+ nodes.setSize(2);
+
+ // number of inter-chip switches
+ int numberOfChipSwitches = m_nodes/MachineType_base_level(MachineType_NUM);
+ // two switches per machine node grouping
+ // one intra-chip switch and one inter-chip switch per chip
+ for(int i=0; i<numberOfChipSwitches; i++){
+ SwitchID new_switch = newSwitchID();
+ new_switch = newSwitchID();
+ }
+
+ makeSwitchesPerChip(nodePairs, latencies, bw_multis, numberOfChipSwitches);
+
+ // connect intra-chip switch to inter-chip switch
+ for (int chip = 0; chip < RubyConfig::numberOfChips(); chip++) {
+
+ int latency = ON_CHIP_LINK_LATENCY; // internal link latency
+ int bw_multiplier = 10; // external link bw multiplier of the global bandwidth
+
+ nodes[0] = chip+m_nodes*2;
+ nodes[1] = chip+m_nodes*2+RubyConfig::numberOfChips();
+
+ // insert link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // opposite direction link
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ otherDirectionNodes[1] = nodes[0];
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+ }
+
+ // point-to-point network between chips
+ for (int chip = 0; chip < RubyConfig::numberOfChips(); chip++) {
+ for (int other_chip = chip+1; other_chip < RubyConfig::numberOfChips(); other_chip++) {
+
+ int latency = NETWORK_LINK_LATENCY; // external link latency
+ int bw_multiplier = 1; // external link bw multiplier of the global bandwidth
+
+ nodes[0] = chip+m_nodes*2+RubyConfig::numberOfChips();
+ nodes[1] = other_chip+m_nodes*2+RubyConfig::numberOfChips();
+
+ // insert link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // opposite direction link
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ otherDirectionNodes[1] = nodes[0];
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+ }
+ }
+
+ // add links
+ ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.size())
+ for (int k = 0; k < nodePairs.size(); k++) {
+ ASSERT(nodePairs[k].size() == 2);
+ addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k]);
+ }
+}
+
+// make a network as described by the networkFile
+void Topology::makeFileSpecified()
+{
+
+ Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+ Vector<int> latencies; // link latencies for each link extracted
+ Vector<int> bw_multis; // bw multipliers for each link extracted
+ Vector<int> weights; // link weights used to enfore e-cube deadlock free routing
+ Vector< SwitchID > int_network_switches; // internal switches extracted from the file
+ Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network
+
+ endpointConnectionExist.setSize(m_nodes);
+
+ // initialize endpoint check vector
+ for (int k = 0; k < endpointConnectionExist.size(); k++) {
+ endpointConnectionExist[k] = false;
+ }
+
+ string filename = "network/simple/Network_Files/";
+ filename = filename+g_CACHE_DESIGN
+ +"_Procs-"+int_to_string(RubyConfig::numberOfProcessors())
+ +"_ProcsPerChip-"+int_to_string(RubyConfig::numberOfProcsPerChip())
+ +"_L2Banks-"+int_to_string(RubyConfig::numberOfL2Cache())
+ +"_Memories-"+int_to_string(RubyConfig::numberOfMemories())
+ +".txt";
+
+ if (g_SIMICS) {
+ filename = "../../../ruby/"+filename;
+ }
+ ifstream networkFile( filename.c_str() , ios::in);
+ if (!networkFile.is_open()) {
+ cerr << "Error: Could not open network file: " << filename << endl;
+ cerr << "Probably no network file exists for " << RubyConfig::numberOfProcessors()
+ << " processors and " << RubyConfig::numberOfProcsPerChip() << " procs per chip " << endl;
+ exit(1);
+ }
+
+ string line = "";
+
+ while (!networkFile.eof()) {
+
+ Vector < SwitchID > nodes;
+ nodes.setSize(2);
+ int latency = -1; // null latency
+ int weight = -1; // null weight
+ int bw_multiplier = DEFAULT_BW_MULTIPLIER; // default multiplier incase the network file doesn't define it
+ int i = 0; // node pair index
+ int varsFound = 0; // number of varsFound on the line
+ int internalNodes = 0; // used to determine if the link is between 2 internal nodes
+ std::getline(networkFile, line, '\n');
+ string varStr = string_split(line, ' ');
+
+ // parse the current line in the file
+ while (varStr != "") {
+ string label = string_split(varStr, ':');
+
+ // valid node labels
+ if (label == "ext_node" || label == "int_node") {
+ ASSERT(i < 2); // one link between 2 switches per line
+ varsFound++;
+ bool isNewIntSwitch = true;
+ if (label == "ext_node") { // input link to node
+ MachineType machine = string_to_MachineType(string_split(varStr, ':'));
+ string nodeStr = string_split(varStr, ':');
+ if (string_split(varStr, ':') == "bank") {
+ nodes[i] = MachineType_base_number(machine)
+ + atoi(nodeStr.c_str())
+ + atoi((string_split(varStr, ':')).c_str())*RubyConfig::numberOfChips();
+ } else {
+ nodes[i] = MachineType_base_number(machine)
+ + atoi(nodeStr.c_str());
+ }
+ // in nodes should be numbered 0 to m_nodes-1
+ ASSERT(nodes[i] >= 0 && nodes[i] < m_nodes);
+ isNewIntSwitch = false;
+ endpointConnectionExist[nodes[i]] = true;
+ }
+ if (label == "int_node") { // interior node
+ nodes[i] = atoi((string_split(varStr, ':')).c_str())+m_nodes*2;
+ // in nodes should be numbered >= m_nodes*2
+ ASSERT(nodes[i] >= m_nodes*2);
+ for (int k = 0; k < int_network_switches.size(); k++) {
+ if (int_network_switches[k] == nodes[i]) {
+ isNewIntSwitch = false;
+ }
+ }
+ if (isNewIntSwitch) { // if internal switch
+ m_number_of_switches++;
+ int_network_switches.insertAtBottom(nodes[i]);
+ }
+ internalNodes++;
+ }
+ i++;
+ } else if (label == "link_latency") {
+ latency = atoi((string_split(varStr, ':')).c_str());
+ varsFound++;
+ } else if (label == "bw_multiplier") { // not necessary, defaults to DEFAULT_BW_MULTIPLIER
+ bw_multiplier = atoi((string_split(varStr, ':')).c_str());
+ } else if (label == "link_weight") { // not necessary, defaults to link_latency
+ weight = atoi((string_split(varStr, ':')).c_str());
+ } else if (label == "processors") {
+ ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfProcessors());
+ } else if (label == "bw_unit") {
+ ASSERT(atoi((string_split(varStr, ':')).c_str()) == g_endpoint_bandwidth);
+ } else if (label == "procs_per_chip") {
+ ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfProcsPerChip());
+ } else if (label == "L2banks") {
+ ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfL2Cache());
+ } else if (label == "memories") {
+ ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfMemories());
+ } else {
+ cerr << "Error: Unexpected Identifier: " << label << endl;
+ exit(1);
+ }
+ varStr = string_split(line, ' ');
+ }
+ if (varsFound == 3) { // all three necessary link variables where found so add the link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ if (weight != -1) {
+ weights.insertAtBottom(weight);
+ } else {
+ weights.insertAtBottom(latency);
+ }
+ bw_multis.insertAtBottom(bw_multiplier);
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ if (internalNodes == 2) { // this is an internal link
+ otherDirectionNodes[1] = nodes[0];
+ } else {
+ otherDirectionNodes[1] = nodes[0]+m_nodes;
+ }
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ if (weight != -1) {
+ weights.insertAtBottom(weight);
+ } else {
+ weights.insertAtBottom(latency);
+ }
+ bw_multis.insertAtBottom(bw_multiplier);
+ } else {
+ if (varsFound != 0) { // if this is not a valid link, then no vars should have been found
+ cerr << "Error in line: " << line << endl;
+ exit(1);
+ }
+ }
+ } // end of file
+
+ // makes sure all enpoints are connected in the soon to be created network
+ for (int k = 0; k < endpointConnectionExist.size(); k++) {
+ if (endpointConnectionExist[k] == false) {
+ cerr << "Error: Unconnected Endpoint: " << k << endl;
+ exit(1);
+ }
+ }
+
+ ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.size() && latencies.size() == weights.size())
+ for (int k = 0; k < nodePairs.size(); k++) {
+ ASSERT(nodePairs[k].size() == 2);
+ addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k], weights[k]);
+ }
+
+ networkFile.close();
+}
+
+void Topology::createLinks(bool isReconfiguration)
+{
+ // Find maximum switchID
+
+ SwitchID max_switch_id = 0;
+ for (int i=0; i<m_links_src_vector.size(); i++) {
+ max_switch_id = max(max_switch_id, m_links_src_vector[i]);
+ max_switch_id = max(max_switch_id, m_links_dest_vector[i]);
+ }
+
+ // Initialize weight vector
+ Matrix topology_weights;
+ Matrix topology_latency;
+ Matrix topology_bw_multis;
+ int num_switches = max_switch_id+1;
+ topology_weights.setSize(num_switches);
+ topology_latency.setSize(num_switches);
+ topology_bw_multis.setSize(num_switches);
+ m_component_latencies.setSize(num_switches); // FIXME setting the size of a member variable here is a HACK!
+ m_component_inter_switches.setSize(num_switches); // FIXME setting the size of a member variable here is a HACK!
+ for(int i=0; i<topology_weights.size(); i++) {
+ topology_weights[i].setSize(num_switches);
+ topology_latency[i].setSize(num_switches);
+ topology_bw_multis[i].setSize(num_switches);
+ m_component_latencies[i].setSize(num_switches);
+ m_component_inter_switches[i].setSize(num_switches); // FIXME setting the size of a member variable here is a HACK!
+ for(int j=0; j<topology_weights[i].size(); j++) {
+ topology_weights[i][j] = INFINITE_LATENCY;
+ topology_latency[i][j] = -1; // initialize to an invalid value
+ topology_bw_multis[i][j] = -1; // initialize to an invalid value
+ m_component_latencies[i][j] = -1; // initialize to an invalid value
+ m_component_inter_switches[i][j] = 0; // initially assume direct connections / no intermediate switches between components
+ }
+ }
+
+ // Set identity weights to zero
+ for(int i=0; i<topology_weights.size(); i++) {
+ topology_weights[i][i] = 0;
+ }
+
+ // Fill in the topology weights and bandwidth multipliers
+ for (int i=0; i<m_links_src_vector.size(); i++) {
+ topology_weights[m_links_src_vector[i]][m_links_dest_vector[i]] = m_links_weight_vector[i];
+ topology_latency[m_links_src_vector[i]][m_links_dest_vector[i]] = m_links_latency_vector[i];
+ m_component_latencies[m_links_src_vector[i]][m_links_dest_vector[i]] = m_links_latency_vector[i]; // initialize to latency vector
+ topology_bw_multis[m_links_src_vector[i]][m_links_dest_vector[i]] = m_bw_multiplier_vector[i];
+ }
+
+ // Walk topology and hookup the links
+ Matrix dist = shortest_path(topology_weights, m_component_latencies, m_component_inter_switches);
+ for(int i=0; i<topology_weights.size(); i++) {
+ for(int j=0; j<topology_weights[i].size(); j++) {
+ int weight = topology_weights[i][j];
+ int bw_multiplier = topology_bw_multis[i][j];
+ int latency = topology_latency[i][j];
+ if (weight > 0 && weight != INFINITE_LATENCY) {
+ NetDest destination_set = shortest_path_to_node(i, j, topology_weights, dist);
+ assert(latency != -1);
+ makeLink(i, j, destination_set, latency, weight, bw_multiplier, isReconfiguration);
+ }
+ }
+ }
+}
+
+SwitchID Topology::newSwitchID()
+{
+ m_number_of_switches++;
+ return m_number_of_switches-1+m_nodes+m_nodes;
+}
+
+void Topology::addLink(SwitchID src, SwitchID dest, int link_latency)
+{
+ addLink(src, dest, link_latency, DEFAULT_BW_MULTIPLIER, link_latency);
+}
+
+void Topology::addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier)
+{
+ addLink(src, dest, link_latency, bw_multiplier, link_latency);
+}
+
+void Topology::addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier, int link_weight)
+{
+ ASSERT(src <= m_number_of_switches+m_nodes+m_nodes);
+ ASSERT(dest <= m_number_of_switches+m_nodes+m_nodes);
+ m_links_src_vector.insertAtBottom(src);
+ m_links_dest_vector.insertAtBottom(dest);
+ m_links_latency_vector.insertAtBottom(link_latency);
+ m_links_weight_vector.insertAtBottom(link_weight);
+ m_bw_multiplier_vector.insertAtBottom(bw_multiplier);
+}
+
+void Topology::makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration)
+{
+ // Make sure we're not trying to connect two end-point nodes directly together
+ assert((src >= 2*m_nodes) || (dest >= 2*m_nodes));
+
+ if (src < m_nodes) {
+ m_network_ptr->makeInLink(src, dest-(2*m_nodes), routing_table_entry, link_latency, bw_multiplier, isReconfiguration);
+ } else if (dest < 2*m_nodes) {
+ assert(dest >= m_nodes);
+ NodeID node = dest-m_nodes;
+ m_network_ptr->makeOutLink(src-(2*m_nodes), node, routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
+ } else {
+ assert((src >= 2*m_nodes) && (dest >= 2*m_nodes));
+ m_network_ptr->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), routing_table_entry, link_latency, link_weight, bw_multiplier, isReconfiguration);
+ }
+}
+
+void Topology::printConfig(ostream& out) const
+{
+ assert(m_component_latencies.size() > 0);
+
+ out << "--- Begin Topology Print ---" << endl;
+ out << endl;
+ out << "Topology print ONLY indicates the _NETWORK_ latency between two machines" << endl;
+ out << "It does NOT include the latency within the machines" << endl;
+ out << endl;
+ for (int m=0; m<MachineType_NUM; m++) {
+ for (int i=0; i<MachineType_base_count((MachineType)m); i++) {
+ MachineID cur_mach = {(MachineType)m, i};
+ out << cur_mach << " Network Latencies" << endl;
+ for (int n=0; n<MachineType_NUM; n++) {
+ for (int j=0; j<MachineType_base_count((MachineType)n); j++) {
+ MachineID dest_mach = {(MachineType)n, j};
+ if (cur_mach != dest_mach) {
+ int link_latency = m_component_latencies[MachineType_base_number((MachineType)m)+i][MachineType_base_number(MachineType_NUM)+MachineType_base_number((MachineType)n)+j];
+ int intermediate_switches = m_component_inter_switches[MachineType_base_number((MachineType)m)+i][MachineType_base_number(MachineType_NUM)+MachineType_base_number((MachineType)n)+j];
+ out << " " << cur_mach << " -> " << dest_mach << " net_lat: "
+ << link_latency+intermediate_switches << endl; // NOTE switches are assumed to have single cycle latency
+ }
+ }
+ }
+ out << endl;
+ }
+ }
+
+ out << "--- End Topology Print ---" << endl;
+}
+
+/**************************************************************************/
+
+// The following all-pairs shortest path algorithm is based on the
+// discussion from Cormen et al., Chapter 26.1.
+
+static void extend_shortest_path(Matrix& current_dist, Matrix& latencies, Matrix& inter_switches)
+{
+ bool change = true;
+ int nodes = current_dist.size();
+
+ while (change) {
+ change = false;
+ for (int i=0; i<nodes; i++) {
+ for (int j=0; j<nodes; j++) {
+ int minimum = current_dist[i][j];
+ int previous_minimum = minimum;
+ int intermediate_switch = -1;
+ for (int k=0; k<nodes; k++) {
+ minimum = min(minimum, current_dist[i][k] + current_dist[k][j]);
+ if (previous_minimum != minimum) {
+ intermediate_switch = k;
+ inter_switches[i][j] = inter_switches[i][k] + inter_switches[k][j] + 1;
+ }
+ previous_minimum = minimum;
+ }
+ if (current_dist[i][j] != minimum) {
+ change = true;
+ current_dist[i][j] = minimum;
+ assert(intermediate_switch >= 0);
+ assert(intermediate_switch < latencies[i].size());
+ latencies[i][j] = latencies[i][intermediate_switch] + latencies[intermediate_switch][j];
+ }
+ }
+ }
+ }
+}
+
+static Matrix shortest_path(const Matrix& weights, Matrix& latencies, Matrix& inter_switches)
+{
+ Matrix dist = weights;
+ extend_shortest_path(dist, latencies, inter_switches);
+ return dist;
+}
+
+static bool link_is_shortest_path_to_node(SwitchID src, SwitchID next, SwitchID final,
+ const Matrix& weights, const Matrix& dist)
+{
+ return (weights[src][next] + dist[next][final] == dist[src][final]);
+}
+
+static NetDest shortest_path_to_node(SwitchID src, SwitchID next,
+ const Matrix& weights, const Matrix& dist)
+{
+ NetDest result;
+ int d = 0;
+ int machines;
+ int max_machines;
+
+ machines = MachineType_NUM;
+ max_machines = MachineType_base_number(MachineType_NUM);
+
+ for (int m=0; m<machines; m++) {
+ for (int i=0; i<MachineType_base_count((MachineType)m); i++) {
+ // we use "d+max_machines" below since the "destination" switches for the machines are numbered
+ // [MachineType_base_number(MachineType_NUM)...2*MachineType_base_number(MachineType_NUM)-1]
+ // for the component network
+ if (link_is_shortest_path_to_node(src, next,
+ d+max_machines,
+ weights, dist)) {
+ MachineID mach = {(MachineType)m, i};
+ result.add(mach);
+ }
+ d++;
+ }
+ }
+
+ DEBUG_MSG(NETWORK_COMP, MedPrio, "returning shortest path");
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, (src-(2*max_machines)));
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, (next-(2*max_machines)));
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, src);
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, next);
+ DEBUG_EXPR(NETWORK_COMP, MedPrio, result);
+ DEBUG_NEWLINE(NETWORK_COMP, MedPrio);
+
+ return result;
+}
+
diff --git a/src/mem/ruby/network/simple/Topology.hh b/src/mem/ruby/network/simple/Topology.hh
new file mode 100644
index 000000000..bfc503087
--- /dev/null
+++ b/src/mem/ruby/network/simple/Topology.hh
@@ -0,0 +1,126 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Topology.h
+ *
+ * Description: The topology here is configurable; it can be a hierachical
+ * (default one) or a 2D torus or a 2D torus with half switches
+ * killed. I think all input port has a
+ * one-input-one-output switch connected just to control and
+ * bandwidth, since we don't control bandwidth on input ports.
+ * Basically, the class has a vector of nodes and edges. First
+ * 2*m_nodes elements in the node vector are input and output
+ * ports. Edges are represented in two vectors of src and dest
+ * nodes. All edges have latency.
+ *
+ * $Id$
+ *
+ * */
+
+#ifndef TOPOLOGY_H
+#define TOPOLOGY_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "NodeID.hh"
+
+class Network;
+class NetDest;
+
+typedef Vector < Vector <int> > Matrix;
+
+class Topology {
+public:
+ // Constructors
+ Topology(Network* network_ptr, int number_of_nodes);
+
+ // Destructor
+ ~Topology() {}
+
+ // Public Methods
+ int numSwitches() const { return m_number_of_switches; }
+ void createLinks(bool isReconfiguration);
+
+ void printStats(ostream& out) const {}
+ void clearStats() {}
+ void printConfig(ostream& out) const;
+ void print(ostream& out) const { out << "[Topology]"; }
+
+private:
+ // Private Methods
+ void init();
+ SwitchID newSwitchID();
+ void addLink(SwitchID src, SwitchID dest, int link_latency);
+ void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier);
+ void addLink(SwitchID src, SwitchID dest, int link_latency, int bw_multiplier, int link_weight);
+ void makeLink(SwitchID src, SwitchID dest, const NetDest& routing_table_entry, int link_latency, int weight, int bw_multiplier, bool isReconfiguration);
+
+ void makeHierarchicalSwitch(int fan_out_degree);
+ void make2DTorus();
+ void makePtToPt();
+ void makeFileSpecified();
+
+ void makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChips);
+
+ string getDesignStr();
+ // Private copy constructor and assignment operator
+ Topology(const Topology& obj);
+ Topology& operator=(const Topology& obj);
+
+ // Data Members (m_ prefix)
+ Network* m_network_ptr;
+ NodeID m_nodes;
+ int m_number_of_switches;
+
+ Vector<SwitchID> m_links_src_vector;
+ Vector<SwitchID> m_links_dest_vector;
+ Vector<int> m_links_latency_vector;
+ Vector<int> m_links_weight_vector;
+ Vector<int> m_bw_multiplier_vector;
+
+ Matrix m_component_latencies;
+ Matrix m_component_inter_switches;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Topology& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Topology& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif