fu_pool.cc revision 9783
14120Sgblack@eecs.umich.edu/*
24120Sgblack@eecs.umich.edu * Copyright (c) 2012-2013 ARM Limited
34120Sgblack@eecs.umich.edu * All rights reserved
44120Sgblack@eecs.umich.edu *
54120Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
64120Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
74120Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
84120Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
94120Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
104120Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
114120Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
124120Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
134120Sgblack@eecs.umich.edu *
144120Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
154120Sgblack@eecs.umich.edu * All rights reserved.
164120Sgblack@eecs.umich.edu *
174120Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
184120Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
194120Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
204120Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
214120Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
224120Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
234120Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
244120Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
254120Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
264120Sgblack@eecs.umich.edu * this software without specific prior written permission.
274120Sgblack@eecs.umich.edu *
284120Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
294120Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
304120Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
315334Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
324120Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
334120Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
344120Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354120Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364120Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
374120Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
384120Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
394120Sgblack@eecs.umich.edu *
404120Sgblack@eecs.umich.edu * Authors: Kevin Lim
414120Sgblack@eecs.umich.edu */
424120Sgblack@eecs.umich.edu
434120Sgblack@eecs.umich.edu#include <sstream>
444120Sgblack@eecs.umich.edu
454120Sgblack@eecs.umich.edu#include "cpu/o3/fu_pool.hh"
464120Sgblack@eecs.umich.edu#include "cpu/func_unit.hh"
474120Sgblack@eecs.umich.edu
484120Sgblack@eecs.umich.eduusing namespace std;
494120Sgblack@eecs.umich.edu
504120Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////////
514120Sgblack@eecs.umich.edu//
524120Sgblack@eecs.umich.edu//  A pool of function units
534120Sgblack@eecs.umich.edu//
544120Sgblack@eecs.umich.edu
554120Sgblack@eecs.umich.eduinline void
564120Sgblack@eecs.umich.eduFUPool::FUIdxQueue::addFU(int fu_idx)
574120Sgblack@eecs.umich.edu{
584120Sgblack@eecs.umich.edu    funcUnitsIdx.push_back(fu_idx);
594120Sgblack@eecs.umich.edu    ++size;
604120Sgblack@eecs.umich.edu}
614120Sgblack@eecs.umich.edu
624120Sgblack@eecs.umich.eduinline int
634120Sgblack@eecs.umich.eduFUPool::FUIdxQueue::getFU()
644120Sgblack@eecs.umich.edu{
654120Sgblack@eecs.umich.edu    int retval = funcUnitsIdx[idx++];
664120Sgblack@eecs.umich.edu
674120Sgblack@eecs.umich.edu    if (idx == size)
684120Sgblack@eecs.umich.edu        idx = 0;
694120Sgblack@eecs.umich.edu
704120Sgblack@eecs.umich.edu    return retval;
714120Sgblack@eecs.umich.edu}
724120Sgblack@eecs.umich.edu
734120Sgblack@eecs.umich.eduFUPool::~FUPool()
744120Sgblack@eecs.umich.edu{
754120Sgblack@eecs.umich.edu    fuListIterator i = funcUnits.begin();
764120Sgblack@eecs.umich.edu    fuListIterator end = funcUnits.end();
774120Sgblack@eecs.umich.edu    for (; i != end; ++i)
784120Sgblack@eecs.umich.edu        delete *i;
794120Sgblack@eecs.umich.edu}
804120Sgblack@eecs.umich.edu
814120Sgblack@eecs.umich.edu
824120Sgblack@eecs.umich.edu// Constructor
834120Sgblack@eecs.umich.eduFUPool::FUPool(const Params *p)
844120Sgblack@eecs.umich.edu    : SimObject(p)
854120Sgblack@eecs.umich.edu{
864202Sbinkertn@umich.edu    numFU = 0;
875069Sgblack@eecs.umich.edu
884202Sbinkertn@umich.edu    funcUnits.clear();
895659Sgblack@eecs.umich.edu
904601Sgblack@eecs.umich.edu    for (int i = 0; i < Num_OpClasses; ++i) {
914202Sbinkertn@umich.edu        maxOpLatencies[i] = Cycles(0);
925124Sgblack@eecs.umich.edu        maxIssueLatencies[i] = Cycles(0);
935083Sgblack@eecs.umich.edu    }
944679Sgblack@eecs.umich.edu
955083Sgblack@eecs.umich.edu    //
964679Sgblack@eecs.umich.edu    //  Iterate through the list of FUDescData structures
974679Sgblack@eecs.umich.edu    //
984202Sbinkertn@umich.edu    const vector<FUDesc *> &paramList =  p->FUList;
994202Sbinkertn@umich.edu    for (FUDDiterator i = paramList.begin(); i != paramList.end(); ++i) {
1005124Sgblack@eecs.umich.edu
1014249Sgblack@eecs.umich.edu        //
1024240Sgblack@eecs.umich.edu        //  Don't bother with this if we're not going to create any FU's
1034202Sbinkertn@umich.edu        //
1044202Sbinkertn@umich.edu        if ((*i)->number) {
1054997Sgblack@eecs.umich.edu            //
1065135Sgblack@eecs.umich.edu            //  Create the FuncUnit object from this structure
1074997Sgblack@eecs.umich.edu            //   - add the capabilities listed in the FU's operation
1084997Sgblack@eecs.umich.edu            //     description
1095800Snate@binkert.org            //
1105800Snate@binkert.org            //  We create the first unit, then duplicate it as needed
1114120Sgblack@eecs.umich.edu            //
1124202Sbinkertn@umich.edu            FuncUnit *fu = new FuncUnit;
1135800Snate@binkert.org
1145904Sgblack@eecs.umich.edu            OPDDiterator j = (*i)->opDescList.begin();
1155904Sgblack@eecs.umich.edu            OPDDiterator end = (*i)->opDescList.end();
1165649Sgblack@eecs.umich.edu            for (; j != end; ++j) {
1175647Sgblack@eecs.umich.edu                // indicate that this pool has this capability
1185132Sgblack@eecs.umich.edu                capabilityList.set((*j)->opClass);
1195132Sgblack@eecs.umich.edu
1204202Sbinkertn@umich.edu                // Add each of the FU's that will have this capability to the
1215647Sgblack@eecs.umich.edu                // appropriate queue.
1225299Sgblack@eecs.umich.edu                for (int k = 0; k < (*i)->number; ++k)
1235245Sgblack@eecs.umich.edu                    fuPerCapList[(*j)->opClass].addFU(numFU + k);
1245132Sgblack@eecs.umich.edu
1255086Sgblack@eecs.umich.edu                // indicate that this FU has the capability
1265086Sgblack@eecs.umich.edu                fu->addCapability((*j)->opClass, (*j)->opLat, (*j)->issueLat);
1274202Sbinkertn@umich.edu
1284202Sbinkertn@umich.edu                if ((*j)->opLat > maxOpLatencies[(*j)->opClass])
1294120Sgblack@eecs.umich.edu                    maxOpLatencies[(*j)->opClass] = (*j)->opLat;
1304202Sbinkertn@umich.edu
1314202Sbinkertn@umich.edu                if ((*j)->issueLat > maxIssueLatencies[(*j)->opClass])
1324202Sbinkertn@umich.edu                    maxIssueLatencies[(*j)->opClass] = (*j)->issueLat;
1334120Sgblack@eecs.umich.edu            }
1345069Sgblack@eecs.umich.edu
1355081Sgblack@eecs.umich.edu            numFU++;
1365081Sgblack@eecs.umich.edu
1375081Sgblack@eecs.umich.edu            //  Add the appropriate number of copies of this FU to the list
1385081Sgblack@eecs.umich.edu            fu->name = (*i)->name() + "(0)";
1395081Sgblack@eecs.umich.edu            funcUnits.push_back(fu);
1405081Sgblack@eecs.umich.edu
1415081Sgblack@eecs.umich.edu            for (int c = 1; c < (*i)->number; ++c) {
1425081Sgblack@eecs.umich.edu                ostringstream s;
1435081Sgblack@eecs.umich.edu                numFU++;
1445081Sgblack@eecs.umich.edu                FuncUnit *fu2 = new FuncUnit(*fu);
1455081Sgblack@eecs.umich.edu
1465081Sgblack@eecs.umich.edu                s << (*i)->name() << "(" << c << ")";
1475081Sgblack@eecs.umich.edu                fu2->name = s.str();
1485081Sgblack@eecs.umich.edu                funcUnits.push_back(fu2);
1495081Sgblack@eecs.umich.edu            }
1505081Sgblack@eecs.umich.edu        }
1515081Sgblack@eecs.umich.edu    }
1525081Sgblack@eecs.umich.edu
1535081Sgblack@eecs.umich.edu    unitBusy.resize(numFU);
1545081Sgblack@eecs.umich.edu
1555081Sgblack@eecs.umich.edu    for (int i = 0; i < numFU; i++) {
1565081Sgblack@eecs.umich.edu        unitBusy[i] = false;
1575081Sgblack@eecs.umich.edu    }
1585081Sgblack@eecs.umich.edu}
1595081Sgblack@eecs.umich.edu
1605081Sgblack@eecs.umich.eduvoid
1615081Sgblack@eecs.umich.eduFUPool::annotateMemoryUnits(Cycles hit_latency)
1625081Sgblack@eecs.umich.edu{
1635081Sgblack@eecs.umich.edu    maxOpLatencies[MemReadOp] = hit_latency;
1645081Sgblack@eecs.umich.edu
1655081Sgblack@eecs.umich.edu    fuListIterator i = funcUnits.begin();
1665081Sgblack@eecs.umich.edu    fuListIterator iend = funcUnits.end();
1675081Sgblack@eecs.umich.edu    for (; i != iend; ++i) {
1685081Sgblack@eecs.umich.edu        if ((*i)->provides(MemReadOp))
1695081Sgblack@eecs.umich.edu            (*i)->opLatency(MemReadOp) = hit_latency;
1705081Sgblack@eecs.umich.edu
1715081Sgblack@eecs.umich.edu        if ((*i)->provides(MemWriteOp))
1725081Sgblack@eecs.umich.edu            (*i)->opLatency(MemWriteOp) = hit_latency;
1735081Sgblack@eecs.umich.edu    }
1745081Sgblack@eecs.umich.edu}
1755081Sgblack@eecs.umich.edu
1765081Sgblack@eecs.umich.eduint
1775081Sgblack@eecs.umich.eduFUPool::getUnit(OpClass capability)
1785081Sgblack@eecs.umich.edu{
1795081Sgblack@eecs.umich.edu    //  If this pool doesn't have the specified capability,
1805081Sgblack@eecs.umich.edu    //  return this information to the caller
1815081Sgblack@eecs.umich.edu    if (!capabilityList[capability])
1825081Sgblack@eecs.umich.edu        return -2;
1835081Sgblack@eecs.umich.edu
1845081Sgblack@eecs.umich.edu    int fu_idx = fuPerCapList[capability].getFU();
1855081Sgblack@eecs.umich.edu    int start_idx = fu_idx;
1865081Sgblack@eecs.umich.edu
1875081Sgblack@eecs.umich.edu    // Iterate through the circular queue if needed, stopping if we've reached
1885081Sgblack@eecs.umich.edu    // the first element again.
1895081Sgblack@eecs.umich.edu    while (unitBusy[fu_idx]) {
1905680Sgblack@eecs.umich.edu        fu_idx = fuPerCapList[capability].getFU();
1915081Sgblack@eecs.umich.edu        if (fu_idx == start_idx) {
1925173Sgblack@eecs.umich.edu            // No FU available
1935359Sgblack@eecs.umich.edu            return -1;
1945081Sgblack@eecs.umich.edu        }
1955149Sgblack@eecs.umich.edu    }
1965298Sgblack@eecs.umich.edu
1975081Sgblack@eecs.umich.edu    assert(fu_idx < numFU);
1985081Sgblack@eecs.umich.edu
1995081Sgblack@eecs.umich.edu    unitBusy[fu_idx] = true;
2005081Sgblack@eecs.umich.edu
2015081Sgblack@eecs.umich.edu    return fu_idx;
2025081Sgblack@eecs.umich.edu}
2035081Sgblack@eecs.umich.edu
2045081Sgblack@eecs.umich.eduvoid
2055081Sgblack@eecs.umich.eduFUPool::freeUnitNextCycle(int fu_idx)
2065081Sgblack@eecs.umich.edu{
2075081Sgblack@eecs.umich.edu    assert(unitBusy[fu_idx]);
2085081Sgblack@eecs.umich.edu    unitsToBeFreed.push_back(fu_idx);
2095081Sgblack@eecs.umich.edu}
2105081Sgblack@eecs.umich.edu
2115081Sgblack@eecs.umich.eduvoid
2125081Sgblack@eecs.umich.eduFUPool::processFreeUnits()
2135081Sgblack@eecs.umich.edu{
2145081Sgblack@eecs.umich.edu    while (!unitsToBeFreed.empty()) {
2155081Sgblack@eecs.umich.edu        int fu_idx = unitsToBeFreed.back();
2165081Sgblack@eecs.umich.edu        unitsToBeFreed.pop_back();
2175081Sgblack@eecs.umich.edu
2185081Sgblack@eecs.umich.edu        assert(unitBusy[fu_idx]);
2195081Sgblack@eecs.umich.edu
2205081Sgblack@eecs.umich.edu        unitBusy[fu_idx] = false;
2215081Sgblack@eecs.umich.edu    }
2225081Sgblack@eecs.umich.edu}
2235081Sgblack@eecs.umich.edu
2245081Sgblack@eecs.umich.eduvoid
2255081Sgblack@eecs.umich.eduFUPool::dump()
2265081Sgblack@eecs.umich.edu{
2275081Sgblack@eecs.umich.edu    cout << "Function Unit Pool (" << name() << ")\n";
2285081Sgblack@eecs.umich.edu    cout << "======================================\n";
2295081Sgblack@eecs.umich.edu    cout << "Free List:\n";
2305081Sgblack@eecs.umich.edu
2315081Sgblack@eecs.umich.edu    for (int i = 0; i < numFU; ++i) {
2325081Sgblack@eecs.umich.edu        if (unitBusy[i]) {
2335081Sgblack@eecs.umich.edu            continue;
2345081Sgblack@eecs.umich.edu        }
2355081Sgblack@eecs.umich.edu
2365081Sgblack@eecs.umich.edu        cout << "  [" << i << "] : ";
2375081Sgblack@eecs.umich.edu
2385081Sgblack@eecs.umich.edu        cout << funcUnits[i]->name << " ";
2395081Sgblack@eecs.umich.edu
2405081Sgblack@eecs.umich.edu        cout << "\n";
2415081Sgblack@eecs.umich.edu    }
2425081Sgblack@eecs.umich.edu
2435081Sgblack@eecs.umich.edu    cout << "======================================\n";
2445081Sgblack@eecs.umich.edu    cout << "Busy List:\n";
2455081Sgblack@eecs.umich.edu    for (int i = 0; i < numFU; ++i) {
2465081Sgblack@eecs.umich.edu        if (!unitBusy[i]) {
2475081Sgblack@eecs.umich.edu            continue;
2485081Sgblack@eecs.umich.edu        }
2495081Sgblack@eecs.umich.edu
2505081Sgblack@eecs.umich.edu        cout << "  [" << i << "] : ";
2515081Sgblack@eecs.umich.edu
2525081Sgblack@eecs.umich.edu        cout << funcUnits[i]->name << " ";
2535081Sgblack@eecs.umich.edu
2545081Sgblack@eecs.umich.edu        cout << "\n";
2555081Sgblack@eecs.umich.edu    }
2565081Sgblack@eecs.umich.edu}
2575081Sgblack@eecs.umich.edu
2585081Sgblack@eecs.umich.edubool
2595081Sgblack@eecs.umich.eduFUPool::isDrained() const
2605081Sgblack@eecs.umich.edu{
2615081Sgblack@eecs.umich.edu    bool is_drained = true;
2625081Sgblack@eecs.umich.edu    for (int i = 0; i < numFU; i++)
2635081Sgblack@eecs.umich.edu        is_drained = is_drained && !unitBusy[i];
2645081Sgblack@eecs.umich.edu
2655081Sgblack@eecs.umich.edu    return is_drained;
2665081Sgblack@eecs.umich.edu}
2675081Sgblack@eecs.umich.edu
2685081Sgblack@eecs.umich.edu//
2695081Sgblack@eecs.umich.edu
2705081Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////////
2715081Sgblack@eecs.umich.edu//
2725081Sgblack@eecs.umich.edu//  The SimObjects we use to get the FU information into the simulator
2735081Sgblack@eecs.umich.edu//
2745081Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////////
2755081Sgblack@eecs.umich.edu
2765081Sgblack@eecs.umich.edu//
2775081Sgblack@eecs.umich.edu//    FUPool - Contails a list of FUDesc objects to make available
2785081Sgblack@eecs.umich.edu//
2795081Sgblack@eecs.umich.edu
2805081Sgblack@eecs.umich.edu//
2815081Sgblack@eecs.umich.edu//  The FuPool object
2825081Sgblack@eecs.umich.edu//
2835081Sgblack@eecs.umich.eduFUPool *
2845081Sgblack@eecs.umich.eduFUPoolParams::create()
2855081Sgblack@eecs.umich.edu{
2865081Sgblack@eecs.umich.edu    return new FUPool(this);
2875081Sgblack@eecs.umich.edu}
2885081Sgblack@eecs.umich.edu