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