diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py index 5e987f0ac..d9517456b 100644 --- a/configs/ruby/Ruby.py +++ b/configs/ruby/Ruby.py @@ -132,27 +132,36 @@ def create_system(options, system, piobus = None, dma_ports = []): # Set the network classes based on the command line options # if options.garnet_network == "fixed": - class NetworkClass(GarnetNetwork_d): pass - class IntLinkClass(GarnetIntLink_d): pass - class ExtLinkClass(GarnetExtLink_d): pass - class RouterClass(GarnetRouter_d): pass + NetworkClass = GarnetNetwork_d + IntLinkClass = GarnetIntLink_d + ExtLinkClass = GarnetExtLink_d + RouterClass = GarnetRouter_d + InterfaceClass = GarnetNetworkInterface_d + elif options.garnet_network == "flexible": - class NetworkClass(GarnetNetwork): pass - class IntLinkClass(GarnetIntLink): pass - class ExtLinkClass(GarnetExtLink): pass - class RouterClass(GarnetRouter): pass + NetworkClass = GarnetNetwork + IntLinkClass = GarnetIntLink + ExtLinkClass = GarnetExtLink + RouterClass = GarnetRouter + InterfaceClass = GarnetNetworkInterface + else: - class NetworkClass(SimpleNetwork): pass - class IntLinkClass(SimpleIntLink): pass - class ExtLinkClass(SimpleExtLink): pass - class RouterClass(Switch): pass + NetworkClass = SimpleNetwork + IntLinkClass = SimpleIntLink + ExtLinkClass = SimpleExtLink + RouterClass = Switch + InterfaceClass = None # Create the network topology network = NetworkClass(ruby_system = ruby, topology = topology.description, - routers = [], ext_links = [], int_links = []) + routers = [], ext_links = [], int_links = [], netifs = []) topology.makeTopology(options, network, IntLinkClass, ExtLinkClass, - RouterClass) + RouterClass) + + if InterfaceClass != None: + netifs = [InterfaceClass(id=i) for (i,n) in enumerate(network.ext_links)] + network.netifs = netifs if options.network_fault_model: assert(options.garnet_network == "fixed") diff --git a/src/mem/ruby/network/Network.py b/src/mem/ruby/network/Network.py index 40f01ca76..4f33dd196 100644 --- a/src/mem/ruby/network/Network.py +++ b/src/mem/ruby/network/Network.py @@ -45,5 +45,6 @@ class RubyNetwork(ClockedObject): ruby_system = Param.RubySystem("") routers = VectorParam.BasicRouter("Network routers") + netifs = VectorParam.ClockedObject("Network Interfaces") ext_links = VectorParam.BasicExtLink("Links to external nodes") int_links = VectorParam.BasicIntLink("Links between internal nodes") diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc index 2a9d37e3e..6de60b285 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc @@ -60,6 +60,17 @@ GarnetNetwork_d::GarnetNetwork_d(const Params *p) i != p->routers.end(); ++i) { Router_d* router = safe_cast(*i); m_routers.push_back(router); + + // initialize the router's network pointers + router->init_net_ptr(this); + } + + // record the network interfaces + for (vector::const_iterator i = p->netifs.begin(); + i != p->netifs.end(); ++i) { + NetworkInterface_d *ni = safe_cast(*i); + m_nis.push_back(ni); + ni->init_net_ptr(this); } } @@ -68,23 +79,13 @@ GarnetNetwork_d::init() { BaseGarnetNetwork::init(); - // initialize the router's network pointers - for (vector::const_iterator i = m_routers.begin(); - i != m_routers.end(); ++i) { - Router_d* router = safe_cast(*i); - router->init_net_ptr(this); + for (int i=0; i < m_nodes; i++) { + m_nis[i]->addNode(m_toNetQueues[i], m_fromNetQueues[i]); } // The topology pointer should have already been initialized in the // parent network constructor assert(m_topology_ptr != NULL); - - 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_nis.push_back(ni); - } m_topology_ptr->createLinks(this); // FaultModel: declare each router to the fault model diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py index 6ebf94e04..0191d45af 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.py @@ -29,10 +29,33 @@ # Brad Beckmann from m5.params import * +from m5.proxy import * from BaseGarnetNetwork import BaseGarnetNetwork +from BasicRouter import BasicRouter +from ClockedObject import ClockedObject + +class GarnetRouter_d(BasicRouter): + type = 'GarnetRouter_d' + cxx_class = 'Router_d' + cxx_header = "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" + vcs_per_vnet = Param.UInt32(Parent.vcs_per_vnet, + "virtual channels per virtual network") + virt_nets = Param.UInt32(Parent.number_of_virtual_networks, + "number of virtual networks") + +class GarnetNetworkInterface_d(ClockedObject): + type = 'GarnetNetworkInterface_d' + cxx_class = 'NetworkInterface_d' + cxx_header = "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh" + + id = Param.UInt32("ID in relation to other network interfaces") + vcs_per_vnet = Param.UInt32(Parent.vcs_per_vnet, + "virtual channels per virtual network") + virt_nets = Param.UInt32(Parent.number_of_virtual_networks, + "number of virtual networks") class GarnetNetwork_d(BaseGarnetNetwork): type = 'GarnetNetwork_d' cxx_header = "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" - buffers_per_data_vc = Param.Int(4, "buffers per data virtual channel"); - buffers_per_ctrl_vc = Param.Int(1, "buffers per ctrl virtual channel"); + buffers_per_data_vc = Param.UInt32(4, "buffers per data virtual channel"); + buffers_per_ctrl_vc = Param.UInt32(1, "buffers per ctrl virtual channel"); diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py deleted file mode 100644 index cd009a807..000000000 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetRouter_d.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2008 Princeton University -# Copyright (c) 2009 Advanced Micro Devices, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Steve Reinhardt -# Brad Beckmann - -from m5.params import * -from m5.proxy import * -from BasicRouter import BasicRouter - -class GarnetRouter_d(BasicRouter): - type = 'GarnetRouter_d' - cxx_class = 'Router_d' - cxx_header = "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" - vcs_per_vnet = Param.Int(Parent.vcs_per_vnet, - "virtual channels per virtual network") - virt_nets = Param.Int(Parent.number_of_virtual_networks, - "number of virtual networks") - - diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc index c4c64b5ea..3e4088038 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc @@ -42,14 +42,12 @@ using namespace std; using m5::stl_helpers::deletePointers; -NetworkInterface_d::NetworkInterface_d(int id, int virtual_networks, - GarnetNetwork_d *network_ptr) - : Consumer(network_ptr) +NetworkInterface_d::NetworkInterface_d(const Params *p) + : ClockedObject(p), Consumer(this) { - m_id = id; - m_net_ptr = network_ptr; - m_virtual_networks = virtual_networks; - m_vc_per_vnet = m_net_ptr->getVCsPerVnet(); + m_id = p->id; + m_virtual_networks = p->virt_nets; + m_vc_per_vnet = p->vcs_per_vnet; m_num_vcs = m_vc_per_vnet*m_virtual_networks; m_vc_round_robin = 0; @@ -64,11 +62,16 @@ NetworkInterface_d::NetworkInterface_d(int id, int virtual_networks, m_ni_buffers[i] = new flitBuffer_d(); m_ni_enqueue_time[i] = INFINITE_; } + m_vc_allocator.resize(m_virtual_networks); // 1 allocator per vnet for (int i = 0; i < m_virtual_networks; i++) { m_vc_allocator[i] = 0; } +} +void +NetworkInterface_d::init() +{ for (int i = 0; i < m_num_vcs; i++) { m_out_vc_state.push_back(new OutVcState_d(i, m_net_ptr)); } @@ -115,9 +118,8 @@ NetworkInterface_d::addNode(vector& in, // the protocol injects messages into the NI inNode_ptr[j]->setConsumer(this); - inNode_ptr[j]->setReceiver(m_net_ptr); - - outNode_ptr[j]->setSender(m_net_ptr); + inNode_ptr[j]->setReceiver(this); + outNode_ptr[j]->setSender(this); } } @@ -172,15 +174,14 @@ NetworkInterface_d::flitisizeMessage(MsgPtr msg_ptr, int vnet) for (int i = 0; i < num_flits; i++) { m_net_ptr->increment_injected_flits(vnet); flit_d *fl = new flit_d(i, vc, vnet, num_flits, new_msg_ptr, - m_net_ptr->curCycle()); + curCycle()); - fl->set_delay(m_net_ptr->curCycle() - - m_net_ptr->ticksToCycles(msg_ptr->getTime())); + fl->set_delay(curCycle() - ticksToCycles(msg_ptr->getTime())); m_ni_buffers[vc]->insert(fl); } - m_ni_enqueue_time[vc] = m_net_ptr->curCycle(); - m_out_vc_state[vc]->setState(ACTIVE_, m_net_ptr->curCycle()); + m_ni_enqueue_time[vc] = curCycle(); + m_out_vc_state[vc]->setState(ACTIVE_, curCycle()); } return true ; } @@ -196,7 +197,7 @@ NetworkInterface_d::calculateVC(int vnet) m_vc_allocator[vnet] = 0; if (m_out_vc_state[(vnet*m_vc_per_vnet) + delta]->isInState( - IDLE_, m_net_ptr->curCycle())) { + IDLE_, curCycle())) { return ((vnet*m_vc_per_vnet) + delta); } } @@ -216,8 +217,7 @@ NetworkInterface_d::calculateVC(int vnet) void NetworkInterface_d::wakeup() { - DPRINTF(RubyNetwork, "m_id: %d woke up at time: %lld", - m_id, m_net_ptr->curCycle()); + DPRINTF(RubyNetwork, "m_id: %d woke up at time: %lld", m_id, curCycle()); MsgPtr msg_ptr; @@ -239,7 +239,7 @@ NetworkInterface_d::wakeup() /*********** Picking messages destined for this NI **********/ - if (inNetLink->isReady(m_net_ptr->curCycle())) { + if (inNetLink->isReady(curCycle())) { flit_d *t_flit = inNetLink->consumeLink(); bool free_signal = false; if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) { @@ -251,15 +251,14 @@ NetworkInterface_d::wakeup() // Simply send a credit back since we are not buffering // this flit in the NI flit_d *credit_flit = new flit_d(t_flit->get_vc(), free_signal, - m_net_ptr->curCycle()); + curCycle()); creditQueue->insert(credit_flit); m_ni_credit_link-> - scheduleEventAbsolute(m_net_ptr->clockEdge(Cycles(1))); + scheduleEventAbsolute(clockEdge(Cycles(1))); int vnet = t_flit->get_vnet(); m_net_ptr->increment_received_flits(vnet); - Cycles network_delay = m_net_ptr->curCycle() - - t_flit->get_enqueue_time(); + Cycles network_delay = curCycle() - t_flit->get_enqueue_time(); Cycles queueing_delay = t_flit->get_delay(); m_net_ptr->increment_network_latency(network_delay, vnet); @@ -269,12 +268,11 @@ NetworkInterface_d::wakeup() /****************** Checking for credit link *******/ - if (m_credit_link->isReady(m_net_ptr->curCycle())) { + if (m_credit_link->isReady(curCycle())) { 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_, - m_net_ptr->curCycle()); + m_out_vc_state[t_flit->get_vc()]->setState(IDLE_, curCycle()); } delete t_flit; } @@ -300,7 +298,7 @@ NetworkInterface_d::scheduleOutputLink() vc = 0; // model buffer backpressure - if (m_ni_buffers[vc]->isReady(m_net_ptr->curCycle()) && + if (m_ni_buffers[vc]->isReady(curCycle()) && m_out_vc_state[vc]->has_credits()) { bool is_candidate_vc = true; @@ -311,7 +309,7 @@ NetworkInterface_d::scheduleOutputLink() 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(m_net_ptr->curCycle())) { + if (m_ni_buffers[t_vc]->isReady(curCycle())) { if (m_ni_enqueue_time[t_vc] < m_ni_enqueue_time[vc]) { is_candidate_vc = false; break; @@ -325,11 +323,10 @@ NetworkInterface_d::scheduleOutputLink() m_out_vc_state[vc]->decrement_credit(); // Just removing the flit flit_d *t_flit = m_ni_buffers[vc]->getTopFlit(); - t_flit->set_time(m_net_ptr->curCycle() + Cycles(1)); + t_flit->set_time(curCycle() + Cycles(1)); outSrcQueue->insert(t_flit); // schedule the out link - outNetLink-> - scheduleEventAbsolute(m_net_ptr->clockEdge(Cycles(1))); + outNetLink->scheduleEventAbsolute(clockEdge(Cycles(1))); if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) { @@ -361,7 +358,7 @@ NetworkInterface_d::checkReschedule() } } for (int vc = 0; vc < m_num_vcs; vc++) { - if (m_ni_buffers[vc]->isReady(m_net_ptr->curCycle() + Cycles(1))) { + if (m_ni_buffers[vc]->isReady(curCycle() + Cycles(1))) { scheduleEvent(Cycles(1)); return; } @@ -385,3 +382,10 @@ NetworkInterface_d::functionalWrite(Packet *pkt) num_functional_writes += outSrcQueue->functionalWrite(pkt); return num_functional_writes; } + +NetworkInterface_d * +GarnetNetworkInterface_dParams::create() +{ + return new NetworkInterface_d(this); +} + diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh index e064b8650..0b8b9f12f 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh @@ -41,19 +41,21 @@ #include "mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/slicc_interface/Message.hh" +#include "params/GarnetNetworkInterface_d.hh" class NetworkMessage; class MessageBuffer; class flitBuffer_d; -class NetworkInterface_d : public Consumer +class NetworkInterface_d : public ClockedObject, public Consumer { public: - NetworkInterface_d(int id, int virtual_networks, - GarnetNetwork_d* network_ptr); - + typedef GarnetNetworkInterface_dParams Params; + NetworkInterface_d(const Params *p); ~NetworkInterface_d(); + void init(); + void addInPort(NetworkLink_d *in_link, CreditLink_d *credit_link); void addOutPort(NetworkLink_d *out_link, CreditLink_d *credit_link); @@ -62,6 +64,7 @@ class NetworkInterface_d : public Consumer std::vector &outNode); void print(std::ostream& out) const; int get_vnet(int vc); + void init_net_ptr(GarnetNetwork_d *net_ptr) { m_net_ptr = net_ptr; } uint32_t functionalWrite(Packet *); diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/SConscript b/src/mem/ruby/network/garnet/fixed-pipeline/SConscript index 82d11cb01..534fdc884 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/SConscript +++ b/src/mem/ruby/network/garnet/fixed-pipeline/SConscript @@ -35,7 +35,6 @@ if env['PROTOCOL'] == 'None': SimObject('GarnetLink_d.py') SimObject('GarnetNetwork_d.py') -SimObject('GarnetRouter_d.py') Source('GarnetLink_d.cc') Source('GarnetNetwork_d.cc') diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc index 856e90d1f..280917bab 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc @@ -56,6 +56,11 @@ GarnetNetwork::GarnetNetwork(const Params *p) Router* router = safe_cast(*i); m_routers.push_back(router); } + + for (int i=0; i < m_nodes; i++) { + NetworkInterface *ni = safe_cast(p->netifs[i]); + m_nis.push_back(ni); + } } void @@ -74,10 +79,8 @@ GarnetNetwork::init() } 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_nis.push_back(ni); + m_nis[i]->init_net_ptr(this); + m_nis[i]->addNode(m_toNetQueues[i], m_fromNetQueues[i]); } m_topology_ptr->createLinks(this); diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.py b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.py index 28f81d732..0c9b143a3 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.py +++ b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.py @@ -29,11 +29,34 @@ # Brad Beckmann from m5.params import * +from m5.proxy import * from BaseGarnetNetwork import BaseGarnetNetwork +from BasicRouter import BasicRouter +from ClockedObject import ClockedObject + +class GarnetRouter(BasicRouter): + type = 'GarnetRouter' + cxx_class = 'Router' + cxx_header = "mem/ruby/network/garnet/flexible-pipeline/Router.hh" + vcs_per_vnet = Param.Int(Parent.vcs_per_vnet, + "virtual channels per virtual network") + virt_nets = Param.Int(Parent.number_of_virtual_networks, + "number of virtual networks") + +class GarnetNetworkInterface(ClockedObject): + type = 'GarnetNetworkInterface' + cxx_class = 'NetworkInterface' + cxx_header = "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh" + + id = Param.UInt32("ID in relation to other network interfaces") + vcs_per_vnet = Param.UInt32(Parent.vcs_per_vnet, + "virtual channels per virtual network") + virt_nets = Param.UInt32(Parent.number_of_virtual_networks, + "number of virtual networks") class GarnetNetwork(BaseGarnetNetwork): type = 'GarnetNetwork' cxx_header = "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh" - buffer_size = Param.Int(0, + buffer_size = Param.UInt32(0, "default buffer size; 0 indicates infinite buffering"); - number_of_pipe_stages = Param.Int(4, "router pipeline stages"); + number_of_pipe_stages = Param.UInt32(4, "router pipeline stages"); diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py b/src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py deleted file mode 100644 index 22d8c8670..000000000 --- a/src/mem/ruby/network/garnet/flexible-pipeline/GarnetRouter.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2008 Princeton University -# Copyright (c) 2009 Advanced Micro Devices, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Steve Reinhardt -# Brad Beckmann - -from m5.params import * -from m5.proxy import * -from BasicRouter import BasicRouter - -class GarnetRouter(BasicRouter): - type = 'GarnetRouter' - cxx_class = 'Router' - cxx_header = "mem/ruby/network/garnet/flexible-pipeline/Router.hh" - vcs_per_vnet = Param.Int(Parent.vcs_per_vnet, - "virtual channels per virtual network") - virt_nets = Param.Int(Parent.number_of_virtual_networks, - "number of virtual networks") diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc index fb918f95d..ba32abd44 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc @@ -42,14 +42,12 @@ using namespace std; using m5::stl_helpers::deletePointers; -NetworkInterface::NetworkInterface(int id, int virtual_networks, - GarnetNetwork *network_ptr) - : FlexibleConsumer(network_ptr) +NetworkInterface::NetworkInterface(const Params *p) + : ClockedObject(p), FlexibleConsumer(this) { - m_id = id; - m_net_ptr = network_ptr; - m_virtual_networks = virtual_networks; - m_vc_per_vnet = m_net_ptr->getVCsPerVnet(); + m_id = p->id; + m_virtual_networks = p->virt_nets; + m_vc_per_vnet = p->vcs_per_vnet; m_num_vcs = m_vc_per_vnet*m_virtual_networks; m_vc_round_robin = 0; @@ -105,9 +103,8 @@ NetworkInterface::addNode(vector& in, // protocol injects messages into the NI for (int j = 0; j < m_virtual_networks; j++) { inNode_ptr[j]->setConsumer(this); - inNode_ptr[j]->setReceiver(m_net_ptr); - - outNode_ptr[j]->setSender(m_net_ptr); + inNode_ptr[j]->setReceiver(this); + outNode_ptr[j]->setSender(this); } } @@ -169,20 +166,18 @@ NetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet) for (int i = 0; i < num_flits; i++) { m_net_ptr->increment_injected_flits(vnet); flit *fl = new flit(i, vc, vnet, num_flits, new_msg_ptr, - m_net_ptr->curCycle()); - fl->set_delay(m_net_ptr->curCycle() - - m_net_ptr->ticksToCycles(msg_ptr->getTime())); + curCycle()); + fl->set_delay(curCycle() - ticksToCycles(msg_ptr->getTime())); m_ni_buffers[vc]->insert(fl); } - m_out_vc_state[vc]->setState(VC_AB_, m_net_ptr->curCycle()); + m_out_vc_state[vc]->setState(VC_AB_, curCycle()); // setting an output vc request for the next hop. // This flit will be ready to traverse the link and into the next hop // only when an output vc is acquired at the next hop - outNetLink->request_vc_link(vc, - new_net_msg_ptr->getInternalDestination(), - m_net_ptr->curCycle()); + outNetLink->request_vc_link( + vc, new_net_msg_ptr->getInternalDestination(), curCycle()); } return true ; @@ -224,8 +219,8 @@ NetworkInterface::calculateVC(int 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_, - m_net_ptr->curCycle())) { + if (m_out_vc_state[(vnet*m_vc_per_vnet) + delta]-> + isInState(IDLE_, curCycle())) { return ((vnet*m_vc_per_vnet) + delta); } } @@ -269,20 +264,19 @@ NetworkInterface::wakeup() flit *t_flit = inNetLink->consumeLink(); if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) { DPRINTF(RubyNetwork, "m_id: %d, Message delivered at time: %lld\n", - m_id, m_net_ptr->curCycle()); + m_id, curCycle()); outNode_ptr[t_flit->get_vnet()]->enqueue( t_flit->get_msg_ptr(), Cycles(1)); // signal the upstream router that this vc can be freed now inNetLink->release_vc_link(t_flit->get_vc(), - m_net_ptr->curCycle() + Cycles(1)); + curCycle() + Cycles(1)); } int vnet = t_flit->get_vnet(); m_net_ptr->increment_received_flits(vnet); - Cycles network_delay = m_net_ptr->curCycle() - - t_flit->get_enqueue_time(); + Cycles network_delay = curCycle() - t_flit->get_enqueue_time(); Cycles queueing_delay = t_flit->get_delay(); m_net_ptr->increment_network_latency(network_delay, vnet); @@ -309,19 +303,18 @@ NetworkInterface::scheduleOutputLink() vc++; if (vc == m_num_vcs) vc = 0; - if (m_ni_buffers[vc]->isReady(m_net_ptr->curCycle())) { - if (m_out_vc_state[vc]->isInState(ACTIVE_, - m_net_ptr->curCycle()) && + if (m_ni_buffers[vc]->isReady(curCycle())) { + if (m_out_vc_state[vc]->isInState(ACTIVE_, curCycle()) && outNetLink->isBufferNotFull_link(vc)) { // buffer backpressure // Just removing the flit flit *t_flit = m_ni_buffers[vc]->getTopFlit(); - t_flit->set_time(m_net_ptr->curCycle() + Cycles(1)); + t_flit->set_time(curCycle() + Cycles(1)); outSrcQueue->insert(t_flit); // schedule the out link outNetLink-> - scheduleEventAbsolute(m_net_ptr->clockEdge(Cycles(1))); + scheduleEventAbsolute(clockEdge(Cycles(1))); return; } } @@ -338,7 +331,7 @@ NetworkInterface::checkReschedule() } } for (int vc = 0; vc < m_num_vcs; vc++) { - if (m_ni_buffers[vc]->isReadyForNext(m_net_ptr->curCycle())) { + if (m_ni_buffers[vc]->isReadyForNext(curCycle())) { scheduleEvent(Cycles(1)); return; } @@ -380,3 +373,9 @@ NetworkInterface::print(std::ostream& out) const { out << "[Network Interface]"; } + +NetworkInterface * +GarnetNetworkInterfaceParams::create() +{ + return new NetworkInterface(this); +} diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh index a4dd36da6..0af538bf2 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh @@ -40,16 +40,17 @@ #include "mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/slicc_interface/Message.hh" +#include "params/GarnetNetworkInterface.hh" class NetworkMessage; class MessageBuffer; class flitBuffer; -class NetworkInterface : public FlexibleConsumer +class NetworkInterface : public ClockedObject, public FlexibleConsumer { public: - NetworkInterface(int id, int virtual_networks, - GarnetNetwork* network_ptr); + typedef GarnetNetworkInterfaceParams Params; + NetworkInterface(const Params *p); ~NetworkInterface(); @@ -62,11 +63,7 @@ class NetworkInterface : public FlexibleConsumer void grant_vc(int out_port, int vc, Cycles grant_time); void release_vc(int out_port, int vc, Cycles release_time); - bool - isBufferNotFull(int vc, int inport) - { - return true; - } + bool isBufferNotFull(int vc, int inport) { return true; } void request_vc(int in_vc, int in_port, NetDest destination, Cycles request_time); @@ -75,9 +72,11 @@ class NetworkInterface : public FlexibleConsumer bool functionalRead(Packet *); uint32_t functionalWrite(Packet *); + void init_net_ptr(GarnetNetwork* net_ptr) { m_net_ptr = net_ptr; } + private: GarnetNetwork *m_net_ptr; - int m_virtual_networks, m_num_vcs, m_vc_per_vnet; + uint32_t m_virtual_networks, m_num_vcs, m_vc_per_vnet; NodeID m_id; std::vector m_out_vc_state; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/SConscript b/src/mem/ruby/network/garnet/flexible-pipeline/SConscript index 0e97f1698..d4c1a2cb9 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/SConscript +++ b/src/mem/ruby/network/garnet/flexible-pipeline/SConscript @@ -35,7 +35,6 @@ if env['PROTOCOL'] == 'None': SimObject('GarnetLink.py') SimObject('GarnetNetwork.py') -SimObject('GarnetRouter.py') Source('GarnetLink.cc') Source('GarnetNetwork.cc')