iew_impl.hh revision 4636
1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 */ 30 31// @todo: Fix the instantaneous communication among all the stages within 32// iew. There's a clear delay between issue and execute, yet backwards 33// communication happens simultaneously. 34 35#include <queue> 36 37#include "base/timebuf.hh" 38#include "cpu/o3/fu_pool.hh" 39#include "cpu/o3/iew.hh" 40 41template<class Impl> 42DefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, Params *params) 43 : issueToExecQueue(params->backComSize, params->forwardComSize), 44 cpu(_cpu), 45 instQueue(_cpu, this, params), 46 ldstQueue(_cpu, this, params), 47 fuPool(params->fuPool), 48 commitToIEWDelay(params->commitToIEWDelay), 49 renameToIEWDelay(params->renameToIEWDelay), 50 issueToExecuteDelay(params->issueToExecuteDelay), 51 dispatchWidth(params->dispatchWidth), 52 issueWidth(params->issueWidth), 53 wbOutstanding(0), 54 wbWidth(params->wbWidth), 55 numThreads(params->numberOfThreads), 56 switchedOut(false) 57{ 58 _status = Active; 59 exeStatus = Running; 60 wbStatus = Idle; 61 62 // Setup wire to read instructions coming from issue. 63 fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 64 65 // Instruction queue needs the queue between issue and execute. 66 instQueue.setIssueToExecuteQueue(&issueToExecQueue); 67 68 for (int i=0; i < numThreads; i++) { 69 dispatchStatus[i] = Running; 70 stalls[i].commit = false; 71 fetchRedirect[i] = false; 72 } 73 74 wbMax = wbWidth * params->wbDepth; 75 76 updateLSQNextCycle = false; 77 78 ableToIssue = true; 79 80 skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth; 81} 82 83template <class Impl> 84std::string 85DefaultIEW<Impl>::name() const 86{ 87 return cpu->name() + ".iew"; 88} 89 90template <class Impl> 91void 92DefaultIEW<Impl>::regStats() 93{ 94 using namespace Stats; 95 96 instQueue.regStats(); 97 ldstQueue.regStats(); 98 99 iewIdleCycles 100 .name(name() + ".iewIdleCycles") 101 .desc("Number of cycles IEW is idle"); 102 103 iewSquashCycles 104 .name(name() + ".iewSquashCycles") 105 .desc("Number of cycles IEW is squashing"); 106 107 iewBlockCycles 108 .name(name() + ".iewBlockCycles") 109 .desc("Number of cycles IEW is blocking"); 110 111 iewUnblockCycles 112 .name(name() + ".iewUnblockCycles") 113 .desc("Number of cycles IEW is unblocking"); 114 115 iewDispatchedInsts 116 .name(name() + ".iewDispatchedInsts") 117 .desc("Number of instructions dispatched to IQ"); 118 119 iewDispSquashedInsts 120 .name(name() + ".iewDispSquashedInsts") 121 .desc("Number of squashed instructions skipped by dispatch"); 122 123 iewDispLoadInsts 124 .name(name() + ".iewDispLoadInsts") 125 .desc("Number of dispatched load instructions"); 126 127 iewDispStoreInsts 128 .name(name() + ".iewDispStoreInsts") 129 .desc("Number of dispatched store instructions"); 130 131 iewDispNonSpecInsts 132 .name(name() + ".iewDispNonSpecInsts") 133 .desc("Number of dispatched non-speculative instructions"); 134 135 iewIQFullEvents 136 .name(name() + ".iewIQFullEvents") 137 .desc("Number of times the IQ has become full, causing a stall"); 138 139 iewLSQFullEvents 140 .name(name() + ".iewLSQFullEvents") 141 .desc("Number of times the LSQ has become full, causing a stall"); 142 143 memOrderViolationEvents 144 .name(name() + ".memOrderViolationEvents") 145 .desc("Number of memory order violations"); 146 147 predictedTakenIncorrect 148 .name(name() + ".predictedTakenIncorrect") 149 .desc("Number of branches that were predicted taken incorrectly"); 150 151 predictedNotTakenIncorrect 152 .name(name() + ".predictedNotTakenIncorrect") 153 .desc("Number of branches that were predicted not taken incorrectly"); 154 155 branchMispredicts 156 .name(name() + ".branchMispredicts") 157 .desc("Number of branch mispredicts detected at execute"); 158 159 branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; 160 161 iewExecutedInsts 162 .name(name() + ".iewExecutedInsts") 163 .desc("Number of executed instructions"); 164 165 iewExecLoadInsts 166 .init(cpu->number_of_threads) 167 .name(name() + ".iewExecLoadInsts") 168 .desc("Number of load instructions executed") 169 .flags(total); 170 171 iewExecSquashedInsts 172 .name(name() + ".iewExecSquashedInsts") 173 .desc("Number of squashed instructions skipped in execute"); 174 175 iewExecutedSwp 176 .init(cpu->number_of_threads) 177 .name(name() + ".EXEC:swp") 178 .desc("number of swp insts executed") 179 .flags(total); 180 181 iewExecutedNop 182 .init(cpu->number_of_threads) 183 .name(name() + ".EXEC:nop") 184 .desc("number of nop insts executed") 185 .flags(total); 186 187 iewExecutedRefs 188 .init(cpu->number_of_threads) 189 .name(name() + ".EXEC:refs") 190 .desc("number of memory reference insts executed") 191 .flags(total); 192 193 iewExecutedBranches 194 .init(cpu->number_of_threads) 195 .name(name() + ".EXEC:branches") 196 .desc("Number of branches executed") 197 .flags(total); 198 199 iewExecStoreInsts 200 .name(name() + ".EXEC:stores") 201 .desc("Number of stores executed") 202 .flags(total); 203 iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts; 204 205 iewExecRate 206 .name(name() + ".EXEC:rate") 207 .desc("Inst execution rate") 208 .flags(total); 209 210 iewExecRate = iewExecutedInsts / cpu->numCycles; 211 212 iewInstsToCommit 213 .init(cpu->number_of_threads) 214 .name(name() + ".WB:sent") 215 .desc("cumulative count of insts sent to commit") 216 .flags(total); 217 218 writebackCount 219 .init(cpu->number_of_threads) 220 .name(name() + ".WB:count") 221 .desc("cumulative count of insts written-back") 222 .flags(total); 223 224 producerInst 225 .init(cpu->number_of_threads) 226 .name(name() + ".WB:producers") 227 .desc("num instructions producing a value") 228 .flags(total); 229 230 consumerInst 231 .init(cpu->number_of_threads) 232 .name(name() + ".WB:consumers") 233 .desc("num instructions consuming a value") 234 .flags(total); 235 236 wbPenalized 237 .init(cpu->number_of_threads) 238 .name(name() + ".WB:penalized") 239 .desc("number of instrctions required to write to 'other' IQ") 240 .flags(total); 241 242 wbPenalizedRate 243 .name(name() + ".WB:penalized_rate") 244 .desc ("fraction of instructions written-back that wrote to 'other' IQ") 245 .flags(total); 246 247 wbPenalizedRate = wbPenalized / writebackCount; 248 249 wbFanout 250 .name(name() + ".WB:fanout") 251 .desc("average fanout of values written-back") 252 .flags(total); 253 254 wbFanout = producerInst / consumerInst; 255 256 wbRate 257 .name(name() + ".WB:rate") 258 .desc("insts written-back per cycle") 259 .flags(total); 260 wbRate = writebackCount / cpu->numCycles; 261} 262 263template<class Impl> 264void 265DefaultIEW<Impl>::initStage() 266{ 267 for (int tid=0; tid < numThreads; tid++) { 268 toRename->iewInfo[tid].usedIQ = true; 269 toRename->iewInfo[tid].freeIQEntries = 270 instQueue.numFreeEntries(tid); 271 272 toRename->iewInfo[tid].usedLSQ = true; 273 toRename->iewInfo[tid].freeLSQEntries = 274 ldstQueue.numFreeEntries(tid); 275 } 276 277 cpu->activateStage(O3CPU::IEWIdx); 278} 279 280template<class Impl> 281void 282DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 283{ 284 timeBuffer = tb_ptr; 285 286 // Setup wire to read information from time buffer, from commit. 287 fromCommit = timeBuffer->getWire(-commitToIEWDelay); 288 289 // Setup wire to write information back to previous stages. 290 toRename = timeBuffer->getWire(0); 291 292 toFetch = timeBuffer->getWire(0); 293 294 // Instruction queue also needs main time buffer. 295 instQueue.setTimeBuffer(tb_ptr); 296} 297 298template<class Impl> 299void 300DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 301{ 302 renameQueue = rq_ptr; 303 304 // Setup wire to read information from rename queue. 305 fromRename = renameQueue->getWire(-renameToIEWDelay); 306} 307 308template<class Impl> 309void 310DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 311{ 312 iewQueue = iq_ptr; 313 314 // Setup wire to write instructions to commit. 315 toCommit = iewQueue->getWire(0); 316} 317 318template<class Impl> 319void 320DefaultIEW<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) 321{ 322 activeThreads = at_ptr; 323 324 ldstQueue.setActiveThreads(at_ptr); 325 instQueue.setActiveThreads(at_ptr); 326} 327 328template<class Impl> 329void 330DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr) 331{ 332 scoreboard = sb_ptr; 333} 334 335template <class Impl> 336bool 337DefaultIEW<Impl>::drain() 338{ 339 // IEW is ready to drain at any time. 340 cpu->signalDrained(); 341 return true; 342} 343 344template <class Impl> 345void 346DefaultIEW<Impl>::resume() 347{ 348} 349 350template <class Impl> 351void 352DefaultIEW<Impl>::switchOut() 353{ 354 // Clear any state. 355 switchedOut = true; 356 assert(insts[0].empty()); 357 assert(skidBuffer[0].empty()); 358 359 instQueue.switchOut(); 360 ldstQueue.switchOut(); 361 fuPool->switchOut(); 362 363 for (int i = 0; i < numThreads; i++) { 364 while (!insts[i].empty()) 365 insts[i].pop(); 366 while (!skidBuffer[i].empty()) 367 skidBuffer[i].pop(); 368 } 369} 370 371template <class Impl> 372void 373DefaultIEW<Impl>::takeOverFrom() 374{ 375 // Reset all state. 376 _status = Active; 377 exeStatus = Running; 378 wbStatus = Idle; 379 switchedOut = false; 380 381 instQueue.takeOverFrom(); 382 ldstQueue.takeOverFrom(); 383 fuPool->takeOverFrom(); 384 385 initStage(); 386 cpu->activityThisCycle(); 387 388 for (int i=0; i < numThreads; i++) { 389 dispatchStatus[i] = Running; 390 stalls[i].commit = false; 391 fetchRedirect[i] = false; 392 } 393 394 updateLSQNextCycle = false; 395 396 for (int i = 0; i < issueToExecQueue.getSize(); ++i) { 397 issueToExecQueue.advance(); 398 } 399} 400 401template<class Impl> 402void 403DefaultIEW<Impl>::squash(unsigned tid) 404{ 405 DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", 406 tid); 407 408 // Tell the IQ to start squashing. 409 instQueue.squash(tid); 410 411 // Tell the LDSTQ to start squashing. 412 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 413 updatedQueues = true; 414 415 // Clear the skid buffer in case it has any data in it. 416 DPRINTF(IEW, "[tid:%i]: Removing skidbuffer instructions until [sn:%i].\n", 417 tid, fromCommit->commitInfo[tid].doneSeqNum); 418 419 while (!skidBuffer[tid].empty()) { 420 if (skidBuffer[tid].front()->isLoad() || 421 skidBuffer[tid].front()->isStore() ) { 422 toRename->iewInfo[tid].dispatchedToLSQ++; 423 } 424 425 toRename->iewInfo[tid].dispatched++; 426 427 skidBuffer[tid].pop(); 428 } 429 430 emptyRenameInsts(tid); 431} 432 433template<class Impl> 434void 435DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid) 436{ 437 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x " 438 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum); 439 440 toCommit->squash[tid] = true; 441 toCommit->squashedSeqNum[tid] = inst->seqNum; 442 toCommit->mispredPC[tid] = inst->readPC(); 443 toCommit->branchMispredict[tid] = true; 444 445#if ISA_HAS_DELAY_SLOT 446 int instSize = sizeof(TheISA::MachInst); 447 toCommit->branchTaken[tid] = 448 !(inst->readNextPC() + instSize == inst->readNextNPC() && 449 (inst->readNextPC() == inst->readPC() + instSize || 450 inst->readNextPC() == inst->readPC() + 2 * instSize)); 451#else 452 toCommit->branchTaken[tid] = inst->readNextPC() != 453 (inst->readPC() + sizeof(TheISA::MachInst)); 454#endif 455 toCommit->nextPC[tid] = inst->readNextPC(); 456 toCommit->nextNPC[tid] = inst->readNextNPC(); 457 toCommit->nextMicroPC[tid] = inst->readNextMicroPC(); 458 459 toCommit->includeSquashInst[tid] = false; 460 461 wroteToTimeBuffer = true; 462} 463 464template<class Impl> 465void 466DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) 467{ 468 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " 469 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 470 471 toCommit->squash[tid] = true; 472 toCommit->squashedSeqNum[tid] = inst->seqNum; 473 toCommit->nextPC[tid] = inst->readNextPC(); 474 toCommit->nextNPC[tid] = inst->readNextNPC(); 475 toCommit->branchMispredict[tid] = false; 476 477 toCommit->includeSquashInst[tid] = false; 478 479 wroteToTimeBuffer = true; 480} 481 482template<class Impl> 483void 484DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) 485{ 486 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 487 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 488 489 toCommit->squash[tid] = true; 490 toCommit->squashedSeqNum[tid] = inst->seqNum; 491 toCommit->nextPC[tid] = inst->readPC(); 492 toCommit->nextNPC[tid] = inst->readNextPC(); 493 toCommit->branchMispredict[tid] = false; 494 495 // Must include the broadcasted SN in the squash. 496 toCommit->includeSquashInst[tid] = true; 497 498 ldstQueue.setLoadBlockedHandled(tid); 499 500 wroteToTimeBuffer = true; 501} 502 503template<class Impl> 504void 505DefaultIEW<Impl>::block(unsigned tid) 506{ 507 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 508 509 if (dispatchStatus[tid] != Blocked && 510 dispatchStatus[tid] != Unblocking) { 511 toRename->iewBlock[tid] = true; 512 wroteToTimeBuffer = true; 513 } 514 515 // Add the current inputs to the skid buffer so they can be 516 // reprocessed when this stage unblocks. 517 skidInsert(tid); 518 519 dispatchStatus[tid] = Blocked; 520} 521 522template<class Impl> 523void 524DefaultIEW<Impl>::unblock(unsigned tid) 525{ 526 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 527 "buffer %u.\n",tid, tid); 528 529 // If the skid bufffer is empty, signal back to previous stages to unblock. 530 // Also switch status to running. 531 if (skidBuffer[tid].empty()) { 532 toRename->iewUnblock[tid] = true; 533 wroteToTimeBuffer = true; 534 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 535 dispatchStatus[tid] = Running; 536 } 537} 538 539template<class Impl> 540void 541DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 542{ 543 instQueue.wakeDependents(inst); 544} 545 546template<class Impl> 547void 548DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 549{ 550 instQueue.rescheduleMemInst(inst); 551} 552 553template<class Impl> 554void 555DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 556{ 557 instQueue.replayMemInst(inst); 558} 559 560template<class Impl> 561void 562DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 563{ 564 // This function should not be called after writebackInsts in a 565 // single cycle. That will cause problems with an instruction 566 // being added to the queue to commit without being processed by 567 // writebackInsts prior to being sent to commit. 568 569 // First check the time slot that this instruction will write 570 // to. If there are free write ports at the time, then go ahead 571 // and write the instruction to that time. If there are not, 572 // keep looking back to see where's the first time there's a 573 // free slot. 574 while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 575 ++wbNumInst; 576 if (wbNumInst == wbWidth) { 577 ++wbCycle; 578 wbNumInst = 0; 579 } 580 581 assert((wbCycle * wbWidth + wbNumInst) <= wbMax); 582 } 583 584 DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n", 585 wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst); 586 // Add finished instruction to queue to commit. 587 (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 588 (*iewQueue)[wbCycle].size++; 589} 590 591template <class Impl> 592unsigned 593DefaultIEW<Impl>::validInstsFromRename() 594{ 595 unsigned inst_count = 0; 596 597 for (int i=0; i<fromRename->size; i++) { 598 if (!fromRename->insts[i]->isSquashed()) 599 inst_count++; 600 } 601 602 return inst_count; 603} 604 605template<class Impl> 606void 607DefaultIEW<Impl>::skidInsert(unsigned tid) 608{ 609 DynInstPtr inst = NULL; 610 611 while (!insts[tid].empty()) { 612 inst = insts[tid].front(); 613 614 insts[tid].pop(); 615 616 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into " 617 "dispatch skidBuffer %i\n",tid, inst->seqNum, 618 inst->readPC(),tid); 619 620 skidBuffer[tid].push(inst); 621 } 622 623 assert(skidBuffer[tid].size() <= skidBufferMax && 624 "Skidbuffer Exceeded Max Size"); 625} 626 627template<class Impl> 628int 629DefaultIEW<Impl>::skidCount() 630{ 631 int max=0; 632 633 std::list<unsigned>::iterator threads = activeThreads->begin(); 634 std::list<unsigned>::iterator end = activeThreads->end(); 635 636 while (threads != end) { 637 unsigned tid = *threads++; 638 unsigned thread_count = skidBuffer[tid].size(); 639 if (max < thread_count) 640 max = thread_count; 641 } 642 643 return max; 644} 645 646template<class Impl> 647bool 648DefaultIEW<Impl>::skidsEmpty() 649{ 650 std::list<unsigned>::iterator threads = activeThreads->begin(); 651 std::list<unsigned>::iterator end = activeThreads->end(); 652 653 while (threads != end) { 654 unsigned tid = *threads++; 655 656 if (!skidBuffer[tid].empty()) 657 return false; 658 } 659 660 return true; 661} 662 663template <class Impl> 664void 665DefaultIEW<Impl>::updateStatus() 666{ 667 bool any_unblocking = false; 668 669 std::list<unsigned>::iterator threads = activeThreads->begin(); 670 std::list<unsigned>::iterator end = activeThreads->end(); 671 672 while (threads != end) { 673 unsigned tid = *threads++; 674 675 if (dispatchStatus[tid] == Unblocking) { 676 any_unblocking = true; 677 break; 678 } 679 } 680 681 // If there are no ready instructions waiting to be scheduled by the IQ, 682 // and there's no stores waiting to write back, and dispatch is not 683 // unblocking, then there is no internal activity for the IEW stage. 684 if (_status == Active && !instQueue.hasReadyInsts() && 685 !ldstQueue.willWB() && !any_unblocking) { 686 DPRINTF(IEW, "IEW switching to idle\n"); 687 688 deactivateStage(); 689 690 _status = Inactive; 691 } else if (_status == Inactive && (instQueue.hasReadyInsts() || 692 ldstQueue.willWB() || 693 any_unblocking)) { 694 // Otherwise there is internal activity. Set to active. 695 DPRINTF(IEW, "IEW switching to active\n"); 696 697 activateStage(); 698 699 _status = Active; 700 } 701} 702 703template <class Impl> 704void 705DefaultIEW<Impl>::resetEntries() 706{ 707 instQueue.resetEntries(); 708 ldstQueue.resetEntries(); 709} 710 711template <class Impl> 712void 713DefaultIEW<Impl>::readStallSignals(unsigned tid) 714{ 715 if (fromCommit->commitBlock[tid]) { 716 stalls[tid].commit = true; 717 } 718 719 if (fromCommit->commitUnblock[tid]) { 720 assert(stalls[tid].commit); 721 stalls[tid].commit = false; 722 } 723} 724 725template <class Impl> 726bool 727DefaultIEW<Impl>::checkStall(unsigned tid) 728{ 729 bool ret_val(false); 730 731 if (stalls[tid].commit) { 732 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 733 ret_val = true; 734 } else if (instQueue.isFull(tid)) { 735 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 736 ret_val = true; 737 } else if (ldstQueue.isFull(tid)) { 738 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 739 740 if (ldstQueue.numLoads(tid) > 0 ) { 741 742 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 743 tid,ldstQueue.getLoadHeadSeqNum(tid)); 744 } 745 746 if (ldstQueue.numStores(tid) > 0) { 747 748 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 749 tid,ldstQueue.getStoreHeadSeqNum(tid)); 750 } 751 752 ret_val = true; 753 } else if (ldstQueue.isStalled(tid)) { 754 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 755 ret_val = true; 756 } 757 758 return ret_val; 759} 760 761template <class Impl> 762void 763DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid) 764{ 765 // Check if there's a squash signal, squash if there is 766 // Check stall signals, block if there is. 767 // If status was Blocked 768 // if so then go to unblocking 769 // If status was Squashing 770 // check if squashing is not high. Switch to running this cycle. 771 772 readStallSignals(tid); 773 774 if (fromCommit->commitInfo[tid].squash) { 775 squash(tid); 776 777 if (dispatchStatus[tid] == Blocked || 778 dispatchStatus[tid] == Unblocking) { 779 toRename->iewUnblock[tid] = true; 780 wroteToTimeBuffer = true; 781 } 782 783 dispatchStatus[tid] = Squashing; 784 785 fetchRedirect[tid] = false; 786 return; 787 } 788 789 if (fromCommit->commitInfo[tid].robSquashing) { 790 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid); 791 792 dispatchStatus[tid] = Squashing; 793 794 emptyRenameInsts(tid); 795 wroteToTimeBuffer = true; 796 return; 797 } 798 799 if (checkStall(tid)) { 800 block(tid); 801 dispatchStatus[tid] = Blocked; 802 return; 803 } 804 805 if (dispatchStatus[tid] == Blocked) { 806 // Status from previous cycle was blocked, but there are no more stall 807 // conditions. Switch over to unblocking. 808 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 809 tid); 810 811 dispatchStatus[tid] = Unblocking; 812 813 unblock(tid); 814 815 return; 816 } 817 818 if (dispatchStatus[tid] == Squashing) { 819 // Switch status to running if rename isn't being told to block or 820 // squash this cycle. 821 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 822 tid); 823 824 dispatchStatus[tid] = Running; 825 826 return; 827 } 828} 829 830template <class Impl> 831void 832DefaultIEW<Impl>::sortInsts() 833{ 834 int insts_from_rename = fromRename->size; 835#ifdef DEBUG 836 for (int i = 0; i < numThreads; i++) 837 assert(insts[i].empty()); 838#endif 839 for (int i = 0; i < insts_from_rename; ++i) { 840 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 841 } 842} 843 844template <class Impl> 845void 846DefaultIEW<Impl>::emptyRenameInsts(unsigned tid) 847{ 848 DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid); 849 850 while (!insts[tid].empty()) { 851 852 if (insts[tid].front()->isLoad() || 853 insts[tid].front()->isStore() ) { 854 toRename->iewInfo[tid].dispatchedToLSQ++; 855 } 856 857 toRename->iewInfo[tid].dispatched++; 858 859 insts[tid].pop(); 860 } 861} 862 863template <class Impl> 864void 865DefaultIEW<Impl>::wakeCPU() 866{ 867 cpu->wakeCPU(); 868} 869 870template <class Impl> 871void 872DefaultIEW<Impl>::activityThisCycle() 873{ 874 DPRINTF(Activity, "Activity this cycle.\n"); 875 cpu->activityThisCycle(); 876} 877 878template <class Impl> 879inline void 880DefaultIEW<Impl>::activateStage() 881{ 882 DPRINTF(Activity, "Activating stage.\n"); 883 cpu->activateStage(O3CPU::IEWIdx); 884} 885 886template <class Impl> 887inline void 888DefaultIEW<Impl>::deactivateStage() 889{ 890 DPRINTF(Activity, "Deactivating stage.\n"); 891 cpu->deactivateStage(O3CPU::IEWIdx); 892} 893 894template<class Impl> 895void 896DefaultIEW<Impl>::dispatch(unsigned tid) 897{ 898 // If status is Running or idle, 899 // call dispatchInsts() 900 // If status is Unblocking, 901 // buffer any instructions coming from rename 902 // continue trying to empty skid buffer 903 // check if stall conditions have passed 904 905 if (dispatchStatus[tid] == Blocked) { 906 ++iewBlockCycles; 907 908 } else if (dispatchStatus[tid] == Squashing) { 909 ++iewSquashCycles; 910 } 911 912 // Dispatch should try to dispatch as many instructions as its bandwidth 913 // will allow, as long as it is not currently blocked. 914 if (dispatchStatus[tid] == Running || 915 dispatchStatus[tid] == Idle) { 916 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run " 917 "dispatch.\n", tid); 918 919 dispatchInsts(tid); 920 } else if (dispatchStatus[tid] == Unblocking) { 921 // Make sure that the skid buffer has something in it if the 922 // status is unblocking. 923 assert(!skidsEmpty()); 924 925 // If the status was unblocking, then instructions from the skid 926 // buffer were used. Remove those instructions and handle 927 // the rest of unblocking. 928 dispatchInsts(tid); 929 930 ++iewUnblockCycles; 931 932 if (validInstsFromRename() && dispatchedAllInsts) { 933 // Add the current inputs to the skid buffer so they can be 934 // reprocessed when this stage unblocks. 935 skidInsert(tid); 936 } 937 938 unblock(tid); 939 } 940} 941 942template <class Impl> 943void 944DefaultIEW<Impl>::dispatchInsts(unsigned tid) 945{ 946 dispatchedAllInsts = true; 947 948 // Obtain instructions from skid buffer if unblocking, or queue from rename 949 // otherwise. 950 std::queue<DynInstPtr> &insts_to_dispatch = 951 dispatchStatus[tid] == Unblocking ? 952 skidBuffer[tid] : insts[tid]; 953 954 int insts_to_add = insts_to_dispatch.size(); 955 956 DynInstPtr inst; 957 bool add_to_iq = false; 958 int dis_num_inst = 0; 959 960 // Loop through the instructions, putting them in the instruction 961 // queue. 962 for ( ; dis_num_inst < insts_to_add && 963 dis_num_inst < dispatchWidth; 964 ++dis_num_inst) 965 { 966 inst = insts_to_dispatch.front(); 967 968 if (dispatchStatus[tid] == Unblocking) { 969 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid " 970 "buffer\n", tid); 971 } 972 973 // Make sure there's a valid instruction there. 974 assert(inst); 975 976 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to " 977 "IQ.\n", 978 tid, inst->readPC(), inst->seqNum, inst->threadNumber); 979 980 // Be sure to mark these instructions as ready so that the 981 // commit stage can go ahead and execute them, and mark 982 // them as issued so the IQ doesn't reprocess them. 983 984 // Check for squashed instructions. 985 if (inst->isSquashed()) { 986 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, " 987 "not adding to IQ.\n", tid); 988 989 ++iewDispSquashedInsts; 990 991 insts_to_dispatch.pop(); 992 993 //Tell Rename That An Instruction has been processed 994 if (inst->isLoad() || inst->isStore()) { 995 toRename->iewInfo[tid].dispatchedToLSQ++; 996 } 997 toRename->iewInfo[tid].dispatched++; 998 999 continue; 1000 } 1001 1002 // Check for full conditions. 1003 if (instQueue.isFull(tid)) { 1004 DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid); 1005 1006 // Call function to start blocking. 1007 block(tid); 1008 1009 // Set unblock to false. Special case where we are using 1010 // skidbuffer (unblocking) instructions but then we still 1011 // get full in the IQ. 1012 toRename->iewUnblock[tid] = false; 1013 1014 dispatchedAllInsts = false; 1015 1016 ++iewIQFullEvents; 1017 break; 1018 } else if (ldstQueue.isFull(tid)) { 1019 DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid); 1020 1021 // Call function to start blocking. 1022 block(tid); 1023 1024 // Set unblock to false. Special case where we are using 1025 // skidbuffer (unblocking) instructions but then we still 1026 // get full in the IQ. 1027 toRename->iewUnblock[tid] = false; 1028 1029 dispatchedAllInsts = false; 1030 1031 ++iewLSQFullEvents; 1032 break; 1033 } 1034 1035 // Otherwise issue the instruction just fine. 1036 if (inst->isLoad()) { 1037 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1038 "encountered, adding to LSQ.\n", tid); 1039 1040 // Reserve a spot in the load store queue for this 1041 // memory access. 1042 ldstQueue.insertLoad(inst); 1043 1044 ++iewDispLoadInsts; 1045 1046 add_to_iq = true; 1047 1048 toRename->iewInfo[tid].dispatchedToLSQ++; 1049 } else if (inst->isStore()) { 1050 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1051 "encountered, adding to LSQ.\n", tid); 1052 1053 ldstQueue.insertStore(inst); 1054 1055 ++iewDispStoreInsts; 1056 1057 if (inst->isStoreConditional()) { 1058 // Store conditionals need to be set as "canCommit()" 1059 // so that commit can process them when they reach the 1060 // head of commit. 1061 // @todo: This is somewhat specific to Alpha. 1062 inst->setCanCommit(); 1063 instQueue.insertNonSpec(inst); 1064 add_to_iq = false; 1065 1066 ++iewDispNonSpecInsts; 1067 } else { 1068 add_to_iq = true; 1069 } 1070 1071 toRename->iewInfo[tid].dispatchedToLSQ++; 1072 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 1073 // Same as non-speculative stores. 1074 inst->setCanCommit(); 1075 instQueue.insertBarrier(inst); 1076 add_to_iq = false; 1077 } else if (inst->isNop()) { 1078 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 1079 "skipping.\n", tid); 1080 1081 inst->setIssued(); 1082 inst->setExecuted(); 1083 inst->setCanCommit(); 1084 1085 instQueue.recordProducer(inst); 1086 1087 iewExecutedNop[tid]++; 1088 1089 add_to_iq = false; 1090 } else if (inst->isExecuted()) { 1091 assert(0 && "Instruction shouldn't be executed.\n"); 1092 DPRINTF(IEW, "Issue: Executed branch encountered, " 1093 "skipping.\n"); 1094 1095 inst->setIssued(); 1096 inst->setCanCommit(); 1097 1098 instQueue.recordProducer(inst); 1099 1100 add_to_iq = false; 1101 } else { 1102 add_to_iq = true; 1103 } 1104 if (inst->isNonSpeculative()) { 1105 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 1106 "encountered, skipping.\n", tid); 1107 1108 // Same as non-speculative stores. 1109 inst->setCanCommit(); 1110 1111 // Specifically insert it as nonspeculative. 1112 instQueue.insertNonSpec(inst); 1113 1114 ++iewDispNonSpecInsts; 1115 1116 add_to_iq = false; 1117 } 1118 1119 // If the instruction queue is not full, then add the 1120 // instruction. 1121 if (add_to_iq) { 1122 instQueue.insert(inst); 1123 } 1124 1125 insts_to_dispatch.pop(); 1126 1127 toRename->iewInfo[tid].dispatched++; 1128 1129 ++iewDispatchedInsts; 1130 } 1131 1132 if (!insts_to_dispatch.empty()) { 1133 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n", tid); 1134 block(tid); 1135 toRename->iewUnblock[tid] = false; 1136 } 1137 1138 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1139 dispatchStatus[tid] = Running; 1140 1141 updatedQueues = true; 1142 } 1143 1144 dis_num_inst = 0; 1145} 1146 1147template <class Impl> 1148void 1149DefaultIEW<Impl>::printAvailableInsts() 1150{ 1151 int inst = 0; 1152 1153 std::cout << "Available Instructions: "; 1154 1155 while (fromIssue->insts[inst]) { 1156 1157 if (inst%3==0) std::cout << "\n\t"; 1158 1159 std::cout << "PC: " << fromIssue->insts[inst]->readPC() 1160 << " TN: " << fromIssue->insts[inst]->threadNumber 1161 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1162 1163 inst++; 1164 1165 } 1166 1167 std::cout << "\n"; 1168} 1169 1170template <class Impl> 1171void 1172DefaultIEW<Impl>::executeInsts() 1173{ 1174 wbNumInst = 0; 1175 wbCycle = 0; 1176 1177 std::list<unsigned>::iterator threads = activeThreads->begin(); 1178 std::list<unsigned>::iterator end = activeThreads->end(); 1179 1180 while (threads != end) { 1181 unsigned tid = *threads++; 1182 fetchRedirect[tid] = false; 1183 } 1184 1185 // Uncomment this if you want to see all available instructions. 1186// printAvailableInsts(); 1187 1188 // Execute/writeback any instructions that are available. 1189 int insts_to_execute = fromIssue->size; 1190 int inst_num = 0; 1191 for (; inst_num < insts_to_execute; 1192 ++inst_num) { 1193 1194 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); 1195 1196 DynInstPtr inst = instQueue.getInstToExecute(); 1197 1198 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n", 1199 inst->readPC(), inst->threadNumber,inst->seqNum); 1200 1201 // Check if the instruction is squashed; if so then skip it 1202 if (inst->isSquashed()) { 1203 DPRINTF(IEW, "Execute: Instruction was squashed.\n"); 1204 1205 // Consider this instruction executed so that commit can go 1206 // ahead and retire the instruction. 1207 inst->setExecuted(); 1208 1209 // Not sure if I should set this here or just let commit try to 1210 // commit any squashed instructions. I like the latter a bit more. 1211 inst->setCanCommit(); 1212 1213 ++iewExecSquashedInsts; 1214 1215 decrWb(inst->seqNum); 1216 continue; 1217 } 1218 1219 Fault fault = NoFault; 1220 1221 // Execute instruction. 1222 // Note that if the instruction faults, it will be handled 1223 // at the commit stage. 1224 if (inst->isMemRef() && 1225 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) { 1226 DPRINTF(IEW, "Execute: Calculating address for memory " 1227 "reference.\n"); 1228 1229 // Tell the LDSTQ to execute this instruction (if it is a load). 1230 if (inst->isLoad()) { 1231 // Loads will mark themselves as executed, and their writeback 1232 // event adds the instruction to the queue to commit 1233 fault = ldstQueue.executeLoad(inst); 1234 } else if (inst->isStore()) { 1235 fault = ldstQueue.executeStore(inst); 1236 1237 // If the store had a fault then it may not have a mem req 1238 if (!inst->isStoreConditional() && fault == NoFault) { 1239 inst->setExecuted(); 1240 1241 instToCommit(inst); 1242 } else if (fault != NoFault) { 1243 // If the instruction faulted, then we need to send it along to commit 1244 // without the instruction completing. 1245 DPRINTF(IEW, "Store has fault %s! [sn:%lli]\n", 1246 fault->name(), inst->seqNum); 1247 1248 // Send this instruction to commit, also make sure iew stage 1249 // realizes there is activity. 1250 inst->setExecuted(); 1251 1252 instToCommit(inst); 1253 activityThisCycle(); 1254 } 1255 1256 // Store conditionals will mark themselves as 1257 // executed, and their writeback event will add the 1258 // instruction to the queue to commit. 1259 } else { 1260 panic("Unexpected memory type!\n"); 1261 } 1262 1263 } else { 1264 inst->execute(); 1265 1266 inst->setExecuted(); 1267 1268 instToCommit(inst); 1269 } 1270 1271 updateExeInstStats(inst); 1272 1273 // Check if branch prediction was correct, if not then we need 1274 // to tell commit to squash in flight instructions. Only 1275 // handle this if there hasn't already been something that 1276 // redirects fetch in this group of instructions. 1277 1278 // This probably needs to prioritize the redirects if a different 1279 // scheduler is used. Currently the scheduler schedules the oldest 1280 // instruction first, so the branch resolution order will be correct. 1281 unsigned tid = inst->threadNumber; 1282 1283 if (!fetchRedirect[tid] || 1284 toCommit->squashedSeqNum[tid] > inst->seqNum) { 1285 1286 if (inst->mispredicted()) { 1287 fetchRedirect[tid] = true; 1288 1289 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1290 DPRINTF(IEW, "Predicted target was %#x, %#x.\n", 1291 inst->readPredPC(), inst->readPredNPC()); 1292 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x," 1293 " NPC: %#x.\n", inst->readNextPC(), 1294 inst->readNextNPC()); 1295 // If incorrect, then signal the ROB that it must be squashed. 1296 squashDueToBranch(inst, tid); 1297 1298 if (inst->readPredTaken()) { 1299 predictedTakenIncorrect++; 1300 } else { 1301 predictedNotTakenIncorrect++; 1302 } 1303 } else if (ldstQueue.violation(tid)) { 1304 assert(inst->isMemRef()); 1305 // If there was an ordering violation, then get the 1306 // DynInst that caused the violation. Note that this 1307 // clears the violation signal. 1308 DynInstPtr violator; 1309 violator = ldstQueue.getMemDepViolator(tid); 1310 1311 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1312 "%#x, inst PC: %#x. Addr is: %#x.\n", 1313 violator->readPC(), inst->readPC(), inst->physEffAddr); 1314 1315 // Ensure the violating instruction is older than 1316 // current squash 1317/* if (fetchRedirect[tid] && 1318 violator->seqNum >= toCommit->squashedSeqNum[tid] + 1) 1319 continue; 1320*/ 1321 fetchRedirect[tid] = true; 1322 1323 // Tell the instruction queue that a violation has occured. 1324 instQueue.violation(inst, violator); 1325 1326 // Squash. 1327 squashDueToMemOrder(inst,tid); 1328 1329 ++memOrderViolationEvents; 1330 } else if (ldstQueue.loadBlocked(tid) && 1331 !ldstQueue.isLoadBlockedHandled(tid)) { 1332 fetchRedirect[tid] = true; 1333 1334 DPRINTF(IEW, "Load operation couldn't execute because the " 1335 "memory system is blocked. PC: %#x [sn:%lli]\n", 1336 inst->readPC(), inst->seqNum); 1337 1338 squashDueToMemBlocked(inst, tid); 1339 } 1340 } else { 1341 // Reset any state associated with redirects that will not 1342 // be used. 1343 if (ldstQueue.violation(tid)) { 1344 assert(inst->isMemRef()); 1345 1346 DynInstPtr violator = ldstQueue.getMemDepViolator(tid); 1347 1348 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1349 "%#x, inst PC: %#x. Addr is: %#x.\n", 1350 violator->readPC(), inst->readPC(), inst->physEffAddr); 1351 DPRINTF(IEW, "Violation will not be handled because " 1352 "already squashing\n"); 1353 1354 ++memOrderViolationEvents; 1355 } 1356 if (ldstQueue.loadBlocked(tid) && 1357 !ldstQueue.isLoadBlockedHandled(tid)) { 1358 DPRINTF(IEW, "Load operation couldn't execute because the " 1359 "memory system is blocked. PC: %#x [sn:%lli]\n", 1360 inst->readPC(), inst->seqNum); 1361 DPRINTF(IEW, "Blocked load will not be handled because " 1362 "already squashing\n"); 1363 1364 ldstQueue.setLoadBlockedHandled(tid); 1365 } 1366 1367 } 1368 } 1369 1370 // Update and record activity if we processed any instructions. 1371 if (inst_num) { 1372 if (exeStatus == Idle) { 1373 exeStatus = Running; 1374 } 1375 1376 updatedQueues = true; 1377 1378 cpu->activityThisCycle(); 1379 } 1380 1381 // Need to reset this in case a writeback event needs to write into the 1382 // iew queue. That way the writeback event will write into the correct 1383 // spot in the queue. 1384 wbNumInst = 0; 1385} 1386 1387template <class Impl> 1388void 1389DefaultIEW<Impl>::writebackInsts() 1390{ 1391 // Loop through the head of the time buffer and wake any 1392 // dependents. These instructions are about to write back. Also 1393 // mark scoreboard that this instruction is finally complete. 1394 // Either have IEW have direct access to scoreboard, or have this 1395 // as part of backwards communication. 1396 for (int inst_num = 0; inst_num < wbWidth && 1397 toCommit->insts[inst_num]; inst_num++) { 1398 DynInstPtr inst = toCommit->insts[inst_num]; 1399 int tid = inst->threadNumber; 1400 1401 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n", 1402 inst->seqNum, inst->readPC()); 1403 1404 iewInstsToCommit[tid]++; 1405 1406 // Some instructions will be sent to commit without having 1407 // executed because they need commit to handle them. 1408 // E.g. Uncached loads have not actually executed when they 1409 // are first sent to commit. Instead commit must tell the LSQ 1410 // when it's ready to execute the uncached load. 1411 if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) { 1412 int dependents = instQueue.wakeDependents(inst); 1413 1414 for (int i = 0; i < inst->numDestRegs(); i++) { 1415 //mark as Ready 1416 DPRINTF(IEW,"Setting Destination Register %i\n", 1417 inst->renamedDestRegIdx(i)); 1418 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1419 } 1420 1421 if (dependents) { 1422 producerInst[tid]++; 1423 consumerInst[tid]+= dependents; 1424 } 1425 writebackCount[tid]++; 1426 } 1427 1428 decrWb(inst->seqNum); 1429 } 1430} 1431 1432template<class Impl> 1433void 1434DefaultIEW<Impl>::tick() 1435{ 1436 wbNumInst = 0; 1437 wbCycle = 0; 1438 1439 wroteToTimeBuffer = false; 1440 updatedQueues = false; 1441 1442 sortInsts(); 1443 1444 // Free function units marked as being freed this cycle. 1445 fuPool->processFreeUnits(); 1446 1447 std::list<unsigned>::iterator threads = activeThreads->begin(); 1448 std::list<unsigned>::iterator end = activeThreads->end(); 1449 1450 // Check stall and squash signals, dispatch any instructions. 1451 while (threads != end) { 1452 unsigned tid = *threads++; 1453 1454 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1455 1456 checkSignalsAndUpdate(tid); 1457 dispatch(tid); 1458 } 1459 1460 if (exeStatus != Squashing) { 1461 executeInsts(); 1462 1463 writebackInsts(); 1464 1465 // Have the instruction queue try to schedule any ready instructions. 1466 // (In actuality, this scheduling is for instructions that will 1467 // be executed next cycle.) 1468 instQueue.scheduleReadyInsts(); 1469 1470 // Also should advance its own time buffers if the stage ran. 1471 // Not the best place for it, but this works (hopefully). 1472 issueToExecQueue.advance(); 1473 } 1474 1475 bool broadcast_free_entries = false; 1476 1477 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1478 exeStatus = Idle; 1479 updateLSQNextCycle = false; 1480 1481 broadcast_free_entries = true; 1482 } 1483 1484 // Writeback any stores using any leftover bandwidth. 1485 ldstQueue.writebackStores(); 1486 1487 // Check the committed load/store signals to see if there's a load 1488 // or store to commit. Also check if it's being told to execute a 1489 // nonspeculative instruction. 1490 // This is pretty inefficient... 1491 1492 threads = activeThreads->begin(); 1493 while (threads != end) { 1494 unsigned tid = (*threads++); 1495 1496 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1497 1498 // Update structures based on instructions committed. 1499 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1500 !fromCommit->commitInfo[tid].squash && 1501 !fromCommit->commitInfo[tid].robSquashing) { 1502 1503 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1504 1505 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1506 1507 updateLSQNextCycle = true; 1508 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1509 } 1510 1511 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1512 1513 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1514 if (fromCommit->commitInfo[tid].uncached) { 1515 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1516 fromCommit->commitInfo[tid].uncachedLoad->setAtCommit(); 1517 } else { 1518 instQueue.scheduleNonSpec( 1519 fromCommit->commitInfo[tid].nonSpecSeqNum); 1520 } 1521 } 1522 1523 if (broadcast_free_entries) { 1524 toFetch->iewInfo[tid].iqCount = 1525 instQueue.getCount(tid); 1526 toFetch->iewInfo[tid].ldstqCount = 1527 ldstQueue.getCount(tid); 1528 1529 toRename->iewInfo[tid].usedIQ = true; 1530 toRename->iewInfo[tid].freeIQEntries = 1531 instQueue.numFreeEntries(); 1532 toRename->iewInfo[tid].usedLSQ = true; 1533 toRename->iewInfo[tid].freeLSQEntries = 1534 ldstQueue.numFreeEntries(tid); 1535 1536 wroteToTimeBuffer = true; 1537 } 1538 1539 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1540 tid, toRename->iewInfo[tid].dispatched); 1541 } 1542 1543 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1544 "LSQ has %i free entries.\n", 1545 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1546 ldstQueue.numFreeEntries()); 1547 1548 updateStatus(); 1549 1550 if (wroteToTimeBuffer) { 1551 DPRINTF(Activity, "Activity this cycle.\n"); 1552 cpu->activityThisCycle(); 1553 } 1554} 1555 1556template <class Impl> 1557void 1558DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) 1559{ 1560 int thread_number = inst->threadNumber; 1561 1562 // 1563 // Pick off the software prefetches 1564 // 1565#ifdef TARGET_ALPHA 1566 if (inst->isDataPrefetch()) 1567 iewExecutedSwp[thread_number]++; 1568 else 1569 iewIewExecutedcutedInsts++; 1570#else 1571 iewExecutedInsts++; 1572#endif 1573 1574 // 1575 // Control operations 1576 // 1577 if (inst->isControl()) 1578 iewExecutedBranches[thread_number]++; 1579 1580 // 1581 // Memory operations 1582 // 1583 if (inst->isMemRef()) { 1584 iewExecutedRefs[thread_number]++; 1585 1586 if (inst->isLoad()) { 1587 iewExecLoadInsts[thread_number]++; 1588 } 1589 } 1590} 1591