SimpleNetwork.cc revision 11663
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
36145Snate@binkert.org * All rights reserved.
46145Snate@binkert.org *
56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
66145Snate@binkert.org * modification, are permitted provided that the following conditions are
76145Snate@binkert.org * met: redistributions of source code must retain the above copyright
86145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
116145Snate@binkert.org * documentation and/or other materials provided with the distribution;
126145Snate@binkert.org * neither the name of the copyright holders nor the names of its
136145Snate@binkert.org * contributors may be used to endorse or promote products derived from
146145Snate@binkert.org * this software without specific prior written permission.
156145Snate@binkert.org *
166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276145Snate@binkert.org */
286145Snate@binkert.org
297832Snate@binkert.org#include <cassert>
307547SBrad.Beckmann@amd.com#include <numeric>
317547SBrad.Beckmann@amd.com
328645Snilay@cs.wisc.edu#include "base/cast.hh"
337454Snate@binkert.org#include "base/stl_helpers.hh"
347054Snate@binkert.org#include "mem/ruby/common/NetDest.hh"
3510301Snilay@cs.wisc.edu#include "mem/ruby/network/MessageBuffer.hh"
368258SBrad.Beckmann@amd.com#include "mem/ruby/network/simple/SimpleLink.hh"
376154Snate@binkert.org#include "mem/ruby/network/simple/SimpleNetwork.hh"
387054Snate@binkert.org#include "mem/ruby/network/simple/Switch.hh"
397547SBrad.Beckmann@amd.com#include "mem/ruby/network/simple/Throttle.hh"
406154Snate@binkert.org#include "mem/ruby/profiler/Profiler.hh"
416145Snate@binkert.org
427055Snate@binkert.orgusing namespace std;
437454Snate@binkert.orgusing m5::stl_helpers::deletePointers;
447055Snate@binkert.org
456876Ssteve.reinhardt@amd.comSimpleNetwork::SimpleNetwork(const Params *p)
4611124Snilay@cs.wisc.edu    : Network(p), m_buffer_size(p->buffer_size),
4711124Snilay@cs.wisc.edu      m_endpoint_bandwidth(p->endpoint_bandwidth),
4811124Snilay@cs.wisc.edu      m_adaptive_routing(p->adaptive_routing)
496285Snate@binkert.org{
509274Snilay@cs.wisc.edu    // record the routers
519593Snilay@cs.wisc.edu    for (vector<BasicRouter*>::const_iterator i = p->routers.begin();
529593Snilay@cs.wisc.edu         i != p->routers.end(); ++i) {
539274Snilay@cs.wisc.edu        Switch* s = safe_cast<Switch*>(*i);
549858Snilay@cs.wisc.edu        m_switches.push_back(s);
559274Snilay@cs.wisc.edu        s->init_net_ptr(this);
569274Snilay@cs.wisc.edu    }
5711021Sjthestness@gmail.com
5811021Sjthestness@gmail.com    m_int_link_buffers = p->int_link_buffers;
5911021Sjthestness@gmail.com    m_num_connected_buffers = 0;
606881SBrad.Beckmann@amd.com}
616285Snate@binkert.org
627054Snate@binkert.orgvoid
637054Snate@binkert.orgSimpleNetwork::init()
646881SBrad.Beckmann@amd.com{
657054Snate@binkert.org    Network::init();
666881SBrad.Beckmann@amd.com
677054Snate@binkert.org    // The topology pointer should have already been initialized in
687054Snate@binkert.org    // the parent class network constructor.
697054Snate@binkert.org    assert(m_topology_ptr != NULL);
709799Snilay@cs.wisc.edu    m_topology_ptr->createLinks(this);
716285Snate@binkert.org}
726145Snate@binkert.org
736145Snate@binkert.orgSimpleNetwork::~SimpleNetwork()
746145Snate@binkert.org{
759858Snilay@cs.wisc.edu    deletePointers(m_switches);
7611021Sjthestness@gmail.com    deletePointers(m_int_link_buffers);
776145Snate@binkert.org}
786145Snate@binkert.org
796145Snate@binkert.org// From a switch to an endpoint node
807054Snate@binkert.orgvoid
8111663Stushar@ece.gatech.eduSimpleNetwork::makeExtOutLink(SwitchID src, NodeID dest, BasicLink* link,
829799Snilay@cs.wisc.edu                           const NetDest& routing_table_entry)
836145Snate@binkert.org{
847054Snate@binkert.org    assert(dest < m_nodes);
859858Snilay@cs.wisc.edu    assert(src < m_switches.size());
869858Snilay@cs.wisc.edu    assert(m_switches[src] != NULL);
877054Snate@binkert.org
888258SBrad.Beckmann@amd.com    SimpleExtLink *simple_link = safe_cast<SimpleExtLink*>(link);
898258SBrad.Beckmann@amd.com
9010311Snilay@cs.wisc.edu    m_switches[src]->addOutPort(m_fromNetQueues[dest], routing_table_entry,
9110311Snilay@cs.wisc.edu                                simple_link->m_latency,
9210311Snilay@cs.wisc.edu                                simple_link->m_bw_multiplier);
936145Snate@binkert.org}
946145Snate@binkert.org
956145Snate@binkert.org// From an endpoint node to a switch
967054Snate@binkert.orgvoid
9711663Stushar@ece.gatech.eduSimpleNetwork::makeExtInLink(NodeID src, SwitchID dest, BasicLink* link,
989799Snilay@cs.wisc.edu                          const NetDest& routing_table_entry)
996145Snate@binkert.org{
1007054Snate@binkert.org    assert(src < m_nodes);
1019858Snilay@cs.wisc.edu    m_switches[dest]->addInPort(m_toNetQueues[src]);
1026145Snate@binkert.org}
1036145Snate@binkert.org
1046145Snate@binkert.org// From a switch to a switch
1057054Snate@binkert.orgvoid
10610917Sbrandon.potter@amd.comSimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
1079799Snilay@cs.wisc.edu                                const NetDest& routing_table_entry)
1086145Snate@binkert.org{
1096145Snate@binkert.org    // Create a set of new MessageBuffers
11010370Snilay@cs.wisc.edu    std::vector<MessageBuffer*> queues(m_virtual_networks);
11110370Snilay@cs.wisc.edu
1126145Snate@binkert.org    for (int i = 0; i < m_virtual_networks; i++) {
1137054Snate@binkert.org        // allocate a buffer
11411021Sjthestness@gmail.com        assert(m_num_connected_buffers < m_int_link_buffers.size());
11511021Sjthestness@gmail.com        MessageBuffer* buffer_ptr = m_int_link_buffers[m_num_connected_buffers];
11611021Sjthestness@gmail.com        m_num_connected_buffers++;
11710311Snilay@cs.wisc.edu        queues[i] = buffer_ptr;
1187054Snate@binkert.org    }
11910311Snilay@cs.wisc.edu
1207054Snate@binkert.org    // Connect it to the two switches
1218258SBrad.Beckmann@amd.com    SimpleIntLink *simple_link = safe_cast<SimpleIntLink*>(link);
1228258SBrad.Beckmann@amd.com
1239858Snilay@cs.wisc.edu    m_switches[dest]->addInPort(queues);
1249858Snilay@cs.wisc.edu    m_switches[src]->addOutPort(queues, routing_table_entry,
12510311Snilay@cs.wisc.edu                                simple_link->m_latency,
12610311Snilay@cs.wisc.edu                                simple_link->m_bw_multiplier);
1277054Snate@binkert.org}
1287054Snate@binkert.org
1297054Snate@binkert.orgvoid
1309863Snilay@cs.wisc.eduSimpleNetwork::regStats()
1317054Snate@binkert.org{
13211523Sdavid.guillen@arm.com    Network::regStats();
13311523Sdavid.guillen@arm.com
1349863Snilay@cs.wisc.edu    for (MessageSizeType type = MessageSizeType_FIRST;
1359863Snilay@cs.wisc.edu         type < MessageSizeType_NUM; ++type) {
1369863Snilay@cs.wisc.edu        m_msg_counts[(unsigned int) type]
1379863Snilay@cs.wisc.edu            .name(name() + ".msg_count." + MessageSizeType_to_string(type))
1389863Snilay@cs.wisc.edu            .flags(Stats::nozero)
1399863Snilay@cs.wisc.edu            ;
1409863Snilay@cs.wisc.edu        m_msg_bytes[(unsigned int) type]
1419863Snilay@cs.wisc.edu            .name(name() + ".msg_byte." + MessageSizeType_to_string(type))
1429863Snilay@cs.wisc.edu            .flags(Stats::nozero)
1439863Snilay@cs.wisc.edu            ;
1447547SBrad.Beckmann@amd.com
1459863Snilay@cs.wisc.edu        // Now state what the formula is.
1469863Snilay@cs.wisc.edu        for (int i = 0; i < m_switches.size(); i++) {
1479863Snilay@cs.wisc.edu            m_msg_counts[(unsigned int) type] +=
1489863Snilay@cs.wisc.edu                sum(m_switches[i]->getMsgCount(type));
1497547SBrad.Beckmann@amd.com        }
1509863Snilay@cs.wisc.edu
1519863Snilay@cs.wisc.edu        m_msg_bytes[(unsigned int) type] =
1529863Snilay@cs.wisc.edu            m_msg_counts[(unsigned int) type] * Stats::constant(
1539863Snilay@cs.wisc.edu                    Network::MessageSizeType_to_int(type));
1547054Snate@binkert.org    }
1557054Snate@binkert.org}
1567054Snate@binkert.org
1577054Snate@binkert.orgvoid
1589863Snilay@cs.wisc.eduSimpleNetwork::collateStats()
1597054Snate@binkert.org{
1609858Snilay@cs.wisc.edu    for (int i = 0; i < m_switches.size(); i++) {
1619863Snilay@cs.wisc.edu        m_switches[i]->collateStats();
1627054Snate@binkert.org    }
1637054Snate@binkert.org}
1647054Snate@binkert.org
1657054Snate@binkert.orgvoid
1667054Snate@binkert.orgSimpleNetwork::print(ostream& out) const
1676145Snate@binkert.org{
1687054Snate@binkert.org    out << "[SimpleNetwork]";
1696145Snate@binkert.org}
1706876Ssteve.reinhardt@amd.com
1716876Ssteve.reinhardt@amd.comSimpleNetwork *
1726876Ssteve.reinhardt@amd.comSimpleNetworkParams::create()
1736876Ssteve.reinhardt@amd.com{
1746876Ssteve.reinhardt@amd.com    return new SimpleNetwork(this);
1756876Ssteve.reinhardt@amd.com}
1769302Snilay@cs.wisc.edu
1779302Snilay@cs.wisc.edu/*
1789302Snilay@cs.wisc.edu * The simple network has an array of switches. These switches have buffers
1799302Snilay@cs.wisc.edu * that need to be accessed for functional reads and writes. Also the links
1809302Snilay@cs.wisc.edu * between different switches have buffers that need to be accessed.
1819302Snilay@cs.wisc.edu */
1829302Snilay@cs.wisc.edubool
1839302Snilay@cs.wisc.eduSimpleNetwork::functionalRead(Packet *pkt)
1849302Snilay@cs.wisc.edu{
1859858Snilay@cs.wisc.edu    for (unsigned int i = 0; i < m_switches.size(); i++) {
1869858Snilay@cs.wisc.edu        if (m_switches[i]->functionalRead(pkt)) {
1879302Snilay@cs.wisc.edu            return true;
1889302Snilay@cs.wisc.edu        }
1899302Snilay@cs.wisc.edu    }
1909302Snilay@cs.wisc.edu
1919302Snilay@cs.wisc.edu    return false;
1929302Snilay@cs.wisc.edu}
1939302Snilay@cs.wisc.edu
1949302Snilay@cs.wisc.eduuint32_t
1959302Snilay@cs.wisc.eduSimpleNetwork::functionalWrite(Packet *pkt)
1969302Snilay@cs.wisc.edu{
1979302Snilay@cs.wisc.edu    uint32_t num_functional_writes = 0;
1989302Snilay@cs.wisc.edu
1999858Snilay@cs.wisc.edu    for (unsigned int i = 0; i < m_switches.size(); i++) {
2009858Snilay@cs.wisc.edu        num_functional_writes += m_switches[i]->functionalWrite(pkt);
2019302Snilay@cs.wisc.edu    }
2029302Snilay@cs.wisc.edu
20311021Sjthestness@gmail.com    for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) {
20411021Sjthestness@gmail.com        num_functional_writes += m_int_link_buffers[i]->functionalWrite(pkt);
2059302Snilay@cs.wisc.edu    }
2069302Snilay@cs.wisc.edu    return num_functional_writes;
2079302Snilay@cs.wisc.edu}
208