fu_pool.cc revision 9550
12292SN/A/* 29444SAndreas.Sandberg@ARM.com * Copyright (c) 2012 ARM Limited 39444SAndreas.Sandberg@ARM.com * All rights reserved 49444SAndreas.Sandberg@ARM.com * 59444SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 69444SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 79444SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 89444SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 99444SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 109444SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 119444SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 129444SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 139444SAndreas.Sandberg@ARM.com * 142689Sktlim@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 152292SN/A * All rights reserved. 162292SN/A * 172292SN/A * Redistribution and use in source and binary forms, with or without 182292SN/A * modification, are permitted provided that the following conditions are 192292SN/A * met: redistributions of source code must retain the above copyright 202292SN/A * notice, this list of conditions and the following disclaimer; 212292SN/A * redistributions in binary form must reproduce the above copyright 222292SN/A * notice, this list of conditions and the following disclaimer in the 232292SN/A * documentation and/or other materials provided with the distribution; 242292SN/A * neither the name of the copyright holders nor the names of its 252292SN/A * contributors may be used to endorse or promote products derived from 262292SN/A * this software without specific prior written permission. 272292SN/A * 282292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392689Sktlim@umich.edu * 402689Sktlim@umich.edu * Authors: Kevin Lim 412292SN/A */ 422292SN/A 432292SN/A#include <sstream> 442292SN/A 452292SN/A#include "cpu/o3/fu_pool.hh" 462736Sktlim@umich.edu#include "cpu/func_unit.hh" 472292SN/A 482292SN/Ausing namespace std; 492292SN/A 502292SN/A//////////////////////////////////////////////////////////////////////////// 512292SN/A// 522292SN/A// A pool of function units 532292SN/A// 542292SN/A 552292SN/Ainline void 562292SN/AFUPool::FUIdxQueue::addFU(int fu_idx) 572292SN/A{ 582292SN/A funcUnitsIdx.push_back(fu_idx); 592292SN/A ++size; 602292SN/A} 612292SN/A 622292SN/Ainline int 632292SN/AFUPool::FUIdxQueue::getFU() 642292SN/A{ 652292SN/A int retval = funcUnitsIdx[idx++]; 662292SN/A 672292SN/A if (idx == size) 682292SN/A idx = 0; 692292SN/A 702292SN/A return retval; 712292SN/A} 722292SN/A 732292SN/AFUPool::~FUPool() 742292SN/A{ 752292SN/A fuListIterator i = funcUnits.begin(); 762292SN/A fuListIterator end = funcUnits.end(); 772292SN/A for (; i != end; ++i) 782292SN/A delete *i; 792292SN/A} 802292SN/A 812292SN/A 822292SN/A// Constructor 835034Smilesck@eecs.umich.eduFUPool::FUPool(const Params *p) 845034Smilesck@eecs.umich.edu : SimObject(p) 852292SN/A{ 862292SN/A numFU = 0; 872292SN/A 882292SN/A funcUnits.clear(); 892292SN/A 902292SN/A for (int i = 0; i < Num_OpClasses; ++i) { 919184Sandreas.hansson@arm.com maxOpLatencies[i] = Cycles(0); 929184Sandreas.hansson@arm.com maxIssueLatencies[i] = Cycles(0); 932292SN/A } 942292SN/A 952292SN/A // 962292SN/A // Iterate through the list of FUDescData structures 972292SN/A // 985034Smilesck@eecs.umich.edu const vector<FUDesc *> ¶mList = p->FUList; 992292SN/A for (FUDDiterator i = paramList.begin(); i != paramList.end(); ++i) { 1002292SN/A 1012292SN/A // 1022292SN/A // Don't bother with this if we're not going to create any FU's 1032292SN/A // 1042292SN/A if ((*i)->number) { 1052292SN/A // 1062292SN/A // Create the FuncUnit object from this structure 1072292SN/A // - add the capabilities listed in the FU's operation 1082292SN/A // description 1092292SN/A // 1102292SN/A // We create the first unit, then duplicate it as needed 1112292SN/A // 1122292SN/A FuncUnit *fu = new FuncUnit; 1132292SN/A 1142292SN/A OPDDiterator j = (*i)->opDescList.begin(); 1152292SN/A OPDDiterator end = (*i)->opDescList.end(); 1162292SN/A for (; j != end; ++j) { 1172292SN/A // indicate that this pool has this capability 1182292SN/A capabilityList.set((*j)->opClass); 1192292SN/A 1202292SN/A // Add each of the FU's that will have this capability to the 1212292SN/A // appropriate queue. 1222292SN/A for (int k = 0; k < (*i)->number; ++k) 1232292SN/A fuPerCapList[(*j)->opClass].addFU(numFU + k); 1242292SN/A 1252292SN/A // indicate that this FU has the capability 1262292SN/A fu->addCapability((*j)->opClass, (*j)->opLat, (*j)->issueLat); 1272292SN/A 1282292SN/A if ((*j)->opLat > maxOpLatencies[(*j)->opClass]) 1292292SN/A maxOpLatencies[(*j)->opClass] = (*j)->opLat; 1302292SN/A 1312292SN/A if ((*j)->issueLat > maxIssueLatencies[(*j)->opClass]) 1322292SN/A maxIssueLatencies[(*j)->opClass] = (*j)->issueLat; 1332292SN/A } 1342292SN/A 1352292SN/A numFU++; 1362292SN/A 1372292SN/A // Add the appropriate number of copies of this FU to the list 1389550Sandreas.hansson@arm.com fu->name = (*i)->name() + "(0)"; 1392292SN/A funcUnits.push_back(fu); 1402292SN/A 1412292SN/A for (int c = 1; c < (*i)->number; ++c) { 1422292SN/A ostringstream s; 1432292SN/A numFU++; 1442292SN/A FuncUnit *fu2 = new FuncUnit(*fu); 1452292SN/A 1462292SN/A s << (*i)->name() << "(" << c << ")"; 1472292SN/A fu2->name = s.str(); 1482292SN/A funcUnits.push_back(fu2); 1492292SN/A } 1502292SN/A } 1512292SN/A } 1522292SN/A 1532292SN/A unitBusy.resize(numFU); 1542292SN/A 1552292SN/A for (int i = 0; i < numFU; i++) { 1562292SN/A unitBusy[i] = false; 1572292SN/A } 1582292SN/A} 1592292SN/A 1602292SN/Avoid 1619184Sandreas.hansson@arm.comFUPool::annotateMemoryUnits(Cycles hit_latency) 1622292SN/A{ 1632292SN/A maxOpLatencies[MemReadOp] = hit_latency; 1642292SN/A 1652292SN/A fuListIterator i = funcUnits.begin(); 1662292SN/A fuListIterator iend = funcUnits.end(); 1672292SN/A for (; i != iend; ++i) { 1682292SN/A if ((*i)->provides(MemReadOp)) 1692292SN/A (*i)->opLatency(MemReadOp) = hit_latency; 1702292SN/A 1712292SN/A if ((*i)->provides(MemWriteOp)) 1722292SN/A (*i)->opLatency(MemWriteOp) = hit_latency; 1732292SN/A } 1742292SN/A} 1752292SN/A 1762292SN/Aint 1772292SN/AFUPool::getUnit(OpClass capability) 1782292SN/A{ 1792292SN/A // If this pool doesn't have the specified capability, 1802292SN/A // return this information to the caller 1812292SN/A if (!capabilityList[capability]) 1822292SN/A return -2; 1832292SN/A 1842292SN/A int fu_idx = fuPerCapList[capability].getFU(); 1852292SN/A int start_idx = fu_idx; 1862292SN/A 1872292SN/A // Iterate through the circular queue if needed, stopping if we've reached 1882292SN/A // the first element again. 1892292SN/A while (unitBusy[fu_idx]) { 1902292SN/A fu_idx = fuPerCapList[capability].getFU(); 1912292SN/A if (fu_idx == start_idx) { 1922292SN/A // No FU available 1932292SN/A return -1; 1942292SN/A } 1952292SN/A } 1962292SN/A 1972348SN/A assert(fu_idx < numFU); 1982348SN/A 1992292SN/A unitBusy[fu_idx] = true; 2002292SN/A 2012292SN/A return fu_idx; 2022292SN/A} 2032292SN/A 2042292SN/Avoid 2052327SN/AFUPool::freeUnitNextCycle(int fu_idx) 2062292SN/A{ 2072292SN/A assert(unitBusy[fu_idx]); 2082292SN/A unitsToBeFreed.push_back(fu_idx); 2092292SN/A} 2102292SN/A 2112292SN/Avoid 2122292SN/AFUPool::processFreeUnits() 2132292SN/A{ 2142292SN/A while (!unitsToBeFreed.empty()) { 2152292SN/A int fu_idx = unitsToBeFreed.back(); 2162292SN/A unitsToBeFreed.pop_back(); 2172292SN/A 2182292SN/A assert(unitBusy[fu_idx]); 2192292SN/A 2202292SN/A unitBusy[fu_idx] = false; 2212292SN/A } 2222292SN/A} 2232292SN/A 2242292SN/Avoid 2252292SN/AFUPool::dump() 2262292SN/A{ 2272292SN/A cout << "Function Unit Pool (" << name() << ")\n"; 2282292SN/A cout << "======================================\n"; 2292292SN/A cout << "Free List:\n"; 2302292SN/A 2312292SN/A for (int i = 0; i < numFU; ++i) { 2322292SN/A if (unitBusy[i]) { 2332292SN/A continue; 2342292SN/A } 2352292SN/A 2362292SN/A cout << " [" << i << "] : "; 2372292SN/A 2382292SN/A cout << funcUnits[i]->name << " "; 2392292SN/A 2402292SN/A cout << "\n"; 2412292SN/A } 2422292SN/A 2432292SN/A cout << "======================================\n"; 2442292SN/A cout << "Busy List:\n"; 2452292SN/A for (int i = 0; i < numFU; ++i) { 2462292SN/A if (!unitBusy[i]) { 2472292SN/A continue; 2482292SN/A } 2492292SN/A 2502292SN/A cout << " [" << i << "] : "; 2512292SN/A 2522292SN/A cout << funcUnits[i]->name << " "; 2532292SN/A 2542292SN/A cout << "\n"; 2552292SN/A } 2562292SN/A} 2572292SN/A 2582307SN/Avoid 2599444SAndreas.Sandberg@ARM.comFUPool::drainSanityCheck() const 2602307SN/A{ 2619444SAndreas.Sandberg@ARM.com assert(unitsToBeFreed.empty()); 2629444SAndreas.Sandberg@ARM.com for (int i = 0; i < numFU; i++) 2639444SAndreas.Sandberg@ARM.com assert(!unitBusy[i]); 2642307SN/A} 2652307SN/A 2662292SN/A// 2672292SN/A 2682292SN/A//////////////////////////////////////////////////////////////////////////// 2692292SN/A// 2702292SN/A// The SimObjects we use to get the FU information into the simulator 2712292SN/A// 2722292SN/A//////////////////////////////////////////////////////////////////////////// 2732292SN/A 2742292SN/A// 2752292SN/A// FUPool - Contails a list of FUDesc objects to make available 2762292SN/A// 2772292SN/A 2782292SN/A// 2792292SN/A// The FuPool object 2802292SN/A// 2814762Snate@binkert.orgFUPool * 2824762Snate@binkert.orgFUPoolParams::create() 2832292SN/A{ 2845034Smilesck@eecs.umich.edu return new FUPool(this); 2852292SN/A} 286