fu_pool.cc revision 9783
15359Sgblack@eecs.umich.edu/* 25359Sgblack@eecs.umich.edu * Copyright (c) 2012-2013 ARM Limited 35359Sgblack@eecs.umich.edu * All rights reserved 45359Sgblack@eecs.umich.edu * 55359Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 65359Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 75359Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 85359Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 95359Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 105359Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 115359Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 125359Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 135359Sgblack@eecs.umich.edu * 145359Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 155359Sgblack@eecs.umich.edu * All rights reserved. 165359Sgblack@eecs.umich.edu * 175359Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 185359Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 195359Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 205359Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 215359Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 225359Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 235359Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 245359Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 255359Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 265359Sgblack@eecs.umich.edu * this software without specific prior written permission. 275359Sgblack@eecs.umich.edu * 285359Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 295359Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 304730Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 314730Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 324730Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 334730Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 344730Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 354730Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 364730Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 374730Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 384730Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 394730Sgblack@eecs.umich.edu * 404730Sgblack@eecs.umich.edu * Authors: Kevin Lim 414730Sgblack@eecs.umich.edu */ 424730Sgblack@eecs.umich.edu 434730Sgblack@eecs.umich.edu#include <sstream> 444730Sgblack@eecs.umich.edu 454730Sgblack@eecs.umich.edu#include "cpu/o3/fu_pool.hh" 464730Sgblack@eecs.umich.edu#include "cpu/func_unit.hh" 474730Sgblack@eecs.umich.edu 484730Sgblack@eecs.umich.eduusing namespace std; 494730Sgblack@eecs.umich.edu 504730Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////////////// 514730Sgblack@eecs.umich.edu// 524730Sgblack@eecs.umich.edu// A pool of function units 534730Sgblack@eecs.umich.edu// 544730Sgblack@eecs.umich.edu 554730Sgblack@eecs.umich.eduinline void 564730Sgblack@eecs.umich.eduFUPool::FUIdxQueue::addFU(int fu_idx) 574730Sgblack@eecs.umich.edu{ 584730Sgblack@eecs.umich.edu funcUnitsIdx.push_back(fu_idx); 594730Sgblack@eecs.umich.edu ++size; 604730Sgblack@eecs.umich.edu} 614730Sgblack@eecs.umich.edu 624730Sgblack@eecs.umich.eduinline int 634730Sgblack@eecs.umich.eduFUPool::FUIdxQueue::getFU() 644730Sgblack@eecs.umich.edu{ 654730Sgblack@eecs.umich.edu int retval = funcUnitsIdx[idx++]; 664730Sgblack@eecs.umich.edu 674730Sgblack@eecs.umich.edu if (idx == size) 684730Sgblack@eecs.umich.edu idx = 0; 694730Sgblack@eecs.umich.edu 704730Sgblack@eecs.umich.edu return retval; 714730Sgblack@eecs.umich.edu} 724730Sgblack@eecs.umich.edu 734730Sgblack@eecs.umich.eduFUPool::~FUPool() 744730Sgblack@eecs.umich.edu{ 754730Sgblack@eecs.umich.edu fuListIterator i = funcUnits.begin(); 764730Sgblack@eecs.umich.edu fuListIterator end = funcUnits.end(); 774730Sgblack@eecs.umich.edu for (; i != end; ++i) 784730Sgblack@eecs.umich.edu delete *i; 794730Sgblack@eecs.umich.edu} 804730Sgblack@eecs.umich.edu 814730Sgblack@eecs.umich.edu 824730Sgblack@eecs.umich.edu// Constructor 834730Sgblack@eecs.umich.eduFUPool::FUPool(const Params *p) 845173Sgblack@eecs.umich.edu : SimObject(p) 855359Sgblack@eecs.umich.edu{ 865173Sgblack@eecs.umich.edu numFU = 0; 875291Sgblack@eecs.umich.edu 885291Sgblack@eecs.umich.edu funcUnits.clear(); 894730Sgblack@eecs.umich.edu 904730Sgblack@eecs.umich.edu for (int i = 0; i < Num_OpClasses; ++i) { 914730Sgblack@eecs.umich.edu maxOpLatencies[i] = Cycles(0); 924730Sgblack@eecs.umich.edu maxIssueLatencies[i] = Cycles(0); 934730Sgblack@eecs.umich.edu } 944730Sgblack@eecs.umich.edu 95 // 96 // Iterate through the list of FUDescData structures 97 // 98 const vector<FUDesc *> ¶mList = p->FUList; 99 for (FUDDiterator i = paramList.begin(); i != paramList.end(); ++i) { 100 101 // 102 // Don't bother with this if we're not going to create any FU's 103 // 104 if ((*i)->number) { 105 // 106 // Create the FuncUnit object from this structure 107 // - add the capabilities listed in the FU's operation 108 // description 109 // 110 // We create the first unit, then duplicate it as needed 111 // 112 FuncUnit *fu = new FuncUnit; 113 114 OPDDiterator j = (*i)->opDescList.begin(); 115 OPDDiterator end = (*i)->opDescList.end(); 116 for (; j != end; ++j) { 117 // indicate that this pool has this capability 118 capabilityList.set((*j)->opClass); 119 120 // Add each of the FU's that will have this capability to the 121 // appropriate queue. 122 for (int k = 0; k < (*i)->number; ++k) 123 fuPerCapList[(*j)->opClass].addFU(numFU + k); 124 125 // indicate that this FU has the capability 126 fu->addCapability((*j)->opClass, (*j)->opLat, (*j)->issueLat); 127 128 if ((*j)->opLat > maxOpLatencies[(*j)->opClass]) 129 maxOpLatencies[(*j)->opClass] = (*j)->opLat; 130 131 if ((*j)->issueLat > maxIssueLatencies[(*j)->opClass]) 132 maxIssueLatencies[(*j)->opClass] = (*j)->issueLat; 133 } 134 135 numFU++; 136 137 // Add the appropriate number of copies of this FU to the list 138 fu->name = (*i)->name() + "(0)"; 139 funcUnits.push_back(fu); 140 141 for (int c = 1; c < (*i)->number; ++c) { 142 ostringstream s; 143 numFU++; 144 FuncUnit *fu2 = new FuncUnit(*fu); 145 146 s << (*i)->name() << "(" << c << ")"; 147 fu2->name = s.str(); 148 funcUnits.push_back(fu2); 149 } 150 } 151 } 152 153 unitBusy.resize(numFU); 154 155 for (int i = 0; i < numFU; i++) { 156 unitBusy[i] = false; 157 } 158} 159 160void 161FUPool::annotateMemoryUnits(Cycles hit_latency) 162{ 163 maxOpLatencies[MemReadOp] = hit_latency; 164 165 fuListIterator i = funcUnits.begin(); 166 fuListIterator iend = funcUnits.end(); 167 for (; i != iend; ++i) { 168 if ((*i)->provides(MemReadOp)) 169 (*i)->opLatency(MemReadOp) = hit_latency; 170 171 if ((*i)->provides(MemWriteOp)) 172 (*i)->opLatency(MemWriteOp) = hit_latency; 173 } 174} 175 176int 177FUPool::getUnit(OpClass capability) 178{ 179 // If this pool doesn't have the specified capability, 180 // return this information to the caller 181 if (!capabilityList[capability]) 182 return -2; 183 184 int fu_idx = fuPerCapList[capability].getFU(); 185 int start_idx = fu_idx; 186 187 // Iterate through the circular queue if needed, stopping if we've reached 188 // the first element again. 189 while (unitBusy[fu_idx]) { 190 fu_idx = fuPerCapList[capability].getFU(); 191 if (fu_idx == start_idx) { 192 // No FU available 193 return -1; 194 } 195 } 196 197 assert(fu_idx < numFU); 198 199 unitBusy[fu_idx] = true; 200 201 return fu_idx; 202} 203 204void 205FUPool::freeUnitNextCycle(int fu_idx) 206{ 207 assert(unitBusy[fu_idx]); 208 unitsToBeFreed.push_back(fu_idx); 209} 210 211void 212FUPool::processFreeUnits() 213{ 214 while (!unitsToBeFreed.empty()) { 215 int fu_idx = unitsToBeFreed.back(); 216 unitsToBeFreed.pop_back(); 217 218 assert(unitBusy[fu_idx]); 219 220 unitBusy[fu_idx] = false; 221 } 222} 223 224void 225FUPool::dump() 226{ 227 cout << "Function Unit Pool (" << name() << ")\n"; 228 cout << "======================================\n"; 229 cout << "Free List:\n"; 230 231 for (int i = 0; i < numFU; ++i) { 232 if (unitBusy[i]) { 233 continue; 234 } 235 236 cout << " [" << i << "] : "; 237 238 cout << funcUnits[i]->name << " "; 239 240 cout << "\n"; 241 } 242 243 cout << "======================================\n"; 244 cout << "Busy List:\n"; 245 for (int i = 0; i < numFU; ++i) { 246 if (!unitBusy[i]) { 247 continue; 248 } 249 250 cout << " [" << i << "] : "; 251 252 cout << funcUnits[i]->name << " "; 253 254 cout << "\n"; 255 } 256} 257 258bool 259FUPool::isDrained() const 260{ 261 bool is_drained = true; 262 for (int i = 0; i < numFU; i++) 263 is_drained = is_drained && !unitBusy[i]; 264 265 return is_drained; 266} 267 268// 269 270//////////////////////////////////////////////////////////////////////////// 271// 272// The SimObjects we use to get the FU information into the simulator 273// 274//////////////////////////////////////////////////////////////////////////// 275 276// 277// FUPool - Contails a list of FUDesc objects to make available 278// 279 280// 281// The FuPool object 282// 283FUPool * 284FUPoolParams::create() 285{ 286 return new FUPool(this); 287} 288