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
2911793Sbrandon.potter@amd.com#include "mem/ruby/common/NetDest.hh"
3011793Sbrandon.potter@amd.com
318946Sandreas.hansson@arm.com#include <algorithm>
328946Sandreas.hansson@arm.com
336145Snate@binkert.orgNetDest::NetDest()
346145Snate@binkert.org{
357454Snate@binkert.org  resize();
366145Snate@binkert.org}
376145Snate@binkert.org
387039Snate@binkert.orgvoid
397039Snate@binkert.orgNetDest::add(MachineID newElement)
406145Snate@binkert.org{
419138Spowerjg@cs.wisc.edu    assert(bitIndex(newElement.num) < m_bits[vecIndex(newElement)].getSize());
427039Snate@binkert.org    m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
436145Snate@binkert.org}
446145Snate@binkert.org
457039Snate@binkert.orgvoid
467039Snate@binkert.orgNetDest::addNetDest(const NetDest& netDest)
476145Snate@binkert.org{
487039Snate@binkert.org    assert(m_bits.size() == netDest.getSize());
497039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
507039Snate@binkert.org        m_bits[i].addSet(netDest.m_bits[i]);
517039Snate@binkert.org    }
526145Snate@binkert.org}
536145Snate@binkert.org
547039Snate@binkert.orgvoid
557039Snate@binkert.orgNetDest::setNetDest(MachineType machine, const Set& set)
566145Snate@binkert.org{
577039Snate@binkert.org    // assure that there is only one set of destinations for this machine
587039Snate@binkert.org    assert(MachineType_base_level((MachineType)(machine + 1)) -
597039Snate@binkert.org           MachineType_base_level(machine) == 1);
607039Snate@binkert.org    m_bits[MachineType_base_level(machine)] = set;
616145Snate@binkert.org}
626145Snate@binkert.org
637039Snate@binkert.orgvoid
647039Snate@binkert.orgNetDest::remove(MachineID oldElement)
656145Snate@binkert.org{
667039Snate@binkert.org    m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
676145Snate@binkert.org}
686145Snate@binkert.org
697039Snate@binkert.orgvoid
707039Snate@binkert.orgNetDest::removeNetDest(const NetDest& netDest)
716145Snate@binkert.org{
727039Snate@binkert.org    assert(m_bits.size() == netDest.getSize());
737039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
747039Snate@binkert.org        m_bits[i].removeSet(netDest.m_bits[i]);
757039Snate@binkert.org    }
766145Snate@binkert.org}
776145Snate@binkert.org
787039Snate@binkert.orgvoid
797039Snate@binkert.orgNetDest::clear()
806145Snate@binkert.org{
817039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
827039Snate@binkert.org        m_bits[i].clear();
837039Snate@binkert.org    }
846145Snate@binkert.org}
856145Snate@binkert.org
867039Snate@binkert.orgvoid
877039Snate@binkert.orgNetDest::broadcast()
886145Snate@binkert.org{
897039Snate@binkert.org    for (MachineType machine = MachineType_FIRST;
907039Snate@binkert.org         machine < MachineType_NUM; ++machine) {
917039Snate@binkert.org        broadcast(machine);
927039Snate@binkert.org    }
936145Snate@binkert.org}
946145Snate@binkert.org
957039Snate@binkert.orgvoid
967039Snate@binkert.orgNetDest::broadcast(MachineType machineType)
977039Snate@binkert.org{
9810005Snilay@cs.wisc.edu    for (NodeID i = 0; i < MachineType_base_count(machineType); i++) {
997039Snate@binkert.org        MachineID mach = {machineType, i};
1007039Snate@binkert.org        add(mach);
1017039Snate@binkert.org    }
1026145Snate@binkert.org}
1036145Snate@binkert.org
1046145Snate@binkert.org//For Princeton Network
1057454Snate@binkert.orgstd::vector<NodeID>
1067039Snate@binkert.orgNetDest::getAllDest()
1077039Snate@binkert.org{
1087454Snate@binkert.org    std::vector<NodeID> dest;
1097039Snate@binkert.org    dest.clear();
1107039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
1117039Snate@binkert.org        for (int j = 0; j < m_bits[i].getSize(); j++) {
1127039Snate@binkert.org            if (m_bits[i].isElement(j)) {
1137039Snate@binkert.org                int id = MachineType_base_number((MachineType)i) + j;
1147454Snate@binkert.org                dest.push_back((NodeID)id);
1157039Snate@binkert.org            }
1166145Snate@binkert.org        }
1177039Snate@binkert.org    }
1187039Snate@binkert.org    return dest;
1196145Snate@binkert.org}
1206145Snate@binkert.org
1217039Snate@binkert.orgint
1227039Snate@binkert.orgNetDest::count() const
1236145Snate@binkert.org{
1247039Snate@binkert.org    int counter = 0;
1257039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
1267039Snate@binkert.org        counter += m_bits[i].count();
1277039Snate@binkert.org    }
1287039Snate@binkert.org    return counter;
1296145Snate@binkert.org}
1306145Snate@binkert.org
1317039Snate@binkert.orgNodeID
1327039Snate@binkert.orgNetDest::elementAt(MachineID index)
1337039Snate@binkert.org{
1347039Snate@binkert.org    return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
1356145Snate@binkert.org}
1366145Snate@binkert.org
1377039Snate@binkert.orgMachineID
1387039Snate@binkert.orgNetDest::smallestElement() const
1396145Snate@binkert.org{
1407039Snate@binkert.org    assert(count() > 0);
1417039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
14210005Snilay@cs.wisc.edu        for (NodeID j = 0; j < m_bits[i].getSize(); j++) {
1437039Snate@binkert.org            if (m_bits[i].isElement(j)) {
1447039Snate@binkert.org                MachineID mach = {MachineType_from_base_level(i), j};
1457039Snate@binkert.org                return mach;
1467039Snate@binkert.org            }
1477039Snate@binkert.org        }
1486145Snate@binkert.org    }
1497805Snilay@cs.wisc.edu    panic("No smallest element of an empty set.");
1506145Snate@binkert.org}
1516145Snate@binkert.org
1527039Snate@binkert.orgMachineID
1537039Snate@binkert.orgNetDest::smallestElement(MachineType machine) const
1546145Snate@binkert.org{
1557039Snate@binkert.org    int size = m_bits[MachineType_base_level(machine)].getSize();
15610005Snilay@cs.wisc.edu    for (NodeID j = 0; j < size; j++) {
1577039Snate@binkert.org        if (m_bits[MachineType_base_level(machine)].isElement(j)) {
1587039Snate@binkert.org            MachineID mach = {machine, j};
1597039Snate@binkert.org            return mach;
1607039Snate@binkert.org        }
1616145Snate@binkert.org    }
1626145Snate@binkert.org
1637805Snilay@cs.wisc.edu    panic("No smallest element of given MachineType.");
1646145Snate@binkert.org}
1656145Snate@binkert.org
1666145Snate@binkert.org// Returns true iff all bits are set
1677039Snate@binkert.orgbool
1687039Snate@binkert.orgNetDest::isBroadcast() const
1696145Snate@binkert.org{
1707039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
1717039Snate@binkert.org        if (!m_bits[i].isBroadcast()) {
1727039Snate@binkert.org            return false;
1737039Snate@binkert.org        }
1746145Snate@binkert.org    }
1757039Snate@binkert.org    return true;
1766145Snate@binkert.org}
1776145Snate@binkert.org
1786145Snate@binkert.org// Returns true iff no bits are set
1797039Snate@binkert.orgbool
1807039Snate@binkert.orgNetDest::isEmpty() const
1816145Snate@binkert.org{
1827039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
1837039Snate@binkert.org        if (!m_bits[i].isEmpty()) {
1847039Snate@binkert.org            return false;
1857039Snate@binkert.org        }
1866145Snate@binkert.org    }
1877039Snate@binkert.org    return true;
1886145Snate@binkert.org}
1896145Snate@binkert.org
1906145Snate@binkert.org// returns the logical OR of "this" set and orNetDest
1917039Snate@binkert.orgNetDest
1927039Snate@binkert.orgNetDest::OR(const NetDest& orNetDest) const
1936145Snate@binkert.org{
1947039Snate@binkert.org    assert(m_bits.size() == orNetDest.getSize());
1957039Snate@binkert.org    NetDest result;
1967039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
1977039Snate@binkert.org        result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
1987039Snate@binkert.org    }
1997039Snate@binkert.org    return result;
2006145Snate@binkert.org}
2016145Snate@binkert.org
2026145Snate@binkert.org// returns the logical AND of "this" set and andNetDest
2037039Snate@binkert.orgNetDest
2047039Snate@binkert.orgNetDest::AND(const NetDest& andNetDest) const
2056145Snate@binkert.org{
2067039Snate@binkert.org    assert(m_bits.size() == andNetDest.getSize());
2077039Snate@binkert.org    NetDest result;
2087039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
2097039Snate@binkert.org        result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
2107039Snate@binkert.org    }
2117039Snate@binkert.org    return result;
2126145Snate@binkert.org}
2136145Snate@binkert.org
2146145Snate@binkert.org// Returns true if the intersection of the two sets is non-empty
2157039Snate@binkert.orgbool
2167039Snate@binkert.orgNetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
2176145Snate@binkert.org{
2187039Snate@binkert.org    assert(m_bits.size() == other_netDest.getSize());
2197039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
2207089Snate@binkert.org        if (!m_bits[i].intersectionIsEmpty(other_netDest.m_bits[i])) {
2217039Snate@binkert.org            return true;
2227039Snate@binkert.org        }
2236145Snate@binkert.org    }
2247039Snate@binkert.org    return false;
2256145Snate@binkert.org}
2266145Snate@binkert.org
2277039Snate@binkert.orgbool
2287039Snate@binkert.orgNetDest::isSuperset(const NetDest& test) const
2296145Snate@binkert.org{
2307039Snate@binkert.org    assert(m_bits.size() == test.getSize());
2316145Snate@binkert.org
2327039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
2337039Snate@binkert.org        if (!m_bits[i].isSuperset(test.m_bits[i])) {
2347039Snate@binkert.org            return false;
2357039Snate@binkert.org        }
2366145Snate@binkert.org    }
2377039Snate@binkert.org    return true;
2386145Snate@binkert.org}
2396145Snate@binkert.org
2407039Snate@binkert.orgbool
2417039Snate@binkert.orgNetDest::isElement(MachineID element) const
2426145Snate@binkert.org{
2437039Snate@binkert.org    return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
2446145Snate@binkert.org}
2456145Snate@binkert.org
2467039Snate@binkert.orgvoid
2477454Snate@binkert.orgNetDest::resize()
2486145Snate@binkert.org{
2497454Snate@binkert.org    m_bits.resize(MachineType_base_level(MachineType_NUM));
2507039Snate@binkert.org    assert(m_bits.size() == MachineType_NUM);
2516145Snate@binkert.org
2527039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
2537039Snate@binkert.org        m_bits[i].setSize(MachineType_base_count((MachineType)i));
2547039Snate@binkert.org    }
2556145Snate@binkert.org}
2566145Snate@binkert.org
2577039Snate@binkert.orgvoid
2587055Snate@binkert.orgNetDest::print(std::ostream& out) const
2596145Snate@binkert.org{
2607039Snate@binkert.org    out << "[NetDest (" << m_bits.size() << ") ";
2616145Snate@binkert.org
2627039Snate@binkert.org    for (int i = 0; i < m_bits.size(); i++) {
2637039Snate@binkert.org        for (int j = 0; j < m_bits[i].getSize(); j++) {
2647039Snate@binkert.org            out << (bool) m_bits[i].isElement(j) << " ";
2657039Snate@binkert.org        }
2667039Snate@binkert.org        out << " - ";
2676145Snate@binkert.org    }
2687039Snate@binkert.org    out << "]";
2696145Snate@binkert.org}
2706145Snate@binkert.org
27110004Snilay@cs.wisc.edubool
27210004Snilay@cs.wisc.eduNetDest::isEqual(const NetDest& n) const
27310004Snilay@cs.wisc.edu{
27410004Snilay@cs.wisc.edu    assert(m_bits.size() == n.m_bits.size());
27510004Snilay@cs.wisc.edu    for (unsigned int i = 0; i < m_bits.size(); ++i) {
27610004Snilay@cs.wisc.edu        if (!m_bits[i].isEqual(n.m_bits[i]))
27710004Snilay@cs.wisc.edu            return false;
27810004Snilay@cs.wisc.edu    }
27910004Snilay@cs.wisc.edu    return true;
28010004Snilay@cs.wisc.edu}
281