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