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