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 *> ¶mList = 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