fu_pool.cc revision 2292
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292SN/A#include <sstream> 302SN/A 311798SN/A#include "cpu/o3/fu_pool.hh" 321798SN/A#include "encumbered/cpu/full/fu_pool.hh" 332SN/A#include "sim/builder.hh" 3456SN/A 352SN/Ausing namespace std; 362SN/A 372SN/A//////////////////////////////////////////////////////////////////////////// 382SN/A// 392667Sstever@eecs.umich.edu// A pool of function units 402SN/A// 412SN/A 422SN/Ainline void 432SN/AFUPool::FUIdxQueue::addFU(int fu_idx) 442SN/A{ 453144Shsul@eecs.umich.edu funcUnitsIdx.push_back(fu_idx); 462SN/A ++size; 472SN/A} 482797Sktlim@umich.edu 492797Sktlim@umich.eduinline int 502797Sktlim@umich.eduFUPool::FUIdxQueue::getFU() 512797Sktlim@umich.edu{ 522797Sktlim@umich.edu int retval = funcUnitsIdx[idx++]; 533144Shsul@eecs.umich.edu 543144Shsul@eecs.umich.edu if (idx == size) 553144Shsul@eecs.umich.edu idx = 0; 563144Shsul@eecs.umich.edu 573144Shsul@eecs.umich.edu return retval; 582667Sstever@eecs.umich.edu} 592SN/A 603144Shsul@eecs.umich.eduFUPool::~FUPool() 615543Ssaidi@eecs.umich.edu{ 625543Ssaidi@eecs.umich.edu fuListIterator i = funcUnits.begin(); 635543Ssaidi@eecs.umich.edu fuListIterator end = funcUnits.end(); 643144Shsul@eecs.umich.edu for (; i != end; ++i) 652SN/A delete *i; 662667Sstever@eecs.umich.edu} 672667Sstever@eecs.umich.edu 682SN/A 695543Ssaidi@eecs.umich.edu// Constructor 702SN/AFUPool::FUPool(string name, vector<FUDesc *> paramList) 715336Shines@cs.fsu.edu : SimObject(name) 722SN/A{ 732SN/A numFU = 0; 742839Sktlim@umich.edu 752797Sktlim@umich.edu funcUnits.clear(); 762797Sktlim@umich.edu 772839Sktlim@umich.edu for (int i = 0; i < Num_OpClasses; ++i) { 782797Sktlim@umich.edu maxOpLatencies[i] = 0; 792797Sktlim@umich.edu maxIssueLatencies[i] = 0; 802839Sktlim@umich.edu } 812797Sktlim@umich.edu 822797Sktlim@umich.edu // 832797Sktlim@umich.edu // Iterate through the list of FUDescData structures 842797Sktlim@umich.edu // 852797Sktlim@umich.edu for (FUDDiterator i = paramList.begin(); i != paramList.end(); ++i) { 862797Sktlim@umich.edu 872797Sktlim@umich.edu // 882797Sktlim@umich.edu // Don't bother with this if we're not going to create any FU's 892797Sktlim@umich.edu // 902SN/A if ((*i)->number) { 912SN/A // 922SN/A // Create the FuncUnit object from this structure 932SN/A // - add the capabilities listed in the FU's operation 942SN/A // description 952SN/A // 962SN/A // We create the first unit, then duplicate it as needed 972SN/A // 985543Ssaidi@eecs.umich.edu FuncUnit *fu = new FuncUnit; 995543Ssaidi@eecs.umich.edu 1002SN/A OPDDiterator j = (*i)->opDescList.begin(); 1012SN/A OPDDiterator end = (*i)->opDescList.end(); 1022SN/A for (; j != end; ++j) { 1032SN/A // indicate that this pool has this capability 1042SN/A capabilityList.set((*j)->opClass); 1055543Ssaidi@eecs.umich.edu 1062SN/A // Add each of the FU's that will have this capability to the 1075336Shines@cs.fsu.edu // appropriate queue. 1082SN/A for (int k = 0; k < (*i)->number; ++k) 1092SN/A fuPerCapList[(*j)->opClass].addFU(numFU + k); 1102SN/A 1111798SN/A // indicate that this FU has the capability 1122SN/A fu->addCapability((*j)->opClass, (*j)->opLat, (*j)->issueLat); 1132SN/A 1142SN/A if ((*j)->opLat > maxOpLatencies[(*j)->opClass]) 1152SN/A maxOpLatencies[(*j)->opClass] = (*j)->opLat; 1162SN/A 1172SN/A if ((*j)->issueLat > maxIssueLatencies[(*j)->opClass]) 1182SN/A maxIssueLatencies[(*j)->opClass] = (*j)->issueLat; 1192SN/A } 1202SN/A 1211798SN/A numFU++; 1222SN/A 1235543Ssaidi@eecs.umich.edu // Add the appropriate number of copies of this FU to the list 1242SN/A ostringstream s; 1255336Shines@cs.fsu.edu 1262SN/A s << (*i)->name() << "(0)"; 1272SN/A fu->name = s.str(); 1281798SN/A 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