fu_pool.cc revision 2292
113372Sgabeblack@google.com/* 213372Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 313372Sgabeblack@google.com * All rights reserved. 413372Sgabeblack@google.com * 513372Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 613372Sgabeblack@google.com * modification, are permitted provided that the following conditions are 713372Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 813372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 913372Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1013372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1113372Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1213372Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1313372Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1413372Sgabeblack@google.com * this software without specific prior written permission. 1513372Sgabeblack@google.com * 1613372Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713372Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813372Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913372Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013372Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113372Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213372Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313372Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413372Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513372Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613372Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713372Sgabeblack@google.com */ 2813372Sgabeblack@google.com 2913463Sgabeblack@google.com#include <sstream> 3013463Sgabeblack@google.com 3113463Sgabeblack@google.com#include "cpu/o3/fu_pool.hh" 3213372Sgabeblack@google.com#include "encumbered/cpu/full/fu_pool.hh" 3313372Sgabeblack@google.com#include "sim/builder.hh" 3413372Sgabeblack@google.com 3513463Sgabeblack@google.comusing namespace std; 3613463Sgabeblack@google.com 3713372Sgabeblack@google.com//////////////////////////////////////////////////////////////////////////// 3813372Sgabeblack@google.com// 3913372Sgabeblack@google.com// A pool of function units 4013463Sgabeblack@google.com// 4113463Sgabeblack@google.com 4213372Sgabeblack@google.cominline void 4313372Sgabeblack@google.comFUPool::FUIdxQueue::addFU(int fu_idx) 4413372Sgabeblack@google.com{ 4513372Sgabeblack@google.com funcUnitsIdx.push_back(fu_idx); 4613372Sgabeblack@google.com ++size; 4713372Sgabeblack@google.com} 4813372Sgabeblack@google.com 4913372Sgabeblack@google.cominline int 5013372Sgabeblack@google.comFUPool::FUIdxQueue::getFU() 5113372Sgabeblack@google.com{ 5213372Sgabeblack@google.com int retval = funcUnitsIdx[idx++]; 5313372Sgabeblack@google.com 5413372Sgabeblack@google.com if (idx == size) 5513372Sgabeblack@google.com idx = 0; 5613372Sgabeblack@google.com 5713372Sgabeblack@google.com return retval; 5813372Sgabeblack@google.com} 5913372Sgabeblack@google.com 6013372Sgabeblack@google.comFUPool::~FUPool() 6113372Sgabeblack@google.com{ 6213372Sgabeblack@google.com fuListIterator i = funcUnits.begin(); 6313372Sgabeblack@google.com fuListIterator end = funcUnits.end(); 6413372Sgabeblack@google.com for (; i != end; ++i) 6513372Sgabeblack@google.com delete *i; 6613372Sgabeblack@google.com} 6713372Sgabeblack@google.com 6813372Sgabeblack@google.com 6913372Sgabeblack@google.com// Constructor 7013372Sgabeblack@google.comFUPool::FUPool(string name, vector<FUDesc *> paramList) 7113372Sgabeblack@google.com : SimObject(name) 7213372Sgabeblack@google.com{ 7313372Sgabeblack@google.com numFU = 0; 7413372Sgabeblack@google.com 7513372Sgabeblack@google.com funcUnits.clear(); 7613372Sgabeblack@google.com 7713372Sgabeblack@google.com for (int i = 0; i < Num_OpClasses; ++i) { 7813372Sgabeblack@google.com maxOpLatencies[i] = 0; 7913372Sgabeblack@google.com maxIssueLatencies[i] = 0; 8013372Sgabeblack@google.com } 8113372Sgabeblack@google.com 8213372Sgabeblack@google.com // 8313372Sgabeblack@google.com // Iterate through the list of FUDescData structures 8413372Sgabeblack@google.com // 8513372Sgabeblack@google.com for (FUDDiterator i = paramList.begin(); i != paramList.end(); ++i) { 8613372Sgabeblack@google.com 87 // 88 // Don't bother with this if we're not going to create any FU's 89 // 90 if ((*i)->number) { 91 // 92 // Create the FuncUnit object from this structure 93 // - add the capabilities listed in the FU's operation 94 // description 95 // 96 // We create the first unit, then duplicate it as needed 97 // 98 FuncUnit *fu = new FuncUnit; 99 100 OPDDiterator j = (*i)->opDescList.begin(); 101 OPDDiterator end = (*i)->opDescList.end(); 102 for (; j != end; ++j) { 103 // indicate that this pool has this capability 104 capabilityList.set((*j)->opClass); 105 106 // Add each of the FU's that will have this capability to the 107 // appropriate queue. 108 for (int k = 0; k < (*i)->number; ++k) 109 fuPerCapList[(*j)->opClass].addFU(numFU + k); 110 111 // indicate that this FU has the capability 112 fu->addCapability((*j)->opClass, (*j)->opLat, (*j)->issueLat); 113 114 if ((*j)->opLat > maxOpLatencies[(*j)->opClass]) 115 maxOpLatencies[(*j)->opClass] = (*j)->opLat; 116 117 if ((*j)->issueLat > maxIssueLatencies[(*j)->opClass]) 118 maxIssueLatencies[(*j)->opClass] = (*j)->issueLat; 119 } 120 121 numFU++; 122 123 // Add the appropriate number of copies of this FU to the list 124 ostringstream s; 125 126 s << (*i)->name() << "(0)"; 127 fu->name = s.str(); 128 funcUnits.push_back(fu); 129 130 for (int c = 1; c < (*i)->number; ++c) { 131 ostringstream s; 132 numFU++; 133 FuncUnit *fu2 = new FuncUnit(*fu); 134 135 s << (*i)->name() << "(" << c << ")"; 136 fu2->name = s.str(); 137 funcUnits.push_back(fu2); 138 } 139 } 140 } 141 142 unitBusy.resize(numFU); 143 144 for (int i = 0; i < numFU; i++) { 145 unitBusy[i] = false; 146 } 147} 148 149void 150FUPool::annotateMemoryUnits(unsigned hit_latency) 151{ 152 maxOpLatencies[MemReadOp] = hit_latency; 153 154 fuListIterator i = funcUnits.begin(); 155 fuListIterator iend = funcUnits.end(); 156 for (; i != iend; ++i) { 157 if ((*i)->provides(MemReadOp)) 158 (*i)->opLatency(MemReadOp) = hit_latency; 159 160 if ((*i)->provides(MemWriteOp)) 161 (*i)->opLatency(MemWriteOp) = hit_latency; 162 } 163} 164 165int 166FUPool::getUnit(OpClass capability) 167{ 168 // If this pool doesn't have the specified capability, 169 // return this information to the caller 170 if (!capabilityList[capability]) 171 return -2; 172 173 int fu_idx = fuPerCapList[capability].getFU(); 174 int start_idx = fu_idx; 175 176 // Iterate through the circular queue if needed, stopping if we've reached 177 // the first element again. 178 while (unitBusy[fu_idx]) { 179 fu_idx = fuPerCapList[capability].getFU(); 180 if (fu_idx == start_idx) { 181 // No FU available 182 return -1; 183 } 184 } 185 186 unitBusy[fu_idx] = true; 187 188 return fu_idx; 189} 190 191void 192FUPool::freeUnit(int fu_idx) 193{ 194 assert(unitBusy[fu_idx]); 195 unitsToBeFreed.push_back(fu_idx); 196} 197 198void 199FUPool::processFreeUnits() 200{ 201 while (!unitsToBeFreed.empty()) { 202 int fu_idx = unitsToBeFreed.back(); 203 unitsToBeFreed.pop_back(); 204 205 assert(unitBusy[fu_idx]); 206 207 unitBusy[fu_idx] = false; 208 } 209} 210 211void 212FUPool::dump() 213{ 214 cout << "Function Unit Pool (" << name() << ")\n"; 215 cout << "======================================\n"; 216 cout << "Free List:\n"; 217 218 for (int i = 0; i < numFU; ++i) { 219 if (unitBusy[i]) { 220 continue; 221 } 222 223 cout << " [" << i << "] : "; 224 225 cout << funcUnits[i]->name << " "; 226 227 cout << "\n"; 228 } 229 230 cout << "======================================\n"; 231 cout << "Busy List:\n"; 232 for (int i = 0; i < numFU; ++i) { 233 if (!unitBusy[i]) { 234 continue; 235 } 236 237 cout << " [" << i << "] : "; 238 239 cout << funcUnits[i]->name << " "; 240 241 cout << "\n"; 242 } 243} 244 245// 246 247//////////////////////////////////////////////////////////////////////////// 248// 249// The SimObjects we use to get the FU information into the simulator 250// 251//////////////////////////////////////////////////////////////////////////// 252 253// 254// FUPool - Contails a list of FUDesc objects to make available 255// 256 257// 258// The FuPool object 259// 260 261BEGIN_DECLARE_SIM_OBJECT_PARAMS(FUPool) 262 263 SimObjectVectorParam<FUDesc *> FUList; 264 265END_DECLARE_SIM_OBJECT_PARAMS(FUPool) 266 267 268BEGIN_INIT_SIM_OBJECT_PARAMS(FUPool) 269 270 INIT_PARAM(FUList, "list of FU's for this pool") 271 272END_INIT_SIM_OBJECT_PARAMS(FUPool) 273 274 275CREATE_SIM_OBJECT(FUPool) 276{ 277 return new FUPool(getInstanceName(), FUList); 278} 279 280REGISTER_SIM_OBJECT("FUPool", FUPool) 281 282