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