fetch_impl.hh (9427:ddf45c1d54d4) | fetch_impl.hh (9444:ab47fe7f03f0) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2010-2011 ARM Limited | 2 * Copyright (c) 2010-2012 ARM Limited |
3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated --- 42 unchanged lines hidden (view full) --- 53#include "arch/vtophys.hh" 54#include "base/types.hh" 55#include "config/the_isa.hh" 56#include "cpu/base.hh" 57//#include "cpu/checker/cpu.hh" 58#include "cpu/o3/fetch.hh" 59#include "cpu/exetrace.hh" 60#include "debug/Activity.hh" | 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated --- 42 unchanged lines hidden (view full) --- 53#include "arch/vtophys.hh" 54#include "base/types.hh" 55#include "config/the_isa.hh" 56#include "cpu/base.hh" 57//#include "cpu/checker/cpu.hh" 58#include "cpu/o3/fetch.hh" 59#include "cpu/exetrace.hh" 60#include "debug/Activity.hh" |
61#include "debug/Drain.hh" |
|
61#include "debug/Fetch.hh" 62#include "mem/packet.hh" 63#include "params/DerivO3CPU.hh" 64#include "sim/byteswap.hh" 65#include "sim/core.hh" 66#include "sim/eventq.hh" 67#include "sim/full_system.hh" 68#include "sim/system.hh" 69 70using namespace std; 71 72template<class Impl> 73DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) 74 : cpu(_cpu), 75 branchPred(params), | 62#include "debug/Fetch.hh" 63#include "mem/packet.hh" 64#include "params/DerivO3CPU.hh" 65#include "sim/byteswap.hh" 66#include "sim/core.hh" 67#include "sim/eventq.hh" 68#include "sim/full_system.hh" 69#include "sim/system.hh" 70 71using namespace std; 72 73template<class Impl> 74DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) 75 : cpu(_cpu), 76 branchPred(params), |
76 numInst(0), | |
77 decodeToFetchDelay(params->decodeToFetchDelay), 78 renameToFetchDelay(params->renameToFetchDelay), 79 iewToFetchDelay(params->iewToFetchDelay), 80 commitToFetchDelay(params->commitToFetchDelay), 81 fetchWidth(params->fetchWidth), | 77 decodeToFetchDelay(params->decodeToFetchDelay), 78 renameToFetchDelay(params->renameToFetchDelay), 79 iewToFetchDelay(params->iewToFetchDelay), 80 commitToFetchDelay(params->commitToFetchDelay), 81 fetchWidth(params->fetchWidth), |
82 cacheBlocked(false), | |
83 retryPkt(NULL), 84 retryTid(InvalidThreadID), 85 numThreads(params->numThreads), 86 numFetchingThreads(params->smtNumFetchingThreads), | 82 retryPkt(NULL), 83 retryTid(InvalidThreadID), 84 numThreads(params->numThreads), 85 numFetchingThreads(params->smtNumFetchingThreads), |
87 interruptPending(false), 88 drainPending(false), 89 switchedOut(false), | |
90 finishTranslationEvent(this) 91{ 92 if (numThreads > Impl::MaxThreads) 93 fatal("numThreads (%d) is larger than compiled limit (%d),\n" 94 "\tincrease MaxThreads in src/cpu/o3/impl.hh\n", 95 numThreads, static_cast<int>(Impl::MaxThreads)); 96 if (fetchWidth > Impl::MaxWidth) 97 fatal("fetchWidth (%d) is larger than compiled limit (%d),\n" 98 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n", 99 fetchWidth, static_cast<int>(Impl::MaxWidth)); 100 | 86 finishTranslationEvent(this) 87{ 88 if (numThreads > Impl::MaxThreads) 89 fatal("numThreads (%d) is larger than compiled limit (%d),\n" 90 "\tincrease MaxThreads in src/cpu/o3/impl.hh\n", 91 numThreads, static_cast<int>(Impl::MaxThreads)); 92 if (fetchWidth > Impl::MaxWidth) 93 fatal("fetchWidth (%d) is larger than compiled limit (%d),\n" 94 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n", 95 fetchWidth, static_cast<int>(Impl::MaxWidth)); 96 |
101 // Set fetch stage's status to inactive. 102 _status = Inactive; 103 | |
104 std::string policy = params->smtFetchPolicy; 105 106 // Convert string to lowercase 107 std::transform(policy.begin(), policy.end(), policy.begin(), 108 (int(*)(int)) tolower); 109 110 // Figure out fetch policy 111 if (policy == "singlethread") { --- 187 unchanged lines hidden (view full) --- 299 // Create wire to write information to proper place in fetch queue. 300 toDecode = fetchQueue->getWire(0); 301} 302 303template<class Impl> 304void 305DefaultFetch<Impl>::startupStage() 306{ | 97 std::string policy = params->smtFetchPolicy; 98 99 // Convert string to lowercase 100 std::transform(policy.begin(), policy.end(), policy.begin(), 101 (int(*)(int)) tolower); 102 103 // Figure out fetch policy 104 if (policy == "singlethread") { --- 187 unchanged lines hidden (view full) --- 292 // Create wire to write information to proper place in fetch queue. 293 toDecode = fetchQueue->getWire(0); 294} 295 296template<class Impl> 297void 298DefaultFetch<Impl>::startupStage() 299{ |
300 assert(priorityList.empty()); 301 resetStage(); 302 303 // Fetch needs to start fetching instructions at the very beginning, 304 // so it must start up in active state. 305 switchToActive(); 306} 307 308template<class Impl> 309void 310DefaultFetch<Impl>::resetStage() 311{ 312 numInst = 0; 313 interruptPending = false; 314 cacheBlocked = false; 315 316 priorityList.clear(); 317 |
|
307 // Setup PC and nextPC with initial state. 308 for (ThreadID tid = 0; tid < numThreads; tid++) { | 318 // Setup PC and nextPC with initial state. 319 for (ThreadID tid = 0; tid < numThreads; tid++) { |
320 fetchStatus[tid] = Running; |
|
309 pc[tid] = cpu->pcState(tid); 310 fetchOffset[tid] = 0; 311 macroop[tid] = NULL; | 321 pc[tid] = cpu->pcState(tid); 322 fetchOffset[tid] = 0; 323 macroop[tid] = NULL; |
312 delayedCommit[tid] = false; 313 } | |
314 | 324 |
315 for (ThreadID tid = 0; tid < numThreads; tid++) { 316 317 fetchStatus[tid] = Running; 318 319 priorityList.push_back(tid); 320 | 325 delayedCommit[tid] = false; |
321 memReq[tid] = NULL; 322 323 stalls[tid].decode = false; 324 stalls[tid].rename = false; 325 stalls[tid].iew = false; 326 stalls[tid].commit = false; | 326 memReq[tid] = NULL; 327 328 stalls[tid].decode = false; 329 stalls[tid].rename = false; 330 stalls[tid].iew = false; 331 stalls[tid].commit = false; |
332 stalls[tid].drain = false; 333 334 priorityList.push_back(tid); |
|
327 } 328 | 335 } 336 |
329 // Schedule fetch to get the correct PC from the CPU 330 // scheduleFetchStartupEvent(1); | 337 wroteToTimeBuffer = false; 338 _status = Inactive; |
331 | 339 |
332 // Fetch needs to start fetching instructions at the very beginning, 333 // so it must start up in active state. 334 switchToActive(); | 340 // this CPU could still be unconnected if we are restoring from a 341 // checkpoint and this CPU is to be switched in, thus we can only 342 // do this here if the instruction port is actually connected, if 343 // not we have to do it as part of takeOverFrom. 344 if (cpu->getInstPort().isConnected()) 345 setIcache(); |
335} 336 337template<class Impl> 338void 339DefaultFetch<Impl>::setIcache() 340{ 341 assert(cpu->getInstPort().isConnected()); 342 --- 14 unchanged lines hidden (view full) --- 357 358template<class Impl> 359void 360DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt) 361{ 362 ThreadID tid = pkt->req->threadId(); 363 364 DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid); | 346} 347 348template<class Impl> 349void 350DefaultFetch<Impl>::setIcache() 351{ 352 assert(cpu->getInstPort().isConnected()); 353 --- 14 unchanged lines hidden (view full) --- 368 369template<class Impl> 370void 371DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt) 372{ 373 ThreadID tid = pkt->req->threadId(); 374 375 DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid); |
376 assert(!cpu->switchedOut()); |
|
365 366 // Only change the status if it's still waiting on the icache access 367 // to return. 368 if (fetchStatus[tid] != IcacheWaitResponse || | 377 378 // Only change the status if it's still waiting on the icache access 379 // to return. 380 if (fetchStatus[tid] != IcacheWaitResponse || |
369 pkt->req != memReq[tid] || 370 isSwitchedOut()) { | 381 pkt->req != memReq[tid]) { |
371 ++fetchIcacheSquashes; 372 delete pkt->req; 373 delete pkt; 374 return; 375 } 376 377 memcpy(cacheData[tid], pkt->getPtr<uint8_t>(), cacheBlkSize); 378 cacheDataValid[tid] = true; 379 | 382 ++fetchIcacheSquashes; 383 delete pkt->req; 384 delete pkt; 385 return; 386 } 387 388 memcpy(cacheData[tid], pkt->getPtr<uint8_t>(), cacheBlkSize); 389 cacheDataValid[tid] = true; 390 |
380 if (!drainPending) { 381 // Wake up the CPU (if it went to sleep and was waiting on 382 // this completion event). 383 cpu->wakeCPU(); | 391 // Wake up the CPU (if it went to sleep and was waiting on 392 // this completion event). 393 cpu->wakeCPU(); |
384 | 394 |
385 DPRINTF(Activity, "[tid:%u] Activating fetch due to cache completion\n", 386 tid); | 395 DPRINTF(Activity, "[tid:%u] Activating fetch due to cache completion\n", 396 tid); |
387 | 397 |
388 switchToActive(); 389 } | 398 switchToActive(); |
390 391 // Only switch to IcacheAccessComplete if we're not stalled as well. 392 if (checkStall(tid)) { 393 fetchStatus[tid] = Blocked; 394 } else { 395 fetchStatus[tid] = IcacheAccessComplete; 396 } 397 398 // Reset the mem req to NULL. 399 delete pkt->req; 400 delete pkt; 401 memReq[tid] = NULL; 402} 403 404template <class Impl> | 399 400 // Only switch to IcacheAccessComplete if we're not stalled as well. 401 if (checkStall(tid)) { 402 fetchStatus[tid] = Blocked; 403 } else { 404 fetchStatus[tid] = IcacheAccessComplete; 405 } 406 407 // Reset the mem req to NULL. 408 delete pkt->req; 409 delete pkt; 410 memReq[tid] = NULL; 411} 412 413template <class Impl> |
405bool 406DefaultFetch | 414void 415DefaultFetch<Impl>::drainResume() |
407{ | 416{ |
408 // Fetch is ready to drain at any time. 409 cpu->signalDrained(); 410 drainPending = true; 411 return true; | 417 for (ThreadID i = 0; i < Impl::MaxThreads; ++i) 418 stalls[i].drain = false; |
412} 413 414template <class Impl> 415void | 419} 420 421template <class Impl> 422void |
416DefaultFetch<Impl>::resume() | 423DefaultFetch<Impl>::drainSanityCheck() const |
417{ | 424{ |
418 drainPending = false; | 425 assert(isDrained()); 426 assert(retryPkt == NULL); 427 assert(retryTid == InvalidThreadID); 428 assert(cacheBlocked == false); 429 assert(interruptPending == false); 430 431 for (ThreadID i = 0; i < numThreads; ++i) { 432 assert(!memReq[i]); 433 assert(!stalls[i].decode); 434 assert(!stalls[i].rename); 435 assert(!stalls[i].iew); 436 assert(!stalls[i].commit); 437 assert(fetchStatus[i] == Idle || stalls[i].drain); 438 } 439 440 branchPred.drainSanityCheck(); |
419} 420 421template <class Impl> | 441} 442 443template <class Impl> |
422void 423DefaultFetch<Impl>::switchOut() | 444bool 445DefaultFetch<Impl>::isDrained() const |
424{ | 446{ |
425 switchedOut = true; 426 // Branch predictor needs to have its state cleared. 427 branchPred.switchOut(); | 447 /* Make sure that threads are either idle of that the commit stage 448 * has signaled that draining has completed by setting the drain 449 * stall flag. This effectively forces the pipeline to be disabled 450 * until the whole system is drained (simulation may continue to 451 * drain other components). 452 */ 453 for (ThreadID i = 0; i < numThreads; ++i) { 454 if (!(fetchStatus[i] == Idle || 455 (fetchStatus[i] == Blocked && stalls[i].drain))) 456 return false; 457 } 458 459 /* The pipeline might start up again in the middle of the drain 460 * cycle if the finish translation event is scheduled, so make 461 * sure that's not the case. 462 */ 463 return !finishTranslationEvent.scheduled(); |
428} 429 430template <class Impl> 431void 432DefaultFetch<Impl>::takeOverFrom() 433{ | 464} 465 466template <class Impl> 467void 468DefaultFetch<Impl>::takeOverFrom() 469{ |
434 // the instruction port is now connected so we can get the block 435 // size 436 setIcache(); | 470 assert(cpu->getInstPort().isConnected()); 471 resetStage(); |
437 | 472 |
438 // Reset all state 439 for (ThreadID i = 0; i < Impl::MaxThreads; ++i) { 440 stalls[i].decode = 0; 441 stalls[i].rename = 0; 442 stalls[i].iew = 0; 443 stalls[i].commit = 0; 444 pc[i] = cpu->pcState(i); 445 fetchStatus[i] = Running; 446 } 447 numInst = 0; 448 wroteToTimeBuffer = false; 449 _status = Inactive; 450 switchedOut = false; 451 interruptPending = false; | |
452 branchPred.takeOverFrom(); 453} 454 455template <class Impl> 456void | 473 branchPred.takeOverFrom(); 474} 475 476template <class Impl> 477void |
478DefaultFetch<Impl>::drainStall(ThreadID tid) 479{ 480 assert(cpu->isDraining()); 481 assert(!stalls[tid].drain); 482 DPRINTF(Drain, "%i: Thread drained.\n", tid); 483 stalls[tid].drain = true; 484} 485 486template <class Impl> 487void |
|
457DefaultFetch<Impl>::wakeFromQuiesce() 458{ 459 DPRINTF(Fetch, "Waking up from quiesce\n"); 460 // Hopefully this is safe 461 // @todo: Allow other threads to wake from quiesce. 462 fetchStatus[0] = Running; 463} 464 --- 66 unchanged lines hidden (view full) --- 531} 532 533template <class Impl> 534bool 535DefaultFetch<Impl>::fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc) 536{ 537 Fault fault = NoFault; 538 | 488DefaultFetch<Impl>::wakeFromQuiesce() 489{ 490 DPRINTF(Fetch, "Waking up from quiesce\n"); 491 // Hopefully this is safe 492 // @todo: Allow other threads to wake from quiesce. 493 fetchStatus[0] = Running; 494} 495 --- 66 unchanged lines hidden (view full) --- 562} 563 564template <class Impl> 565bool 566DefaultFetch<Impl>::fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc) 567{ 568 Fault fault = NoFault; 569 |
570 assert(!cpu->switchedOut()); 571 |
|
539 // @todo: not sure if these should block translation. 540 //AlphaDep 541 if (cacheBlocked) { 542 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n", 543 tid); 544 return false; | 572 // @todo: not sure if these should block translation. 573 //AlphaDep 574 if (cacheBlocked) { 575 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n", 576 tid); 577 return false; |
545 } else if (isSwitchedOut()) { 546 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, switched out\n", 547 tid); 548 return false; | |
549 } else if (checkInterrupt(pc) && !delayedCommit[tid]) { 550 // Hold off fetch from getting new instructions when: 551 // Cache is blocked, or 552 // while an interrupt is pending and we're not in PAL mode, or 553 // fetch is switched out. 554 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n", 555 tid); 556 return false; --- 24 unchanged lines hidden (view full) --- 581 582template <class Impl> 583void 584DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req) 585{ 586 ThreadID tid = mem_req->threadId(); 587 Addr block_PC = mem_req->getVaddr(); 588 | 578 } else if (checkInterrupt(pc) && !delayedCommit[tid]) { 579 // Hold off fetch from getting new instructions when: 580 // Cache is blocked, or 581 // while an interrupt is pending and we're not in PAL mode, or 582 // fetch is switched out. 583 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n", 584 tid); 585 return false; --- 24 unchanged lines hidden (view full) --- 610 611template <class Impl> 612void 613DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req) 614{ 615 ThreadID tid = mem_req->threadId(); 616 Addr block_PC = mem_req->getVaddr(); 617 |
618 assert(!cpu->switchedOut()); 619 |
|
589 // Wake up CPU if it was idle 590 cpu->wakeCPU(); 591 592 if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] || | 620 // Wake up CPU if it was idle 621 cpu->wakeCPU(); 622 623 if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] || |
593 mem_req->getVaddr() != memReq[tid]->getVaddr() || isSwitchedOut()) { | 624 mem_req->getVaddr() != memReq[tid]->getVaddr()) { |
594 DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n", 595 tid); 596 ++fetchTlbSquashes; 597 delete mem_req; 598 return; 599 } 600 601 --- 150 unchanged lines hidden (view full) --- 752bool 753DefaultFetch<Impl>::checkStall(ThreadID tid) const 754{ 755 bool ret_val = false; 756 757 if (cpu->contextSwitch) { 758 DPRINTF(Fetch,"[tid:%i]: Stalling for a context switch.\n",tid); 759 ret_val = true; | 625 DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n", 626 tid); 627 ++fetchTlbSquashes; 628 delete mem_req; 629 return; 630 } 631 632 --- 150 unchanged lines hidden (view full) --- 783bool 784DefaultFetch<Impl>::checkStall(ThreadID tid) const 785{ 786 bool ret_val = false; 787 788 if (cpu->contextSwitch) { 789 DPRINTF(Fetch,"[tid:%i]: Stalling for a context switch.\n",tid); 790 ret_val = true; |
791 } else if (stalls[tid].drain) { 792 assert(cpu->isDraining()); 793 DPRINTF(Fetch,"[tid:%i]: Drain stall detected.\n",tid); 794 ret_val = true; |
|
760 } else if (stalls[tid].decode) { 761 DPRINTF(Fetch,"[tid:%i]: Stall from Decode stage detected.\n",tid); 762 ret_val = true; 763 } else if (stalls[tid].rename) { 764 DPRINTF(Fetch,"[tid:%i]: Stall from Rename stage detected.\n",tid); 765 ret_val = true; 766 } else if (stalls[tid].iew) { 767 DPRINTF(Fetch,"[tid:%i]: Stall from IEW stage detected.\n",tid); --- 324 unchanged lines hidden (view full) --- 1092void 1093DefaultFetch<Impl>::fetch(bool &status_change) 1094{ 1095 ////////////////////////////////////////// 1096 // Start actual fetch 1097 ////////////////////////////////////////// 1098 ThreadID tid = getFetchingThread(fetchPolicy); 1099 | 795 } else if (stalls[tid].decode) { 796 DPRINTF(Fetch,"[tid:%i]: Stall from Decode stage detected.\n",tid); 797 ret_val = true; 798 } else if (stalls[tid].rename) { 799 DPRINTF(Fetch,"[tid:%i]: Stall from Rename stage detected.\n",tid); 800 ret_val = true; 801 } else if (stalls[tid].iew) { 802 DPRINTF(Fetch,"[tid:%i]: Stall from IEW stage detected.\n",tid); --- 324 unchanged lines hidden (view full) --- 1127void 1128DefaultFetch<Impl>::fetch(bool &status_change) 1129{ 1130 ////////////////////////////////////////// 1131 // Start actual fetch 1132 ////////////////////////////////////////// 1133 ThreadID tid = getFetchingThread(fetchPolicy); 1134 |
1100 if (tid == InvalidThreadID || drainPending) { | 1135 assert(!cpu->switchedOut()); 1136 1137 if (tid == InvalidThreadID) { |
1101 // Breaks looping condition in tick() 1102 threadFetched = numFetchingThreads; 1103 1104 if (numThreads == 1) { // @todo Per-thread stats 1105 profileStall(0); 1106 } 1107 1108 return; --- 33 unchanged lines hidden (view full) --- 1142 1143 if (fetchStatus[tid] == IcacheWaitResponse) 1144 ++icacheStallCycles; 1145 else if (fetchStatus[tid] == ItlbWait) 1146 ++fetchTlbCycles; 1147 else 1148 ++fetchMiscStallCycles; 1149 return; | 1138 // Breaks looping condition in tick() 1139 threadFetched = numFetchingThreads; 1140 1141 if (numThreads == 1) { // @todo Per-thread stats 1142 profileStall(0); 1143 } 1144 1145 return; --- 33 unchanged lines hidden (view full) --- 1179 1180 if (fetchStatus[tid] == IcacheWaitResponse) 1181 ++icacheStallCycles; 1182 else if (fetchStatus[tid] == ItlbWait) 1183 ++fetchTlbCycles; 1184 else 1185 ++fetchMiscStallCycles; 1186 return; |
1150 } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid]) 1151 || isSwitchedOut()) { | 1187 } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid])) { |
1152 // Stall CPU if an interrupt is posted and we're not issuing 1153 // an delayed commit micro-op currently (delayed commit instructions 1154 // are not interruptable by interrupts, only faults) 1155 ++fetchMiscStallCycles; 1156 DPRINTF(Fetch, "[tid:%i]: Fetch is stalled!\n", tid); 1157 return; 1158 } 1159 } else { --- 401 unchanged lines hidden (view full) --- 1561 1562template<class Impl> 1563void 1564DefaultFetch<Impl>::profileStall(ThreadID tid) { 1565 DPRINTF(Fetch,"There are no more threads available to fetch from.\n"); 1566 1567 // @todo Per-thread stats 1568 | 1188 // Stall CPU if an interrupt is posted and we're not issuing 1189 // an delayed commit micro-op currently (delayed commit instructions 1190 // are not interruptable by interrupts, only faults) 1191 ++fetchMiscStallCycles; 1192 DPRINTF(Fetch, "[tid:%i]: Fetch is stalled!\n", tid); 1193 return; 1194 } 1195 } else { --- 401 unchanged lines hidden (view full) --- 1597 1598template<class Impl> 1599void 1600DefaultFetch<Impl>::profileStall(ThreadID tid) { 1601 DPRINTF(Fetch,"There are no more threads available to fetch from.\n"); 1602 1603 // @todo Per-thread stats 1604 |
1569 if (drainPending) { | 1605 if (stalls[tid].drain) { |
1570 ++fetchPendingDrainCycles; 1571 DPRINTF(Fetch, "Fetch is waiting for a drain!\n"); 1572 } else if (activeThreads->empty()) { 1573 ++fetchNoActiveThreadStallCycles; 1574 DPRINTF(Fetch, "Fetch has no active thread!\n"); 1575 } else if (fetchStatus[tid] == Blocked) { 1576 ++fetchBlockedCycles; 1577 DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid); --- 31 unchanged lines hidden --- | 1606 ++fetchPendingDrainCycles; 1607 DPRINTF(Fetch, "Fetch is waiting for a drain!\n"); 1608 } else if (activeThreads->empty()) { 1609 ++fetchNoActiveThreadStallCycles; 1610 DPRINTF(Fetch, "Fetch has no active thread!\n"); 1611 } else if (fetchStatus[tid] == Blocked) { 1612 ++fetchBlockedCycles; 1613 DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid); --- 31 unchanged lines hidden --- |