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