SimpleNetwork.cc revision 11664
14348Sgblack@eecs.umich.edu/*
24348Sgblack@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
34348Sgblack@eecs.umich.edu * All rights reserved.
44348Sgblack@eecs.umich.edu *
54348Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
64348Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
74348Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
84348Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
94348Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
104348Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
114348Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
124348Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
134348Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
144348Sgblack@eecs.umich.edu * this software without specific prior written permission.
154348Sgblack@eecs.umich.edu *
164348Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174348Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184348Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194348Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204348Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214348Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224348Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234348Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244348Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254348Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264348Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274348Sgblack@eecs.umich.edu */
284348Sgblack@eecs.umich.edu
294348Sgblack@eecs.umich.edu#include <cassert>
304348Sgblack@eecs.umich.edu#include <numeric>
314348Sgblack@eecs.umich.edu
324348Sgblack@eecs.umich.edu#include "base/cast.hh"
334348Sgblack@eecs.umich.edu#include "base/stl_helpers.hh"
344348Sgblack@eecs.umich.edu#include "mem/ruby/common/NetDest.hh"
354348Sgblack@eecs.umich.edu#include "mem/ruby/network/MessageBuffer.hh"
364348Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/SimpleLink.hh"
374348Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/SimpleNetwork.hh"
384348Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/Switch.hh"
394348Sgblack@eecs.umich.edu#include "mem/ruby/network/simple/Throttle.hh"
404348Sgblack@eecs.umich.edu#include "mem/ruby/profiler/Profiler.hh"
414348Sgblack@eecs.umich.edu
424348Sgblack@eecs.umich.eduusing namespace std;
434348Sgblack@eecs.umich.eduusing m5::stl_helpers::deletePointers;
444348Sgblack@eecs.umich.edu
454348Sgblack@eecs.umich.eduSimpleNetwork::SimpleNetwork(const Params *p)
464348Sgblack@eecs.umich.edu    : Network(p), m_buffer_size(p->buffer_size),
474348Sgblack@eecs.umich.edu      m_endpoint_bandwidth(p->endpoint_bandwidth),
484348Sgblack@eecs.umich.edu      m_adaptive_routing(p->adaptive_routing)
494348Sgblack@eecs.umich.edu{
504348Sgblack@eecs.umich.edu    // record the routers
514348Sgblack@eecs.umich.edu    for (vector<BasicRouter*>::const_iterator i = p->routers.begin();
524348Sgblack@eecs.umich.edu         i != p->routers.end(); ++i) {
534348Sgblack@eecs.umich.edu        Switch* s = safe_cast<Switch*>(*i);
544348Sgblack@eecs.umich.edu        m_switches.push_back(s);
554348Sgblack@eecs.umich.edu        s->init_net_ptr(this);
564348Sgblack@eecs.umich.edu    }
574348Sgblack@eecs.umich.edu
584348Sgblack@eecs.umich.edu    m_int_link_buffers = p->int_link_buffers;
594348Sgblack@eecs.umich.edu    m_num_connected_buffers = 0;
604348Sgblack@eecs.umich.edu}
614348Sgblack@eecs.umich.edu
624348Sgblack@eecs.umich.eduvoid
634348Sgblack@eecs.umich.eduSimpleNetwork::init()
644348Sgblack@eecs.umich.edu{
654348Sgblack@eecs.umich.edu    Network::init();
664348Sgblack@eecs.umich.edu
674348Sgblack@eecs.umich.edu    // The topology pointer should have already been initialized in
684348Sgblack@eecs.umich.edu    // the parent class network constructor.
694528Sgblack@eecs.umich.edu    assert(m_topology_ptr != NULL);
704542Sgblack@eecs.umich.edu    m_topology_ptr->createLinks(this);
714542Sgblack@eecs.umich.edu}
724348Sgblack@eecs.umich.edu
734542Sgblack@eecs.umich.eduSimpleNetwork::~SimpleNetwork()
744542Sgblack@eecs.umich.edu{
754542Sgblack@eecs.umich.edu    deletePointers(m_switches);
764542Sgblack@eecs.umich.edu    deletePointers(m_int_link_buffers);
774348Sgblack@eecs.umich.edu}
784542Sgblack@eecs.umich.edu
794542Sgblack@eecs.umich.edu// From a switch to an endpoint node
804542Sgblack@eecs.umich.eduvoid
814542Sgblack@eecs.umich.eduSimpleNetwork::makeExtOutLink(SwitchID src, NodeID dest, BasicLink* link,
824542Sgblack@eecs.umich.edu                           const NetDest& routing_table_entry)
834542Sgblack@eecs.umich.edu{
844348Sgblack@eecs.umich.edu    assert(dest < m_nodes);
854348Sgblack@eecs.umich.edu    assert(src < m_switches.size());
864348Sgblack@eecs.umich.edu    assert(m_switches[src] != NULL);
874348Sgblack@eecs.umich.edu
884528Sgblack@eecs.umich.edu    SimpleExtLink *simple_link = safe_cast<SimpleExtLink*>(link);
894348Sgblack@eecs.umich.edu
904348Sgblack@eecs.umich.edu    m_switches[src]->addOutPort(m_fromNetQueues[dest], routing_table_entry,
914348Sgblack@eecs.umich.edu                                simple_link->m_latency,
924348Sgblack@eecs.umich.edu                                simple_link->m_bw_multiplier);
934348Sgblack@eecs.umich.edu}
944348Sgblack@eecs.umich.edu
954348Sgblack@eecs.umich.edu// From an endpoint node to a switch
964528Sgblack@eecs.umich.eduvoid
974348Sgblack@eecs.umich.eduSimpleNetwork::makeExtInLink(NodeID src, SwitchID dest, BasicLink* link,
984548Sgblack@eecs.umich.edu                          const NetDest& routing_table_entry)
994548Sgblack@eecs.umich.edu{
1004548Sgblack@eecs.umich.edu    assert(src < m_nodes);
1014348Sgblack@eecs.umich.edu    m_switches[dest]->addInPort(m_toNetQueues[src]);
1024528Sgblack@eecs.umich.edu}
1034528Sgblack@eecs.umich.edu
1044542Sgblack@eecs.umich.edu// From a switch to a switch
1054348Sgblack@eecs.umich.eduvoid
1064528Sgblack@eecs.umich.eduSimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
1074542Sgblack@eecs.umich.edu                                const NetDest& routing_table_entry,
1084348Sgblack@eecs.umich.edu                                PortDirection src_outport,
1094348Sgblack@eecs.umich.edu                                PortDirection dst_inport)
1104348Sgblack@eecs.umich.edu{
1114528Sgblack@eecs.umich.edu    // Create a set of new MessageBuffers
1124542Sgblack@eecs.umich.edu    std::vector<MessageBuffer*> queues(m_virtual_networks);
1134542Sgblack@eecs.umich.edu
1144542Sgblack@eecs.umich.edu    for (int i = 0; i < m_virtual_networks; i++) {
1154542Sgblack@eecs.umich.edu        // allocate a buffer
1164528Sgblack@eecs.umich.edu        assert(m_num_connected_buffers < m_int_link_buffers.size());
1174528Sgblack@eecs.umich.edu        MessageBuffer* buffer_ptr = m_int_link_buffers[m_num_connected_buffers];
1184528Sgblack@eecs.umich.edu        m_num_connected_buffers++;
1194528Sgblack@eecs.umich.edu        queues[i] = buffer_ptr;
1204528Sgblack@eecs.umich.edu    }
1214528Sgblack@eecs.umich.edu
1224528Sgblack@eecs.umich.edu    // Connect it to the two switches
1234348Sgblack@eecs.umich.edu    SimpleIntLink *simple_link = safe_cast<SimpleIntLink*>(link);
1244348Sgblack@eecs.umich.edu
1254348Sgblack@eecs.umich.edu    m_switches[dest]->addInPort(queues);
1264348Sgblack@eecs.umich.edu    m_switches[src]->addOutPort(queues, routing_table_entry,
1274548Sgblack@eecs.umich.edu                                simple_link->m_latency,
1284348Sgblack@eecs.umich.edu                                simple_link->m_bw_multiplier);
1294348Sgblack@eecs.umich.edu}
1304348Sgblack@eecs.umich.edu
1314348Sgblack@eecs.umich.eduvoid
1324528Sgblack@eecs.umich.eduSimpleNetwork::regStats()
1334528Sgblack@eecs.umich.edu{
1344548Sgblack@eecs.umich.edu    Network::regStats();
1354348Sgblack@eecs.umich.edu
1364348Sgblack@eecs.umich.edu    for (MessageSizeType type = MessageSizeType_FIRST;
1374348Sgblack@eecs.umich.edu         type < MessageSizeType_NUM; ++type) {
1384348Sgblack@eecs.umich.edu        m_msg_counts[(unsigned int) type]
1394528Sgblack@eecs.umich.edu            .name(name() + ".msg_count." + MessageSizeType_to_string(type))
1404528Sgblack@eecs.umich.edu            .flags(Stats::nozero)
1414542Sgblack@eecs.umich.edu            ;
1424528Sgblack@eecs.umich.edu        m_msg_bytes[(unsigned int) type]
1434542Sgblack@eecs.umich.edu            .name(name() + ".msg_byte." + MessageSizeType_to_string(type))
1444348Sgblack@eecs.umich.edu            .flags(Stats::nozero)
1454532Sgblack@eecs.umich.edu            ;
1464528Sgblack@eecs.umich.edu
1474348Sgblack@eecs.umich.edu        // Now state what the formula is.
1484348Sgblack@eecs.umich.edu        for (int i = 0; i < m_switches.size(); i++) {
1494348Sgblack@eecs.umich.edu            m_msg_counts[(unsigned int) type] +=
1504348Sgblack@eecs.umich.edu                sum(m_switches[i]->getMsgCount(type));
1514528Sgblack@eecs.umich.edu        }
1524348Sgblack@eecs.umich.edu
1534348Sgblack@eecs.umich.edu        m_msg_bytes[(unsigned int) type] =
1544348Sgblack@eecs.umich.edu            m_msg_counts[(unsigned int) type] * Stats::constant(
1554548Sgblack@eecs.umich.edu                    Network::MessageSizeType_to_int(type));
1564348Sgblack@eecs.umich.edu    }
1574348Sgblack@eecs.umich.edu}
1584528Sgblack@eecs.umich.edu
1594348Sgblack@eecs.umich.eduvoid
1604532Sgblack@eecs.umich.eduSimpleNetwork::collateStats()
1614532Sgblack@eecs.umich.edu{
1624528Sgblack@eecs.umich.edu    for (int i = 0; i < m_switches.size(); i++) {
1634348Sgblack@eecs.umich.edu        m_switches[i]->collateStats();
164    }
165}
166
167void
168SimpleNetwork::print(ostream& out) const
169{
170    out << "[SimpleNetwork]";
171}
172
173SimpleNetwork *
174SimpleNetworkParams::create()
175{
176    return new SimpleNetwork(this);
177}
178
179/*
180 * The simple network has an array of switches. These switches have buffers
181 * that need to be accessed for functional reads and writes. Also the links
182 * between different switches have buffers that need to be accessed.
183 */
184bool
185SimpleNetwork::functionalRead(Packet *pkt)
186{
187    for (unsigned int i = 0; i < m_switches.size(); i++) {
188        if (m_switches[i]->functionalRead(pkt)) {
189            return true;
190        }
191    }
192
193    return false;
194}
195
196uint32_t
197SimpleNetwork::functionalWrite(Packet *pkt)
198{
199    uint32_t num_functional_writes = 0;
200
201    for (unsigned int i = 0; i < m_switches.size(); i++) {
202        num_functional_writes += m_switches[i]->functionalWrite(pkt);
203    }
204
205    for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) {
206        num_functional_writes += m_int_link_buffers[i]->functionalWrite(pkt);
207    }
208    return num_functional_writes;
209}
210