iew_impl.hh revision 8240
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 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 = inst->pcState(); 489 TheISA::advancePC(pc, inst->staticInst); 490 toCommit->pc[tid] = pc; 491 toCommit->mispredictInst[tid] = NULL; 492 493 toCommit->includeSquashInst[tid] = false; 494 495 wroteToTimeBuffer = true; 496 } 497} 498 499template<class Impl> 500void 501DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid) 502{ 503 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 504 "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum); 505 if (toCommit->squash[tid] == false || 506 inst->seqNum < toCommit->squashedSeqNum[tid]) { 507 toCommit->squash[tid] = true; 508 509 toCommit->squashedSeqNum[tid] = inst->seqNum; 510 toCommit->pc[tid] = inst->pcState(); 511 toCommit->mispredictInst[tid] = NULL; 512 513 // Must include the broadcasted SN in the squash. 514 toCommit->includeSquashInst[tid] = true; 515 516 ldstQueue.setLoadBlockedHandled(tid); 517 518 wroteToTimeBuffer = true; 519 } 520} 521 522template<class Impl> 523void 524DefaultIEW<Impl>::block(ThreadID tid) 525{ 526 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 527 528 if (dispatchStatus[tid] != Blocked && 529 dispatchStatus[tid] != Unblocking) { 530 toRename->iewBlock[tid] = true; 531 wroteToTimeBuffer = true; 532 } 533 534 // Add the current inputs to the skid buffer so they can be 535 // reprocessed when this stage unblocks. 536 skidInsert(tid); 537 538 dispatchStatus[tid] = Blocked; 539} 540 541template<class Impl> 542void 543DefaultIEW<Impl>::unblock(ThreadID tid) 544{ 545 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 546 "buffer %u.\n",tid, tid); 547 548 // If the skid bufffer is empty, signal back to previous stages to unblock. 549 // Also switch status to running. 550 if (skidBuffer[tid].empty()) { 551 toRename->iewUnblock[tid] = true; 552 wroteToTimeBuffer = true; 553 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 554 dispatchStatus[tid] = Running; 555 } 556} 557 558template<class Impl> 559void 560DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 561{ 562 instQueue.wakeDependents(inst); 563} 564 565template<class Impl> 566void 567DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 568{ 569 instQueue.rescheduleMemInst(inst); 570} 571 572template<class Impl> 573void 574DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 575{ 576 instQueue.replayMemInst(inst); 577} 578 579template<class Impl> 580void 581DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 582{ 583 // This function should not be called after writebackInsts in a 584 // single cycle. That will cause problems with an instruction 585 // being added to the queue to commit without being processed by 586 // writebackInsts prior to being sent to commit. 587 588 // First check the time slot that this instruction will write 589 // to. If there are free write ports at the time, then go ahead 590 // and write the instruction to that time. If there are not, 591 // keep looking back to see where's the first time there's a 592 // free slot. 593 while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 594 ++wbNumInst; 595 if (wbNumInst == wbWidth) { 596 ++wbCycle; 597 wbNumInst = 0; 598 } 599 600 assert((wbCycle * wbWidth + wbNumInst) <= wbMax); 601 } 602 603 DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n", 604 wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst); 605 // Add finished instruction to queue to commit. 606 (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 607 (*iewQueue)[wbCycle].size++; 608} 609 610template <class Impl> 611unsigned 612DefaultIEW<Impl>::validInstsFromRename() 613{ 614 unsigned inst_count = 0; 615 616 for (int i=0; i<fromRename->size; i++) { 617 if (!fromRename->insts[i]->isSquashed()) 618 inst_count++; 619 } 620 621 return inst_count; 622} 623 624template<class Impl> 625void 626DefaultIEW<Impl>::skidInsert(ThreadID tid) 627{ 628 DynInstPtr inst = NULL; 629 630 while (!insts[tid].empty()) { 631 inst = insts[tid].front(); 632 633 insts[tid].pop(); 634 635 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%s into " 636 "dispatch skidBuffer %i\n",tid, inst->seqNum, 637 inst->pcState(),tid); 638 639 skidBuffer[tid].push(inst); 640 } 641 642 assert(skidBuffer[tid].size() <= skidBufferMax && 643 "Skidbuffer Exceeded Max Size"); 644} 645 646template<class Impl> 647int 648DefaultIEW<Impl>::skidCount() 649{ 650 int max=0; 651 652 list<ThreadID>::iterator threads = activeThreads->begin(); 653 list<ThreadID>::iterator end = activeThreads->end(); 654 655 while (threads != end) { 656 ThreadID tid = *threads++; 657 unsigned thread_count = skidBuffer[tid].size(); 658 if (max < thread_count) 659 max = thread_count; 660 } 661 662 return max; 663} 664 665template<class Impl> 666bool 667DefaultIEW<Impl>::skidsEmpty() 668{ 669 list<ThreadID>::iterator threads = activeThreads->begin(); 670 list<ThreadID>::iterator end = activeThreads->end(); 671 672 while (threads != end) { 673 ThreadID tid = *threads++; 674 675 if (!skidBuffer[tid].empty()) 676 return false; 677 } 678 679 return true; 680} 681 682template <class Impl> 683void 684DefaultIEW<Impl>::updateStatus() 685{ 686 bool any_unblocking = false; 687 688 list<ThreadID>::iterator threads = activeThreads->begin(); 689 list<ThreadID>::iterator end = activeThreads->end(); 690 691 while (threads != end) { 692 ThreadID tid = *threads++; 693 694 if (dispatchStatus[tid] == Unblocking) { 695 any_unblocking = true; 696 break; 697 } 698 } 699 700 // If there are no ready instructions waiting to be scheduled by the IQ, 701 // and there's no stores waiting to write back, and dispatch is not 702 // unblocking, then there is no internal activity for the IEW stage. 703 instQueue.intInstQueueReads++; 704 if (_status == Active && !instQueue.hasReadyInsts() && 705 !ldstQueue.willWB() && !any_unblocking) { 706 DPRINTF(IEW, "IEW switching to idle\n"); 707 708 deactivateStage(); 709 710 _status = Inactive; 711 } else if (_status == Inactive && (instQueue.hasReadyInsts() || 712 ldstQueue.willWB() || 713 any_unblocking)) { 714 // Otherwise there is internal activity. Set to active. 715 DPRINTF(IEW, "IEW switching to active\n"); 716 717 activateStage(); 718 719 _status = Active; 720 } 721} 722 723template <class Impl> 724void 725DefaultIEW<Impl>::resetEntries() 726{ 727 instQueue.resetEntries(); 728 ldstQueue.resetEntries(); 729} 730 731template <class Impl> 732void 733DefaultIEW<Impl>::readStallSignals(ThreadID tid) 734{ 735 if (fromCommit->commitBlock[tid]) { 736 stalls[tid].commit = true; 737 } 738 739 if (fromCommit->commitUnblock[tid]) { 740 assert(stalls[tid].commit); 741 stalls[tid].commit = false; 742 } 743} 744 745template <class Impl> 746bool 747DefaultIEW<Impl>::checkStall(ThreadID tid) 748{ 749 bool ret_val(false); 750 751 if (stalls[tid].commit) { 752 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 753 ret_val = true; 754 } else if (instQueue.isFull(tid)) { 755 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 756 ret_val = true; 757 } else if (ldstQueue.isFull(tid)) { 758 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 759 760 if (ldstQueue.numLoads(tid) > 0 ) { 761 762 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 763 tid,ldstQueue.getLoadHeadSeqNum(tid)); 764 } 765 766 if (ldstQueue.numStores(tid) > 0) { 767 768 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 769 tid,ldstQueue.getStoreHeadSeqNum(tid)); 770 } 771 772 ret_val = true; 773 } else if (ldstQueue.isStalled(tid)) { 774 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 775 ret_val = true; 776 } 777 778 return ret_val; 779} 780 781template <class Impl> 782void 783DefaultIEW<Impl>::checkSignalsAndUpdate(ThreadID tid) 784{ 785 // Check if there's a squash signal, squash if there is 786 // Check stall signals, block if there is. 787 // If status was Blocked 788 // if so then go to unblocking 789 // If status was Squashing 790 // check if squashing is not high. Switch to running this cycle. 791 792 readStallSignals(tid); 793 794 if (fromCommit->commitInfo[tid].squash) { 795 squash(tid); 796 797 if (dispatchStatus[tid] == Blocked || 798 dispatchStatus[tid] == Unblocking) { 799 toRename->iewUnblock[tid] = true; 800 wroteToTimeBuffer = true; 801 } 802 803 dispatchStatus[tid] = Squashing; 804 fetchRedirect[tid] = false; 805 return; 806 } 807 808 if (fromCommit->commitInfo[tid].robSquashing) { 809 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid); 810 811 dispatchStatus[tid] = Squashing; 812 emptyRenameInsts(tid); 813 wroteToTimeBuffer = true; 814 return; 815 } 816 817 if (checkStall(tid)) { 818 block(tid); 819 dispatchStatus[tid] = Blocked; 820 return; 821 } 822 823 if (dispatchStatus[tid] == Blocked) { 824 // Status from previous cycle was blocked, but there are no more stall 825 // conditions. Switch over to unblocking. 826 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 827 tid); 828 829 dispatchStatus[tid] = Unblocking; 830 831 unblock(tid); 832 833 return; 834 } 835 836 if (dispatchStatus[tid] == Squashing) { 837 // Switch status to running if rename isn't being told to block or 838 // squash this cycle. 839 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 840 tid); 841 842 dispatchStatus[tid] = Running; 843 844 return; 845 } 846} 847 848template <class Impl> 849void 850DefaultIEW<Impl>::sortInsts() 851{ 852 int insts_from_rename = fromRename->size; 853#ifdef DEBUG 854 for (ThreadID tid = 0; tid < numThreads; tid++) 855 assert(insts[tid].empty()); 856#endif 857 for (int i = 0; i < insts_from_rename; ++i) { 858 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 859 } 860} 861 862template <class Impl> 863void 864DefaultIEW<Impl>::emptyRenameInsts(ThreadID tid) 865{ 866 DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid); 867 868 while (!insts[tid].empty()) { 869 870 if (insts[tid].front()->isLoad() || 871 insts[tid].front()->isStore() ) { 872 toRename->iewInfo[tid].dispatchedToLSQ++; 873 } 874 875 toRename->iewInfo[tid].dispatched++; 876 877 insts[tid].pop(); 878 } 879} 880 881template <class Impl> 882void 883DefaultIEW<Impl>::wakeCPU() 884{ 885 cpu->wakeCPU(); 886} 887 888template <class Impl> 889void 890DefaultIEW<Impl>::activityThisCycle() 891{ 892 DPRINTF(Activity, "Activity this cycle.\n"); 893 cpu->activityThisCycle(); 894} 895 896template <class Impl> 897inline void 898DefaultIEW<Impl>::activateStage() 899{ 900 DPRINTF(Activity, "Activating stage.\n"); 901 cpu->activateStage(O3CPU::IEWIdx); 902} 903 904template <class Impl> 905inline void 906DefaultIEW<Impl>::deactivateStage() 907{ 908 DPRINTF(Activity, "Deactivating stage.\n"); 909 cpu->deactivateStage(O3CPU::IEWIdx); 910} 911 912template<class Impl> 913void 914DefaultIEW<Impl>::dispatch(ThreadID tid) 915{ 916 // If status is Running or idle, 917 // call dispatchInsts() 918 // If status is Unblocking, 919 // buffer any instructions coming from rename 920 // continue trying to empty skid buffer 921 // check if stall conditions have passed 922 923 if (dispatchStatus[tid] == Blocked) { 924 ++iewBlockCycles; 925 926 } else if (dispatchStatus[tid] == Squashing) { 927 ++iewSquashCycles; 928 } 929 930 // Dispatch should try to dispatch as many instructions as its bandwidth 931 // will allow, as long as it is not currently blocked. 932 if (dispatchStatus[tid] == Running || 933 dispatchStatus[tid] == Idle) { 934 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run " 935 "dispatch.\n", tid); 936 937 dispatchInsts(tid); 938 } else if (dispatchStatus[tid] == Unblocking) { 939 // Make sure that the skid buffer has something in it if the 940 // status is unblocking. 941 assert(!skidsEmpty()); 942 943 // If the status was unblocking, then instructions from the skid 944 // buffer were used. Remove those instructions and handle 945 // the rest of unblocking. 946 dispatchInsts(tid); 947 948 ++iewUnblockCycles; 949 950 if (validInstsFromRename()) { 951 // Add the current inputs to the skid buffer so they can be 952 // reprocessed when this stage unblocks. 953 skidInsert(tid); 954 } 955 956 unblock(tid); 957 } 958} 959 960template <class Impl> 961void 962DefaultIEW<Impl>::dispatchInsts(ThreadID tid) 963{ 964 // Obtain instructions from skid buffer if unblocking, or queue from rename 965 // otherwise. 966 std::queue<DynInstPtr> &insts_to_dispatch = 967 dispatchStatus[tid] == Unblocking ? 968 skidBuffer[tid] : insts[tid]; 969 970 int insts_to_add = insts_to_dispatch.size(); 971 972 DynInstPtr inst; 973 bool add_to_iq = false; 974 int dis_num_inst = 0; 975 976 // Loop through the instructions, putting them in the instruction 977 // queue. 978 for ( ; dis_num_inst < insts_to_add && 979 dis_num_inst < dispatchWidth; 980 ++dis_num_inst) 981 { 982 inst = insts_to_dispatch.front(); 983 984 if (dispatchStatus[tid] == Unblocking) { 985 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid " 986 "buffer\n", tid); 987 } 988 989 // Make sure there's a valid instruction there. 990 assert(inst); 991 992 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %s [sn:%lli] [tid:%i] to " 993 "IQ.\n", 994 tid, inst->pcState(), inst->seqNum, inst->threadNumber); 995 996 // Be sure to mark these instructions as ready so that the 997 // commit stage can go ahead and execute them, and mark 998 // them as issued so the IQ doesn't reprocess them. 999 1000 // Check for squashed instructions. 1001 if (inst->isSquashed()) { 1002 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, " 1003 "not adding to IQ.\n", tid); 1004 1005 ++iewDispSquashedInsts; 1006 1007 insts_to_dispatch.pop(); 1008 1009 //Tell Rename That An Instruction has been processed 1010 if (inst->isLoad() || inst->isStore()) { 1011 toRename->iewInfo[tid].dispatchedToLSQ++; 1012 } 1013 toRename->iewInfo[tid].dispatched++; 1014 1015 continue; 1016 } 1017 1018 // Check for full conditions. 1019 if (instQueue.isFull(tid)) { 1020 DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid); 1021 1022 // Call function to start blocking. 1023 block(tid); 1024 1025 // Set unblock to false. Special case where we are using 1026 // skidbuffer (unblocking) instructions but then we still 1027 // get full in the IQ. 1028 toRename->iewUnblock[tid] = false; 1029 1030 ++iewIQFullEvents; 1031 break; 1032 } else if (ldstQueue.isFull(tid)) { 1033 DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid); 1034 1035 // Call function to start blocking. 1036 block(tid); 1037 1038 // Set unblock to false. Special case where we are using 1039 // skidbuffer (unblocking) instructions but then we still 1040 // get full in the IQ. 1041 toRename->iewUnblock[tid] = false; 1042 1043 ++iewLSQFullEvents; 1044 break; 1045 } 1046 1047 // Otherwise issue the instruction just fine. 1048 if (inst->isLoad()) { 1049 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1050 "encountered, adding to LSQ.\n", tid); 1051 1052 // Reserve a spot in the load store queue for this 1053 // memory access. 1054 ldstQueue.insertLoad(inst); 1055 1056 ++iewDispLoadInsts; 1057 1058 add_to_iq = true; 1059 1060 toRename->iewInfo[tid].dispatchedToLSQ++; 1061 } else if (inst->isStore()) { 1062 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1063 "encountered, adding to LSQ.\n", tid); 1064 1065 ldstQueue.insertStore(inst); 1066 1067 ++iewDispStoreInsts; 1068 1069 if (inst->isStoreConditional()) { 1070 // Store conditionals need to be set as "canCommit()" 1071 // so that commit can process them when they reach the 1072 // head of commit. 1073 // @todo: This is somewhat specific to Alpha. 1074 inst->setCanCommit(); 1075 instQueue.insertNonSpec(inst); 1076 add_to_iq = false; 1077 1078 ++iewDispNonSpecInsts; 1079 } else { 1080 add_to_iq = true; 1081 } 1082 1083 toRename->iewInfo[tid].dispatchedToLSQ++; 1084 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 1085 // Same as non-speculative stores. 1086 inst->setCanCommit(); 1087 instQueue.insertBarrier(inst); 1088 add_to_iq = false; 1089 } else if (inst->isNop()) { 1090 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 1091 "skipping.\n", tid); 1092 1093 inst->setIssued(); 1094 inst->setExecuted(); 1095 inst->setCanCommit(); 1096 1097 instQueue.recordProducer(inst); 1098 1099 iewExecutedNop[tid]++; 1100 1101 add_to_iq = false; 1102 } else if (inst->isExecuted()) { 1103 assert(0 && "Instruction shouldn't be executed.\n"); 1104 DPRINTF(IEW, "Issue: Executed branch encountered, " 1105 "skipping.\n"); 1106 1107 inst->setIssued(); 1108 inst->setCanCommit(); 1109 1110 instQueue.recordProducer(inst); 1111 1112 add_to_iq = false; 1113 } else { 1114 add_to_iq = true; 1115 } 1116 if (inst->isNonSpeculative()) { 1117 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 1118 "encountered, skipping.\n", tid); 1119 1120 // Same as non-speculative stores. 1121 inst->setCanCommit(); 1122 1123 // Specifically insert it as nonspeculative. 1124 instQueue.insertNonSpec(inst); 1125 1126 ++iewDispNonSpecInsts; 1127 1128 add_to_iq = false; 1129 } 1130 1131 // If the instruction queue is not full, then add the 1132 // instruction. 1133 if (add_to_iq) { 1134 instQueue.insert(inst); 1135 } 1136 1137 insts_to_dispatch.pop(); 1138 1139 toRename->iewInfo[tid].dispatched++; 1140 1141 ++iewDispatchedInsts; 1142 } 1143 1144 if (!insts_to_dispatch.empty()) { 1145 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n", tid); 1146 block(tid); 1147 toRename->iewUnblock[tid] = false; 1148 } 1149 1150 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1151 dispatchStatus[tid] = Running; 1152 1153 updatedQueues = true; 1154 } 1155 1156 dis_num_inst = 0; 1157} 1158 1159template <class Impl> 1160void 1161DefaultIEW<Impl>::printAvailableInsts() 1162{ 1163 int inst = 0; 1164 1165 std::cout << "Available Instructions: "; 1166 1167 while (fromIssue->insts[inst]) { 1168 1169 if (inst%3==0) std::cout << "\n\t"; 1170 1171 std::cout << "PC: " << fromIssue->insts[inst]->pcState() 1172 << " TN: " << fromIssue->insts[inst]->threadNumber 1173 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1174 1175 inst++; 1176 1177 } 1178 1179 std::cout << "\n"; 1180} 1181 1182template <class Impl> 1183void 1184DefaultIEW<Impl>::executeInsts() 1185{ 1186 wbNumInst = 0; 1187 wbCycle = 0; 1188 1189 list<ThreadID>::iterator threads = activeThreads->begin(); 1190 list<ThreadID>::iterator end = activeThreads->end(); 1191 1192 while (threads != end) { 1193 ThreadID tid = *threads++; 1194 fetchRedirect[tid] = false; 1195 } 1196 1197 // Uncomment this if you want to see all available instructions. 1198 // @todo This doesn't actually work anymore, we should fix it. 1199// printAvailableInsts(); 1200 1201 // Execute/writeback any instructions that are available. 1202 int insts_to_execute = fromIssue->size; 1203 int inst_num = 0; 1204 for (; inst_num < insts_to_execute; 1205 ++inst_num) { 1206 1207 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); 1208 1209 DynInstPtr inst = instQueue.getInstToExecute(); 1210 1211 DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%i].\n", 1212 inst->pcState(), inst->threadNumber,inst->seqNum); 1213 1214 // Check if the instruction is squashed; if so then skip it 1215 if (inst->isSquashed()) { 1216 DPRINTF(IEW, "Execute: Instruction was squashed.\n"); 1217 1218 // Consider this instruction executed so that commit can go 1219 // ahead and retire the instruction. 1220 inst->setExecuted(); 1221 1222 // Not sure if I should set this here or just let commit try to 1223 // commit any squashed instructions. I like the latter a bit more. 1224 inst->setCanCommit(); 1225 1226 ++iewExecSquashedInsts; 1227 1228 decrWb(inst->seqNum); 1229 continue; 1230 } 1231 1232 Fault fault = NoFault; 1233 1234 // Execute instruction. 1235 // Note that if the instruction faults, it will be handled 1236 // at the commit stage. 1237 if (inst->isMemRef()) { 1238 DPRINTF(IEW, "Execute: Calculating address for memory " 1239 "reference.\n"); 1240 1241 // Tell the LDSTQ to execute this instruction (if it is a load). 1242 if (inst->isLoad()) { 1243 // Loads will mark themselves as executed, and their writeback 1244 // event adds the instruction to the queue to commit 1245 fault = ldstQueue.executeLoad(inst); 1246 1247 if (inst->isTranslationDelayed() && 1248 fault == NoFault) { 1249 // A hw page table walk is currently going on; the 1250 // instruction must be deferred. 1251 DPRINTF(IEW, "Execute: Delayed translation, deferring " 1252 "load.\n"); 1253 instQueue.deferMemInst(inst); 1254 continue; 1255 } 1256 1257 if (inst->isDataPrefetch() || inst->isInstPrefetch()) { 1258 inst->fault = NoFault; 1259 } 1260 } else if (inst->isStore()) { 1261 fault = ldstQueue.executeStore(inst); 1262 1263 if (inst->isTranslationDelayed() && 1264 fault == NoFault) { 1265 // A hw page table walk is currently going on; the 1266 // instruction must be deferred. 1267 DPRINTF(IEW, "Execute: Delayed translation, deferring " 1268 "store.\n"); 1269 instQueue.deferMemInst(inst); 1270 continue; 1271 } 1272 1273 // If the store had a fault then it may not have a mem req 1274 if (fault != NoFault || inst->readPredicate() == false || 1275 !inst->isStoreConditional()) { 1276 // If the instruction faulted, then we need to send it along 1277 // to commit without the instruction completing. 1278 // Send this instruction to commit, also make sure iew stage 1279 // realizes there is activity. 1280 inst->setExecuted(); 1281 instToCommit(inst); 1282 activityThisCycle(); 1283 } 1284 1285 // Store conditionals will mark themselves as 1286 // executed, and their writeback event will add the 1287 // instruction to the queue to commit. 1288 } else { 1289 panic("Unexpected memory type!\n"); 1290 } 1291 1292 } else { 1293 // If the instruction has already faulted, then skip executing it. 1294 // Such case can happen when it faulted during ITLB translation. 1295 // If we execute the instruction (even if it's a nop) the fault 1296 // will be replaced and we will lose it. 1297 if (inst->getFault() == NoFault) { 1298 inst->execute(); 1299 if (inst->readPredicate() == false) 1300 inst->forwardOldRegs(); 1301 } 1302 1303 inst->setExecuted(); 1304 1305 instToCommit(inst); 1306 } 1307 1308 updateExeInstStats(inst); 1309 1310 // Check if branch prediction was correct, if not then we need 1311 // to tell commit to squash in flight instructions. Only 1312 // handle this if there hasn't already been something that 1313 // redirects fetch in this group of instructions. 1314 1315 // This probably needs to prioritize the redirects if a different 1316 // scheduler is used. Currently the scheduler schedules the oldest 1317 // instruction first, so the branch resolution order will be correct. 1318 ThreadID tid = inst->threadNumber; 1319 1320 if (!fetchRedirect[tid] || 1321 !toCommit->squash[tid] || 1322 toCommit->squashedSeqNum[tid] > inst->seqNum) { 1323 1324 // Prevent testing for misprediction on load instructions, 1325 // that have not been executed. 1326 bool loadNotExecuted = !inst->isExecuted() && inst->isLoad(); 1327 1328 if (inst->mispredicted() && !loadNotExecuted) { 1329 fetchRedirect[tid] = true; 1330 1331 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1332 DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n", 1333 inst->predInstAddr(), inst->predNextInstAddr()); 1334 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %s.\n", 1335 inst->pcState(), inst->nextInstAddr()); 1336 // If incorrect, then signal the ROB that it must be squashed. 1337 squashDueToBranch(inst, tid); 1338 1339 if (inst->readPredTaken()) { 1340 predictedTakenIncorrect++; 1341 } else { 1342 predictedNotTakenIncorrect++; 1343 } 1344 } else if (ldstQueue.violation(tid)) { 1345 assert(inst->isMemRef()); 1346 // If there was an ordering violation, then get the 1347 // DynInst that caused the violation. Note that this 1348 // clears the violation signal. 1349 DynInstPtr violator; 1350 violator = ldstQueue.getMemDepViolator(tid); 1351 1352 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s " 1353 "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n", 1354 violator->pcState(), violator->seqNum, 1355 inst->pcState(), inst->seqNum, inst->physEffAddr); 1356 1357 fetchRedirect[tid] = true; 1358 1359 // Tell the instruction queue that a violation has occured. 1360 instQueue.violation(inst, violator); 1361 1362 // Squash. 1363 squashDueToMemOrder(inst,tid); 1364 1365 ++memOrderViolationEvents; 1366 } else if (ldstQueue.loadBlocked(tid) && 1367 !ldstQueue.isLoadBlockedHandled(tid)) { 1368 fetchRedirect[tid] = true; 1369 1370 DPRINTF(IEW, "Load operation couldn't execute because the " 1371 "memory system is blocked. PC: %s [sn:%lli]\n", 1372 inst->pcState(), inst->seqNum); 1373 1374 squashDueToMemBlocked(inst, tid); 1375 } 1376 } else { 1377 // Reset any state associated with redirects that will not 1378 // be used. 1379 if (ldstQueue.violation(tid)) { 1380 assert(inst->isMemRef()); 1381 1382 DynInstPtr violator = ldstQueue.getMemDepViolator(tid); 1383 1384 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1385 "%s, inst PC: %s. Addr is: %#x.\n", 1386 violator->pcState(), inst->pcState(), 1387 inst->physEffAddr); 1388 DPRINTF(IEW, "Violation will not be handled because " 1389 "already squashing\n"); 1390 1391 ++memOrderViolationEvents; 1392 } 1393 if (ldstQueue.loadBlocked(tid) && 1394 !ldstQueue.isLoadBlockedHandled(tid)) { 1395 DPRINTF(IEW, "Load operation couldn't execute because the " 1396 "memory system is blocked. PC: %s [sn:%lli]\n", 1397 inst->pcState(), inst->seqNum); 1398 DPRINTF(IEW, "Blocked load will not be handled because " 1399 "already squashing\n"); 1400 1401 ldstQueue.setLoadBlockedHandled(tid); 1402 } 1403 1404 } 1405 } 1406 1407 // Update and record activity if we processed any instructions. 1408 if (inst_num) { 1409 if (exeStatus == Idle) { 1410 exeStatus = Running; 1411 } 1412 1413 updatedQueues = true; 1414 1415 cpu->activityThisCycle(); 1416 } 1417 1418 // Need to reset this in case a writeback event needs to write into the 1419 // iew queue. That way the writeback event will write into the correct 1420 // spot in the queue. 1421 wbNumInst = 0; 1422 1423} 1424 1425template <class Impl> 1426void 1427DefaultIEW<Impl>::writebackInsts() 1428{ 1429 // Loop through the head of the time buffer and wake any 1430 // dependents. These instructions are about to write back. Also 1431 // mark scoreboard that this instruction is finally complete. 1432 // Either have IEW have direct access to scoreboard, or have this 1433 // as part of backwards communication. 1434 for (int inst_num = 0; inst_num < wbWidth && 1435 toCommit->insts[inst_num]; inst_num++) { 1436 DynInstPtr inst = toCommit->insts[inst_num]; 1437 ThreadID tid = inst->threadNumber; 1438 1439 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %s.\n", 1440 inst->seqNum, inst->pcState()); 1441 1442 iewInstsToCommit[tid]++; 1443 1444 // Some instructions will be sent to commit without having 1445 // executed because they need commit to handle them. 1446 // E.g. Uncached loads have not actually executed when they 1447 // are first sent to commit. Instead commit must tell the LSQ 1448 // when it's ready to execute the uncached load. 1449 if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) { 1450 int dependents = instQueue.wakeDependents(inst); 1451 1452 for (int i = 0; i < inst->numDestRegs(); i++) { 1453 //mark as Ready 1454 DPRINTF(IEW,"Setting Destination Register %i\n", 1455 inst->renamedDestRegIdx(i)); 1456 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1457 } 1458 1459 if (dependents) { 1460 producerInst[tid]++; 1461 consumerInst[tid]+= dependents; 1462 } 1463 writebackCount[tid]++; 1464 } 1465 1466 decrWb(inst->seqNum); 1467 } 1468} 1469 1470template<class Impl> 1471void 1472DefaultIEW<Impl>::tick() 1473{ 1474 wbNumInst = 0; 1475 wbCycle = 0; 1476 1477 wroteToTimeBuffer = false; 1478 updatedQueues = false; 1479 1480 sortInsts(); 1481 1482 // Free function units marked as being freed this cycle. 1483 fuPool->processFreeUnits(); 1484 1485 list<ThreadID>::iterator threads = activeThreads->begin(); 1486 list<ThreadID>::iterator end = activeThreads->end(); 1487 1488 // Check stall and squash signals, dispatch any instructions. 1489 while (threads != end) { 1490 ThreadID tid = *threads++; 1491 1492 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1493 1494 checkSignalsAndUpdate(tid); 1495 dispatch(tid); 1496 } 1497 1498 if (exeStatus != Squashing) { 1499 executeInsts(); 1500 1501 writebackInsts(); 1502 1503 // Have the instruction queue try to schedule any ready instructions. 1504 // (In actuality, this scheduling is for instructions that will 1505 // be executed next cycle.) 1506 instQueue.scheduleReadyInsts(); 1507 1508 // Also should advance its own time buffers if the stage ran. 1509 // Not the best place for it, but this works (hopefully). 1510 issueToExecQueue.advance(); 1511 } 1512 1513 bool broadcast_free_entries = false; 1514 1515 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1516 exeStatus = Idle; 1517 updateLSQNextCycle = false; 1518 1519 broadcast_free_entries = true; 1520 } 1521 1522 // Writeback any stores using any leftover bandwidth. 1523 ldstQueue.writebackStores(); 1524 1525 // Check the committed load/store signals to see if there's a load 1526 // or store to commit. Also check if it's being told to execute a 1527 // nonspeculative instruction. 1528 // This is pretty inefficient... 1529 1530 threads = activeThreads->begin(); 1531 while (threads != end) { 1532 ThreadID tid = (*threads++); 1533 1534 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1535 1536 // Update structures based on instructions committed. 1537 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1538 !fromCommit->commitInfo[tid].squash && 1539 !fromCommit->commitInfo[tid].robSquashing) { 1540 1541 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1542 1543 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1544 1545 updateLSQNextCycle = true; 1546 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1547 } 1548 1549 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1550 1551 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1552 if (fromCommit->commitInfo[tid].uncached) { 1553 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1554 fromCommit->commitInfo[tid].uncachedLoad->setAtCommit(); 1555 } else { 1556 instQueue.scheduleNonSpec( 1557 fromCommit->commitInfo[tid].nonSpecSeqNum); 1558 } 1559 } 1560 1561 if (broadcast_free_entries) { 1562 toFetch->iewInfo[tid].iqCount = 1563 instQueue.getCount(tid); 1564 toFetch->iewInfo[tid].ldstqCount = 1565 ldstQueue.getCount(tid); 1566 1567 toRename->iewInfo[tid].usedIQ = true; 1568 toRename->iewInfo[tid].freeIQEntries = 1569 instQueue.numFreeEntries(); 1570 toRename->iewInfo[tid].usedLSQ = true; 1571 toRename->iewInfo[tid].freeLSQEntries = 1572 ldstQueue.numFreeEntries(tid); 1573 1574 wroteToTimeBuffer = true; 1575 } 1576 1577 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1578 tid, toRename->iewInfo[tid].dispatched); 1579 } 1580 1581 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1582 "LSQ has %i free entries.\n", 1583 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1584 ldstQueue.numFreeEntries()); 1585 1586 updateStatus(); 1587 1588 if (wroteToTimeBuffer) { 1589 DPRINTF(Activity, "Activity this cycle.\n"); 1590 cpu->activityThisCycle(); 1591 } 1592} 1593 1594template <class Impl> 1595void 1596DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) 1597{ 1598 ThreadID tid = inst->threadNumber; 1599 1600 // 1601 // Pick off the software prefetches 1602 // 1603#ifdef TARGET_ALPHA 1604 if (inst->isDataPrefetch()) 1605 iewExecutedSwp[tid]++; 1606 else 1607 iewIewExecutedcutedInsts++; 1608#else 1609 iewExecutedInsts++; 1610#endif 1611 1612 // 1613 // Control operations 1614 // 1615 if (inst->isControl()) 1616 iewExecutedBranches[tid]++; 1617 1618 // 1619 // Memory operations 1620 // 1621 if (inst->isMemRef()) { 1622 iewExecutedRefs[tid]++; 1623 1624 if (inst->isLoad()) { 1625 iewExecLoadInsts[tid]++; 1626 } 1627 } 1628} 1629 1630template <class Impl> 1631void 1632DefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst) 1633{ 1634 ThreadID tid = inst->threadNumber; 1635 1636 if (!fetchRedirect[tid] || 1637 !toCommit->squash[tid] || 1638 toCommit->squashedSeqNum[tid] > inst->seqNum) { 1639 1640 if (inst->mispredicted()) { 1641 fetchRedirect[tid] = true; 1642 1643 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1644 DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n", 1645 inst->predInstAddr(), inst->predNextInstAddr()); 1646 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x," 1647 " NPC: %#x.\n", inst->nextInstAddr(), 1648 inst->nextInstAddr()); 1649 // If incorrect, then signal the ROB that it must be squashed. 1650 squashDueToBranch(inst, tid); 1651 1652 if (inst->readPredTaken()) { 1653 predictedTakenIncorrect++; 1654 } else { 1655 predictedNotTakenIncorrect++; 1656 } 1657 } 1658 } 1659} 1660